ATLAS Offline Software
Loading...
Searching...
No Matches
MSConstraintTracksProvider.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
13
17
18
19#include "TTree.h"
20#include "TFile.h"
21
22
23namespace Trk {
24
25 //________________________________________________________________________
27 const std::string& name,
28 const IInterface* parent)
29
30 : AthAlgTool(type,name,parent)
31 {
32 declareInterface<ITrackCollectionProvider>(this);
33 }
34
35 //________________________________________________________________________
37 = default;
38
39 //________________________________________________________________________
41 {
42 // configure main track fitter
43 ATH_CHECK(m_trackFitter.retrieve());
44 ATH_MSG_DEBUG("Retrieved " << m_trackFitter);
46
47 ATH_CHECK(m_muonContainerKey.initialize());
48 ATH_CHECK(m_trackContainerKey.initialize());
49 //
50 bookNtuple();
51 return StatusCode::SUCCESS;
52 }
53
54
55
56
58 m_ntuple = ntuple;
59 bookNtuple();
60 }
61
62
63
64
66
67 ATH_MSG_DEBUG("in MSConstraintTracksProvider::bookNtuple");
68
69 if (m_doTree && !m_tree && m_ntuple) {
70 m_ntuple->cd();
71 m_tree = new TTree("MSMomentumConstraint","MSMomentumConstraint");
72
73 ATH_MSG_DEBUG(" Start book Ntuple");
74
75 m_tree->Branch("run", &m_run, "run/I" );
76 m_tree->Branch("event", &m_event, "event/I" );
77 m_tree->Branch("pID", &m_pID, "pID/D" );
78 m_tree->Branch("pMS", &m_pMS, "pMS/D" );
79 m_tree->Branch("ptID", &m_ptID, "ptID/D" );
80 m_tree->Branch("ptMS", &m_ptMS, "ptMS/D" );
81 m_tree->Branch("charge", &m_charge, "charge/D" );
82
83 m_tree->Branch("combinedEta", &m_combinedEta, "combinedEta/D" );
84 m_tree->Branch("IDEta", &m_IDEta, "IDEta/D" );
85 m_tree->Branch("combinedPhi", &m_combinedPhi, "combinedPhi/D" );
86 m_tree->Branch("IDPhi", &m_IDPhi, "IDPhi/D" );
87
88 m_tree->Branch("pID_constrained", &m_pID_constrained, "pID_constrained/D" );
89 m_tree->Branch("ptID_constrained", &m_ptID_constrained, "ptID_constrained/D" );
90 m_tree->Branch("IDEta_constrained", &m_IDEta_constrained, "IDEta_constrained/D" );
91 m_tree->Branch("IDPhi_constrained", &m_IDPhi_constrained, "IDPhi_constrained/D" );
92 m_tree->Branch("charge_constrained", &m_charge_constrained, "charge_constrained/D" );
93
94
95 m_tree->Branch("eBLhits", &m_eBLhits, "eBLhits/I" );
96 m_tree->Branch("nBLhits", &m_nBLhits, "nBLhits/I" );
97
98 m_tree->Branch("nPIXDS", &m_nPIXDS, "nPIXDS/I" );
99 m_tree->Branch("nSCTDS", &m_nSCTDS, "nSCTDS/I" );
100
101 m_tree->Branch("nPIXH", &m_nPIXH, "nPIXH/I" );
102 m_tree->Branch("nSCTH", &m_nSCTH, "nSCTH/I" );
103
104 m_tree->Branch("nPIXHits", &m_nPIXHits, "nPIXHits/I" );
105 m_tree->Branch("nSCTHits", &m_nSCTHits, "nSCTHits/I" );
106 m_tree->Branch("nTRTHits", &m_nTRTHits, "nTRTHits/I" );
107
108 m_tree->Branch("sectors", &m_sectors, "sectors/I" );
109 m_tree->Branch("phiLayers", &m_phiLayers, "phiLayers/I" );
110 m_tree->Branch("stationLayers", &m_stationLayers, "stationLayers/I" );
111
112 m_tree->Branch("sectorNum", &m_sectorNum, "sectorNum/I" );
113 m_tree->Branch("phiLayerNum", &m_phiLayerNum, "phiLayerNum/I" );
114 m_tree->Branch("stationLayerNum", &m_stationLayerNum, "stationLayerNum/I" );
115
116 }
117
118 ATH_MSG_DEBUG("done with bookNtuple");
119
120 return true;
121
122}
123
124
125
127
128 m_run = -999;
129 m_event = -999;
130 m_pID = -999.;
131 m_pMS = -999.;
132 m_ptID = -999.;
133 m_ptMS = -999.;
134 m_charge = -999.;
135
136 m_combinedEta = -999.;
137 m_IDEta = -999.;
138 m_combinedPhi = -999.;
139 m_IDPhi = -999.;
140
141 m_pID_constrained = -999.;
142 m_ptID_constrained = -999.;
143 m_IDEta_constrained = -999.;
144 m_IDPhi_constrained = -999.;
145 m_charge_constrained = -999.;
146
147
148 m_eBLhits = -999;
149 m_nBLhits = -999;
150 m_nPIXDS = -999,
151 m_nSCTDS = -999,
152
153 m_nPIXH = -999;
154 m_nSCTH = -999;
155
156
157 m_nPIXHits = -999;
158 m_nSCTHits = -999;
159 m_nTRTHits = -999;
160
161 m_sectors = -999;
162 m_phiLayers = -999;
163 m_stationLayers = -999;
164
165 m_sectorNum = -999;
166 m_phiLayerNum = -999;
167 m_stationLayerNum = -999;
168
169 }
170
171
172
174 {
175 ATH_MSG_DEBUG("writing tree");
176 int success=1;
177 if (m_tree) {
178 m_ntuple->cd();
179 success = m_tree->Write();
180 }
181 return success>0 ? StatusCode::SUCCESS : StatusCode::FAILURE;
182 }
183
184
185
186 //________________________________________________________________________
188 {
189 return StatusCode::SUCCESS;
190 }
191
192
194
195 const Trk::Perigee* IDTrkMeasuredPerigee = dynamic_cast<const Trk::Perigee*>(& (it->inDetTrackParticle()->definingParameters()));
196 if(!IDTrkMeasuredPerigee){
197 ATH_MSG_DEBUG("NO inDetTrackParticle or no IDTrkMeasuredPerigee");
198 return false;
199 }
200
201 const Trk::Perigee* METrkMeasuredPerigee = dynamic_cast<const Trk::Perigee*>(&(it->muonExtrapolatedTrackParticle()->definingParameters()));
202 if(!METrkMeasuredPerigee){
203 ATH_MSG_DEBUG("NO muonExtrapolatedTrackParticle or no METrkMeasuredPerigee");
204 return false;
205 }
206
207 const double pt = fabs(it->pt())/1000.;
208 const double eta = fabs(it->eta());
209 ATH_MSG_DEBUG(" the combined pt : "<< pt );
210
211 if ( pt < m_minPt ||
212 eta > 2.7 ||
213 (eta > 0.8 && eta < 1.2) ){
214 ATH_MSG_DEBUG(" this combinedMuon not pass basic pt and eta cuts --- pt: "<< pt << " eta: " << eta);
215 return false;
216 }
217
218 const int nPixHits = it->numberOfPixelHits();
219 const int nSCTHits = it->numberOfSCTHits();
220 const int nTRTHits = it->numberOfTRTHits();
221
222 // Do you need fit quality cuts???
223 // const Trk::FitQuality* idfq = idtrk->fitQuality();
224 // const double chisqID = idfq->chiSquared();
225 // const int ndofID = idfq->numberDoF();
226
227
228 const double idQoverPatIP = IDTrkMeasuredPerigee->parameters()[Trk::qOverP] * 1000.;
229 const double idz0atIP = IDTrkMeasuredPerigee->parameters()[Trk::z0];
230 const double idd0atIP = IDTrkMeasuredPerigee->parameters()[Trk::d0];
231 double ptIDatIP = 0.;
232 if ( idQoverPatIP != 0 ) ptIDatIP = fabs(1.0/idQoverPatIP)*sin(IDTrkMeasuredPerigee->parameters()[Trk::theta]);
233
234 ATH_MSG_DEBUG( " ID pt : "<< ptIDatIP );
235
236
237 if( nPixHits < m_minPIXHits ||
238 nSCTHits < m_minSCTHits ||
239 nTRTHits < m_minTRTHits ||
240 idd0atIP > m_maxIDd0 ||
241 idz0atIP > m_maxIDz0 ||
242 ptIDatIP < m_minIDPt ) {
243 ATH_MSG_DEBUG("this combined muon not pass ID cuts --- nPixHits: " << nPixHits << " nSCTHits: " << nSCTHits <<
244 "nTRTHits: " << nTRTHits << " idd0atIP: " << idd0atIP << " idz0atIP: " << idz0atIP <<" ptIDatIP: " << ptIDatIP );
245 return false;
246 }
247
248
249
250 const int nMDTHits = it->numberOfMDTHits();
251 const int nRPCPhiHits = it->numberOfRPCPhiHits();
252 const int nTGCPhiHits = it->numberOfTGCPhiHits();
253
254 const double msQoverPatIP = METrkMeasuredPerigee->parameters()[Trk::qOverP] * 1000.;
255 const double msz0atIP = METrkMeasuredPerigee->parameters()[Trk::z0];
256 const double msd0atIP = METrkMeasuredPerigee->parameters()[Trk::d0];
257
258 double ptMSatIP = 0.;
259 if ( msQoverPatIP != 0 ) ptMSatIP = fabs(1.0/msQoverPatIP)*sin(METrkMeasuredPerigee->parameters()[Trk::theta]);
260
261 ATH_MSG_DEBUG( " ME pt : "<< ptMSatIP);
262
263
264
265 if( nMDTHits < m_minMDTHits ||
266 nRPCPhiHits < m_minRPCPhiHits ||
267 nTGCPhiHits < m_minTGCPhiHits ||
268 msd0atIP > m_maxMSd0 ||
269 msz0atIP > m_maxMSz0 ||
270 ptMSatIP < m_minMSPt ){
271
272 ATH_MSG_DEBUG("this combined muon not pass MS cuts --- nMDTHits: " << nMDTHits << " nRPCPhiHits: " << nRPCPhiHits <<
273 " nTGCPhiHits: " << nTGCPhiHits << " msd0atIP: " << msd0atIP <<
274 " msz0atIP: " << msz0atIP << " pMSatIP:" << ptMSatIP);
275 return false;
276 }
277
278
280 const Rec::TrackParticle* aTrackParticle = it->track();
281
282 const Trk::Track* aTrack = nullptr;
283 if (aTrackParticle) aTrack = aTrackParticle->originalTrack();
284
285 if (aTrack && aTrack != it->inDetTrkTrack()) {
286 summary = m_muonHitSummaryTool->summary(*aTrack);
287 }
288 else {
289 ATH_MSG_WARNING("aTrack possible null !");
290 std::vector<const Muon::MuonSegment*> segments;
291 unsigned int nSeg = it->numberOfSegments();
292 segments.reserve(nSeg); // avoid death by push back
293 for( unsigned int si=0; si<nSeg; ++si ){
294 const Muon::MuonSegment* seg = dynamic_cast<const Muon::MuonSegment*>(it->muonSegment(si));
295 if( seg ) segments.push_back(seg);
296 }
297 summary = m_muonHitSummaryTool->summary(segments);
298 }
299
300 // it is possible to avoid the verbose summary construction in the above,
301 const int sectors = summary.sectors.size();
302 const int phiLayers = summary.phiLayers.size();
303 const int stationLayers = summary.stationLayers.size();
304
305
306 if ( sectors > m_maxNumberOfSectors ||
307 phiLayers < m_minNumberOfPhiLayers ||
308 stationLayers < m_minStationLayers ){
309
310 ATH_MSG_DEBUG("this combined muon not pass muonHitSummary cuts --- sectors: "<< sectors << " phiLayers: "<< phiLayers << " stationLayers: " << stationLayers);
311
312 return false;
313 }
314
315 m_pID = it->inDetTrackParticle()->p();
316 m_pMS = it->muonExtrapolatedTrackParticle()->p();
317 m_ptID = it->inDetTrackParticle()->pt();
318 m_ptMS = it->muonExtrapolatedTrackParticle()->pt();
319 m_charge = it->inDetTrackParticle()->charge();
320
321 m_combinedEta = it->eta();
322 m_IDEta = it->inDetTrackParticle()->eta();
323 m_combinedPhi = it->phi();
324 m_IDPhi = it->inDetTrackParticle()->phi();
325
326 m_nPIXHits = it->numberOfPixelHits();
327 m_nSCTHits = it->numberOfSCTHits();
328 m_nTRTHits = it->numberOfTRTHits();
329
330 m_sectors = sectors;
331 m_phiLayers = phiLayers;
332 m_stationLayers = stationLayers;
333
334 m_sectorNum = *(summary.sectors.begin());
335 //m_phiLayerNum = (summary.phiLayers)[0];
336 //m_stationLayerNum = (summary.stationLayers)[0];
337
338
339
340 return true;
341 }
342
343
344
347
348 originalTracks = nullptr;
349
351 if (!muonContainer.isValid()){
352 ATH_MSG_WARNING(" Can't retrieve " << m_muonContainerKey);
353 ATH_MSG_WARNING("One probability is that you are not running on ESD/DESD ");
354
355 // Can't do MS constraint refit, resort to retrieve tracks directly
357 if (!trackContainer.isValid()){
358 originalTracks = nullptr;
359 ATH_MSG_WARNING(" Can't retrieve " << m_trackContainerKey);
360 } else {
361 originalTracks = trackContainer.cptr();
362 ATH_MSG_DEBUG(" have tracks of this event: " << originalTracks->size());
363 }
364
365 return StatusCode::SUCCESS;
366 } else {
367
369 ATH_MSG_DEBUG("have combined Muons of the event: " << muonContainer->size());
370
371 Analysis::MuonContainer::const_iterator combinedTrackIt = muonContainer->begin();
372 Analysis::MuonContainer::const_iterator combinedTrackItE = muonContainer->end();
373 int goodQualityCombinedMuon = 0;
374
375 for ( ; combinedTrackIt != combinedTrackItE; ++combinedTrackIt ) {
377 const Analysis::Muon* muon = *combinedTrackIt;
378 if ( muon->isCombinedMuon() && muon->hasMuonExtrapolatedTrackParticle() && muon->hasInDetTrackParticle() ){
381 ATH_MSG_DEBUG("have good quality combined Muons of the event: " << ++goodQualityCombinedMuon);
383 const Trk::Perigee* METrkMeasuredPerigee = dynamic_cast<const Trk::Perigee*>(&(muon->muonExtrapolatedTrackParticle()->definingParameters()));
384 if(!METrkMeasuredPerigee){
385 ATH_MSG_DEBUG("NO muonExtrapolatedTrackParticle or no METrkMeasuredPerigee");
386 continue;
387 }
388
389 const Trk::Surface* surf = &(METrkMeasuredPerigee->associatedSurface()) ;
390 if( !surf ) {
391 ATH_MSG_DEBUG("NO surface of the METrkMeasuredPerigee");
392 continue;
393 }
394
395 const Trk::Perigee* IDTrkMeasuredPerigee = dynamic_cast<const Trk::Perigee*>(&(muon->inDetTrackParticle()->definingParameters()));
396 if(!IDTrkMeasuredPerigee){
397 ATH_MSG_DEBUG("NO inDetTrackParticle or no IDTrkMeasuredPerigee");
398 continue;
399 }
400
401 Trk::DefinedParameter qOverPFromMS(METrkMeasuredPerigee->parameters()[Trk::qOverP], Trk::qOverP) ;
402
403 std::vector<Trk::DefinedParameter> parFromMSVec;
404 parFromMSVec.push_back( qOverPFromMS) ;
405
406 Amg::MatrixX covFromMS( 1,1 ) ;
407 covFromMS( 1, 1 ) = (*METrkMeasuredPerigee->covariance())( Trk::qOverP, Trk::qOverP ) ;
408
409 auto pmot = std::make_unique<Trk::PseudoMeasurementOnTrack>(
410 Trk::LocalParameters(parFromMSVec), std::move(covFromMS), *surf);
411
412 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
413 trackStateOnSurfaces->reserve(muon->inDetTrackParticle()->originalTrack()->trackStateOnSurfaces()->size() + 1);
414 Trk::TrackStates::const_iterator sb = muon->inDetTrackParticle()->originalTrack()->trackStateOnSurfaces()->begin();
415
416 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> type;
418
419 const Perigee* IDPerigeeParameters = muon->inDetTrackParticle()->originalTrack()->perigeeParameters();
420
421 auto IDPerigeeParametersClone =
422 (IDPerigeeParameters)
423 ? std::make_unique<Perigee>(*IDPerigeeParameters)
424 : nullptr;
425
426 if(IDPerigeeParameters && IDPerigeeParametersClone ){
427 trackStateOnSurfaces->push_back(new const Trk::TrackStateOnSurface(std::move(pmot), std::move(IDPerigeeParametersClone), nullptr, type));
428
429 for ( ; sb != muon->inDetTrackParticle()->originalTrack()->trackStateOnSurfaces()->end(); ++sb) trackStateOnSurfaces->push_back((**sb).clone());
430
431 Trk::Track* tmpTrack = new Trk::Track(
432 muon->inDetTrackParticle()->originalTrack()->info(),
433 std::move(trackStateOnSurfaces),
434 nullptr);
435
436 Trk::Track* MSConstraintFittedTrack = (m_trackFitter->fit(Gaudi::Hive::currentContext(),
437 *tmpTrack, m_runOutlierRemoval,
438 Trk::muon)).release();
439
440 if(!MSConstraintFittedTrack){
442 ATH_MSG_WARNING("MSConstraintFittedTrack refit failed!");
443
445 ATH_MSG_WARNING("Try to push the originalIDTrack into the trackCollection");
446 Trk::Track* IDOriginalTrackClone = new Trk::Track(*(muon->inDetTrackParticle()->originalTrack()));
447 if(IDOriginalTrackClone){
448 const Trk::Perigee * aMeasPerClone = IDOriginalTrackClone->perigeeParameters();
449 if (aMeasPerClone) {
451 "IDOriginalTrackClone parameters --- pt: "
452 << fabs(1. / (aMeasPerClone->parameters()[Trk::qOverP])) *
453 sin(aMeasPerClone->parameters()[Trk::theta])
454 << " d0: " << aMeasPerClone->parameters()[Trk::d0]);
455 }
456 }
457 if(!IDOriginalTrackClone){
458 ATH_MSG_WARNING("Exception when IDOriginalTrackClone!");
459 } else
460 trackCollection->push_back(IDOriginalTrackClone);
461 }
462 } else {
464 ATH_MSG_DEBUG("Got 1 successful MSConstraintFittedTrack ");
465
466 Trk::Track* MSConstraintFittedTrackClone = new Trk::Track(*MSConstraintFittedTrack);
467 const Trk::Perigee * MSConstraintFittedTrackMPClone = (MSConstraintFittedTrackClone->perigeeParameters());
468 m_pID_constrained = fabs(1./(MSConstraintFittedTrackMPClone->parameters()[Trk::qOverP]));
469 m_IDEta_constrained = -log(tan(MSConstraintFittedTrackMPClone->parameters()[Trk::theta]/2.));
470 m_IDPhi_constrained = MSConstraintFittedTrackMPClone->parameters()[Trk::phi];
471 m_ptID_constrained = fabs( m_pID_constrained*sin(MSConstraintFittedTrackMPClone->parameters()[Trk::theta]) );
472 m_charge_constrained = MSConstraintFittedTrackMPClone->parameters()[Trk::qOverP]/fabs(MSConstraintFittedTrackMPClone->parameters()[Trk::qOverP]);
473
474 delete MSConstraintFittedTrackClone;
475 // only fill the tracks used in the alignment
476 m_ntuple->cd();
477 m_tree->Fill();
478
479 trackCollection->push_back(MSConstraintFittedTrack);
480 }
481
482 // clean up
483 delete tmpTrack;
484 } else{
485 ATH_MSG_WARNING("failed in IDPerigeeParameters or IDPerigeeParametersClone !");
486 }
487
488 }
489 }
490 }// end loop over tracks
491
492 if (StatusCode::SUCCESS != evtStore()->record(trackCollection, "MSMomentumConstraintTracks")){
493 ATH_MSG_WARNING("problem with recording MSMomentumConstraintTracks to StoreGate!");
494 return StatusCode::SUCCESS;
495 }
496
497 ATH_MSG_DEBUG(" The final trackCollection size : " << trackCollection->size() );
498 if ( not trackCollection->empty() ){
499 originalTracks = trackCollection;
500 }
501
502 }
503 return StatusCode::SUCCESS;
504}
505
506
508
509 if(m_logStream) {
510
511 *m_logStream<<"*************************************************************"<<std::endl;
512 *m_logStream<<"****** MSConstraintTracksProvider Summary ******"<<std::endl;
513 *m_logStream<<"*"<<std::endl;
514 *m_logStream<<"* number of combined muons From SG : " << m_nCBMuonsFromSG << std::endl;
515 *m_logStream<<"* number of combined muons have Extrapolated && InDet TrackParticle : " << m_nCBMuonsHasEXandID << std::endl;
516 *m_logStream<<"* number of combined muons pass selection: " << m_nCBMuonsPassSelection << std::endl;
517 *m_logStream<<"* number of combined muons failed in refit: " << m_nCBMuonsFailedRefit << std::endl;
518 *m_logStream<<"* number of combined muons succeeded in refit: " << m_nCBMuonsSucRefit << std::endl;
519
520 *m_logStream<<"*"<<std::endl;
521 }
522 }
523
524
525} // end namespace
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
xAOD::MuonContainer * muonContainer
The ATLAS Muon object - see doxygen, physics workbookd and the Muon Combined Performance WG's pages f...
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
ServiceHandle< StoreGateSvc > & evtStore()
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
size_type size() const noexcept
Returns the number of elements in the collection.
This is the common class for 3D segments used in the muon spectrometer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
std::ostream * m_logStream
logfile output stream
Gaudi::Property< RunOutlierRemoval > m_runOutlierRemoval
bool combinedMuonSelection(const Analysis::Muon *)
MSConstraintTracksProvider(const std::string &type, const std::string &name, const IInterface *parent)
StatusCode fillNtuple()
writes tree to ntuple
Gaudi::Property< bool > m_useMSConstraintTrkOnly
ToolHandle< IGlobalTrackFitter > m_trackFitter
void setNtuple(TFile *ntuple)
sets ntuple
SG::ReadHandleKey< TrackCollection > m_trackContainerKey
ToolHandle< Muon::IMuonHitSummaryTool > m_muonHitSummaryTool
virtual void printSummary()
Print statistical summary to logfile.
SG::ReadHandleKey< Analysis::MuonContainer > m_muonContainerKey
virtual StatusCode trackCollection(const TrackCollection *&tracks)
virtual const S & associatedSurface() const override final
Access to the Surface method.
Abstract Base Class for tracking surfaces.
const Track * originalTrack() const
Return pointer to associated track.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
const Perigee * perigeeParameters() const
return Perigee.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Ensure that the ATLAS eigen extensions are properly loaded.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
std::pair< double, ParamDefs > DefinedParameter
Typedef to of a std::pair<double, ParamDefs> to identify a passed-through double as a specific type o...