ATLAS Offline Software
PadTriggerLogicOfflineTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "GaudiKernel/ConcurrencyFlags.h"
6 
10 
11 namespace NSWL1 {
12 //------------------------------------------------------------------------------
13 PadTriggerLogicOfflineTool::PadTriggerLogicOfflineTool(const std::string& type, const std::string& name, const IInterface* parent) :
15  m_etaBandsLargeSector(BandsInEtaLargeSector),
16  m_etaBandsSmallSector(BandsInEtaSmallSector),
17  m_detManager(nullptr),
18  m_tdrLogic()
19  {
20  declareInterface<NSWL1::IPadTriggerLogicTool>(this);
21  }
22 
24  ATH_MSG_DEBUG( "initializing " << name() );
25  ATH_MSG_DEBUG( name() << " configuration:");
26 
27  const IInterface* parent = this->parent();
28  const INamedInterface* pnamed = dynamic_cast<const INamedInterface*>(parent);
29  const std::string& algo_name = pnamed->name();
30 
31  if ( m_doNtuple ) {
32  if (Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents() > 1) {
33  ATH_MSG_ERROR("DoNtuple is not possible in multi-threaded mode");
34  return StatusCode::FAILURE;
35  }
36  m_validation_tree = std::make_unique<PadTriggerValidationTree>();
37 
38  ATH_CHECK( m_incidentSvc.retrieve() );
39  m_incidentSvc->addListener(this,IncidentType::BeginEvent);
40 
41  if ( algo_name=="NSWL1Simulation" ) {
42  ITHistSvc* tHistSvc=nullptr;
43  ATH_CHECK(service("THistSvc", tHistSvc));
44 
45  TTree *tree=nullptr;
46  std::string treename = algo_name+"Tree";
47  ATH_CHECK(tHistSvc->getTree(treename, tree));
48  m_validation_tree->init_tree(tree);
49  }
50  }
51 
52  // retrieve the MuonDetectormanager
54 
55  fillPhiTable();
56  return StatusCode::SUCCESS;
57 }
58 //------------------------------------------------------------------------------
59 void PadTriggerLogicOfflineTool::handle(const Incident& inc) {
60  if( inc.type()==IncidentType::BeginEvent && m_doNtuple ) {
61  // Ntuple can only be enabled in single-threaded mode (see initialize)
62  [[maybe_unused]] bool success ATLAS_THREAD_SAFE = m_validation_tree->reset_ntuple_variables();
63  }
64 }
65 
66 void PadTriggerLogicOfflineTool::fillGeometricInformation(const std::shared_ptr<PadOfflineData>& pod) const {
67  const MuonGM::sTgcReadoutElement* rdoEl = m_detManager->getsTgcReadoutElement(pod->Identity());
68  const Trk::PlaneSurface &surface = rdoEl->surface(pod->Identity());
69  std::array<Amg::Vector2D, 4> local_pad_corners{make_array<Amg::Vector2D, 4>(Amg::Vector2D::Zero())};
70  //From MuonPadDesign... read pad local corners
71  rdoEl->padCorners(pod->Identity(),local_pad_corners);
72  Amg::Vector3D pad_corner_global;
73  for(unsigned int i=0; i<4; i++) {
74  surface.localToGlobal(local_pad_corners.at(i), pad_corner_global, pad_corner_global);
75  pod->m_cornerXyz[i][0] = pad_corner_global.x();
76  pod->m_cornerXyz[i][1] = pad_corner_global.y();
77  pod->m_cornerXyz[i][2] = pad_corner_global.z();
78  }
79 }
80 
82 std::vector<std::shared_ptr<PadData>> filterByMultiplet(const std::vector<std::shared_ptr<PadData>> &pads_in, const int multiplet){
83  std::vector<std::shared_ptr<PadData>> pads_out;
84  pads_out.reserve(0.5*pads_in.size()); // educated guess (half inner multiplet, half outer multiplet)
85  for(const auto& p : pads_in)
86  if(p->multipletId()==multiplet)
87  pads_out.push_back(p);
88  return pads_out;
89 }
91 std::vector<std::shared_ptr<PadData>> filterByGasGap(const std::vector<std::shared_ptr<PadData>> &pads_in, const int gasgap){
92  std::vector<std::shared_ptr<PadData>> pads_out;
93  pads_out.reserve(0.25*pads_in.size()); // educated guess (4 gas gaps)
94  for(const auto& p : pads_in)
95  if(p->gasGapId()==gasgap)
96  pads_out.push_back(p);
97  return pads_out;
98 }
99 
100 std::vector<std::unique_ptr<PadTrigger>> PadTriggerLogicOfflineTool::build4of4SingleWedgeTriggers(const std::vector<std::shared_ptr<PadData>> &pads) {
101  std::vector<std::unique_ptr<PadTrigger>> triggers;
102  for(const auto& p0 : filterByGasGap(pads, 1)){
103  int p0ieta = p0->padEtaId();
104  int p0iphi = p0->padPhiId();
105  for(const auto& p1 : filterByGasGap(pads, 2)){
106  int p1ieta = p1->padEtaId();
107  int p1iphi = p1->padPhiId();
108  bool p0_p1_match = ((p1ieta == p0ieta || p1ieta == p0ieta+1 ) &&
109  (p1iphi == p0iphi || p1iphi == p0iphi+1 ) );
110  if(not p0_p1_match) continue;
111  for(const auto& p2 :filterByGasGap(pads, 3) ){
112  int p2ieta = p2->padEtaId();
113  int p2iphi = p2->padPhiId();
114  bool p1_p2_match = ((p2ieta == p1ieta || p2ieta == p1ieta+1 ) &&
115  (p2iphi == p1iphi || p2iphi == p1iphi+1 ) );
116  if(not p1_p2_match) continue;
117  for(const auto& p3 : filterByGasGap(pads, 4)){
118  int p3ieta = p3->padEtaId();
119  int p3iphi = p3->padPhiId();
120  bool p2_p3_match = ((p3ieta == p2ieta || p3ieta == p2ieta+1 ) &&
121  (p3iphi == p2iphi || p3iphi == p2iphi+1 ) );
122  if(p2_p3_match){
123  auto trg=std::make_unique<PadTrigger>();
124  trg->m_pads.push_back(p0);
125  trg->m_pads.push_back(p1);
126  trg->m_pads.push_back(p2);
127  trg->m_pads.push_back(p3);
128  triggers.push_back(std::move(trg));
129  }
130  } // for(p3)
131  } // for(p2)
132  } // for(p1)
133  } // for(p0)
134  return triggers;
135 }
136 
137 
138 StatusCode PadTriggerLogicOfflineTool::compute_pad_triggers(const std::vector<std::shared_ptr<PadData>>& pads,
139  std::vector<std::unique_ptr<PadTrigger>> &triggers) const
140 {
141  ATH_MSG_DEBUG(" <N> receiving "<<pads.size()<<" pad data");
142  ATH_MSG_DEBUG("calling compute_pad_triggers() (pads.size() "<<pads.size()<<")");
143  for(const auto& pad : pads){
144  ATH_MSG_DEBUG(" <N> building trig from pad "
145  <<" side "<<pad->sideId()<<""
146  <<", sector "<<pad->sectorId()
147  <<", sector type "<<pad->sectorType()
148  <<", module "<<pad->moduleId()
149  <<", multiplet "<<pad->multipletId()
150  <<", gas gap "<<pad->gasGapId()
151  <<", pad eta "<<pad->padEtaId()
152  <<", pad phi "<<pad->padPhiId());
153  }
154  for(const size_t side : SIDES){
155  for(const size_t sector : SECTORS){
156  std::vector<std::shared_ptr<PadData>> sector_pads;
157  std::copy_if(pads.begin(), pads.end(),
158  back_inserter(sector_pads),
159  [&](const std::shared_ptr<PadData>& p) { return (p->sideId()==static_cast<int>(side) &&
160  (2*p->sectorId()-1-p->sectorType())==static_cast<int>(sector));});
161 
162  if(!sector_pads.empty()){
163  const std::shared_ptr<PadData> firstPad = sector_pads[0];
164  ATH_MSG_DEBUG("<N> side "
165  <<(firstPad->sideId()==0?"A":"C")
166  <<" trigger sector "<< (2*firstPad->sectorId()-1-firstPad->sectorType())
167  <<" : "<<sector_pads.size()<<" pads");
168  if(m_useSimple4of4) {
169  const int innerMultiplet(1), outerMultiplet(2); // DG-2015-10-07 move to enum?
170  std::vector<std::shared_ptr<PadData>> padsInner(filterByMultiplet(sector_pads, innerMultiplet));
171  std::vector<std::shared_ptr<PadData>> padsOuter(filterByMultiplet(sector_pads, outerMultiplet));
172  std::vector<std::unique_ptr<PadTrigger>> triggersInner = build4of4SingleWedgeTriggers(padsInner);
173  std::vector<std::unique_ptr<PadTrigger>> triggersOuter = build4of4SingleWedgeTriggers(padsOuter);
174  ATH_MSG_DEBUG("found "
175  <<triggersInner.size()<<" inner triggers"
176  <<" and "
177  <<triggersOuter.size()<<" outer triggers");
178  triggers.reserve(triggers.size() + triggersInner.size()+triggersOuter.size());
179 
180  triggers.insert(triggers.end(),std::make_move_iterator(triggersInner.begin()),std::make_move_iterator(triggersInner.end()));
181  triggers.insert(triggers.end(),std::make_move_iterator(triggersOuter.begin()),std::make_move_iterator(triggersOuter.end()));
182  }
183  else {
184  std::vector<std::shared_ptr<PadOfflineData>> trgpads;
185  for(const auto& p : sector_pads){
186  auto pod=std::dynamic_pointer_cast<PadOfflineData> (p);
188  trgpads.push_back(pod);
189  }
190  const std::vector<SectorTriggerCandidate> candidates = m_tdrLogic.buildSectorTriggers(trgpads,m_Zratio);
191  int index=0;
192  for( const auto& st : candidates){
193  auto p=std::make_unique<PadTrigger>(convert(st));
194  p->m_triggerindex=index;
195  if (p->m_pads.empty()) continue;//don't record null triggers (rejected or empty)
196  triggers.push_back(std::move(p));
197  index++;
198  }
199  ATH_MSG_DEBUG("found " << candidates.size() << " triggers using the tdr logic");
200  }
201  } // if(sector_pads)
202  } // for(sector)
203  } // for(side)
204  // Fill Ntuple
205  if(m_doNtuple) {
206  // Ntuple can only be enabled in single-threaded mode (see initialize)
207  [[maybe_unused]] bool b1 ATLAS_THREAD_SAFE = m_validation_tree->fill_num_pad_triggers(triggers.size());
208  [[maybe_unused]] bool b2 ATLAS_THREAD_SAFE = m_validation_tree->fill_pad_trigger_basics(triggers);
209  }
210  return StatusCode::SUCCESS;
211 }
212 //------------------------------------------------------------------------------
213 
214 int PadTriggerLogicOfflineTool::ROI2BandId(const float EtaTrigAtCenter, const int SectorType) const {
215 
216  switch(SectorType){
217  case(1): //L
218  if(EtaTrigAtCenter < m_etaBandsLargeSector.back() || EtaTrigAtCenter > m_etaBandsLargeSector.front()) return -999;
219  for(unsigned int i=0;i<m_etaBandsLargeSector.size();i++){
220  if(EtaTrigAtCenter < m_etaBandsLargeSector.at(i) && EtaTrigAtCenter > m_etaBandsLargeSector.at(i+1) ) return i;
221  }
222  break;
223 
224  case(0): //S
225  if(EtaTrigAtCenter < m_etaBandsSmallSector.back() || EtaTrigAtCenter > m_etaBandsSmallSector.front()) return -999;
226  for(unsigned int i=0;i<m_etaBandsSmallSector.size();i++){
227  if(EtaTrigAtCenter < m_etaBandsSmallSector.at(i) && EtaTrigAtCenter > m_etaBandsSmallSector.at(i+1) ) return i;
228  }
229  break;
230 
231  default:
232  ATH_MSG_FATAL(" Unexpected SectorType="<<SectorType);
233  break;
234  }
235  return -999;
236 }
237 
238 //------------------------------------------------------------------------------
240 
241  PadTrigger pt;
242  const Polygon roi=stc.triggerRegion3();
243  Vertex trgCntr=centroid(roi);
244  SingleWedgePadTrigger innertrg = stc.wedgeTrigs().at(0);
245 
246  //*********** assign central etaphi cordinates of the triggering region *****************
247  const float xcntr=coordinate<0>(trgCntr);
248  const float ycntr=coordinate<1>(trgCntr);
249  const float zcntr=innertrg.pads().at(0)->m_cornerXyz[1][2];
250  ROOT::Math::XYZVector trigVector(xcntr,ycntr,zcntr);
251  const float etaTrig=trigVector.Eta();
252  const float phiTrig=trigVector.Phi();
253  pt.m_eta = etaTrig;
254  pt.m_phi = phiTrig;
255 
256  /*
257  ===== Recipe for projecting eta of the trigger centroid to the axis of symmetry on a sector =======
258  */
259  //**************************************************************************************
260  auto pad0=innertrg.pads().at(0);
261  Identifier idt(pad0->id());
263  Amg::Vector3D global_trgCoordinates(xcntr,ycntr,zcntr);
264  Amg::Vector2D local_trgCoordinates;
265  surf.globalToLocal(global_trgCoordinates,Amg::Vector3D(),local_trgCoordinates);
266 
267  float yloc_trg=local_trgCoordinates.y();
268  Amg::Vector2D local_trgCoordinateOnAxis(0,yloc_trg);
269  Amg::Vector3D global_trgCoordinateProjectedOnAxis;
270  surf.localToGlobal(local_trgCoordinateOnAxis, Amg::Vector3D(),global_trgCoordinateProjectedOnAxis);
271  ROOT::Math::XYZVector trgVectorProjectedOnAxis(global_trgCoordinateProjectedOnAxis.x(),global_trgCoordinateProjectedOnAxis.y(),global_trgCoordinateProjectedOnAxis.z());
272  float etaProjected=trgVectorProjectedOnAxis.Eta();
273  int secType=pad0->sectorType();
274  int matchedBandId=ROI2BandId(std::abs(etaProjected),secType);
275  pt.m_bandid = (matchedBandId < 0) ? 0 : matchedBandId+2;// Y.R Bands start from 2
276  if(pt.m_bandid == 0) ATH_MSG_WARNING("PadTrigger out of current eta bands");
277 
278  /* ======== End of band Id matching and assignment ======================= */
279 
280  pt.m_multiplet_id = pad0->multipletId();
281  pt.m_eta_id = innertrg.halfPadCoordinates().ieta;//this is meaningless and shoiuld be removed
282  pt.m_isSmall= int(innertrg.isSmallSector());
283 
284  //************** assign extrema of the trigger region coordinates in eta-phi and some other variables for offline analysis **************
285  std::vector<std::pair<float,float>> trg_etaphis;
286  for(const auto& v : boost::geometry::exterior_ring(roi)){
287  const float xcurr=coordinate<0>(v);
288  const float ycurr=coordinate<1>(v);
289  const float zcurr=zcntr;
290  const float etacurr=eta(xcurr,ycurr,zcurr);
291  const float phicurr=phi(xcurr,ycurr,zcurr);
292  trg_etaphis.emplace_back(etacurr,phicurr);
293  }
294  const auto trg_phiminmax=std::minmax_element(trg_etaphis.begin(),trg_etaphis.end(),[](
295  const std::pair<float,float>& l,const std::pair<float,float>& r){return l.second<r.second;}
296  );
297  float trgEtaMin=0;
298  float trgEtaMax=0;
299 
300  if(pt.m_isSmall && matchedBandId > 0){
301  trgEtaMin=m_etaBandsSmallSector.at(matchedBandId+1);
302  trgEtaMax=m_etaBandsSmallSector.at(matchedBandId);
303  } else if(!pt.m_isSmall && matchedBandId > 0) {
304  trgEtaMin=m_etaBandsLargeSector.at(matchedBandId+1);
305  trgEtaMax=m_etaBandsLargeSector.at(matchedBandId);
306  }
307 
308  pt.m_etamin=trgEtaMin;
309  pt.m_etamax=trgEtaMax;
310  pt.m_phimin=(trg_phiminmax.first)->second;
311  pt.m_phimax=(trg_phiminmax.second)->second;
312  pt.m_moduleIdInner=-1;
313  pt.m_moduleIdOuter=-1;
314 
315  if(stc.wedgeTrigs().size()==2){//double wedge trigger
316  pt.m_moduleIdInner=stc.wedgeTrigs().at(0).pads().at(0)->moduleId();
317  pt.m_moduleIdOuter=stc.wedgeTrigs().at(1).pads().at(1)->moduleId();
318  }
319  else{
320  int multId0=stc.wedgeTrigs().at(0).pads().at(0)->multipletId();
321  if( multId0==1){
322  pt.m_moduleIdInner=stc.wedgeTrigs().at(0).pads().at(0)->moduleId();
323  }
324  else{
325  pt.m_moduleIdOuter=stc.wedgeTrigs().at(0).pads().at(0)->moduleId();
326  }
327  //one of the module Ids remain as -1 /single wedge trigger
328  }
329 
330  //****************************************************************************************
331 
332  for(const SingleWedgePadTrigger& swt : stc.wedgeTrigs()){
333  int currwedge=swt.pads().at(0)->multipletId();
334  std::vector<float> trglocalminY;
335  std::vector<float> trglocalmaxY;
336  std::vector<int> trgSelectedLayers;
337  std::vector<int> trgSelectedBands;
338  std::vector<int> trgPadPhiIndices;
339  std::vector<int> trgPadEtaIndices;
340  std::vector< std::shared_ptr<PadData>> trgPads;
341  for(const auto &p : swt.pads()){
342  const float padZ=p->m_cornerXyz[0][2];
343  Identifier Id( p->id());
344  const Trk::PlaneSurface &padsurface = m_detManager->getsTgcReadoutElement(Id)->surface(Id);
345  float Phi=p->stationPhiAngle();
346 
347  //Find the radial boundaries of the band within the sector axis
348  float Rmin=std::abs(padZ*std::tan(2*std::atan(-1*std::exp(pt.m_etamax))) );
349  float Rmax=std::abs(padZ*std::tan(2*std::atan(-1*std::exp(pt.m_etamin))) );
350  float xmin=Rmin*std::cos(Phi);
351  float ymin=Rmin*std::sin(Phi);
352  float xmax=Rmax*std::cos(Phi);
353  float ymax=Rmax*std::sin(Phi);
354 
355  Amg::Vector3D global_trgMinOnAxis(xmin,ymin,padZ);
356  Amg::Vector3D global_trgMaxOnAxis(xmax,ymax,padZ);
357 
358  Amg::Vector2D local_trgMinOnAxis;
359  Amg::Vector2D local_trgMaxOnAxis;
360  padsurface.globalToLocal(global_trgMinOnAxis,Amg::Vector3D(),local_trgMinOnAxis);
361  padsurface.globalToLocal(global_trgMaxOnAxis,Amg::Vector3D(),local_trgMaxOnAxis);
362 
363  float bandLocalMaxY=local_trgMaxOnAxis.y();
364  float bandLocalMinY=local_trgMinOnAxis.y();
365 
366  trglocalminY.push_back(bandLocalMinY);
367  trglocalmaxY.push_back(bandLocalMaxY);
368  trgSelectedLayers.push_back(p->gasGapId());
369  trgSelectedBands.push_back(matchedBandId+2);
370  trgPadPhiIndices.push_back(p->padPhiId());
371  trgPadEtaIndices.push_back(p->padEtaId());
372  trgPads.push_back(p);
373  pt.m_pads.push_back(p);
374  } // eof for(p) pads
375  //assign variables / wedgewise
376  if(currwedge==1){
377  pt.m_trglocalminYInner=trglocalminY;
378  pt.m_trglocalmaxYInner=trglocalmaxY;
379  pt.m_trgSelectedLayersInner=trgSelectedLayers;
380  pt.m_trgSelectedBandsInner=trgSelectedBands;
381  pt.m_trgPadPhiIndicesInner=trgPadPhiIndices;
382  pt.m_trgPadEtaIndicesInner=trgPadEtaIndices;
383  pt.m_padsInner=trgPads;
384  }
385  if(currwedge==2){
386  pt.m_trglocalminYOuter=trglocalminY;
387  pt.m_trglocalmaxYOuter=trglocalmaxY;
388  pt.m_trgSelectedLayersOuter=trgSelectedLayers;
389  pt.m_trgSelectedBandsOuter=trgSelectedBands;
390  pt.m_trgPadPhiIndicesOuter=trgPadPhiIndices;
391  pt.m_trgPadEtaIndicesOuter=trgPadEtaIndices;
392  pt.m_padsOuter=trgPads;
393  }
394 
395  trglocalminY.clear();
396  trglocalmaxY.clear();
397  trgSelectedLayers.clear();
398  trgSelectedBands.clear();
399  trgPadPhiIndices.clear();
400  trgPadEtaIndices.clear();
401  trgPads.clear();
402  } // eof for (swt) single wedge trigger
403 
404  //Assignment of Phi Id using 6 bits slicing
405  Identifier padIdentifier(pt.m_pads.at(0)->id() );
406  IdentifierHash moduleHashId;
407  const IdContext ModuleContext = m_detManager->stgcIdHelper()->module_context();
408 
409  //get the module Identifier using the pad's
410  m_detManager->stgcIdHelper()->get_hash( padIdentifier, moduleHashId, &ModuleContext );
411  float stationPhiMin=0.0;
412  float stationPhiMax=0.0;
413  std::map<IdentifierHash,std::pair<double,double>>::const_iterator itPhi = m_phiTable.find(moduleHashId);
414  if (itPhi != m_phiTable.end()) {
415  stationPhiMin=(*itPhi).second.first;
416  stationPhiMax=(*itPhi).second.second;
417  }
418  else {
419  ATH_MSG_WARNING("Could not find the hash Id: " << moduleHashId << " in the map");
420  }
421 
422  float trgPhiCntr=pt.m_phi;
423  int nPhiSlices=1<<m_phiIdBits;//6 bits for Phi Id; i.e interval of [0,....63]
424 
425  // special treatment for the last phi region
426  if ( stationPhiMax > M_PI && trgPhiCntr<0 ) {
427  trgPhiCntr=2*M_PI-fabs(trgPhiCntr);
428  }
429 
430  if ( trgPhiCntr<stationPhiMin || trgPhiCntr>stationPhiMax ) {
431  ATH_MSG_WARNING("Trigger phi: " << trgPhiCntr << " outside the station. Min, max: " << stationPhiMin << " " << stationPhiMax );
432  }
433 
434  float step=(stationPhiMax-stationPhiMin)/nPhiSlices;
435  for( int i=0;i<nPhiSlices;i++){
436  if(stationPhiMin+i*step>=trgPhiCntr){
437  pt.m_phi_id=i;
438  break;
439  }
440  }
441  return pt;
442 }
443 
444  // fill the map with the phi ranges
446 
448 
449  std::vector<Identifier>::const_iterator idfirst = helper->module_begin();
450  std::vector<Identifier>::const_iterator idlast = helper->module_end();
451 
452  const IdContext ModuleContext = helper->module_context();
453 
454  for ( std::vector<Identifier>::const_iterator i=idfirst ; i!=idlast ; ++i ) {
455 
456  Identifier Id = *i;
457  IdentifierHash hashId;
458 
459  helper->get_hash( Id, hashId, &ModuleContext );
460 
462  if (!module) continue;
463  int multilayer = helper->multilayer(Id);
464 
465  char side = module->getStationEta() < 0 ? 'C' : 'A';
466  char sector_l = module->getStationName().substr(2,1)=="L" ? 'L' : 'S';
467 
468  sTGCDetectorHelper aHelper;
469  sTGCDetectorDescription* md = aHelper.Get_sTGCDetector( sector_l, std::abs(module->getStationEta()), module->getStationPhi(), multilayer, side );
470 
471  Amg::Vector3D pos = module->center();
472  double swidth = md->sWidth();
473  double lwidth = md->lWidth();
474  double ycutout = md->yCutout();
475  double length = md->Length();
476  double moduleR = std::sqrt( pos.mag()*pos.mag() - pos.z()*pos.z());
477  double dphi1 = std::atan( (0.5*lwidth)/(moduleR+0.5*length) );
478  double dphi2 = std::atan( (0.5*swidth)/(moduleR-0.5*length) );
479 
480  double dphi = ( dphi1 > dphi2 ? dphi1 : dphi2 );
481  if ( ycutout > 0 ) {
482  double rcutout = moduleR+0.5*length - ycutout;
483  double dphicutout = std::atan( (0.5*lwidth)/rcutout );
484  if ( dphi < dphicutout ) dphi = dphicutout;
485  }
486  double phimin = pos.phi()-dphi;
487  double phimax = pos.phi()+dphi;
488 
489  if ( phimin > M_PI ) phimin -= 2*M_PI;
490  if ( phimin < -M_PI ) phimin += 2*M_PI;
491 
492  std::pair<double,double> phiRange(phimin,phimax);
493  m_phiTable[hashId]=phiRange;
494 
495  if((sector_l=='L' && m_Zratio.first==0) || (sector_l=='S' && m_Zratio.second==0)) {
496  double ratio=1/pos.z();
497  Id=helper->multilayerID(Id,2);
499  Amg::Vector3D pos2 = module2->center();
500  ratio*=pos2.z();
501  if(sector_l=='L') m_Zratio.first=ratio;
502  else if(sector_l=='S') m_Zratio.second=ratio;
503  }
504  }
505 
506  }
507 
508 
509 } // NSWL1
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
MuonGM::sTgcReadoutElement::padCorners
bool padCorners(const Identifier &id, std::array< Amg::Vector2D, 4 > &corners) const
pad corners
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/sTgcReadoutElement.h:360
NSWL1::PadTriggerLogicOfflineTool::m_tdrLogic
L1TdrStgcTriggerLogic m_tdrLogic
Definition: PadTriggerLogicOfflineTool.h:109
beamspotman.r
def r
Definition: beamspotman.py:676
Trk::PlaneSurface::globalToLocal
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
Definition: PlaneSurface.cxx:213
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
NSWL1::PadTriggerLogicOfflineTool::m_phiTable
std::map< IdentifierHash, std::pair< double, double > > m_phiTable
Definition: PadTriggerLogicOfflineTool.h:95
NSWL1::eta
float eta(float x, float y, float z)
Definition: GeoUtils.cxx:9
ymin
double ymin
Definition: listroot.cxx:63
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
NSWL1::PadTriggerLogicOfflineTool::ROI2BandId
int ROI2BandId(const float EtaTrigAtCenter, const int SectorType) const
Definition: PadTriggerLogicOfflineTool.cxx:214
NSWL1::SIDES
const std::vector< size_t > SIDES
Definition: tdr_compat_enum.h:20
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
sTGCDetectorDescription::sWidth
double sWidth() const
Definition: sTGCDetectorDescription.h:70
NSWL1::filterByGasGap
std::vector< std::shared_ptr< PadData > > filterByGasGap(const std::vector< std::shared_ptr< PadData >> &pads_in, const int gasgap)
! helper function: copy pads with a given gas gap
Definition: PadTriggerLogicOfflineTool.cxx:91
NSWL1::filterByMultiplet
std::vector< std::shared_ptr< PadData > > filterByMultiplet(const std::vector< std::shared_ptr< PadData >> &pads_in, const int multiplet)
! helper function: copy pads with a given multiplet
Definition: PadTriggerLogicOfflineTool.cxx:82
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
MuonGM::MuonClusterReadoutElement::center
virtual const Amg::Vector3D & center() const override
Return the center of the element.
Definition: MuonClusterReadoutElement.h:125
NSWL1::SingleWedgePadTrigger
Definition: SingleWedgePadTrigger.h:28
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
NSWL1::SectorTriggerCandidate::triggerRegion3
Polygon triggerRegion3() const
Definition: SectorTriggerCandidate.cxx:23
index
Definition: index.py:1
drawFromPickle.candidates
candidates
Definition: drawFromPickle.py:271
NSWL1::Vertex
boost::geometry::model::d2::point_xy< double > Vertex
Definition: GeoUtils.h:17
initialize
void initialize()
Definition: run_EoverP.cxx:894
PadTriggerLogicOfflineTool.h
NSWL1::BandsInEtaLargeSector
const std::vector< float > BandsInEtaLargeSector
Definition: sTGCTriggerBandsInEta.h:16
NSWL1::BandsInEtaSmallSector
const std::vector< float > BandsInEtaSmallSector
Definition: sTGCTriggerBandsInEta.h:111
tree
TChain * tree
Definition: tile_monitor.h:30
NSWL1::Polygon
boost::geometry::model::polygon< Vertex > Polygon
Definition: GeoUtils.h:18
test_pyathena.pt
pt
Definition: test_pyathena.py:11
NSWL1::PadTriggerLogicOfflineTool::compute_pad_triggers
virtual StatusCode compute_pad_triggers(const std::vector< std::shared_ptr< PadData >> &pads, std::vector< std::unique_ptr< PadTrigger >> &triggers) const override
Log a message using the Athena controlled logging system.
Definition: PadTriggerLogicOfflineTool.cxx:138
M_PI
#define M_PI
Definition: ActiveFraction.h:11
sTGCDetectorDescription::Length
double Length() const
Definition: sTGCDetectorDescription.h:72
NSWL1::PadTriggerLogicOfflineTool::m_Zratio
std::pair< double, double > m_Zratio
Definition: PadTriggerLogicOfflineTool.h:96
NSWL1::PadTriggerLogicOfflineTool::PadTriggerLogicOfflineTool
PadTriggerLogicOfflineTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: PadTriggerLogicOfflineTool.cxx:13
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
NSWL1::SingleWedgePadTrigger::isSmallSector
bool isSmallSector() const
use the first pad to determine whether it's a small/large sector
Definition: SingleWedgePadTrigger.cxx:72
Phi
@ Phi
Definition: RPCdef.h:8
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
python.TrigTLAMonitorAlgorithm.triggers
triggers
Definition: TrigTLAMonitorAlgorithm.py:196
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
MuonGM::MuonClusterReadoutElement::surface
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
Definition: MuonClusterReadoutElement.h:123
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
sTGCDetectorDescription
Definition: sTGCDetectorDescription.h:51
ParticleJetTools::p3
Amg::Vector3D p3(const xAOD::TruthVertex *p)
Definition: ParticleJetLabelCommon.cxx:55
NSWL1::PadTriggerLogicOfflineTool::m_incidentSvc
ServiceHandle< IIncidentSvc > m_incidentSvc
Athena/Gaudi incident Service.
Definition: PadTriggerLogicOfflineTool.h:98
TRT::Hit::side
@ side
Definition: HitInfo.h:83
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:112
sTGCDetectorDescription.h
python.PyAthena.module
module
Definition: PyAthena.py:134
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
NSWL1::SingleWedgePadTrigger::EtaPhi::ieta
int ieta
Definition: SingleWedgePadTrigger.h:32
lumiFormat.i
int i
Definition: lumiFormat.py:92
xmin
double xmin
Definition: listroot.cxx:60
NSWL1::PadTriggerLogicOfflineTool::m_doNtuple
Gaudi::Property< bool > m_doNtuple
Definition: PadTriggerLogicOfflineTool.h:104
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
NSWL1::PadTriggerLogicOfflineTool::m_detManager
const MuonGM::MuonDetectorManager * m_detManager
MuonDetectorManager.
Definition: PadTriggerLogicOfflineTool.h:99
MuonGM::sTgcReadoutElement
An sTgcReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station c...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/sTgcReadoutElement.h:28
NSWL1::SECTORS
const std::vector< size_t > SECTORS
Definition: tdr_compat_enum.h:19
test_pyathena.parent
parent
Definition: test_pyathena.py:15
MuonGM::MuonDetectorManager::stgcIdHelper
const sTgcIdHelper * stgcIdHelper() const
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:233
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
sTGCDetectorHelper.h
NSWL1::PadTriggerLogicOfflineTool::convert
PadTrigger convert(const SectorTriggerCandidate &t) const
from TDR-style SectorTriggerCandidate to PadTrigger
Definition: PadTriggerLogicOfflineTool.cxx:239
NSWL1::PadTriggerLogicOfflineTool::build4of4SingleWedgeTriggers
static std::vector< std::unique_ptr< PadTrigger > > build4of4SingleWedgeTriggers(const std::vector< std::shared_ptr< PadData >> &pads)
Definition: PadTriggerLogicOfflineTool.cxx:100
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
NSWL1::PadTriggerLogicOfflineTool::m_validation_tree
std::unique_ptr< PadTriggerValidationTree > m_validation_tree
Definition: PadTriggerLogicOfflineTool.h:106
sTgcIdHelper
Definition: sTgcIdHelper.h:55
sTGCDetectorDescription::yCutout
void yCutout(double y)
Definition: sTGCDetectorDescription.h:75
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
NSWL1::PadTriggerLogicOfflineTool::m_etaBandsLargeSector
const std::vector< float > m_etaBandsLargeSector
get the output tree from the athena histogram service
Definition: PadTriggerLogicOfflineTool.h:92
NSWL1::PadTriggerLogicOfflineTool::handle
virtual void handle(const Incident &inc) override
Definition: PadTriggerLogicOfflineTool.cxx:59
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
NSWL1::SectorTriggerCandidate
Definition: SectorTriggerCandidate.h:26
NSWL1::PadTriggerLogicOfflineTool::m_etaBandsSmallSector
const std::vector< float > m_etaBandsSmallSector
Definition: PadTriggerLogicOfflineTool.h:93
SectorType
SectorType
Definition: sTGCenumeration.h:39
python.PyAthena.v
v
Definition: PyAthena.py:157
NSWL1::PadTrigger
Holder of the pad trigger information.
Definition: PadTrigger.h:26
DeMoScan.index
string index
Definition: DeMoScan.py:362
python.compareTCTs.ratio
ratio
Definition: compareTCTs.py:295
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MuonIdHelper::get_hash
virtual int get_hash(const Identifier &id, IdentifierHash &hash_id, const IdContext *context=0) const override
Create hash id from compact id (return == 0 for OK)
Definition: MuonIdHelper.cxx:143
NSWL1::L1TdrStgcTriggerLogic::buildSectorTriggers
std::vector< SectorTriggerCandidate > buildSectorTriggers(const std::vector< std::shared_ptr< PadOfflineData >> &pads, const std::pair< double, double > &Zratio) const
main function to compute trigger candidates
Definition: L1TdrStgcTriggerLogic.cxx:342
Trk::PlaneSurface
Definition: PlaneSurface.h:64
NSWL1::PadTriggerLogicOfflineTool::fillGeometricInformation
void fillGeometricInformation(const std::shared_ptr< PadOfflineData > &) const
Definition: PadTriggerLogicOfflineTool.cxx:66
sTGCDetectorDescription::lWidth
double lWidth() const
Definition: sTGCDetectorDescription.h:71
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
MuonIdHelper::module_context
IdContext module_context() const
id for module
Definition: MuonIdHelper.cxx:735
NSWL1::SingleWedgePadTrigger::halfPadCoordinates
EtaPhiHalf halfPadCoordinates() const
Definition: SingleWedgePadTrigger.cxx:35
xmax
double xmax
Definition: listroot.cxx:61
NSWL1::SectorTriggerCandidate::wedgeTrigs
const std::vector< SingleWedgePadTrigger > & wedgeTrigs() const
Definition: SectorTriggerCandidate.h:31
NSWL1::PadTriggerLogicOfflineTool::m_phiIdBits
Gaudi::Property< int > m_phiIdBits
Definition: PadTriggerLogicOfflineTool.h:102
Rmin
double Rmin
Definition: LArDetectorConstructionTBEC.cxx:54
LArCellBinning.step
step
Definition: LArCellBinning.py:158
NSWL1::SingleWedgePadTrigger::pads
const std::vector< std::shared_ptr< PadOfflineData > > & pads() const
Definition: SingleWedgePadTrigger.h:72
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
LArCellBinning.phiRange
phiRange
Filling Phi ranges.
Definition: LArCellBinning.py:107
MuonGM::MuonDetectorManager::getsTgcReadoutElement
const sTgcReadoutElement * getsTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonDetectorManager.cxx:259
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
Definition: IdentifierHash.h:38
Trk::PlaneSurface::localToGlobal
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation.
Definition: PlaneSurface.cxx:204
NSWL1::phi
float phi(float x, float y, float z)
Definition: GeoUtils.cxx:14
NSWL1::PadTriggerLogicOfflineTool::fillPhiTable
void fillPhiTable()
Definition: PadTriggerLogicOfflineTool.cxx:445
NSWL1::PadTriggerLogicOfflineTool::m_useSimple4of4
Gaudi::Property< bool > m_useSimple4of4
Definition: PadTriggerLogicOfflineTool.h:103
NSWL1
A trigger trigger candidate for a stgc sector.
Definition: NSWL1Simulation.cxx:9
IdContext
class IdContext
Definition: IdContext.h:34
sTGCDetectorHelper
Definition: sTGCDetectorHelper.h:24
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
NSWL1::centroid
Vertex centroid(const Polygon &p)
Definition: GeoUtils.cxx:59
sTGCDetectorHelper::Get_sTGCDetector
sTGCDetectorDescription * Get_sTGCDetector(char type, int ieta, int iphi, int layer=1, char side='A')
Definition: sTGCDetectorHelper.cxx:35
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
ymax
double ymax
Definition: listroot.cxx:64