ATLAS Offline Software
Loading...
Searching...
No Matches
MdtVsTgcRawData_PRDonTrack.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Package : MdtVsTgcRawDataValAlg
7// Author: M.King(Kobe)
8// Feb. 2011
9//
10// DESCRIPTION:
11// Subject: TGC Efficiency -->TGC Efficiency plots including EIFI by comparing with MDT Segments
13
15
21
26
27#include <inttypes.h>
28
29#include <sstream>
30#include <algorithm>
31#include <fstream>
32
33// Search for PRD around tracks
34void
35MdtVsTgcRawDataValAlg::CheckTGConTrack(std::vector<SegmTrack> (&matchedSegments)[2],
36 const Muon::TgcPrepDataContainer *tgc_prepcontainer){
37 // Define Cuts:
38 // Loose cut for PRD and Extrapolated
39 const float dPhiCut_Loose = M_PI/8;
40 // Cut for Global Position Efficiencies
41 const float dPhiCutGlobal[2] = {static_cast<float>(M_PI/24),static_cast<float>(M_PI/12)}; //[WireStrip]
42 const float dRhoCutGlobal[2] = { 0.08, 0.5}; //[WireStrip]
43 // Cut for Sector Efficiencies
44 const float dPhiCutSector[2] = { 0.2, 0.1}; //[WireStrip]
45 const float dRhoCutSector[2] = { 200, 2000}; //[WireStrip]
46
47 // Loop over sides
48 for(int i=0;i<2;i++){// AC
49 // Get number of tracks
50 unsigned int nTrack=matchedSegments[i].size();
51
52 // Fill nEvents histograms
53 m_mvt_cutspassed[i]->Fill(1);
54 if(nTrack==0)m_mvt_cutspassed[i]->Fill(2);
55 if(nTrack>1)m_mvt_cutspassed[i]->Fill(3);
56 if(nTrack==1)m_mvt_cutspassed[i]->Fill(4);
57
58 // Cut events without exactly one set of matched Segments
59 if(nTrack!=1)continue;
60
61 // Declare Position variables for inner
62 //Trk::GlobalPosition innerSegmPos;
63 Amg::Vector3D innerSegmPos = {0, 0, 0};
64
65 // float innerSegmEta=0;
66 float innerSegmRho=0; float innerSegmPhi=0; float innerSegmZ=0;
67 //Trk::GlobalDirection innerSegmDirzunit;
68 Amg::Vector3D innerSegmDirzunit = {0, 0, 0};
69
70 // Declare Position variables for midstation
71 //Trk::GlobalPosition midSegmPos;
72 Amg::Vector3D midSegmPos = {0, 0, 0};
73
74 // float midSegmRho =0; float midSegmEta =0;
75 float midSegmPhi =0; float midSegmZ =0;
76 //Trk::GlobalDirection midSegmDirzunit;
77 Amg::Vector3D midSegmDirzunit = {0, 0, 0};
78
79 // Check which layers have sufficienct segments to operate on for global coordinates
80 bool canCheckGlobal[4] = {0, 0, 0, 0};// [TGCStation]
81 if(matchedSegments[i].at(0).at(2)!=nullptr){
82 // Check Midstation
83 canCheckGlobal[0]=true; canCheckGlobal[1]=true; canCheckGlobal[2]=true;
84 // Read Midstation Segment Values into variables
85 midSegmPos = Amg::Vector3D(matchedSegments[i].at(0).at(2)->globalPosition());
86 midSegmPhi = midSegmPos.phi();
87 midSegmZ = midSegmPos.z();
88 if(midSegmPhi<0)midSegmPhi+=2*M_PI;
89 midSegmDirzunit = Amg::Vector3D(midSegmPos/std::abs(midSegmZ));
90 }
91 if((matchedSegments[i].at(0).at(0)!=nullptr)&&(matchedSegments[i].at(0).at(2)!=nullptr)){
92 // Check EIFI
93 canCheckGlobal[3]=true;
94 // Read Inner Segment Values
95 innerSegmPos = Amg::Vector3D(matchedSegments[i].at(0).at(0)->globalPosition());
96 innerSegmRho = std::abs(innerSegmPos.perp());
97 innerSegmZ = std::abs(innerSegmPos.z());
98 // Modify position
99 innerSegmPhi = midSegmPhi;
100
101 innerSegmPos = Amg::Vector3D(innerSegmRho*std::cos(innerSegmPhi), innerSegmRho*std::sin(innerSegmPhi), innerSegmZ);
102 innerSegmDirzunit = Amg::Vector3D(innerSegmPos/std::abs(innerSegmZ));
103 }
104
105 // If no layers can be checked (i.e. no midstation segment matched) skip side
106 bool skipSide = true;
107 for(int jTGC=0;jTGC<4;jTGC++)if(canCheckGlobal[jTGC]==true)skipSide=false;
108 if(skipSide==true)continue;
109
110 // Initialize variables for TRE array search
111 int TGCStationNames[8] ={41, 42, 43, 44, 45, 46, 47, 48};
112 int TGCstation_StationFE[4] ={-1,-1,-1,-1};// [TGCStation]
113 int TGCstation_StationEta[4]={ 0, 0, 0, 0};// [TGCStation]
114 int TGCstation_StationPhi[4]={ 0, 0, 0, 0};// [TGCStation]
115 int nStationMatch[4] ={ 0, 0, 0, 0};// [TGCStation]
116 bool canCheckSector[4] ={ true, true, true, true};// [TGCStation]
117
118 // Loop through TRE array, finding sectors which match the track in each layer
119 for(int stationnameindex=0; stationnameindex<8; stationnameindex++){// Station {T1F,T1E,T2F,T2E,T3F,T3E,T4F,T4E}
120 // Skip stations which don't have sufficient Segments to run efficiency check
121 int stationName = TGCStationNames[stationnameindex];
122 int stationIndex= TGCstationname2stationindex(stationName);
123 if(stationIndex<0) continue;
124 if(!canCheckGlobal[stationIndex])continue;
125
126 // Loop over StationEta&StationPhi
127 for(int stationeta=1; stationeta<=8; stationeta++){// AbsStationEta
128 for(int stationphi=1; stationphi<=48; stationphi++){// StationPhi
129 // Cut Station EtaPhi combinations with no TGC element
130 if(m_TREarray[stationnameindex][i][stationeta][stationphi]==nullptr)continue;
131 const MuonGM::TgcReadoutElement *tre=m_TREarray[stationnameindex][i][stationeta][stationphi];
132
133 // Extrapolate position from nearest Station's Segment to Sector's Z
134 float sectorZ=tre->globalPosition().z();
135 //Trk::GlobalPosition sectorExtrapolatedPos;
136 Amg::Vector3D sectorExtrapolatedPos;
137
138 if(stationIndex==3){// Inner
139 float dZ_sector=std::abs(sectorZ)-std::abs(innerSegmZ);
140 //sectorExtrapolatedPos = Trk::GlobalPosition(innerSegmPos+(innerSegmDirzunit*dZ_sector));
141 sectorExtrapolatedPos = Amg::Vector3D(innerSegmPos+(innerSegmDirzunit*dZ_sector));
142 }
143 else{// Midstation
144 float dZ_sector=std::abs(sectorZ)-std::abs(midSegmZ);
145 sectorExtrapolatedPos = Amg::Vector3D(midSegmPos+(midSegmDirzunit*dZ_sector));
146 }
147
148 // Convert extrapolated position to local position on the Sector
149 Identifier sector_id=tre->identify();
150 const Amg::Vector3D sectorLocalPos3D=tre->globalToLocalTransf(sector_id)*sectorExtrapolatedPos;
151 Amg::Vector2D sectorLocalPos2D(sectorLocalPos3D.y(),sectorLocalPos3D.z());
152
153 double avWidth = (tre->getLongSsize()+tre->getSsize())/2;
154 //double dWidth = (tre->longWidth()-tre->shortWidth());
155 double length = tre->length();
156
157 // Cut sectors which the track does not go through the central 80% of (avoids double counts)
158 double tol1=-0.1*(avWidth/2);
159 double tol2=-0.1*(length/2);
160
161 bool insideSectorBounds=tre->bounds().inside(sectorLocalPos2D,tol1,tol2);
162 if(!insideSectorBounds)continue;
163
164 // Assign values to matching station variables
165 TGCstation_StationFE[stationIndex]= (tre->isForward()==false);
166 TGCstation_StationEta[stationIndex]=stationeta;
167 TGCstation_StationPhi[stationIndex]=stationphi;
168 nStationMatch[stationIndex]++;
169 }// StationPhi
170 }// StationEta
171 }// StationName
172
173 // Don't check stations that don't have exactly 1 match for this track
174 for(int jTGC=0;jTGC<4;jTGC++){// TGC Station
175 if(nStationMatch[jTGC]==0){
176 canCheckSector[jTGC]=false;
177 }
178 else if(nStationMatch[jTGC]>1){
179 canCheckSector[jTGC]=false;
180 // Should be impossible, but happens due a problem with the bounds().inside function
181 // commenting out until this bug is resolved
182 //m_log << MSG::WARNING << "SegmTrack: Number of matches for TGC" << jTGC+1 << " is " << nStationMatch[jTGC] << endl;
183 }
184 }// TGC Station
185
186 // Loop through segments to check number of TGC Strips in each
187 int nTGCStrips[4] = {0, 0, 0, 0};//[TGCStation]
188 for(int jMDT=0;jMDT<4;jMDT++){// MDT Station
189 if(matchedSegments[i].at(0).at(jMDT)==nullptr)continue;
190 const Muon::MuonSegment *segm=matchedSegments[i].at(0).at(jMDT);
191 // Loop through contained ROTs and identify used stations
192 const std::vector<const Trk::MeasurementBase*> mMeasTrk = segm->containedMeasurements();
193 ATH_MSG_DEBUG( "number of MeasurementBase: "<<mMeasTrk.size() );
194 for (unsigned int i=0; i<mMeasTrk.size(); i++) {
195 const Trk::MeasurementBase* m = mMeasTrk[i];
196 //const Trk::RIO_OnTrack* rio = dynamic_cast<const Trk::RIO_OnTrack*>(m);
198 if(crot) {
199 for(const auto& rio : crot->containedROTs()){
200 //const Trk::RIO_OnTrack* rio = crot->rioOnTrack(iROT);
201 Identifier id = rio->identify();
202 int stationName = int(m_idHelperSvc->mdtIdHelper().stationName(id));
203 // 41=T1F 42=T1E 43=T2F 44=T2E 45=T3F 46=T3E 47=T4F 48=T4E
204 if(m_idHelperSvc->tgcIdHelper().isStrip(id)){
205 if((jMDT==2)&&((stationName==41)||(stationName==42)))nTGCStrips[0]++;// TGC
206 if((jMDT==2)&&((stationName==43)||(stationName==44)))nTGCStrips[1]++;// TGC
207 if((jMDT==2)&&((stationName==45)||(stationName==46)))nTGCStrips[2]++;// TGC
208 if((jMDT==0)&&((stationName==47)||(stationName==48)))nTGCStrips[3]++;// TGC
209 }
210
211 ATH_MSG_DEBUG( " check if TGC strip: "<<m_idHelperSvc->tgcIdHelper().isStrip(id)<<" StationName: "<<stationName );
212 }
213 }
214 }
215 }// MDT Station
216
217
218 // Don't check mid-stations when there are no strips in other mid-stations
219 if((nTGCStrips[1]==0)&&(nTGCStrips[2]==0)){canCheckSector[0]=false;canCheckGlobal[0]=false;}
220 if((nTGCStrips[0]==0)&&(nTGCStrips[2]==0)){canCheckSector[1]=false;canCheckGlobal[1]=false;}
221 if((nTGCStrips[0]==0)&&(nTGCStrips[1]==0)){canCheckSector[2]=false;canCheckGlobal[2]=false;}
222
223 // Initialise hit registered arrays
224 // bool hitregistered[9][2];
225 bool sectorhitregistered[9][2];
226 for(int l=0;l<9;l++){// Layer
227 for(int k=0;k<2;k++){// WireStrip
228 // hitregistered[l][k]=false;
229 sectorhitregistered[l][k]=false;
230 }// WireStrip
231 }// Layer
232
233 // Initialise flags for whether a layer in this event has PRD and PRD which matched the current track
234 bool HasPRD[9] ={false,false,false,false,false,false,false,false,false};
235 bool PRDMatch[9]={false,false,false,false,false,false,false,false,false};
236
237 // Loop over TGC Prep Data container
238 Muon::TgcPrepDataContainer::const_iterator prepit_end=tgc_prepcontainer->end();
239 for( Muon::TgcPrepDataContainer::const_iterator prepit=tgc_prepcontainer->begin();
240 prepit!=prepit_end;
241 ++prepit){
242
243 //loop over TGC Prep Data collection
244 Muon::TgcPrepDataCollection::const_iterator prepitc_end=(*prepit)->end();
245 for( Muon::TgcPrepDataCollection::const_iterator prepitc=(*prepit)->begin();
246 prepitc!= prepitc_end;
247 ++prepitc){
248 // Get PRD and variables
249 const Muon::TgcPrepData* tpd=*prepitc;
250 const MuonGM::TgcReadoutElement *tre = tpd->detectorElement();
251 const std::string stationType = tre->getStationType();
252
253 // Get id values
254 Identifier tgcid=(*prepitc)->identify();
255 int tgcAC=(tre->sideA()==false);//isNotAside a:0, c:1
256 int tgcFE=(tre->isForward()==false);//isNotForward f:0, e:1
257 int tgcWS=(m_idHelperSvc->tgcIdHelper().isStrip(tgcid));//isStrip w=0, s=1
258 int stationName = m_idHelperSvc->tgcIdHelper().stationName(tgcid);
259 int stationEta = std::abs(tre->getStationEta());
260 int stationPhi = tre->getStationPhi();
261 int gasGap = m_idHelperSvc->tgcIdHelper().gasGap(tgcid);
262
263 // Cut hits except those from same side EIFI & Midstation
264 if(tgcAC!=i) continue;
265 if(stationName>48 || stationName<41) continue;
266
267 // Get layer number and stationIndex
268 int layer = TGCgetlayer(stationName,gasGap);
269 int stationIndex = TGCstationname2stationindex(stationName);
270
271 // Skip PRD in stations which can't be checked
272 if(stationIndex<0) continue;
273 if(!(canCheckGlobal[stationIndex]||canCheckSector[stationIndex]))continue;
274 if(layer<0) continue;
275 HasPRD[layer]=true;
276
277 // Get position variables
278 // const Trk::GlobalPosition prdPos = tpd->globalPosition();
279 const Amg::Vector3D prdPos = tpd->globalPosition();
280 float tgcRho = std::abs(prdPos.perp());
281 float tgcPhi = prdPos.phi();
282 float tgcZ = prdPos.z();
283 if(tgcPhi<0)tgcPhi+=2*M_PI;
284
285 // Run Extrapolation
286 // Trk::GlobalPosition tgcExtrapolatedPos;
287 Amg::Vector3D tgcExtrapolatedPos;
288 if(stationIndex==3){// Extrapolate position from Inner Position to PRD Z position
289 //if(innerSegmPos=0)m_log << MSG::WARNING << "MidstationOnly: innerSegmPos=0 but passed canCheckGlobal" );
290 float dZ = std::abs(tgcZ) - std::abs(innerSegmZ);
291 //tgcExtrapolatedPos = Trk::GlobalPosition(innerSegmPos+(innerSegmDirzunit*dZ));
292 tgcExtrapolatedPos = Amg::Vector3D(innerSegmPos+(innerSegmDirzunit*dZ));
293 }
294 else{// Extrapolate position from Midstation Position to PRD Z position
295 float dZ = std::abs(tgcZ) - std::abs(midSegmZ);
296 //tgcExtrapolatedPos = Trk::GlobalPosition(midSegmPos+(midSegmDirzunit*dZ));
297 tgcExtrapolatedPos = Amg::Vector3D(midSegmPos+(midSegmDirzunit*dZ));
298 }
299 float tgcExtrRho = std::abs(tgcExtrapolatedPos.perp());
300 float tgcExtrPhi = tgcExtrapolatedPos.phi();
301 if(tgcExtrPhi<0)tgcExtrPhi+=2*M_PI;
302
303 // Get differences between extrapolated and segm2 positions
304 float dRho = tgcRho-tgcExtrRho;
305 float dPhi = tgcPhi-tgcExtrPhi;
306 if(dPhi<-M_PI)dPhi+=2*M_PI;
307 if(dPhi> M_PI)dPhi-=2*M_PI;
308
309 // Pass through loose phi cut to eliminate some noise
310 if(std::abs(dPhi)<dPhiCut_Loose){
311 // Fill PRD sagitta histograms
312 if(m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][0]) m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][0]->Fill(dRho);
313 if(m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][2]) m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][2]->Fill(dPhi);
314
315 // Global efficiency check
316 if(canCheckGlobal[stationIndex]){
317 // Do check
318 float dRhoCut = dRhoCutGlobal[tgcWS]*tgcExtrRho;
319 if(std::abs(dPhi)<dPhiCutGlobal[tgcWS] && std::abs(dRho)<dRhoCut){
320 }
321 }
322
323 // Sector Efficiency Check
324 if(canCheckSector[stationIndex]){// If this station can be checked
325 if((stationEta==TGCstation_StationEta[stationIndex])&&
326 (stationPhi==TGCstation_StationPhi[stationIndex])&&
327 (tgcFE==TGCstation_StationFE[stationIndex])){// If Station FE&Eta&Phi match
328 if(std::abs(dPhi)<dPhiCutSector[tgcWS] && std::abs(dRho)<dRhoCutSector[tgcWS]){
329 sectorhitregistered[layer][tgcWS]=true;
330 }
331 }// Station EtaPhi
332 }
333
334 }// dPhi Loose Cut
335 }// TGC PRD Collection
336 }// TGC PRD Container
337
338 // Fill Efficiency Histograms
339 for(int l=0;l<9;l++){// Layer
340 // Get Station Number
341 int stationIndex=TGClayer2stationindex(l);
342 if(stationIndex<0) continue;
343 for(int k=0;k<2;k++){// WireStrip
344 // If Segment Track matches a Sector
345 if(canCheckSector[stationIndex]){
346 if((TGCstation_StationFE[stationIndex]<0)||(TGCstation_StationEta[stationIndex]==0)||(TGCstation_StationPhi[stationIndex]==0)){
347 ATH_MSG_WARNING( "SegmTrack: canCheckSector passed for jTGC=" << stationIndex
348 << " but, FE=" << TGCstation_StationFE[stationIndex]
349 << " Eta=" << TGCstation_StationEta[stationIndex]
350 << " Phi=" << TGCstation_StationPhi[stationIndex] );
351 continue;
352 }
353 // Get Sector histogram indexes
354 int stationMap_EtaIndex=getStationMapIndex(1, l, TGCstation_StationFE[stationIndex], TGCstation_StationEta[stationIndex], TGCstation_StationPhi[stationIndex]);
355 int stationMap_PhiIndex=getStationMapIndex(2, l, TGCstation_StationFE[stationIndex], TGCstation_StationEta[stationIndex], TGCstation_StationPhi[stationIndex]);
356 // Fill Sector efficiency histograms
357 if(sectorhitregistered[l][k]){// Hit in Sector matches extrapolated track
358 m_eff_stationmapbase[i][k][1]->Fill(stationMap_EtaIndex, stationMap_PhiIndex);
359 }
360 m_eff_stationmapbase[i][k][2]->Fill(stationMap_EtaIndex, stationMap_PhiIndex);
361 }
362 }// WireStrip
363 }// Layer
364
365 // Fill +Has Station bins of histogram
366 if(HasPRD[0]||HasPRD[1]||HasPRD[2])m_mvt_cutspassed[i]->Fill(7);
367 if(HasPRD[3]||HasPRD[4])m_mvt_cutspassed[i]->Fill(9);
368 if(HasPRD[5]||HasPRD[6])m_mvt_cutspassed[i]->Fill(11);
369 if(HasPRD[7]||HasPRD[8])m_mvt_cutspassed[i]->Fill(5);
370
371 // Fill Match Station bins of histogram
372 if(PRDMatch[0]||PRDMatch[1]||PRDMatch[2])m_mvt_cutspassed[i]->Fill(8);
373 if(PRDMatch[3]||PRDMatch[4])m_mvt_cutspassed[i]->Fill(10);
374 if(PRDMatch[5]||PRDMatch[6])m_mvt_cutspassed[i]->Fill(12);
375 if(PRDMatch[7]||PRDMatch[8])m_mvt_cutspassed[i]->Fill(6);
376 if((PRDMatch[0]||PRDMatch[1]||PRDMatch[2])&&
377 (PRDMatch[3]||PRDMatch[4])&&
378 (PRDMatch[5]||PRDMatch[6])&&
379 (PRDMatch[7]||PRDMatch[8]))m_mvt_cutspassed[i]->Fill(13);
380 if((PRDMatch[0]&&PRDMatch[1]&&PRDMatch[2])&&
381 (PRDMatch[3]&&PRDMatch[4])&&
382 (PRDMatch[5]&&PRDMatch[6])&&
383 (PRDMatch[7]&&PRDMatch[8]))m_mvt_cutspassed[i]->Fill(14);
384
385
386 }// AC
387}// End of function
#define M_PI
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double length(const pvec &v)
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const
return const_iterator for end of container
const_iterator begin() const
return const_iterator for first entry
int TGCgetlayer(int stationName, int g)
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
TH1 * m_mvt_extrprdsag[2][4][2][2][4]
void CheckTGConTrack(std::vector< SegmTrack >(&matchedSegments)[2], const Muon::TgcPrepDataContainer *tgc_prepcontainer)
int getStationMapIndex(int x, int l, int stationFE, int stationEta, int stationPhi)
const MuonGM::TgcReadoutElement * m_TREarray[8][2][9][49]
int TGCstationname2stationindex(int stationName)
virtual const Trk::SurfaceBounds & bounds() const override
Return the boundaries of the element.
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Amg::Transform3D globalToLocalTransf(const Identifier &id) const
Returns the global -> local transformation.
bool isForward() const
Returns true if the chamber is mounted on the most inner ring, i.e. a TxF chamber.
Class for competing MuonClusters, it extends the Trk::CompetingRIOsOnTrack base class.
const std::vector< std::unique_ptr< const MuonClusterOnTrack > > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
This is the common class for 3D segments used in the muon spectrometer.
Class to represent TGC measurements.
Definition TgcPrepData.h:32
virtual const Amg::Vector3D & globalPosition() const override final
Returns the global position.
virtual const MuonGM::TgcReadoutElement * detectorElement() const override final
Returns the detector element corresponding to this PRD The pointer will be zero if the det el is not ...
This class is the pure abstract base class for all fittable tracking measurements.
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const =0
Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
MuonPrepDataContainerT< TgcPrepData > TgcPrepDataContainer