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 const std::vector<const Muon::MuonClusterOnTrack*> mc_list = crot->containedROTs();
201 for(unsigned int iROT=0; iROT< mc_list.size(); iROT++){
202 const Muon::MuonClusterOnTrack * rio = mc_list[iROT];
203 //const Trk::RIO_OnTrack* rio = crot->rioOnTrack(iROT);
204 Identifier id = rio->identify();
205 int stationName = int(m_idHelperSvc->mdtIdHelper().stationName(id));
206 // 41=T1F 42=T1E 43=T2F 44=T2E 45=T3F 46=T3E 47=T4F 48=T4E
207 if(m_idHelperSvc->tgcIdHelper().isStrip(id)){
208 if((jMDT==2)&&((stationName==41)||(stationName==42)))nTGCStrips[0]++;// TGC
209 if((jMDT==2)&&((stationName==43)||(stationName==44)))nTGCStrips[1]++;// TGC
210 if((jMDT==2)&&((stationName==45)||(stationName==46)))nTGCStrips[2]++;// TGC
211 if((jMDT==0)&&((stationName==47)||(stationName==48)))nTGCStrips[3]++;// TGC
212 }
213
214 ATH_MSG_DEBUG( " check if TGC strip: "<<m_idHelperSvc->tgcIdHelper().isStrip(id)<<" StationName: "<<stationName );
215 }
216 }
217 }
218 }// MDT Station
219
220
221 // Don't check mid-stations when there are no strips in other mid-stations
222 if((nTGCStrips[1]==0)&&(nTGCStrips[2]==0)){canCheckSector[0]=false;canCheckGlobal[0]=false;}
223 if((nTGCStrips[0]==0)&&(nTGCStrips[2]==0)){canCheckSector[1]=false;canCheckGlobal[1]=false;}
224 if((nTGCStrips[0]==0)&&(nTGCStrips[1]==0)){canCheckSector[2]=false;canCheckGlobal[2]=false;}
225
226 // Initialise hit registered arrays
227 // bool hitregistered[9][2];
228 bool sectorhitregistered[9][2];
229 for(int l=0;l<9;l++){// Layer
230 for(int k=0;k<2;k++){// WireStrip
231 // hitregistered[l][k]=false;
232 sectorhitregistered[l][k]=false;
233 }// WireStrip
234 }// Layer
235
236 // Initialise flags for whether a layer in this event has PRD and PRD which matched the current track
237 bool HasPRD[9] ={false,false,false,false,false,false,false,false,false};
238 bool PRDMatch[9]={false,false,false,false,false,false,false,false,false};
239
240 // Loop over TGC Prep Data container
241 Muon::TgcPrepDataContainer::const_iterator prepit_end=tgc_prepcontainer->end();
242 for( Muon::TgcPrepDataContainer::const_iterator prepit=tgc_prepcontainer->begin();
243 prepit!=prepit_end;
244 ++prepit){
245
246 //loop over TGC Prep Data collection
247 Muon::TgcPrepDataCollection::const_iterator prepitc_end=(*prepit)->end();
248 for( Muon::TgcPrepDataCollection::const_iterator prepitc=(*prepit)->begin();
249 prepitc!= prepitc_end;
250 ++prepitc){
251 // Get PRD and variables
252 const Muon::TgcPrepData* tpd=*prepitc;
253 const MuonGM::TgcReadoutElement *tre = tpd->detectorElement();
254 const std::string stationType = tre->getStationType();
255
256 // Get id values
257 Identifier tgcid=(*prepitc)->identify();
258 int tgcAC=(tre->sideA()==false);//isNotAside a:0, c:1
259 int tgcFE=(tre->isForward()==false);//isNotForward f:0, e:1
260 int tgcWS=(m_idHelperSvc->tgcIdHelper().isStrip(tgcid));//isStrip w=0, s=1
261 int stationName = m_idHelperSvc->tgcIdHelper().stationName(tgcid);
262 int stationEta = std::abs(tre->getStationEta());
263 int stationPhi = tre->getStationPhi();
264 int gasGap = m_idHelperSvc->tgcIdHelper().gasGap(tgcid);
265
266 // Cut hits except those from same side EIFI & Midstation
267 if(tgcAC!=i) continue;
268 if(stationName>48 || stationName<41) continue;
269
270 // Get layer number and stationIndex
271 int layer = TGCgetlayer(stationName,gasGap);
272 int stationIndex = TGCstationname2stationindex(stationName);
273
274 // Skip PRD in stations which can't be checked
275 if(stationIndex<0) continue;
276 if(!(canCheckGlobal[stationIndex]||canCheckSector[stationIndex]))continue;
277 if(layer<0) continue;
278 HasPRD[layer]=true;
279
280 // Get position variables
281 // const Trk::GlobalPosition prdPos = tpd->globalPosition();
282 const Amg::Vector3D prdPos = tpd->globalPosition();
283 float tgcRho = std::abs(prdPos.perp());
284 float tgcPhi = prdPos.phi();
285 float tgcZ = prdPos.z();
286 if(tgcPhi<0)tgcPhi+=2*M_PI;
287
288 // Run Extrapolation
289 // Trk::GlobalPosition tgcExtrapolatedPos;
290 Amg::Vector3D tgcExtrapolatedPos;
291 if(stationIndex==3){// Extrapolate position from Inner Position to PRD Z position
292 //if(innerSegmPos=0)m_log << MSG::WARNING << "MidstationOnly: innerSegmPos=0 but passed canCheckGlobal" );
293 float dZ = std::abs(tgcZ) - std::abs(innerSegmZ);
294 //tgcExtrapolatedPos = Trk::GlobalPosition(innerSegmPos+(innerSegmDirzunit*dZ));
295 tgcExtrapolatedPos = Amg::Vector3D(innerSegmPos+(innerSegmDirzunit*dZ));
296 }
297 else{// Extrapolate position from Midstation Position to PRD Z position
298 float dZ = std::abs(tgcZ) - std::abs(midSegmZ);
299 //tgcExtrapolatedPos = Trk::GlobalPosition(midSegmPos+(midSegmDirzunit*dZ));
300 tgcExtrapolatedPos = Amg::Vector3D(midSegmPos+(midSegmDirzunit*dZ));
301 }
302 float tgcExtrRho = std::abs(tgcExtrapolatedPos.perp());
303 float tgcExtrPhi = tgcExtrapolatedPos.phi();
304 if(tgcExtrPhi<0)tgcExtrPhi+=2*M_PI;
305
306 // Get differences between extrapolated and segm2 positions
307 float dRho = tgcRho-tgcExtrRho;
308 float dPhi = tgcPhi-tgcExtrPhi;
309 if(dPhi<-M_PI)dPhi+=2*M_PI;
310 if(dPhi> M_PI)dPhi-=2*M_PI;
311
312 // Pass through loose phi cut to eliminate some noise
313 if(std::abs(dPhi)<dPhiCut_Loose){
314 // Fill PRD sagitta histograms
315 if(m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][0]) m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][0]->Fill(dRho);
316 if(m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][2]) m_mvt_extrprdsag[i][stationIndex][tgcFE][tgcWS][2]->Fill(dPhi);
317
318 // Global efficiency check
319 if(canCheckGlobal[stationIndex]){
320 // Do check
321 float dRhoCut = dRhoCutGlobal[tgcWS]*tgcExtrRho;
322 if(std::abs(dPhi)<dPhiCutGlobal[tgcWS] && std::abs(dRho)<dRhoCut){
323 }
324 }
325
326 // Sector Efficiency Check
327 if(canCheckSector[stationIndex]){// If this station can be checked
328 if((stationEta==TGCstation_StationEta[stationIndex])&&
329 (stationPhi==TGCstation_StationPhi[stationIndex])&&
330 (tgcFE==TGCstation_StationFE[stationIndex])){// If Station FE&Eta&Phi match
331 if(std::abs(dPhi)<dPhiCutSector[tgcWS] && std::abs(dRho)<dRhoCutSector[tgcWS]){
332 sectorhitregistered[layer][tgcWS]=true;
333 }
334 }// Station EtaPhi
335 }
336
337 }// dPhi Loose Cut
338 }// TGC PRD Collection
339 }// TGC PRD Container
340
341 // Fill Efficiency Histograms
342 for(int l=0;l<9;l++){// Layer
343 // Get Station Number
344 int stationIndex=TGClayer2stationindex(l);
345 if(stationIndex<0) continue;
346 for(int k=0;k<2;k++){// WireStrip
347 // If Segment Track matches a Sector
348 if(canCheckSector[stationIndex]){
349 if((TGCstation_StationFE[stationIndex]<0)||(TGCstation_StationEta[stationIndex]==0)||(TGCstation_StationPhi[stationIndex]==0)){
350 ATH_MSG_WARNING( "SegmTrack: canCheckSector passed for jTGC=" << stationIndex
351 << " but, FE=" << TGCstation_StationFE[stationIndex]
352 << " Eta=" << TGCstation_StationEta[stationIndex]
353 << " Phi=" << TGCstation_StationPhi[stationIndex] );
354 continue;
355 }
356 // Get Sector histogram indexes
357 int stationMap_EtaIndex=getStationMapIndex(1, l, TGCstation_StationFE[stationIndex], TGCstation_StationEta[stationIndex], TGCstation_StationPhi[stationIndex]);
358 int stationMap_PhiIndex=getStationMapIndex(2, l, TGCstation_StationFE[stationIndex], TGCstation_StationEta[stationIndex], TGCstation_StationPhi[stationIndex]);
359 // Fill Sector efficiency histograms
360 if(sectorhitregistered[l][k]){// Hit in Sector matches extrapolated track
361 m_eff_stationmapbase[i][k][1]->Fill(stationMap_EtaIndex, stationMap_PhiIndex);
362 }
363 m_eff_stationmapbase[i][k][2]->Fill(stationMap_EtaIndex, stationMap_PhiIndex);
364 }
365 }// WireStrip
366 }// Layer
367
368 // Fill +Has Station bins of histogram
369 if(HasPRD[0]||HasPRD[1]||HasPRD[2])m_mvt_cutspassed[i]->Fill(7);
370 if(HasPRD[3]||HasPRD[4])m_mvt_cutspassed[i]->Fill(9);
371 if(HasPRD[5]||HasPRD[6])m_mvt_cutspassed[i]->Fill(11);
372 if(HasPRD[7]||HasPRD[8])m_mvt_cutspassed[i]->Fill(5);
373
374 // Fill Match Station bins of histogram
375 if(PRDMatch[0]||PRDMatch[1]||PRDMatch[2])m_mvt_cutspassed[i]->Fill(8);
376 if(PRDMatch[3]||PRDMatch[4])m_mvt_cutspassed[i]->Fill(10);
377 if(PRDMatch[5]||PRDMatch[6])m_mvt_cutspassed[i]->Fill(12);
378 if(PRDMatch[7]||PRDMatch[8])m_mvt_cutspassed[i]->Fill(6);
379 if((PRDMatch[0]||PRDMatch[1]||PRDMatch[2])&&
380 (PRDMatch[3]||PRDMatch[4])&&
381 (PRDMatch[5]||PRDMatch[6])&&
382 (PRDMatch[7]||PRDMatch[8]))m_mvt_cutspassed[i]->Fill(13);
383 if((PRDMatch[0]&&PRDMatch[1]&&PRDMatch[2])&&
384 (PRDMatch[3]&&PRDMatch[4])&&
385 (PRDMatch[5]&&PRDMatch[6])&&
386 (PRDMatch[7]&&PRDMatch[8]))m_mvt_cutspassed[i]->Fill(14);
387
388
389 }// AC
390}// 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< const MuonClusterOnTrack * > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
Base class for Muon cluster RIO_OnTracks.
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.
Identifier identify() const
return the identifier -extends MeasurementBase
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