Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
StripSegmentTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "GaudiKernel/ConcurrencyFlags.h"
6 
8 
9 namespace NSWL1 {
10 
11  StripSegmentTool::StripSegmentTool( const std::string& type, const std::string& name, const IInterface* parent) :
13  {
14  declareInterface<NSWL1::IStripSegmentTool>(this);
15  }
16 
18  ATH_MSG_DEBUG("initializing " << name() );
19  ATH_MSG_DEBUG(name() << " configuration:");
20 
21  ATH_CHECK(m_idHelperSvc.retrieve());
22  ATH_CHECK(m_regSelTableKey.initialize());
23  return StatusCode::SUCCESS;
24  }
25 
27  const MuonGM::MuonDetectorManager* p_det;
28  ATH_CHECK(detStore()->retrieve(p_det));
30  const auto regSelector = dynamic_cast<const RegSelSiLUT*>(rh_stgcLUT->payload());
31  std::vector<const RegSelModule*> moduleList;
32  for(const auto& i : m_idHelperSvc->stgcIdHelper().idVector()) { // all modules
33  IdentifierHash moduleHashId;
34  m_idHelperSvc->stgcIdHelper().get_module_hash(i, moduleHashId);
35  moduleList.push_back(regSelector->Module(moduleHashId));
36  }
37  float etamin=-1;
38  float etamax=-1;
39  float rmin=-1;
40  float rmax=-1;
41  float zmin=-1;
42  float zmax=-1;
43  std::sort(moduleList.begin(),moduleList.end(),[](const auto& M1,const auto& M2){ return std::abs(M1->_etaMin()) < std::abs(M2->_etaMin());} );
44  etamin=moduleList.at(0)->_etaMin();
45  std::sort(moduleList.begin(),moduleList.end(),[](const auto& M1,const auto& M2){ return std::abs(M1->_etaMax()) > std::abs(M2->_etaMax());} );
46  etamax=moduleList.at(0)->_etaMax();
47  std::sort(moduleList.begin(),moduleList.end(),[](const auto& M1,const auto& M2){ return std::abs(M1->rMin()) < std::abs(M2->rMin());} );
48  rmin=moduleList.at(0)->rMin();
49  std::sort(moduleList.begin(),moduleList.end(),[](const auto& M1,const auto& M2){ return std::abs(M1->rMax()) > std::abs(M2->rMax());} );
50  rmax=moduleList.at(0)->rMax();
51  std::sort(moduleList.begin(),moduleList.end(),[](const auto& M1,const auto& M2){ return std::abs(M1->zMin()) < std::abs(M2->zMin());} );
52  zmin=moduleList.at(0)->zMin();
53  std::sort(moduleList.begin(),moduleList.end(),[](const auto& M1,const auto& M2){ return std::abs(M1->zMax()) > std::abs(M2->zMax());} );
54  zmax=moduleList.at(0)->zMax();
55 
56  if(rmin<=0 || rmax<=0) ATH_MSG_WARNING("Unable to fetch NSW r/z boundaries");
57  env.lower_r = rmin;
58  env.upper_r = rmax;
59  env.lower_eta = etamin;
60  env.upper_eta = etamax;
61  env.lower_z = zmin;
62  env.upper_z = zmax;
63  ATH_MSG_DEBUG("rmin=" << rmin << " rmax=" << rmax << " zmin=" << zmin << " zmax=" << zmax << " etamin=" << etamin << " etamax=" << etamax);
64  return StatusCode::SUCCESS;
65  }
66 
67  uint8_t StripSegmentTool::findRIdx(const float val, const Envelope_t &env) const {
68  unsigned int nSlices=(1<<m_rIndexBits); //256
69  std::pair<float,float> range;
70  switch(m_ridxScheme){
71  case 0:
72  range=std::make_pair(env.lower_r, env.upper_r);
73  break;
74  case 1:
75  range=std::make_pair(env.lower_eta, env.upper_eta);
76  break;
77  default:
78  break;
79  }
80  float step=(range.second-range.first)/nSlices;
81 
82  // the cases with val<=range.first or val>=range.second have been abandoned before
83  for(uint8_t i=0;i<nSlices;i++) {
84  if(range.first+i*step <= val && val < range.first+(i+1)*step) return i;
85  }
86  ATH_MSG_ERROR( "StripSegmentTool: findRIdx failed!");
87  return 0;
88  }
89 
91  uint8_t nbins_dtheta=1<<m_dThetaBits;
92  float step_dtheta=(m_dtheta_max-m_dtheta_min)/nbins_dtheta;
93  for(uint8_t i=0;i<nbins_dtheta;++i) {
94  if(val<m_dtheta_min+i*step_dtheta) return i;
95  }
96  return 0;
97  }
98 
99  StatusCode StripSegmentTool::find_segments(std::vector< std::unique_ptr<StripClusterData> >& clusters,
100  const std::unique_ptr<Muon::NSW_TrigRawDataContainer>& trgContainer) const {
101  Envelope_t envelope;
102  ATH_CHECK(FetchDetectorEnvelope(envelope));
103 
104  if (clusters.empty()) {
105  ATH_MSG_WARNING("Received event with no clusters. Skipping...");
106  return StatusCode::SUCCESS;
107  }
108 
109  std::map<uint32_t, std::vector<std::unique_ptr<StripClusterData>>[2] > cluster_map; // gather clusters by hash_bandid and seperate in wedge
110 
111  int sectorid=-1; // [1,8]
112  int sideid=-1; // sideid==0: C
113  int sectorNumber=-1; // [1,16]
114  int hash=-1; // [1,32]
115 
116  int bandId=-1; // bandId is different for large and small sector type, the same for side / specific sector
117 
118  for(auto& cl : clusters){
119  // combine the side, sectortype, sectorid to form the hash
120  sideid=cl->sideId();
121  sectorid=cl->sectorId();
122  if(cl->isSmall()) sectorNumber=2*sectorid;
123  else sectorNumber=2*sectorid-1;
124  hash=16*sideid+sectorNumber;
125 
126  bandId=cl->bandId();
127 
128 
129  std::string id_str=std::to_string(hash)+"000"+std::to_string(bandId); // [1,32]*1000 + [0,90](could be extended in the future), the 1000 factor promise there's no confusion, such as '1'+'12" and '11'+'2'
130  uint32_t hash_bandid=atoi(id_str.c_str());
131 
132  // use the clusters in 2 wedges, with the same bandId, to form the sector segment
133  /*****************************************************************************************************/
134  auto item =cluster_map.find(hash_bandid);
135  if (item != cluster_map.end()){
136  item->second[cl->wedge()-1].push_back(std::move(cl));
137  }
138  else{
139  cluster_map[hash_bandid][cl->wedge()-1].push_back(std::move(cl));
140  }
141  }
142 
143  ATH_MSG_DEBUG(" Building NSW Segment RDO at hash=" << hash);
144 
145  for(const auto& band : cluster_map){//main band loop
146  int bandId=band.first;
147  if (band.second[0].size() == 0){
148  ATH_MSG_WARNING("Cluster size is zero for inner wedge trg with bandId "<<bandId<<"...skipping");
149  continue;
150  }
151  if(band.second[1].size() == 0){
152  ATH_MSG_WARNING("Cluster size is zero for outer wedge trg with bandId "<<bandId<<"...skipping");
153  continue;
154  }
155  float glx1=0;
156  float gly1=0;
157  float glx2=0;
158  float gly2=0;
159  float charge1=0;
160  float charge2=0;
161 
162  float eta=0;
163  float phi=0;
164  float theta=0;
165  float theta_inf=0;
166  float dtheta=0;
167  float eta_inf=0;
168 
169  // First measurement, corresponding to the inner wedge
170  float z1=0;
171  uint16_t sectorID = 0, bcID = 0;
172  char sectorSide = '-';
173  for( const auto& cl : band.second[0] ){
174  z1+=cl->globZ()*cl->charge();
175  glx1+=cl->globX()*cl->charge();
176  gly1+=cl->globY()*cl->charge();
177  charge1+=cl->charge();
178  sectorID = (cl->isSmall()) ? 2*cl->sectorId()-1 : 2*(cl->sectorId()-1);
179  sectorSide = (cl->sideId() == 0) ? 'C' : 'A';
180  bcID = cl->BCID();
181  }
182  auto trgRawData=std::make_unique< Muon::NSW_TrigRawData>(sectorID, sectorSide, bcID);
183 
184  // Second measurement, corresponding to the outer wedge
185  float z2=0;
186  for( const auto& cl : band.second[1] ){
187  z2+=cl->globZ()*cl->charge();
188  glx2+=cl->globX()*cl->charge();
189  gly2+=cl->globY()*cl->charge();
190  charge2+=cl->charge();
191  sectorID = (cl->isSmall()) ? 2*cl->sectorId()-1 : 2*(cl->sectorId()-1);
192  sectorSide = (cl->sideId() == 0) ? 'C' : 'A';
193  bcID = cl->BCID();
194  if (( sectorID != trgRawData->sectorId() ) ||
195  ( sectorSide != trgRawData->sectorSide() ) ||
196  ( bcID != trgRawData->bcId() )) ATH_MSG_WARNING("Possible mismatch between inner and outer wedge RDO parameters");
197  }
198  if(charge1!=0){
199  z1=z1/charge1;
200  glx1=glx1/charge1;
201  gly1=gly1/charge1;
202  }
203  if(charge2!=0){
204  z2=z2/charge2;
205  glx2=glx2/charge2;
206  gly2=gly2/charge2;
207  }
208 
209  //segment calc
210  ROOT::Math::XYZVector v3_centr1(glx1,gly1,z1), v3_centr2(glx2,gly2,z2);
211  ROOT::Math::XYZVector v3_segment = v3_centr2 - v3_centr1;
212  phi=v3_segment.Phi();
213  theta=v3_segment.Theta();
214  eta=v3_segment.Eta();
215 
216  //inf momentum track
217  theta_inf=v3_centr1.Theta();
218  eta_inf=v3_centr1.Eta();
219  dtheta=(theta-theta_inf)*1000;//In Milliradian
220 
221  ATH_MSG_DEBUG("StripSegmentTool: phi:" << phi << " theta:" << theta << " eta: " << eta << " theta_inf: " << theta_inf << " eta_inf: " << eta_inf << " dtheta: " << dtheta);
222 
223  //do not get confused. this one is trigger phiId
224  int phiId=band.second[0].at(0)->phiId();
225 
226  float rfar=envelope.upper_z*std::abs(std::tan(theta_inf));
227 
228  if( rfar >= envelope.upper_r || rfar < envelope.lower_r || std::abs(eta_inf) >= envelope.upper_eta || std::abs(eta_inf) < envelope.lower_eta){
229  ATH_MSG_WARNING("measured r/eta is out of detector envelope!");
230  return StatusCode::SUCCESS;
231  }
232 
233  uint8_t rIndex=0;
234  switch(m_ridxScheme) {
235  case 0:
236  rIndex=findRIdx(rfar, envelope);
237  break;
238  case 1:
239  rIndex=findRIdx(std::abs(eta_inf), envelope);
240  break;
241  default:
242  break;
243  }
244 
245  bool phiRes=true;
246  bool lowRes=false;//we do not have a recipe for a singlewedge trigger. so lowres is always false for now
247  uint8_t dtheta_int=findDtheta(dtheta);
248 
249  //However it needs to be kept an eye on... will be something in between 7 and 15 mrad needs to be decided
250  if(std::abs(dtheta)>15) continue;
251  auto rdo_segment= std::make_unique<Muon::NSW_TrigRawDataSegment>( dtheta_int, (uint8_t)phiId, (rIndex), lowRes, phiRes);
252  trgRawData->push_back(std::move(rdo_segment));
253  trgContainer->push_back(std::move(trgRawData));
254 
255  }//end of clmap loop
256  return StatusCode::SUCCESS;
257  }
258 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
NSWL1::eta
float eta(float x, float y, float z)
Definition: GeoUtils.cxx:9
NSWL1::StripSegmentTool::findRIdx
uint8_t findRIdx(const float val, const Envelope_t &env) const
Definition: StripSegmentTool.cxx:67
NSWL1::StripSegmentTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: StripSegmentTool.h:78
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
NSWL1::StripSegmentTool::m_ridxScheme
Gaudi::Property< int > m_ridxScheme
Definition: StripSegmentTool.h:86
NSWL1::StripSegmentTool::initialize
virtual StatusCode initialize() override
Definition: StripSegmentTool.cxx:17
NSWL1::StripSegmentTool::m_dtheta_max
Gaudi::Property< float > m_dtheta_max
Definition: StripSegmentTool.h:85
Envelope_t::upper_r
float upper_r
Definition: StripSegmentTool.h:43
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
NSWL1::StripSegmentTool::StripSegmentTool
StripSegmentTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: StripSegmentTool.cxx:11
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
NSWL1::StripSegmentTool::FetchDetectorEnvelope
StatusCode FetchDetectorEnvelope(Envelope_t &env) const
Definition: StripSegmentTool.cxx:26
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
NSWL1::StripSegmentTool::m_rIndexBits
Gaudi::Property< int > m_rIndexBits
Definition: StripSegmentTool.h:82
lumiFormat.i
int i
Definition: lumiFormat.py:85
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
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Envelope_t::upper_z
float upper_z
Definition: StripSegmentTool.h:47
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
NSWL1::StripSegmentTool::m_dThetaBits
Gaudi::Property< int > m_dThetaBits
Definition: StripSegmentTool.h:83
Envelope_t::lower_r
float lower_r
Definition: StripSegmentTool.h:42
NSWL1::StripSegmentTool::m_dtheta_min
Gaudi::Property< float > m_dtheta_min
Definition: StripSegmentTool.h:84
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
NSWL1::StripSegmentTool::find_segments
virtual StatusCode find_segments(std::vector< std::unique_ptr< StripClusterData > > &, const std::unique_ptr< Muon::NSW_TrigRawDataContainer > &) const override
Definition: StripSegmentTool.cxx:99
item
Definition: ItemListSvc.h:43
NSWL1::StripSegmentTool::findDtheta
uint8_t findDtheta(const float) const
Definition: StripSegmentTool.cxx:90
Envelope_t::upper_eta
float upper_eta
Definition: StripSegmentTool.h:45
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
StripSegmentTool.h
MuonGM::MuonDetectorManager
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:50
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
Envelope_t::lower_eta
float lower_eta
Definition: StripSegmentTool.h:44
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
RegSelSiLUT
Definition: RegSelSiLUT.h:41
LArCellBinning.step
step
Definition: LArCellBinning.py:158
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
Envelope_t
Definition: StripSegmentTool.h:41
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
python.DataFormatRates.env
env
Definition: DataFormatRates.py:32
NSWL1::phi
float phi(float x, float y, float z)
Definition: GeoUtils.cxx:14
LArCellBinning.etamin
etamin
Definition: LArCellBinning.py:137
NSWL1
A trigger trigger candidate for a stgc sector.
Definition: NSWL1Simulation.cxx:7
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
NSWL1::StripSegmentTool::m_regSelTableKey
SG::ReadCondHandleKey< IRegSelLUTCondData > m_regSelTableKey
Definition: StripSegmentTool.h:79
WriteBchToCool.moduleList
moduleList
Definition: WriteBchToCool.py:72
RegSelCondData::payload
const T * payload() const
Definition: RegSelCondData.h:33