5 #include "GaudiKernel/ConcurrencyFlags.h"
17 m_detManager(nullptr),
20 declareInterface<NSWL1::IPadTriggerLogicTool>(
this);
28 const INamedInterface* pnamed =
dynamic_cast<const INamedInterface*
>(
parent);
29 const std::string& algo_name = pnamed->name();
32 if (Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents() > 1) {
33 ATH_MSG_ERROR(
"DoNtuple is not possible in multi-threaded mode");
34 return StatusCode::FAILURE;
41 if ( algo_name==
"NSWL1Simulation" ) {
42 SmartIF<ITHistSvc> tHistSvc{service(
"THistSvc")};
46 std::string
treename = algo_name+
"Tree";
56 return StatusCode::SUCCESS;
60 if( inc.type()==IncidentType::BeginEvent &&
m_doNtuple ) {
69 std::array<Amg::Vector2D, 4> local_pad_corners{make_array<Amg::Vector2D, 4>(
Amg::Vector2D::Zero())};
73 for(
unsigned int i=0;
i<4;
i++) {
74 surface.
localToGlobal(local_pad_corners.at(
i), pad_corner_global, pad_corner_global);
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());
85 for(
const auto&
p : pads_in)
86 if(
p->multipletId()==multiplet)
87 pads_out.push_back(
p);
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());
94 for(
const auto&
p : pads_in)
95 if(
p->gasGapId()==gasgap)
96 pads_out.push_back(
p);
101 std::vector<std::unique_ptr<PadTrigger>>
triggers;
103 int p0ieta =
p0->padEtaId();
104 int p0iphi =
p0->padPhiId();
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;
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;
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 ) );
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);
139 std::vector<std::unique_ptr<PadTrigger>> &
triggers)
const
142 ATH_MSG_DEBUG(
"calling compute_pad_triggers() (pads.size() "<<pads.size()<<
")");
143 for(
const auto& pad : pads){
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());
155 for(
const size_t sector :
SECTORS){
156 std::vector<std::shared_ptr<PadData>> sector_pads;
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));});
162 if(!sector_pads.empty()){
163 const std::shared_ptr<PadData> firstPad = sector_pads[0];
165 <<(firstPad->sideId()==0?
"A":
"C")
166 <<
" trigger sector "<< (2*firstPad->sectorId()-1-firstPad->sectorType())
167 <<
" : "<<sector_pads.size()<<
" pads");
169 const int innerMultiplet(1), outerMultiplet(2);
170 std::vector<std::shared_ptr<PadData>> padsInner(
filterByMultiplet(sector_pads, innerMultiplet));
171 std::vector<std::shared_ptr<PadData>> padsOuter(
filterByMultiplet(sector_pads, outerMultiplet));
175 <<triggersInner.size()<<
" inner triggers"
177 <<triggersOuter.size()<<
" outer triggers");
178 triggers.reserve(
triggers.size() + triggersInner.size()+triggersOuter.size());
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()));
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.emplace_back(std::move(pod));
193 auto p=std::make_unique<PadTrigger>(
convert(st));
195 if (
p->m_pads.empty())
continue;
210 return StatusCode::SUCCESS;
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();
260 auto pad0=innertrg.
pads().at(0);
267 float yloc_trg=local_trgCoordinates.y();
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;
280 pt.m_multiplet_id = pad0->multipletId();
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);
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;}
300 if(
pt.m_isSmall && matchedBandId > 0){
303 }
else if(!
pt.m_isSmall && matchedBandId > 0) {
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;
316 pt.m_moduleIdInner=stc.
wedgeTrigs().at(0).pads().at(0)->moduleId();
317 pt.m_moduleIdOuter=stc.
wedgeTrigs().at(1).pads().at(1)->moduleId();
320 int multId0=stc.
wedgeTrigs().at(0).pads().at(0)->multipletId();
322 pt.m_moduleIdInner=stc.
wedgeTrigs().at(0).pads().at(0)->moduleId();
325 pt.m_moduleIdOuter=stc.
wedgeTrigs().at(0).pads().at(0)->moduleId();
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];
345 float Phi=
p->stationPhiAngle();
363 float bandLocalMaxY=local_trgMaxOnAxis.y();
364 float bandLocalMinY=local_trgMinOnAxis.y();
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);
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;
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;
395 trglocalminY.clear();
396 trglocalmaxY.clear();
397 trgSelectedLayers.clear();
398 trgSelectedBands.clear();
399 trgPadPhiIndices.clear();
400 trgPadEtaIndices.clear();
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);
415 stationPhiMin=(*itPhi).second.first;
416 stationPhiMax=(*itPhi).second.second;
419 ATH_MSG_WARNING(
"Could not find the hash Id: " << moduleHashId <<
" in the map");
422 float trgPhiCntr=
pt.m_phi;
426 if ( stationPhiMax >
M_PI && trgPhiCntr<0 ) {
427 trgPhiCntr=2*
M_PI-fabs(trgPhiCntr);
430 if ( trgPhiCntr<stationPhiMin || trgPhiCntr>stationPhiMax ) {
431 ATH_MSG_WARNING(
"Trigger phi: " << trgPhiCntr <<
" outside the station. Min, max: " << stationPhiMin <<
" " << stationPhiMax );
434 float step=(stationPhiMax-stationPhiMin)/nPhiSlices;
435 for(
int i=0;
i<nPhiSlices;
i++){
436 if(stationPhiMin+
i*
step>=trgPhiCntr){
449 std::vector<Identifier>::const_iterator idfirst =
helper->module_begin();
450 std::vector<Identifier>::const_iterator idlast =
helper->module_end();
454 for ( std::vector<Identifier>::const_iterator
i=idfirst ;
i!=idlast ; ++
i ) {
459 helper->get_hash( Id, hashId, &ModuleContext );
463 int multilayer =
helper->multilayer(Id);
465 char side =
module->getStationEta() < 0 ?
'C' :
'A';
466 char sector_l =
module->getStationName().substr(2,1)==
"L" ?
'L' :
'S';
472 double swidth = md->
sWidth();
473 double lwidth = md->
lWidth();
474 double ycutout = md->
yCutout();
476 double moduleR = std::sqrt(
pos.mag()*
pos.mag() -
pos.z()*
pos.z());
480 double dphi = ( dphi1 > dphi2 ? dphi1 : dphi2 );
482 double rcutout = moduleR+0.5*
length - ycutout;
483 double dphicutout =
std::atan( (0.5*lwidth)/rcutout );
484 if ( dphi < dphicutout ) dphi = dphicutout;
486 double phimin =
pos.phi()-dphi;
487 double phimax =
pos.phi()+dphi;
489 if ( phimin >
M_PI ) phimin -= 2*
M_PI;
490 if ( phimin < -
M_PI ) phimin += 2*
M_PI;
492 std::pair<double,double>
phiRange(phimin,phimax);
495 if((sector_l==
'L' &&
m_Zratio.first==0) || (sector_l==
'S' &&
m_Zratio.second==0)) {
497 Id=
helper->multilayerID(Id,2);