5 #include "GaudiKernel/ConcurrencyFlags.h"
19 declareInterface<NSWL1::IPadTriggerLogicTool>(
this);
29 return StatusCode::SUCCESS;
36 std::array<Amg::Vector2D, 4> local_pad_corners{make_array<Amg::Vector2D, 4>(
Amg::Vector2D::Zero())};
40 for(
unsigned int i=0;
i<4;
i++) {
41 surface.
localToGlobal(local_pad_corners.at(
i), pad_corner_global, pad_corner_global);
49 std::vector<std::shared_ptr<PadData>>
filterByMultiplet(
const std::vector<std::shared_ptr<PadData>> &pads_in,
const int multiplet){
50 std::vector<std::shared_ptr<PadData>> pads_out;
51 pads_out.reserve(0.5*pads_in.size());
52 for(
const auto&
p : pads_in)
53 if(
p->multipletId()==multiplet)
54 pads_out.push_back(
p);
58 std::vector<std::shared_ptr<PadData>>
filterByGasGap(
const std::vector<std::shared_ptr<PadData>> &pads_in,
const int gasgap){
59 std::vector<std::shared_ptr<PadData>> pads_out;
60 pads_out.reserve(0.25*pads_in.size());
61 for(
const auto&
p : pads_in)
62 if(
p->gasGapId()==gasgap)
63 pads_out.push_back(
p);
68 std::vector<std::unique_ptr<PadTrigger>>
triggers;
70 int p0ieta =
p0->padEtaId();
71 int p0iphi =
p0->padPhiId();
73 int p1ieta =
p1->padEtaId();
74 int p1iphi =
p1->padPhiId();
75 bool p0_p1_match = ((p1ieta == p0ieta || p1ieta == p0ieta+1 ) &&
76 (p1iphi == p0iphi || p1iphi == p0iphi+1 ) );
77 if(not p0_p1_match)
continue;
79 int p2ieta =
p2->padEtaId();
80 int p2iphi =
p2->padPhiId();
81 bool p1_p2_match = ((p2ieta == p1ieta || p2ieta == p1ieta+1 ) &&
82 (p2iphi == p1iphi || p2iphi == p1iphi+1 ) );
83 if(not p1_p2_match)
continue;
85 int p3ieta =
p3->padEtaId();
86 int p3iphi =
p3->padPhiId();
87 bool p2_p3_match = ((p3ieta == p2ieta || p3ieta == p2ieta+1 ) &&
88 (p3iphi == p2iphi || p3iphi == p2iphi+1 ) );
90 auto trg=std::make_unique<PadTrigger>();
91 trg->m_pads.push_back(
p0);
92 trg->m_pads.push_back(
p1);
93 trg->m_pads.push_back(
p2);
94 trg->m_pads.push_back(
p3);
106 std::vector<std::unique_ptr<PadTrigger>> &
triggers)
const
110 ATH_MSG_DEBUG(
"calling compute_pad_triggers() (pads.size() "<<pads.size()<<
")");
111 for(
const auto& pad : pads){
113 <<
" side "<<pad->sideId()<<
""
114 <<
", sector "<<pad->sectorId()
115 <<
", sector type "<<pad->sectorType()
116 <<
", module "<<pad->moduleId()
117 <<
", multiplet "<<pad->multipletId()
118 <<
", gas gap "<<pad->gasGapId()
119 <<
", pad eta "<<pad->padEtaId()
120 <<
", pad phi "<<pad->padPhiId());
123 for(
const size_t sector :
SECTORS){
124 std::vector<std::shared_ptr<PadData>> sector_pads;
126 back_inserter(sector_pads),
127 [&](
const std::shared_ptr<PadData>&
p) {
return (
p->sideId()==
static_cast<int>(
side) &&
128 (2*
p->sectorId()-1-
p->sectorType())==
static_cast<int>(sector));});
130 if(!sector_pads.empty()){
131 const std::shared_ptr<PadData> firstPad = sector_pads[0];
133 <<(firstPad->sideId()==0?
"A":
"C")
134 <<
" trigger sector "<< (2*firstPad->sectorId()-1-firstPad->sectorType())
135 <<
" : "<<sector_pads.size()<<
" pads");
137 const int innerMultiplet(1), outerMultiplet(2);
138 std::vector<std::shared_ptr<PadData>> padsInner(
filterByMultiplet(sector_pads, innerMultiplet));
139 std::vector<std::shared_ptr<PadData>> padsOuter(
filterByMultiplet(sector_pads, outerMultiplet));
143 <<triggersInner.size()<<
" inner triggers"
145 <<triggersOuter.size()<<
" outer triggers");
146 triggers.reserve(
triggers.size() + triggersInner.size()+triggersOuter.size());
148 triggers.insert(
triggers.end(),std::make_move_iterator(triggersInner.begin()),std::make_move_iterator(triggersInner.end()));
149 triggers.insert(
triggers.end(),std::make_move_iterator(triggersOuter.begin()),std::make_move_iterator(triggersOuter.end()));
152 std::vector<std::shared_ptr<PadOfflineData>> trgpads;
153 for(
const auto&
p : sector_pads){
154 auto pod=std::dynamic_pointer_cast<PadOfflineData> (
p);
156 trgpads.emplace_back(std::move(pod));
161 auto p=std::make_unique<PadTrigger>(
convert(st));
163 if (
p->m_pads.empty())
continue;
172 return StatusCode::SUCCESS;
209 const float xcntr=coordinate<0>(trgCntr);
210 const float ycntr=coordinate<1>(trgCntr);
211 const float zcntr=innertrg.
pads().at(0)->m_cornerXyz[1][2];
212 ROOT::Math::XYZVector trigVector(xcntr,ycntr,zcntr);
213 const float etaTrig=trigVector.Eta();
214 const float phiTrig=trigVector.Phi();
222 auto pad0=innertrg.
pads().at(0);
225 const Trk::PlaneSurface &surf = detManager->getsTgcReadoutElement(idt)->surface(idt);
230 float yloc_trg=local_trgCoordinates.y();
234 ROOT::Math::XYZVector trgVectorProjectedOnAxis(global_trgCoordinateProjectedOnAxis.x(),global_trgCoordinateProjectedOnAxis.y(),global_trgCoordinateProjectedOnAxis.z());
235 float etaProjected=trgVectorProjectedOnAxis.Eta();
236 int secType=pad0->sectorType();
237 int matchedBandId=
ROI2BandId(std::abs(etaProjected),secType);
238 pt.m_bandid = (matchedBandId < 0) ? 0 : matchedBandId+2;
243 pt.m_multiplet_id = pad0->multipletId();
248 std::vector<std::pair<float,float>> trg_etaphis;
249 for(
const auto&
v : boost::geometry::exterior_ring(roi)){
250 const float xcurr=coordinate<0>(
v);
251 const float ycurr=coordinate<1>(
v);
252 const float zcurr=zcntr;
253 const float etacurr=
eta(xcurr,ycurr,zcurr);
254 const float phicurr=
phi(xcurr,ycurr,zcurr);
255 trg_etaphis.emplace_back(etacurr,phicurr);
257 const auto trg_phiminmax=std::minmax_element(trg_etaphis.begin(),trg_etaphis.end(),[](
258 const std::pair<float,float>&
l,
const std::pair<float,float>&
r){return l.second<r.second;}
263 if(
pt.m_isSmall && matchedBandId > 0){
266 }
else if(!
pt.m_isSmall && matchedBandId > 0) {
271 pt.m_etamin=trgEtaMin;
272 pt.m_etamax=trgEtaMax;
273 pt.m_phimin=(trg_phiminmax.first)->
second;
274 pt.m_phimax=(trg_phiminmax.second)->
second;
275 pt.m_moduleIdInner=-1;
276 pt.m_moduleIdOuter=-1;
279 pt.m_moduleIdInner=stc.
wedgeTrigs().at(0).pads().at(0)->moduleId();
280 pt.m_moduleIdOuter=stc.
wedgeTrigs().at(1).pads().at(1)->moduleId();
283 int multId0=stc.
wedgeTrigs().at(0).pads().at(0)->multipletId();
285 pt.m_moduleIdInner=stc.
wedgeTrigs().at(0).pads().at(0)->moduleId();
288 pt.m_moduleIdOuter=stc.
wedgeTrigs().at(0).pads().at(0)->moduleId();
296 int currwedge=swt.pads().at(0)->multipletId();
297 std::vector<float> trglocalminY;
298 std::vector<float> trglocalmaxY;
299 std::vector<int> trgSelectedLayers;
300 std::vector<int> trgSelectedBands;
301 std::vector<int> trgPadPhiIndices;
302 std::vector<int> trgPadEtaIndices;
303 std::vector< std::shared_ptr<PadData>> trgPads;
304 for(
const auto &
p : swt.pads()){
305 const float padZ=
p->m_cornerXyz[0][2];
307 const Trk::PlaneSurface &padsurface = detManager->getsTgcReadoutElement(Id)->surface(Id);
308 float Phi=
p->stationPhiAngle();
326 float bandLocalMaxY=local_trgMaxOnAxis.y();
327 float bandLocalMinY=local_trgMinOnAxis.y();
329 trglocalminY.push_back(bandLocalMinY);
330 trglocalmaxY.push_back(bandLocalMaxY);
331 trgSelectedLayers.push_back(
p->gasGapId());
332 trgSelectedBands.push_back(matchedBandId+2);
333 trgPadPhiIndices.push_back(
p->padPhiId());
334 trgPadEtaIndices.push_back(
p->padEtaId());
335 trgPads.push_back(
p);
336 pt.m_pads.push_back(
p);
340 pt.m_trglocalminYInner=trglocalminY;
341 pt.m_trglocalmaxYInner=trglocalmaxY;
342 pt.m_trgSelectedLayersInner=trgSelectedLayers;
343 pt.m_trgSelectedBandsInner=trgSelectedBands;
344 pt.m_trgPadPhiIndicesInner=trgPadPhiIndices;
345 pt.m_trgPadEtaIndicesInner=trgPadEtaIndices;
346 pt.m_padsInner=trgPads;
349 pt.m_trglocalminYOuter=trglocalminY;
350 pt.m_trglocalmaxYOuter=trglocalmaxY;
351 pt.m_trgSelectedLayersOuter=trgSelectedLayers;
352 pt.m_trgSelectedBandsOuter=trgSelectedBands;
353 pt.m_trgPadPhiIndicesOuter=trgPadPhiIndices;
354 pt.m_trgPadEtaIndicesOuter=trgPadEtaIndices;
355 pt.m_padsOuter=trgPads;
358 trglocalminY.clear();
359 trglocalmaxY.clear();
360 trgSelectedLayers.clear();
361 trgSelectedBands.clear();
362 trgPadPhiIndices.clear();
363 trgPadEtaIndices.clear();
370 const IdContext ModuleContext = detManager->stgcIdHelper()->module_context();
373 detManager->stgcIdHelper()->get_hash( padIdentifier, moduleHashId, &ModuleContext );
374 float stationPhiMin=0.0;
375 float stationPhiMax=0.0;
377 std::map<IdentifierHash,std::pair<double,double>>::const_iterator itPhi = m_phiTable.find(moduleHashId);
378 if (itPhi != m_phiTable.end()) {
379 stationPhiMin=(*itPhi).second.first;
380 stationPhiMax=(*itPhi).second.second;
383 ATH_MSG_WARNING(
"Could not find the hash Id: " << moduleHashId <<
" in the map");
386 float trgPhiCntr=
pt.m_phi;
390 if ( stationPhiMax >
M_PI && trgPhiCntr<0 ) {
391 trgPhiCntr=2*
M_PI-fabs(trgPhiCntr);
394 if ( trgPhiCntr<stationPhiMin || trgPhiCntr>stationPhiMax ) {
395 ATH_MSG_WARNING(
"Trigger phi: " << trgPhiCntr <<
" outside the station. Min, max: " << stationPhiMin <<
" " << stationPhiMax );
398 float step=(stationPhiMax-stationPhiMin)/nPhiSlices;
399 for(
int i=0;
i<nPhiSlices;
i++){
400 if(stationPhiMin+
i*
step>=trgPhiCntr){
411 std::lock_guard guard{m_mutex};
412 if (m_isInitialized) {
418 std::vector<Identifier>::const_iterator idfirst =
helper->module_begin();
419 std::vector<Identifier>::const_iterator idlast =
helper->module_end();
423 for ( std::vector<Identifier>::const_iterator
i=idfirst ;
i!=idlast ; ++
i ) {
428 helper->get_hash( Id, hashId, &ModuleContext );
432 char sector_l =
module->getStationName().substr(2,1)==
"L" ?
'L' :
'S';
435 double swidth =
module->getSsize();
436 double lwidth =
module->getLongSsize();
438 double ycutout =
module->getDesign(1, sTgcIdHelper::sTgcChannelTypes::Strip)->yCutout();
440 double moduleR =
pos.perp();
444 double dphi = ( dphi1 > dphi2 ? dphi1 : dphi2 );
446 double rcutout = moduleR+0.5*
length - ycutout;
447 double dphicutout =
std::atan( (0.5*lwidth)/rcutout );
448 if ( dphi < dphicutout ) dphi = dphicutout;
450 double phimin =
pos.phi()-dphi;
451 double phimax =
pos.phi()+dphi;
453 if ( phimin >
M_PI ) phimin -= 2*
M_PI;
454 if ( phimin < -
M_PI ) phimin += 2*
M_PI;
456 std::pair<double,double>
phiRange(phimin,phimax);
459 if((sector_l==
'L' && m_Zratio.first==0) || (sector_l==
'S' && m_Zratio.second==0)) {
461 Id=
helper->multilayerID(Id,2);
465 if(sector_l==
'L') m_Zratio.first=
ratio;
466 else if(sector_l==
'S') m_Zratio.second=
ratio;
469 m_isInitialized =
true;