ATLAS Offline Software
Loading...
Searching...
No Matches
InDetTrackSelectionToolTester.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// a testing utility for the track selection tool mostly copied from CPToolTests.cxx
6
7// System include(s):
8#include <memory>
9#include <cstdlib>
10
11// ROOT include(s):
12#include <TFile.h>
13#include <TError.h>
14#include <TH2F.h>
15
16// Infrastructure include(s):
17#ifdef ROOTCORE
18# include "xAODRootAccess/Init.h"
20#endif // ROOTCORE
21
22// Local include(s):
27
28using std::vector;
29using std::string;
30using std::unique_ptr;
32
34{
35public:
36 HistFamily(const string&);
37 void fill(const xAOD::TrackParticle&, const xAOD::Vertex*);
38 HistFamily(const HistFamily &) = delete;
39 HistFamily & operator =(const HistFamily &) = delete;
40private:
41 TH2* h_pt = nullptr; // these show eta dependence
42 TH2* h_si_hits_phys = nullptr;
43 TH2* h_si_hits = nullptr;
44 TH2* h_si_holes = nullptr;
45 TH2* h_si_shared = nullptr;
46 TH2* h_ibl_hits = nullptr;
47 TH2* h_bl_hits = nullptr;
48 TH2* h_ibl_expected = nullptr;
49 TH2* h_bl_expected = nullptr;
50 TH2* h_pix_hits_phys = nullptr;
51 TH2* h_pix_hits = nullptr;
52 TH2* h_pix_holes = nullptr;
53 TH2* h_pix_shared = nullptr;
54 TH2* h_sct_hits_phys = nullptr;
55 TH2* h_sct_hits = nullptr;
56 TH2* h_sct_holes = nullptr;
57 TH2* h_sct_shared = nullptr;
58 TH2* h_trt_hits = nullptr;
59 TH2* h_trt_outlier_fraction = nullptr;
60
61 TH2* h_d0 = nullptr; // these show IP vs. uncertainty in IP
62 TH2* h_z0sintheta = nullptr;
63
64 // a helper function to return the summary
65 uint8_t getSum(const xAOD::TrackParticle&, xAOD::SummaryType) const;
66};
67
68
69int main( int argc, char* argv[] ) {
70
71 // The application's name:
72 const char* APP_NAME = argv[ 0 ];
73#define CHECK( ARG ) do {ASG_CHECK_SA( APP_NAME, ARG );} while (false)
74
75 string fileName;
76 // Check if we received a file name:
77 if( argc < 2 ) {
78 fileName = getenv("ROOTCORE_TEST_FILE");
79 if (fileName.empty()) {
80 Error( APP_NAME, "No file name received!" );
81 Error( APP_NAME, " Usage: %s [xAOD file name]", APP_NAME );
82 return 1;
83 }
84 } else {
85 fileName = argv[ 1 ];
86 }
87
88 // fail on an unchecked StatusCode
89 StatusCode::enableFailure();
90
91 // Initialise the application:
92 CHECK( static_cast<StatusCode>(xAOD::Init( APP_NAME )) );
93
94 // Open the input file:
95 Info( APP_NAME, "Opening file: %s", fileName.data() );
96 unique_ptr< TFile > ifile( TFile::Open( fileName.data(), "READ" ) );
97 StatusCode gotFile = ifile.get()!=nullptr ? StatusCode::SUCCESS : StatusCode::FAILURE;
98 CHECK( gotFile );
99
100 // Create a TEvent object:
101 xAOD::TEvent event( static_cast<TFile*>(nullptr), xAOD::TEvent::kClassAccess );
102 CHECK( static_cast<StatusCode>(event.readFrom( ifile.get() )) );
103 Info( APP_NAME, "Number of events in the file: %llu", event.getEntries() );
104
105 // Decide how many events to run over:
106 Long64_t entries = event.getEntries();
107 if( argc > 2 ) {
108 const Long64_t e = atoll( argv[ 2 ] );
109 if( e < entries ) {
110 entries = e;
111 }
112 }
113
114 unique_ptr< TFile > outFile(new TFile("IDTrackSelectionToolTestOut.root", "RECREATE"));
115 Info( APP_NAME, "Creating output file %s", outFile->GetName() );
116
117 const vector<string> cutNames = {"NoCut", "Loose", "LoosePrimary", "TightPrimary", "LooseMuon", "LooseElectron", "MinBias", "HILoose", "HITight", "HILooseOptimized", "HITightOptimized"}; // these are names of pre-defined selections
118 const vector<string> otherCutNames = {"IP", "IPSigma", "IPSignificance"}; // other configurations we will define manually
119 std::map<string, unique_ptr<TrkSelTool> > selToolMap;
120 std::map<string, unique_ptr<HistFamily> > histFamilyMap;
121 for (const auto& cut : cutNames) {
122 selToolMap[cut] = unique_ptr<TrkSelTool>(new TrkSelTool( (cut+"TrackSelection") ));
123 CHECK( selToolMap[cut]->setProperty( "CutLevel", cut) );
124 CHECK( selToolMap[cut]->initialize() );
125 histFamilyMap[cut] = unique_ptr<HistFamily>(new HistFamily(cut));
126 }
127 selToolMap["IP"] = unique_ptr<TrkSelTool>(new TrkSelTool("IPTrackSelection"));
128 CHECK( selToolMap["IP"]->setProperty( "maxD0", 1.5 ) );
129 CHECK( selToolMap["IP"]->setProperty( "maxZ0SinTheta", 1.5 ) );
130 CHECK( selToolMap["IP"]->initialize() );
131 histFamilyMap["IP"] = unique_ptr<HistFamily>(new HistFamily("IP"));
132 selToolMap["IPSigma"] = unique_ptr<TrkSelTool>(new TrkSelTool("IPSigmaTrackSelection"));
133 CHECK( selToolMap["IPSigma"]->setProperty( "maxSigmaD0", 1.5 ) );
134 CHECK( selToolMap["IPSigma"]->setProperty( "maxSigmaZ0SinTheta", 1.5 ) );
135 CHECK( selToolMap["IPSigma"]->initialize() );
136 histFamilyMap["IPSigma"] = unique_ptr<HistFamily>(new HistFamily("IPSigma"));
137 selToolMap["IPSignificance"] = unique_ptr<TrkSelTool>(new TrkSelTool("IPSignificanceTrackSelection"));
138 CHECK( selToolMap["IPSignificance"]->setProperty( "maxD0overSigmaD0", 3.0 ) );
139 CHECK( selToolMap["IPSignificance"]->setProperty( "maxZ0SinThetaoverSigmaZ0SinTheta", 3.0 ) );
140 CHECK( selToolMap["IPSignificance"]->initialize() );
141 histFamilyMap["IPSignificance"] = unique_ptr<HistFamily>(new HistFamily("IPSignificance"));
142
143 // Loop over the events:
144 for( Long64_t entry = 0; entry < entries; ++entry ) {
145
146 // Tell the object which entry to look at:
147 CHECK( !event.getEntry( entry ) );
148
149 // Get the InDetTrackParticles from the event:
150 const xAOD::TrackParticleContainer* tracks = nullptr;
151 CHECK( static_cast<StatusCode>(event.retrieve( tracks, "InDetTrackParticles" )) );
152
153 const xAOD::VertexContainer* vertices = nullptr;
154 CHECK( static_cast<StatusCode>(event.retrieve( vertices, "PrimaryVertices" )) );
155 const auto it_pv = std::find_if(vertices->cbegin(), vertices->cend(),
156 [](const xAOD::Vertex* vtx)
157 {return vtx->vertexType() == xAOD::VxType::PriVtx;});
158 const xAOD::Vertex* primaryVertex = (it_pv == vertices->cend()) ? nullptr : *it_pv;
159 if (primaryVertex == nullptr) Warning( APP_NAME, "No primary vertex found." );
160
161 for( const xAOD::TrackParticle* track : *tracks ) {
162 if (track == nullptr) {
163 Error( APP_NAME, "Null pointer to track!" );
164 continue;
165 }
166 for (const auto& cut : cutNames) {
167 if (selToolMap[cut]->accept(*track, primaryVertex)) histFamilyMap[cut]->fill(*track, primaryVertex);
168 }
169 for (const auto& cut : otherCutNames) {
170 if (selToolMap[cut]->accept(*track, primaryVertex)) histFamilyMap[cut]->fill(*track, primaryVertex);
171 }
172
173 } // end loop over tracks
174
175 } // end loop over events
176
177 for (const auto& selTool : selToolMap) CHECK( selTool.second->finalize() );
178
179 // draw histogram
180 outFile->Write();
181
182 // Return gracefully:
183 return 0;
184}
185
186
188{
189 auto* currentFile = TFile::CurrentFile();
190 currentFile->mkdir(cut_name.data())->cd(); // create a directory for this cut type and cd into it
191#define HIST_INIT( NAME, AXIS_LABEL, AXIS_N, AXIS_XL, AXIS_XH ) \
192 do{ \
193 h_##NAME = new TH2F(#NAME, #NAME ";#eta;" AXIS_LABEL, 50,-2.5,2.5, \
194 AXIS_N, AXIS_XL, AXIS_XH); \
195 } while (false)
196
197 HIST_INIT( pt, "p_{T} [GeV]", 100, 0, 20 );
198 HIST_INIT( si_hits_phys, "Si physical hits", 24, 0, 24 );
199 HIST_INIT( si_hits, "Si hits", 24, 0, 24 );
200 HIST_INIT( si_holes, "Si holes", 6, 0, 6 );
201 HIST_INIT( si_shared, "Si shared hits", 6, 0, 6 );
202 HIST_INIT( pix_hits_phys, "Pixel physical hits", 10, 0, 10 );
203 HIST_INIT( pix_hits, "Pixel hits", 10, 0, 10 );
204 HIST_INIT( pix_holes, "Pixel holes", 4, 0, 4 );
205 HIST_INIT( pix_shared, "Pixel shared hits", 4, 0, 4 );
206 HIST_INIT( sct_hits_phys, "SCT physical hits", 16, 0, 16 );
207 HIST_INIT( sct_hits, "SCT hits", 16, 0, 16 );
208 HIST_INIT( sct_holes, "SCT holes", 4, 0, 4 );
209 HIST_INIT( sct_shared, "SCT shared hits", 4, 0, 4 );
210 HIST_INIT( ibl_hits, "IBL hits", 4, 0, 4 );
211 HIST_INIT( ibl_expected, "expect IBL hit", 2, 0, 2 );
212 HIST_INIT( bl_hits, "BLayer hits", 4, 0, 4 );
213 HIST_INIT( bl_expected, "expect BLayer hit", 2, 0, 2 );
214 HIST_INIT( trt_hits, "TRT hits + outliers", 60, 0, 60 );
215 HIST_INIT( trt_outlier_fraction, "TRT outlier fraction", 25, 0., 1. );
216
217 h_d0 = new TH2F( "d0", "d_{0}^{BL};d_{0}^{BL} [mm];#sigma_{d_{0}} [mm]", 60, -3., 3., 60, 0., 3. );
218 h_z0sintheta = new TH2F( "z0sintheta", "z_{0}^{PV} sin #theta;z_{0}^{PV} sin #theta [mm];#sigma_{z_{0} sin #theta} [mm]", 100, -5., 5., 50, 0., 5. );
219
220#undef HIST_INIT
221
222 currentFile->cd(); // move back to the parent directory
223}
224
226{
227 uint8_t nPixHits = getSum(trk, xAOD::numberOfPixelHits);
228 uint8_t nPixDead = getSum(trk, xAOD::numberOfPixelDeadSensors);
229 uint8_t nPixShared = getSum(trk, xAOD::numberOfPixelSharedHits);
230 uint8_t nPixHoles = getSum(trk, xAOD::numberOfPixelHoles);
231 uint8_t nSctHits = getSum(trk, xAOD::numberOfSCTHits);
232 uint8_t nSctDead = getSum(trk, xAOD::numberOfSCTDeadSensors);
233 uint8_t nSctShared = getSum(trk, xAOD::numberOfSCTSharedHits);
234 uint8_t nSctHoles = getSum(trk, xAOD::numberOfSCTHoles);
235 uint8_t nIblHits = getSum(trk, xAOD::numberOfInnermostPixelLayerHits);
236 uint8_t expectIbl = getSum(trk, xAOD::expectInnermostPixelLayerHit);
238 uint8_t expectBl = getSum(trk, xAOD::expectNextToInnermostPixelLayerHit);
239 uint8_t nTrtHits = getSum(trk, xAOD::numberOfTRTHits);
240 uint8_t nTrtOutliers = getSum(trk, xAOD::numberOfTRTOutliers);
241
242 double eta = trk.eta();
243 h_pt->Fill(eta, trk.pt()*1e-3);
244 h_ibl_hits->Fill(eta, nIblHits);
245 h_ibl_expected->Fill(eta, expectIbl);
246 h_bl_hits->Fill(eta, nBlHits);
247 h_bl_expected->Fill(eta, expectBl);
248 h_pix_hits_phys->Fill(eta, nPixHits);
249 h_pix_hits->Fill(eta, nPixHits + nPixDead);
250 h_pix_holes->Fill(eta, nPixHoles);
251 h_pix_shared->Fill(eta, nPixShared);
252 h_sct_hits_phys->Fill(eta, nSctHits);
253 h_sct_hits->Fill(eta, nSctHits + nSctDead);
254 h_sct_holes->Fill(eta, nSctHoles);
255 h_sct_shared->Fill(eta, nSctShared);
256 h_si_hits_phys->Fill(eta, nPixHits + nSctHits);
257 h_si_hits->Fill(eta, nPixHits + nPixDead + nSctHits + nSctDead);
258 h_si_holes->Fill(eta, nPixHoles + nSctHoles);
259 h_si_shared->Fill(eta, nPixShared + nSctShared);
260 h_trt_hits->Fill(eta, nTrtHits + nTrtOutliers);
261 h_trt_outlier_fraction->Fill(eta, nTrtOutliers / static_cast<double>(nTrtHits + nTrtOutliers));
262
263 const auto& covMatrix = trk.definingParametersCovMatrix();
264 h_d0->Fill(trk.d0(), std::sqrt(covMatrix(0,0)) );
265 double z0 = trk.z0();
266 if (vtx != nullptr) {
267 z0 += trk.vz() - vtx->z();
268 }
269 double sinTheta = std::sin(trk.theta());
270 double cosTheta = std::cos(trk.theta());
271 double varZ0SinTheta = 0.;
272 varZ0SinTheta += covMatrix(1,1)*sinTheta*sinTheta;
273 varZ0SinTheta += 2*covMatrix(1,3)*z0*sinTheta*cosTheta;
274 varZ0SinTheta += covMatrix(3,3)*z0*z0*cosTheta*cosTheta;
275 h_z0sintheta->Fill(z0*sinTheta, std::sqrt(varZ0SinTheta));
276
277 return;
278}
279
281{
282 uint8_t sum_val = 0;
283 if (!trk.summaryValue(sum_val, sum_type)) {
284 Error( "HistFamily::getSum()", "Could not get summary type %i", sum_type );
285 }
286 return sum_val;
287}
Scalar eta() const
pseudorapidity method
#define APP_NAME
#define CHECK(ARG)
#define HIST_INIT(NAME, AXIS_LABEL, AXIS_N, AXIS_XL, AXIS_XH)
InDet::InDetTrackSelectionTool TrkSelTool
void setProperty(columnar::PythonToolHandle &self, const std::string &key, nb::object value)
const char * cut_name[]
const_iterator cbegin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
const_iterator cend() const noexcept
Return a const_iterator pointing past the end of the collection.
Implementation of the track selector tool.
Tool for accessing xAOD files outside of Athena.
@ kClassAccess
Access auxiliary data using the aux containers.
float z0() const
Returns the parameter.
float theta() const
Returns the parameter, which has range 0 to .
const ParametersCovMatrix_t definingParametersCovMatrix() const
Returns the 5x5 symmetric matrix containing the defining parameters covariance matrix.
float vz() const
The z origin for the parameters.
float d0() const
Returns the parameter.
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
float z() const
Returns the z position.
int main()
Definition hello.cxx:18
double entries
Definition listroot.cxx:49
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition Init.cxx:31
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
SummaryType
Enumerates the different types of information stored in Summary.
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfNextToInnermostPixelLayerHits
these are the hits in the 1st pixel barrel layer
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
@ expectNextToInnermostPixelLayerHit
Do we expect a 1st-layer barrel hit for this track?
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
@ numberOfSCTHoles
number of SCT holes [unit8_t].
void initialize()
uint8_t getSum(const xAOD::TrackParticle &, xAOD::SummaryType) const
void fill(const xAOD::TrackParticle &, const xAOD::Vertex *)
HistFamily & operator=(const HistFamily &)=delete
HistFamily(const HistFamily &)=delete