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