ATLAS Offline Software
SingleWedgePadTrigger.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 #include <algorithm>
9 #include <cassert>
10 #include <cmath>
11 #include <iostream>
12 #include <sstream>
13 
14 namespace NSWL1{
15 
16  bool sortByLayer(const std::shared_ptr<PadOfflineData> &p0, const std::shared_ptr<PadOfflineData>& p1) {
17  return p0->gasGapId()<p1->gasGapId();
18  }
20  const std::vector<std::shared_ptr<PadOfflineData>> &pads,
21  const std::vector<size_t> &padIndices) :
22  m_pattern(pattern), m_halfPadIndices(-999,-999), m_padIndices(padIndices),m_alreadyCombined(false){
23  assert(m_padIndices.size()>0); // a trigger without pads doesn't make sense
24  for(size_t i=0; i<padIndices.size(); ++i) m_pads.push_back(pads[padIndices[i]]);
25  std::sort(m_pads.begin(), m_pads.end(), sortByLayer);
27  }
28 
29  std::string SingleWedgePadTrigger::EtaPhi::str() const {
30  std::ostringstream oss;
31  oss<<"("<<ieta<<", "<<iphi<<")";
32  return oss.str();
33  }
34 
36  const std::vector<std::shared_ptr<PadOfflineData>> &pads = m_pads;
37 
38  const auto &pad0=pads[0], &pad1=pads[1], &pad2=pads[2];
39  int l0(pad0->gasGapId()), l1(pad1->gasGapId()), l2(pad2->gasGapId());
40 
41  bool missLast (l0==STGC_LAYER_1 && l1==STGC_LAYER_2);
42  bool missMiddle(l0==STGC_LAYER_1 && l2==STGC_LAYER_4);
43  bool missFirst (l0==STGC_LAYER_2 && l1==STGC_LAYER_3);
44 
45  //YR: the following is wrong but we keep it for phi as it isn't used much - for eta we use the simple calculation that follows.
46  EtaPhiHalf pos(-999,-999);
47  EtaPhi posA(-999,-999), posB(-999,-999);
48  if(missLast) {
49  posA = EtaPhi(pad0->padEtaId(), pad0->padPhiId());
50  posB = EtaPhi(pad1->padEtaId(), pad1->padPhiId());
51  }
52  else if(missMiddle) {
53  posA = EtaPhi(pad0->padEtaId(), pad0->padPhiId());
54  posB = EtaPhi(pad2->padEtaId(), pad2->padPhiId());
55  }
56  else if (missFirst) {
57  posA = EtaPhi(pad1->padEtaId(), pad1->padPhiId());
58  posB = EtaPhi(pad0->padEtaId(), pad0->padPhiId());
59  }
60  //S.I : else ??? :D
61 
62  pos.ieta = ((posA.ieta==posB.ieta) ? (posA.ieta * 2) : (posA.ieta * 2 + 1));
63  pos.iphi = ((posA.iphi==posB.iphi) ? (posA.iphi * 2) : (posA.iphi * 2 + 1));
64  //S.I Shouldnt it be pad0.ieta+pad1.ieta ??? SI 13-06-2018
65  pos.ieta = pad0->padEtaId()+pad2->padEtaId() -1; //YR 1-5-2018 any of the first two layers define the 2-bandids and any of the last two layers select the bandid from that pair
66  //YR Module specific corrections:
67  if(pad0->sectorType()==1 && pad0->moduleId()==1) pos.ieta +=1;
68  if(pad0->sectorType()==0 && pad0->moduleId()!=1) pos.ieta +=1;
69  return pos;
70  }
71 
73  const std::shared_ptr<PadOfflineData> &firstPad = m_pads[0];
74  bool isEven = (firstPad->sectorType())==0;
75  return isEven;
76  }
77 
78 
79 
80  bool SingleWedgePadTrigger::isInTransitionRegion(const std::pair<double,double>& Zratio) const{
81  Polygon ROI=padOverlap3(this->pads());
82  if(area(ROI)==0) return false;
83  float phi0=m_pads[0]->sectorType()==1 ? (M_PI/4)*(m_pads[0]->sectorId()-1) : (M_PI/8)+(M_PI/4)*(m_pads[0]->sectorId()-1);
84  if(phi0>M_PI) phi0-=2*M_PI;
85  float ROIx=centroid(ROI).x();
86  float ROIy=centroid(ROI).y(); //YR 8-18 using the center local Y of the ROI for the decision if in the TR
87 
88  auto vector = ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<float>>(ROIx,ROIy);
89  float ROILocalY=(vector.R())*std::cos(std::abs(vector.Phi()-phi0));
90 
91  bool isTr=false;
92  float TransitonSmall[7] ={2104,2243,3248,3445,4216,4411,ROILocalY}; // YR should be taken from the XML (H1 active_max, H2 active min... projected from 7 to 1)
93  float TransitonLarge[7] ={2144,2278,3294,3483,4406,4596,ROILocalY};
94  if(m_pads[0]->multipletId()==2){
95  for(int i= 0; i<6; i++){
96  TransitonSmall[i] = TransitonSmall[i]*Zratio.second; //Z5/Z1 ratio
97  TransitonLarge[i] = TransitonLarge[i]*Zratio.first;
98  }
99  }
100 
101  if(isSmallSector()){
102  std::sort(TransitonSmall, TransitonSmall + 7);
103  if(TransitonSmall[1]==ROILocalY || TransitonSmall[3]==ROILocalY || TransitonSmall[5]==ROILocalY) return true;
104  }
105  else{
106  std::sort(TransitonLarge, TransitonLarge + 7);
107  if(TransitonLarge[1]==ROILocalY || TransitonLarge[3]==ROILocalY || TransitonLarge[5]==ROILocalY) return true;
108  }
109  return isTr;
110 }
111 
112  //S.I 3
113  Polygon SingleWedgePadTrigger::padOverlap3(const std::vector<std::shared_ptr<PadOfflineData>> &pads){ // \todo some duplication with halfPadCoordinates()...refactor
114  size_t nPads(pads.size());
115  bool haveEnoughPads(nPads>2);
116  if(not haveEnoughPads){
117  std::cerr<<"SingleWedgePadTrigger::halfPadCoordinates: need at least 3 pads"<<std::endl;
118  }
119  assert(haveEnoughPads);
120  const std::shared_ptr<PadOfflineData> &pad0=pads[0], &pad1=pads[1], &pad2=pads[2];
121  int l0(pad0->gasGapId()), l1(pad1->gasGapId()), l2(pad2->gasGapId()); // DG: Are we assuming that the pad indices are sorted? this assumption might not be always valid
122  // identify the two staggered pads (see parameter book)
123  bool hasL1L2(l0==STGC_LAYER_1 && l1==STGC_LAYER_2); // also includes 4 out of 4.
124  bool hasL1L4(l0==STGC_LAYER_1 && l2==STGC_LAYER_4);
125  bool hasL2L3(l0==STGC_LAYER_2 && l1==STGC_LAYER_3);
126  bool validLayerCombination(hasL1L2 || hasL1L4 || hasL2L3);
127  //S.I if buggy combination so ??
128  //if(!validLayerCombination) cout<<"buggy layer combination? layers: "<<l0<<","<<l1<<","<<l2<<endl;
129  assert(validLayerCombination); // probably got a pattern we don't know how to interpret
130  (void) validLayerCombination;//not o.k
131 
132  //make a vector of pad etaphi polygons
133  //calculate the intersection and return it
134  std::vector<Polygon> projected_pads;
135  //one pad --> one polygon
136  //S.I VERY IMPORTANT : A polygon is an ordered set of vertices. So order matters !
137  //According to the previous experience (our drawing tool) vertices are connected in the order :
138  //Do not play with the order array 0132.
139  constexpr std::array<int,4> vertexordering={0,1,3,2};
140  //project each pad polygon onto the first plane of the wedge
141  float Zproj=pads[0]->m_cornerXyz[1][2];//second index x:0 y:1 z:2
142  for(const auto& pad : pads){
143  Vertices vts;
144  for(unsigned int i=0;i<4;i++){
145  int icorner=vertexordering[i];
146  float x=pad->m_cornerXyz[icorner][0];
147  float y=pad->m_cornerXyz[icorner][1];
148  vts.push_back(Vertex(x,y));
149  }
150  Polygon padPolygon=buildPolygon(vts);
151  projected_pads.push_back(Project(padPolygon,pad->m_cornerXyz[2][2],Zproj));
152  }
153  Polygon res=intersectionRegion(projected_pads);
154  return res;
155  }
156  //eof S.I
157 
159  // ASM-2016-10-4 : Figure out the logic behind this, the staggering changed now relaxing this a bit
160  //S.I : Relaxing? what is "this"?
161  // bool mismatchEta(outer.ieta < inner.ieta || outer.ieta > inner.ieta + 1);
162  // bool mismatchPhi(outer.iphi < inner.iphi || outer.iphi > inner.iphi + 1);
163  bool mismatchEta(outer.ieta < inner.ieta - 4 || outer.ieta > inner.ieta + 4);
164  bool mismatchPhi(outer.iphi < inner.iphi - 4 || outer.iphi > inner.iphi + 4);
165  bool mismatch(mismatchEta || mismatchPhi);
166  return !mismatch;
167  }
168 
170  // DG check that we should actually multiply *2 twice (it seems to be the case in the 1st implem)
171  bool sameEta(inner.ieta == outer.ieta), samePhi(inner.iphi == outer.iphi);
172  return EtaPhiHalf((sameEta ? inner.ieta * 2 : inner.ieta * 2 + 1),
173  (samePhi ? inner.iphi * 2 : inner.iphi * 2 + 1));
174  }
175 }
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
NSWL1::SingleWedgePadTrigger::m_pads
std::vector< std::shared_ptr< PadOfflineData > > m_pads
Definition: SingleWedgePadTrigger.h:77
tdr_compat_enum.h
NSWL1::SingleWedgePadTrigger::m_padIndices
std::vector< size_t > m_padIndices
Definition: SingleWedgePadTrigger.h:76
NSWL1::Vertex
boost::geometry::model::d2::point_xy< double > Vertex
Definition: GeoUtils.h:17
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
NSWL1::SingleWedgePadTrigger::isInTransitionRegion
bool isInTransitionRegion(const std::pair< double, double > &Zratio) const
determine whether we are in the transition region
Definition: SingleWedgePadTrigger.cxx:80
NSWL1::STGC_LAYER_3
const int STGC_LAYER_3
Definition: tdr_compat_enum.h:14
NSWL1::Polygon
boost::geometry::model::polygon< Vertex > Polygon
Definition: GeoUtils.h:18
M_PI
#define M_PI
Definition: ActiveFraction.h:11
NSWL1::SingleWedgePadTrigger::isSmallSector
bool isSmallSector() const
use the first pad to determine whether it's a small/large sector
Definition: SingleWedgePadTrigger.cxx:72
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
NSWL1::Project
Polygon Project(const Polygon &p, float Zinit, float Zfin)
Definition: GeoUtils.cxx:19
x
#define x
NSWL1::SingleWedgePadTrigger::EtaPhiHalf
Definition: SingleWedgePadTrigger.h:37
NSWL1::area
float area(const Polygon &p)
Definition: GeoUtils.cxx:55
skel.l2
l2
Definition: skel.GENtoEVGEN.py:426
NSWL1::SingleWedgePadTrigger::EtaPhi::ieta
int ieta
Definition: SingleWedgePadTrigger.h:32
lumiFormat.i
int i
Definition: lumiFormat.py:92
NSWL1::STGC_LAYER_4
const int STGC_LAYER_4
Definition: tdr_compat_enum.h:14
vector
Definition: MultiHisto.h:13
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
NSWL1::SingleWedgePadTrigger::EtaPhi
Definition: SingleWedgePadTrigger.h:31
NSWL1::SingleWedgePadTrigger::bandIndices
static EtaPhiHalf bandIndices(const EtaPhiHalf &inner, const EtaPhiHalf &outer)
Definition: SingleWedgePadTrigger.cxx:169
PadOfflineData.h
NSWL1::sortByLayer
bool sortByLayer(const std::shared_ptr< PadOfflineData > &p0, const std::shared_ptr< PadOfflineData > &p1)
Definition: SingleWedgePadTrigger.cxx:16
NSWL1::SingleWedgePadTrigger::padIndices
const std::vector< size_t > padIndices() const
Definition: SingleWedgePadTrigger.h:57
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
NSWL1::SingleWedgePadTrigger::EtaPhi::iphi
int iphi
Definition: SingleWedgePadTrigger.h:32
NSWL1::SingleWedgePadTrigger::areInnerOuterConsistent
static bool areInnerOuterConsistent(const EtaPhiHalf &inner, const EtaPhiHalf &outer)
Determine whether two single-wedge triggers are consistent with each other.
Definition: SingleWedgePadTrigger.cxx:158
y
#define y
NSWL1::SingleWedgePadTrigger::halfPadCoordinates
EtaPhiHalf halfPadCoordinates() const
Definition: SingleWedgePadTrigger.cxx:35
ReadCellNoiseFromCoolCompare.l0
l0
Definition: ReadCellNoiseFromCoolCompare.py:359
NSWL1::SingleWedgePadTrigger::m_halfPadIndices
EtaPhiHalf m_halfPadIndices
Definition: SingleWedgePadTrigger.h:75
NSWL1::intersectionRegion
Polygon intersectionRegion(const std::vector< Polygon > &polygons)
Definition: GeoUtils.cxx:91
NSWL1::SingleWedgePadTrigger::pads
const std::vector< std::shared_ptr< PadOfflineData > > & pads() const
Definition: SingleWedgePadTrigger.h:72
NSWL1::SingleWedgePadTrigger::SingleWedgePadTrigger
SingleWedgePadTrigger(const std::string &pattern, const std::vector< std::shared_ptr< PadOfflineData >> &pads, const std::vector< size_t > &padIndices)
Definition: SingleWedgePadTrigger.cxx:19
skel.l1
l1
Definition: skel.GENtoEVGEN.py:425
NSWL1::STGC_LAYER_2
const int STGC_LAYER_2
Definition: tdr_compat_enum.h:14
NSWL1::PadOfflineData::gasGapId
int gasGapId() const
get the gas gap (ranging from 1 to 4, 1 is at lowest |z|)
Definition: PadOfflineData.cxx:60
NSWL1::SingleWedgePadTrigger::padOverlap3
static Polygon padOverlap3(const std::vector< std::shared_ptr< PadOfflineData >> &pads)
area that is overlapping between the pads that cause the trigger (pads are staggered)
Definition: SingleWedgePadTrigger.cxx:113
SingleWedgePadTrigger.h
NSWL1::SingleWedgePadTrigger::EtaPhi::str
std::string str() const
Definition: SingleWedgePadTrigger.cxx:29
NSWL1::STGC_LAYER_1
const int STGC_LAYER_1
Definition: tdr_compat_enum.h:14
NSWL1
A trigger trigger candidate for a stgc sector.
Definition: NSWL1Simulation.cxx:9
NSWL1::Vertices
std::vector< Vertex > Vertices
Definition: GeoUtils.h:19
NSWL1::centroid
Vertex centroid(const Polygon &p)
Definition: GeoUtils.cxx:59
NSWL1::buildPolygon
Polygon buildPolygon(const Vertices &pts)
Definition: GeoUtils.cxx:44