ATLAS Offline Software
Loading...
Searching...
No Matches
ShiftingDerivCalcTool.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#include "TrkTrack/Track.h"
13
19
22
24
25#include "TGraph.h"
26#include "TF1.h"
27#include "TCanvas.h"
28#include "TPaveText.h"
29#include "TAxis.h"
30
31
32namespace Trk {
33
34 //________________________________________________________________________
36 const std::string& name,
37 const IInterface* parent)
38
39 : AthAlgTool(type,name,parent)
40 , m_unshiftedTrackChi2MeasType(std::make_unique<double[]>(TrackState::NumberOfMeasurementTypes))
41 {
42 declareInterface<IDerivCalcTool>(this);
43
44 m_logStream = nullptr;
45 }
46
47 //________________________________________________________________________
52
53 //________________________________________________________________________
55 {
56
57 msg(MSG::DEBUG) << "in ShiftingDerivCalcTool initialize()"<<endmsg;
58 ATH_CHECK(m_trackFitterTool.retrieve());
61 ATH_CHECK(m_alignModuleTool.retrieve());
62
64 msg(MSG::INFO) << "ParticleNumber: " << m_particleNumber << endmsg;
65 msg(MSG::INFO) << "ParticleHypothesis: " << m_particleHypothesis << endmsg;
66
67
68 if(!m_doFits){
69 m_nFits = 2;
70 }
71
72 m_traSize = 5.*m_traSize/(double)m_nFits;
73 m_rotSize = 5.*m_rotSize/(double)m_nFits;
74
75 msg(MSG::INFO) << "doFits: " << m_doFits << endmsg;
76 msg(MSG::INFO) << "nFits: " << m_nFits << endmsg;
77
78 return StatusCode::SUCCESS;
79 }
80
81 //________________________________________________________________________
83 {
84 ATH_MSG_INFO("number tracks processed: "<<m_ntracksProcessed<<
85 "\nnumber tracks passing initial scan: "<<m_ntracksPassInitScan<<
86 "\nnumber tracks passing setting unshifted residuals: "<< m_ntracksPassSetUnshiftedRes<<
87 "\nnumber tracks pass getting derivatives (1st pass): "<<m_ntracksPassGetDeriv<<
88 "\nnumber tracks pass getting derivatives (2nd pass): "<<m_ntracksPassGetDerivSecPass<<
89 "\nnumber tracks pass getting derivatives (3rd pass): "<<m_ntracksPassGetDerivLastPass<<
90 "\nnumber tracks pass setting derivatives: "<<m_ntracksPassDerivatives);
91 ATH_MSG_INFO("number tracks fail max iterations: "<<m_ntracksFailMaxIter<<
92 "\nnumber tracks fail track refit: "<<m_ntracksFailTrackRefit<<
93 "\nnumber tracks fail align param cut: "<<m_ntracksFailAlignParamCut<<
94 "\nnumber tracks fail final attempt: "<<m_ntracksFailFinalAttempt);
95
96 return StatusCode::SUCCESS;
97 }
98
99 //________________________________________________________________________
101 const std::vector<AlignModule*>& alignModules)
102 {
103 ATH_MSG_DEBUG("in scanShifts");
104
105 const EventContext& ctx = Gaudi::Hive::currentContext();
106
107 const Trk::Track* trackForRefit =
109 dynamic_cast<const Trk::Track*>(alignTrack);
110
111 // see whether straight track or not
112 m_fitter = alignTrack->isSLTrack() ?
114 ATH_MSG_DEBUG("refitting unshifted track with "<<m_fitter<<" (isSLTrack="
115 <<alignTrack->isSLTrack()<<")");
116
117 ATH_MSG_DEBUG("setting minNIterations to "<<m_nIterations);
118
119 // refit track
120
122 alignCache.m_minIterations = m_nIterations;
123 const Track* refittedTrack = m_fitter->alignmentFit(ctx, alignCache, *trackForRefit,
126 if (!refittedTrack) {
127 msg(MSG::WARNING) << "initial track refit failed" << endmsg;
128 return false;
129 }
130 else
131 ATH_MSG_DEBUG("initial track refit successful");
132
135 ATH_MSG_DEBUG("exceeded maximum number of iterations");
136 return false;
137 }
138 ATH_MSG_DEBUG("initial nIterations: "<<m_nIterations);
139
140 // loop over AlignModules
141 for (std::vector<AlignModule*>::const_iterator moduleIt=alignModules.begin();
142 moduleIt!=alignModules.end(); ++moduleIt) {
143
144 // loop over AlignPar
145 DataVector<AlignPar>* alignPars=m_alignModuleTool->getAlignPars(*moduleIt);
146 for (DataVector<AlignPar>::iterator alignParIt=alignPars->begin();
147 alignParIt!=alignPars->end(); ++alignParIt) {
148
149 for (int ishift=0;ishift<2;ishift++) {
150
151 double shiftsize = shiftSize(*alignParIt);
152 if (ishift>0) shiftsize*=-1.;
153 m_alignModuleTool->shiftModule(*moduleIt,alignTrack,(**alignParIt).paramType(),shiftsize);
154 refittedTrack = (m_fitter->fit(ctx,
155 *trackForRefit,m_runOutlierRemoval,
156 m_particleHypothesis)).release();
157 m_alignModuleTool->restoreModule(*moduleIt);
158 if (!refittedTrack) {
159 msg(MSG::WARNING) << "track refit failed!"<<endmsg;
161 return false;
162 }
163
164 int nIter=alignCache.m_iterationsOfLastFit;
165 ATH_MSG_DEBUG("nIter: "<<nIter);
166 if (nIter>m_maxIter) {
167 ATH_MSG_DEBUG("exceeded maximum number of iterations");
169 return false;
170 }
171
172 if (nIter>m_nIterations) m_nIterations=nIter;
173 }
174 } // loop over AlignPar
175 } // loop over AlignModules
176
177 ATH_MSG_DEBUG("done with scanShifts, m_nIterations="<<m_nIterations);
178 return true;
179 }
180
181 //________________________________________________________________________
183 {
184 const EventContext& ctx = Gaudi::Hive::currentContext();
185
186 // see whether straight track or not
187 m_fitter = alignTrack->isSLTrack() ?
189 ATH_MSG_DEBUG("refitting unshifted track with "<<m_fitter<<" (isSLTrack="
190 <<alignTrack->isSLTrack()<<")");
191
192 // refit track
193 ATH_MSG_DEBUG("\nsetting min number iterations to "<<m_nIterations);
195 alignCache.m_minIterations = m_nIterations;
196
197 const Trk::Track* trackForRefit =
199 dynamic_cast<const Trk::Track*>(alignTrack);
200 if (!trackForRefit) {
201 ATH_MSG_ERROR("no track for refit!");
202 return false;
203 }
204
205 const Track* refittedTrack = m_fitter->alignmentFit( ctx, alignCache,
206 *trackForRefit,
209
210 if (!refittedTrack) {
211 ATH_MSG_WARNING( "initial track refit failed" );
212 return false;
213 }
214 else
215 ATH_MSG_DEBUG("initial track refit successful");
216
217 // dump local track chi2 for debugging
218 double localChi2=m_residualCalculator->setResiduals(alignTrack,refittedTrack);
219 msg()<<MSG::DEBUG<<"local Chi2(unshifted) in setChi2VAlignParam="<<localChi2<<endmsg;
220 m_unshiftedTrackChi2 = localChi2;
221 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++) {
222 ATH_MSG_DEBUG("getting chi2 for measType "<<i);
224 }
225 ATH_MSG_DEBUG("done");
226
227 // create vector containing unshifted residuals and matrices containing errors
228 const int NMEAS=alignTrack->nAlignTSOSMeas();
229
230 // unshiftedResiduals owned by AlignTrack
232
233 // unshiftedResErrors owned by ShiftingDerivCalcTool
236
237 // loop over atsos and determine residuals and errors
238 int imeas=0;
239 AlignTSOSCollection::const_iterator atsosItr=alignTrack->firstAtsos();
240 for (; atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
241 if (!(**atsosItr).isValid()) continue;
242 for (std::vector<Residual>::const_iterator itRes=(**atsosItr).firstResidual();
243 itRes!=(**atsosItr).lastResidual();++itRes,++imeas) {
244 double residual = itRes->residual();
245 double errSq = itRes->errSq();
246 (*m_unshiftedResiduals)[imeas]=residual;
247 (*m_unshiftedResErrors)[imeas]=std::sqrt(errSq);
248 //ATH_MSG_DEBUG("weight: "<<1./errSq<<", unshiftedRes["<<imeas<<"]="
249 // <<(*m_unshiftedResiduals)[imeas]
250 // <<", resNorm="<<itRes->residualNorm());
251 }
252 }
253 if (imeas!=NMEAS) {
254 msg(MSG::ERROR)<<"problem with nmeas, imeas="<<imeas<<", NMEAS="<<NMEAS<<endmsg;
255 throw std::runtime_error("Error in ShiftingDerivCalcTool::setUnshiftedResiduals");
256 }
258
259 delete refittedTrack; refittedTrack=nullptr;
260
261 return true;
262 }
263
264//________________________________________________________________________
266{
267 ATH_MSG_DEBUG("in ShiftingDerivCalcTool setDerivatives");
269
270 // loop over AlignTSOSCollection,
271 // find modules that are in the AlignModuleList,
272 std::vector<AlignModule*> alignModules;
273 for (AlignTSOSCollection::iterator atsosItr=alignTrack->firstAtsos();
274 atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
275
276 ATH_MSG_VERBOSE("getting module");
277 AlignModule* module=(*atsosItr)->module();
278 if (module)
279 ATH_MSG_VERBOSE("have ATSOS for module "<<module->identify());
280 else
281 ATH_MSG_VERBOSE("no module!");
282
283 if (!(*atsosItr)->isValid() || !module) continue;
284 if (find(alignModules.begin(),alignModules.end(),module) == alignModules.end())
285 alignModules.push_back(module);
286 }
287
288 // find perigee of best track fit and use as starting perigee for all fits
290 if (m_setMinIterations && !scanShifts(alignTrack, alignModules)) {
291 return false;
292 };
293
295
296 // set unshifted residuals (this is done in AlignTrackDresser but redone here with track refit)
297 if (!setUnshiftedResiduals(alignTrack)) {
298 ATH_MSG_WARNING("problem with refitting track!");
299 return false;
300 };
301
303
304 // Determine derivatives from shifting these modules
305 std::vector<AlignModuleDerivatives> * derivatives = new std::vector<AlignModuleDerivatives>;
306 std::vector<AlignModuleDerivatives> * derivativeErr = new std::vector<AlignModuleDerivatives>;
307 std::vector<std::pair<AlignModule*, std::vector<double> > > * actualSecondDerivatives =
308 new std::vector<std::pair<AlignModule*, std::vector<double> > >;
310 for (auto *alignModule : alignModules) {
311
312 ATH_MSG_DEBUG("finding derivatives for module "<<(*alignModule).identify());
313
314 std::vector<Amg::VectorX> deriv_vec;
315 std::vector<Amg::VectorX> derivErr_vec;
316 std::vector<double> actualsecderiv_vec;
317
318 // get alignPars and create arrays to store chi2 vs. align pars
319 DataVector<AlignPar>* alignPars=m_alignModuleTool->getAlignPars(alignModule);
320 const int nAlignPar = alignPars->size();
321 m_tmpChi2VAlignParam = new double*[nAlignPar];
322 m_tmpChi2VAlignParamX = new double*[nAlignPar];
325 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++)
326 m_tmpChi2VAlignParamMeasType[i] = new double*[nAlignPar];
327 }
328
329
330 // get derivatives and arrays of chi2 vs. align params
331 bool resetIPar=false;
332 std::vector<Amg::VectorX> tmpderiv_vec;
333 std::vector<Amg::VectorX> tmpderivErr_vec;
334 std::vector<double> tmpactualsecderiv_vec;
335 m_secPass=false;
336
337 // first attempt with normal number of fitter iterations
338 bool success=getAllDerivatives(
339 alignTrack, alignModule,
340 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
341 resetIPar);
342 if (!success){
343 delete derivatives;
344 delete derivativeErr;
345 delete actualSecondDerivatives;
346 return false;
347 }
348
350
351 if (resetIPar) {
352 // second attempt with increased number of fitter iterations
353 m_secPass=true;
354 success=getAllDerivatives(alignTrack,alignModule,
355 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
356 resetIPar);
357 }
358
359 if (!success){
360 delete derivatives;
361 delete derivativeErr;
362 delete actualSecondDerivatives;
363 return false;
364 }
365
367
368 if (resetIPar) {
369 // third and last attempt with number of fitter iterations set to maximum
371 success=getAllDerivatives(alignTrack,alignModule,
372 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
373 resetIPar);
374 }
375
376 if (!success){
377 delete derivatives;
378 delete derivativeErr;
379 delete actualSecondDerivatives;
380 return false;
381 }
382
383
385
386 if (success && !resetIPar) {
387 for (int i=0;i<(int)tmpderiv_vec.size();i++) {
388 deriv_vec.push_back(tmpderiv_vec[i]);
389 derivErr_vec.push_back(tmpderivErr_vec[i]);
390 actualsecderiv_vec.push_back(tmpactualsecderiv_vec[i]);
391 }
392 }
393 else{
394 delete derivatives;
395 delete derivativeErr;
396 delete actualSecondDerivatives;
397 return false;
398 }
399 // set the chi2 vs. align param arrays
400 ATH_MSG_DEBUG("setting chi2 vs. align param arrays");
403 (*alignModule).setChi2VAlignParamArray (m_tmpChi2VAlignParam);
404 (*alignModule).setChi2VAlignParamXArray(m_tmpChi2VAlignParamX);
405
406 // arrays for measurement types
408 ATH_MSG_DEBUG("pushing back for measType");
410 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++)
411 (*alignModule).setChi2VAlignParamArrayMeasType(i,m_tmpChi2VAlignParamMeasType[i]);
412 }
413 ATH_MSG_DEBUG("done setting arrays");
414
415 derivatives->push_back(make_pair(alignModule,deriv_vec));
416 derivativeErr->push_back(make_pair(alignModule,derivErr_vec));
417 actualSecondDerivatives->push_back(make_pair(alignModule,actualsecderiv_vec));
418 }
419
421
422 alignTrack->setDerivatives(derivatives);
423 alignTrack->setDerivativeErr(derivativeErr);
424 alignTrack->setActualSecondDerivatives(actualSecondDerivatives);
425
426 // restore unshifted residuals in AlignTSOS
427 setUnshiftedResiduals(alignTrack);
428
429 return true;
430}
431
432//________________________________________________________________________
434 AlignTrack* alignTrack,
435 int ipar, AlignPar* alignPar,
436 Amg::VectorX& derivativeErr,
437 bool& resetIPar,
438 double& actualSecondDeriv)
439{
440 const EventContext& ctx = Gaudi::Hive::currentContext();
441
442 const Trk::Track* trackForRefit =
444 dynamic_cast<const Trk::Track*>(alignTrack);
445
446 ATH_MSG_DEBUG("m_nIterations: "<<m_nIterations);
447
448 // gets derivatives of residuals w.r.t. a specific alignment parameter given by alignPar
449 if (!m_fitter)
450 ATH_MSG_ERROR("set m_fitter before calling getDerivatives (by calling setUnshiftedResiduals)");
451
452 AlignModule* module=alignPar->alignModule();
453
454 // set derivatives for 2 shifts up and 2 shifts down
455 const int NFITS = m_nFits;
456 const int NMEAS = alignTrack->nAlignTSOSMeas();
457 module->setNChamberShifts(m_nFits);
458
459 ATH_MSG_DEBUG("NMEAS="<<NMEAS);
460 double** residuals=new double*[NFITS];
461 double** resErrors=new double*[NFITS];
462 double* chi2Array =new double[NFITS];
463 double* chi2ArrayX=new double[NFITS];
464
466 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++)
467 m_tmpChi2VAlignParamMeasType[i][ipar] =new double[NFITS];
468 }
469
470 for (int ifit=0;ifit<NFITS;ifit++) {
471 residuals[ifit]=new double[NMEAS];
472 resErrors[ifit]=new double[NMEAS];
473 }
474
475 // set the values for the unshifted track
476 const int unshiftedTrackIndex = m_doFits ? (m_nFits-1)/2 : 1;
477 chi2Array [unshiftedTrackIndex] = m_unshiftedTrackChi2;
478 ATH_MSG_DEBUG("chi2Array["<<unshiftedTrackIndex<<"]="<<chi2Array[unshiftedTrackIndex]);
479 chi2ArrayX[unshiftedTrackIndex] = 0.;
481 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++) {
482 m_tmpChi2VAlignParamMeasType[i][ipar][unshiftedTrackIndex]=
484 ATH_MSG_DEBUG("chi2ArrayMeasType["<<i<<"]["<<unshiftedTrackIndex<<"]="<<m_unshiftedTrackChi2MeasType[i]);
485 }
486 }
487
488
489 // get shift size
490 double shiftsize=shiftSize(alignPar);
491
493
494
495 ATH_MSG_VERBOSE("doing refits");
496 for (int ifit=0;ifit<NFITS;ifit++) {
497
498 ATH_MSG_VERBOSE("ifit="<<ifit);
499 int jfit=ifit;
500 if (ifit>unshiftedTrackIndex) {
501 jfit=NFITS-ifit+unshiftedTrackIndex;
502 }
503 if (m_doFits && ifit==unshiftedTrackIndex) {
504 for (int i=0;i<(int)m_unshiftedResiduals->rows();i++) {
505 residuals[ifit][i]=(*m_unshiftedResiduals)[i];
506 resErrors[ifit][i]=(*m_unshiftedResErrors)[i];
507 }
508 // change back in case it got changed on the other side of zero
509 shiftsize=shiftSize(alignPar);
510 continue;
511 }
512
513 // shift module and fit track
514 double currentshift = 0.;
515 if(m_doFits)
516 currentshift = shiftsize * (double)(jfit-unshiftedTrackIndex);
517 else
518 currentshift = (ifit==0) ? -1.*shiftsize : shiftsize;
519
520 ATH_MSG_DEBUG("current shift="<<currentshift<<" in getDerivatives");
521
522 m_alignModuleTool->shiftModule(module,alignTrack,
523 alignPar->paramType(),currentshift);
524
525
526 ATH_MSG_VERBOSE("fitting after shift");
527 const Track* refittedTrack=m_fitter->alignmentFit(ctx, alignCache,
528 *trackForRefit,
533 ATH_MSG_DEBUG("exceeded max number of iterations");
534 m_alignModuleTool->restoreModule(module);
535 resetIPar=false;
536 ATH_MSG_DEBUG("resetIPar set to false");
537 delete [] residuals; delete [] resErrors;
538 delete [] chi2Array; delete [] chi2ArrayX;
539 ATH_MSG_DEBUG("fail max iter");
541 Amg::VectorX derivatives(1);
542 return derivatives;
543 }
544 ATH_MSG_DEBUG("increasing m_nIterations to "<<m_nIterations<<" (not changing in fit yet)");
545 resetIPar=true;
546 ATH_MSG_DEBUG("resetIPar set to true");
547 }
548
549 // if resetIPar refit the rest of the tracks, but don't do anything with them until next pass
550 if (resetIPar) {
551 m_alignModuleTool->restoreModule(module);
552 continue;
553 }
554
555 if (!refittedTrack) {
556 msg(MSG::WARNING) << "track refit failed for jfit "<<jfit <<endmsg;
557 delete [] residuals; delete [] resErrors;
558 delete [] chi2Array; delete [] chi2ArrayX;
559 m_alignModuleTool->restoreModule(module);
560 if (!resetIPar || m_secPass) {
562 }
563 ATH_MSG_DEBUG("fail track refit, resetIPar "<<resetIPar<<", secPass "<<m_secPass);
564 Amg::VectorX derivatives(1);
565 return derivatives;
566 }
567 else
568 ATH_MSG_VERBOSE("track refit successful");
569
570 double chi2=refittedTrack->fitQuality()->chiSquared();
571
572 ATH_MSG_VERBOSE("jfit = "<<jfit);
573 double localChi2=m_residualCalculator->setResiduals(alignTrack,refittedTrack);
574 ATH_MSG_DEBUG("localChi2/fittedChi2="<<localChi2<<"/"<<chi2);
575
576 chi2ArrayX[jfit]= shiftsize * (double)(jfit-unshiftedTrackIndex);// / module->sigma(idof);
577 chi2Array[jfit]=localChi2;
578 ATH_MSG_DEBUG("chi2Array["<<jfit<<"]="<<chi2Array[jfit]);
580 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++) {
581 m_tmpChi2VAlignParamMeasType[i][ipar][jfit]= m_residualCalculator->chi2ForMeasType(i);
582 ATH_MSG_DEBUG("chi2ArrayMeasType["<<i<<"]["<<jfit<<"]="
583 <<m_tmpChi2VAlignParamMeasType[i][ipar][jfit]);
584 }
585 }
586
587 ATH_MSG_DEBUG("positions["<<jfit<<"]="<<chi2ArrayX[jfit]);
588
589 int imeas(0);
590 AlignTSOSCollection::const_iterator atsosItr=alignTrack->firstAtsos();
591 for (; atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
592 if (!(*atsosItr)->isValid()) continue;
593 for (std::vector<Residual>::const_iterator itRes=(**atsosItr).firstResidual();
594 itRes!=(**atsosItr).lastResidual();++itRes,++imeas) {
595
596 if (refittedTrack) {
597 residuals[jfit][imeas]=itRes->residual();
598 resErrors[jfit][imeas]=std::sqrt(itRes->errSq());
599 }
600 else {
601 residuals[jfit][imeas]=resErrors[jfit][imeas]=0.;
602 }
603 ATH_MSG_DEBUG("residuals["<<jfit<<"]["<<imeas<<"]="<<residuals[jfit][imeas]);
604 ATH_MSG_DEBUG("resErrors["<<jfit<<"]["<<imeas<<"]="<<resErrors[jfit][imeas]);
605 }
606 }
607
608 delete refittedTrack; refittedTrack=nullptr;
609 ATH_MSG_VERBOSE("calling restoreModule");
610 m_alignModuleTool->restoreModule(module);
611 } // NFITS
612
613 int iimeas(0);
614 AlignTSOSCollection::const_iterator aatsosItr=alignTrack->firstAtsos();
615 for (; aatsosItr != alignTrack->lastAtsos(); ++aatsosItr) {
616 if (!(*aatsosItr)->isValid()) continue;
617 for (std::vector<Residual>::const_iterator itRes=(**aatsosItr).firstResidual();
618 itRes!=(**aatsosItr).lastResidual();++itRes,++iimeas) {
619 for (int ifit=0;ifit<NFITS;ifit++) {
620 ATH_MSG_DEBUG("["<<ifit<<"]["<<iimeas<<"] res="<<residuals[ifit][iimeas]<<
621 ", resErr="<<resErrors[ifit][iimeas]);
622 }
623 }
624 }
625
626 if (resetIPar) {
627 //resetIPar=false;
628 delete [] residuals; delete [] resErrors;
629 delete [] chi2Array; delete [] chi2ArrayX;
630 if (m_secPass) ATH_MSG_WARNING("failed second pass!");
631 ATH_MSG_DEBUG("returning to reset IPar");
632 Amg::VectorX derivatives;
633 return derivatives;
634 }
635
636 // check chi2 vs. chamber pos to see if discontinuous
637 TGraph* gr = new TGraph(m_nFits,chi2ArrayX,chi2Array);
638 gr->Fit("pol2","QF");
639 TF1* fit=gr->GetFunction("pol2");
640 double chi2 =fit->GetChisquare()/double(m_nFits-3);
641 double slope=fit->GetParameter(1);
642 actualSecondDeriv=fit->GetParameter(2);
643 delete gr;
644
645 ATH_MSG_DEBUG("discontinuity check: chi2="<<chi2);
646 alignTrack->setTrackAlignParamQuality(alignPar->paramType(),chi2);
647
648 // EventInfo
649 if (chi2>1.e-6 || std::fabs(slope)<1.e-10) {
650 const xAOD::EventInfo* eventInfo;
651 StatusCode sc=evtStore()->retrieve(eventInfo);
652 if (sc.isFailure())
653 ATH_MSG_ERROR("Couldn't retrieve event info");
654 int run=eventInfo->runNumber();
655 int evt=eventInfo->eventNumber();
656 ATH_MSG_DEBUG("discontinuity check: chi2="<<chi2<<", run/evt "<<run<<"/"<<evt);
657 }
658
659 //reset in case it got changed somewhere
660 shiftsize = shiftSize(alignPar);
661
662 //-----------------------------------------//
663 //-- get derivatives from residuals --//
664 //-----------------------------------------//
665 ATH_MSG_VERBOSE("calculating residuals");
666 Amg::VectorX derivatives(alignTrack->nAlignTSOSMeas(),0);
667 ATH_MSG_DEBUG("created derivatives with "<<derivatives.rows()<<" rows");
668
669 // if bad fit or first derivative close to zero, replace derivatives with zeros
670 if (chi2>m_trackAlignParamCut) {// || std::fabs(slope)<1.e-10 ) {
671 ATH_MSG_DEBUG("chi2/"<<m_nFits-3<<"="<<chi2);
672 delete [] residuals; delete [] resErrors;
673 delete [] chi2Array; delete [] chi2ArrayX;
674
677 ATH_MSG_DEBUG("exceeded max number of iterations");
678 resetIPar=false;
679 }
680 ATH_MSG_DEBUG("increasing m_nIterations to "<<m_nIterations<<" (not changing in fit yet)");
681 resetIPar=true;
682 ATH_MSG_INFO("fail align param cut, secPass "<<m_secPass);
683 if (m_secPass) {
685 }
686 Amg::VectorX emptyDerivatives;
687 return emptyDerivatives;
688 }
689
690 int imeas(0);
691 TCanvas* canv(nullptr);
692 std::vector<TGraph*> vecGraphs;
693 AlignTSOSCollection::const_iterator atsosItr=alignTrack->firstAtsos();
694 for (; atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
695 if (!(*atsosItr)->isValid()) continue;
696 for (int idim=0;idim<(*atsosItr)->nResDim();idim++) {
697
698 double* gr_x = new double[NFITS];
699 double* gr_y = new double[NFITS]; // residuals only have float precision if determined from ESD
700 int ngoodfits=0;
701 for (int ifit=0;ifit<NFITS;ifit++) {
702 double residual=residuals[ifit][imeas];
703 double resError=resErrors[ifit][imeas];
704 if (residual>-999.) {
705 gr_x[ngoodfits] =chi2ArrayX[ifit];
706 gr_y[ngoodfits] =residual/resError;
707 ngoodfits++;
708 }
709 }
710
711 if (!m_doFits && ngoodfits==2) {
712 derivatives[imeas]=(residuals[1][imeas]-residuals[0][imeas])/(2.*shiftsize)*
713 resErrors[unshiftedTrackIndex][imeas];
714 }
715 else if (m_doFits && ngoodfits>3) {
716 TGraph* gr=new TGraph(ngoodfits,gr_x,gr_y);
717
719 gr->Fit("pol2","VF");
720 else
721 gr->Fit("pol2","QF");
722 TF1* fit=gr->GetFunction("pol2");
723
724 //double derivRatio=fit->GetParameter(2)/fit->GetParameter(1);
725 ATH_MSG_DEBUG("deriv["<<imeas<<"]="<<fit->GetParameter(1)<<" +/- "<<fit->GetParError(1)
726 <<", chi2="<<fit->GetChisquare());
727 derivatives[imeas]=fit->GetParameter(1)*resErrors[unshiftedTrackIndex][imeas]; // first derivative at x=0
728 derivativeErr[imeas]=fit->GetParError(1)*resErrors[unshiftedTrackIndex][imeas];
729
730
731 // plot residuals vs. chamber position
732 if (m_doResidualPlots) {
733 if (!canv) canv=new TCanvas("resPlots","resPlots");
734 canv->cd();
735 gr->SetMarkerStyle(20);
736 gr->Draw("AP");
737
738 gr->GetXaxis()->SetTitle("shift in chamber pos. from nominal (CLHEP::mm)");
739 gr->GetYaxis()->SetTitle("residual (CLHEP::mm)");
740
741 TPaveText* pave=new TPaveText(.4,.65,.97,.92,"NDC");
742 pave->SetFillColor(0);
743 pave->SetBorderSize(1);
744 std::stringstream measType; measType<<"meas type: ";
745 if ((*atsosItr)->measType()==TrackState::MDT) measType<<" MDT";
746 else if ((*atsosItr)->measType()==TrackState::TGC) measType<<" TGC";
747 else if ((*atsosItr)->measType()==TrackState::RPC) measType<<" RPC";
748 else measType<<" undefined";
749
750 pave->AddText(measType.str().c_str());
751
752 std::stringstream firstderivtxt,secndderivtxt,aptxt,chi2txt;
753 firstderivtxt<<fit->GetParameter(1)<<" +/- "<<fit->GetParError(1);
754 secndderivtxt<<fit->GetParameter(2)<<" +/- "<<fit->GetParError(2);
755 aptxt <<"alignPar "<<alignPar->paramType()<<", RIO in "<<(*atsosItr)->identify();
756 chi2txt<<"chi2="<<fit->GetChisquare();
757
758 pave->AddText(firstderivtxt.str().c_str());
759 pave->AddText(secndderivtxt.str().c_str());
760 pave->AddText(aptxt.str().c_str());
761 pave->AddText(chi2txt.str().c_str());
762 pave->Draw();
763
764 std::stringstream canvName;
765 canvName<<"resPlots_ap"<<alignPar->paramType()<<"_measType"
766 <<(*atsosItr)->measType()<<"_"<<imeas<<".eps";
767 canv->Print(canvName.str().c_str());
768 canv->Clear();
769
770 delete pave;
771 }
772 vecGraphs.push_back(gr);
773 }
774 else {
775 derivatives[imeas]=-999.;
776 derivativeErr[imeas]=-999.;
777 }
778
779 delete [] gr_y;
780 delete [] gr_x;
781
782 ++imeas;
783 }
784 }
785
786 // delete TGraphs and TCanvas
787 for (auto & vecGraph : vecGraphs)
788 delete vecGraph;
789 delete canv;
790
791 delete [] residuals;
792 delete [] resErrors;
793
794 // set chi2 v alignparam
795 for (int ifit=0;ifit<NFITS;ifit++) {
796 m_tmpChi2VAlignParamX[ipar]=chi2ArrayX;
797 m_tmpChi2VAlignParam [ipar]=chi2Array;
798 }
799
800 ATH_MSG_DEBUG("derivativeErr: "<<derivativeErr);
801 return derivatives;
802}
803
804//________________________________________________________________________
805double ShiftingDerivCalcTool::shiftSize(const AlignPar* alignPar) const {
806 bool rotation =
807 alignPar->paramType() == AlignModule::RotX ||
808 alignPar->paramType() == AlignModule::RotY ||
809 alignPar->paramType() == AlignModule::RotZ;
810
811 double shift = rotation ? m_rotSize : m_traSize;
812
813 //ok... this is kind of ugly.
814 double sigma=alignPar->sigma();
815 return shift * sigma;
816}
817
818//________________________________________________________________________
820{
821 Amg::MatrixX W(alignTrack->nAlignTSOSMeas(),alignTrack->nAlignTSOSMeas());
822
823 if (alignTrack->localErrorMatrixInv()) {
824 ATH_MSG_ERROR("Need to assign this matrix correctly: ShiftingDerivCalcTool.cxx:888");
825 W = *(alignTrack->localErrorMatrixInv());
826 //W.assign(*(alignTrack->localErrorMatrixInv()));
827 } else{
828 return false;
829 }
830 ATH_MSG_DEBUG("W: "<<W);
831
832 bool Wisvalid(true);
833 const double epsilon=1e-10;
834 for( int irow=0; irow<W.rows(); ++irow) {
835 Wisvalid = Wisvalid && W(irow,irow)>0;
836 if( !(W(irow,irow)>0) )
837 msg(MSG::WARNING) << "matrix invalid: " << W(irow,irow) << endmsg;
838
839 for(int icol=0; icol<=irow; ++icol) {
840
841 // this one must be true if everything else succeeded
842 double Wcorr = W(irow,icol)/sqrt(W(irow,irow)*W(icol,icol));
843 bool Wcorrisvalid = Wcorr+epsilon>=-1 && Wcorr-epsilon<=1;
844 Wisvalid = Wisvalid && Wcorrisvalid;
845 if( !Wcorrisvalid )
846 msg(MSG::WARNING) << "matrix corr invalid: " << Wcorr-1 << " " << Wcorr+1 << endmsg;
847 }
848 }
849
850 if (Wisvalid)
851 alignTrack->setWeightMatrix(new Amg::MatrixX(W));
852
853 alignTrack->setWeightMatrixFirstDeriv(new Amg::MatrixX(std::move(W)));
854
855 return true;
856}
857
858//________________________________________________________________________
860{
861 for (int i=0;i<(int)m_chi2VAlignParamVec.size();i++) {
862 delete [] m_chi2VAlignParamVec[i]; m_chi2VAlignParamVec[i]=nullptr;
863 delete [] m_chi2VAlignParamXVec[i]; m_chi2VAlignParamXVec[i]=nullptr;
864 }
865 m_chi2VAlignParamVec.clear();
866 m_chi2VAlignParamXVec.clear();
867
868 for (auto & i : m_chi2VAlignParamVecMeasType) {
869 delete [] i; i=nullptr;
870 }
872}
873
874//________________________________________________________________________
876 AlignTrack* alignTrack,
877 const AlignModule* alignModule,
878 std::vector<Amg::VectorX>& deriv_vec,
879 std::vector<Amg::VectorX>& derivErr_vec,
880 std::vector<double>& actualsecderiv_vec,
881 bool& resetIPar)
882{
883 resetIPar=false;
884
885 deriv_vec.clear();
886 derivErr_vec.clear();
887 actualsecderiv_vec.clear();
888
889 setUnshiftedResiduals(alignTrack); // this will set the min number of iterations to the new value
890
891 int ipar(0);
892 DataVector<AlignPar>* alignPars=m_alignModuleTool->getAlignPars(alignModule);
893 for (DataVector<AlignPar>::iterator it=alignPars->begin(); it!=alignPars->end(); ++it,ipar++) {
894 ATH_MSG_DEBUG("ipar: "<<ipar);
895 Amg::VectorX derivErr(alignTrack->nAlignTSOSMeas());
896 double actualSecondDeriv(0.);
897 const Amg::VectorX vec=getDerivatives(alignTrack,ipar,*it,derivErr,resetIPar,actualSecondDeriv);
898 ATH_MSG_DEBUG("vec size: "<<vec.rows());
899
900 ATH_MSG_DEBUG("resetIPar="<<resetIPar);
901 if (resetIPar) continue; // continue with derivatives to find max iteration
902
903 if (vec.rows()<1) return false; // derivatives won't be set for alignTrack because it's a bad track
904
905 deriv_vec.push_back(vec);
906 derivErr_vec.push_back(derivErr);
907 actualsecderiv_vec.push_back(actualSecondDeriv);
908
909 for (int i=0;i<m_nFits;i++) {
910 ATH_MSG_DEBUG("m_tmpChi2VAlignParam["<<ipar<<"]["
911 <<i<<"]="<<m_tmpChi2VAlignParam[ipar][i]);
912 }
913 }
914
915 return true;
916}
917
918} // end namespace
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
#define gr
static Double_t sc
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
ServiceHandle< StoreGateSvc > & evtStore()
MsgStream & msg() const
Derived DataVector<T>.
Definition DataVector.h:795
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
DataModel_detail::iterator< DataVector > iterator
Standard iterator.
Definition DataVector.h:842
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
double sigma() const
returns sigma
Definition AlignPar.h:65
AlignModule::TransformParameters paramType() const
returns the type of parameter (i.e.
Definition AlignPar.h:47
const AlignModule * alignModule() const
returns the AlignModule
Definition AlignPar.h:40
void setWeightMatrix(Amg::SymMatrixX *mat)
Definition AlignTrack.h:157
AlignTSOSCollection::const_iterator lastAtsos() const
returns iterator pointer to last element in collection
Definition AlignTrack.h:280
const Amg::SymMatrixX * localErrorMatrixInv() const
inverse local error matrix, calculated by AlignTrack by calling atsos->hitDistanceVar()
Definition AlignTrack.h:125
int nAlignTSOSMeas() const
number of alignTSOS (including scatterers if included on AlignTrack
Definition AlignTrack.h:128
void setActualSecondDerivatives(std::vector< std::pair< AlignModule *, std::vector< double > > > *vec)
Definition AlignTrack.h:147
void setTrackAlignParamQuality(int i, double val)
Definition AlignTrack.h:182
void setDerivatives(std::vector< AlignModuleDerivatives > *vec)
Definition AlignTrack.h:134
AlignTSOSCollection::const_iterator firstAtsos() const
retrieve iterator pointer to first element in collection
Definition AlignTrack.h:279
void setWeightMatrixFirstDeriv(Amg::SymMatrixX *mat)
Definition AlignTrack.h:162
const Trk::Track * trackWithoutScattering() const
returns track with ScatteringAngle pointers all set to zero (used for refit by iPat)
void setDerivativeErr(std::vector< AlignModuleDerivatives > *vec)
Definition AlignTrack.h:141
void setResidualVector(Amg::VectorX *vec)
Definition AlignTrack.h:151
bool isSLTrack() const
method to determine whether a straight line track or not
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
std::ostream * m_logStream
logfile output stream
Gaudi::Property< bool > m_removeScatteringBeforeRefit
Gaudi::Property< int > m_minIter
flag to remove scattering before refitting track
std::vector< double ** > m_chi2VAlignParamVec
track chi2[idof][ichambershift]
Gaudi::Property< int > m_particleNumber
ToolHandle< IGlobalTrackFitter > m_trackFitterTool
ToolHandle< IGlobalTrackFitter > m_fitter
int m_ntracksProcessed
number tracks processed
bool setUnshiftedResiduals(AlignTrack *alignTrack)
int m_ntracksPassSetUnshiftedRes
number tracks pass setting unshifted residuals
double shiftSize(const AlignPar *alignPar) const
Gaudi::Property< int > m_maxIter
set minimum number of iterations for first track fits
bool getAllDerivatives(AlignTrack *alignTrack, const AlignModule *alignModule, std::vector< Amg::VectorX > &deriv_vec, std::vector< Amg::VectorX > &derivErr_vec, std::vector< double > &actualsecderiv_vec, bool &resetIPar)
ShiftingDerivCalcTool(const std::string &type, const std::string &name, const IInterface *parent)
int m_ntracksPassInitScan
number tracks pass initial scan
std::unique_ptr< double[]> m_unshiftedTrackChi2MeasType
cut on value of track alignment parameter, determined from fit of chi2 vs.
Gaudi::Property< bool > m_doFits
int m_ntracksPassGetDeriv
number tracks pass getting derivatives
ToolHandle< IAlignResidualCalculator > m_residualCalculator
int m_ntracksPassGetDerivSecPass
number tracks pass 2nd pass of getting derivatives
Amg::VectorX getDerivatives(AlignTrack *alignTrack, int ipar, AlignPar *alignPar, Amg::VectorX &derivativeErr, bool &resetIPar, double &actualSecondDerivative)
int m_ntracksPassGetDerivLastPass
number tracks pass 2nd pass of getting derivatives
bool setDerivatives(AlignTrack *track)
sets derivatives of residuals w.r.t.
int m_ntracksPassDerivatives
number tracks pass setting derivatives
ToolHandle< IAlignModuleTool > m_alignModuleTool
ParticleHypothesis m_particleHypothesis
Gaudi::Property< double > m_rotSize
bool scanShifts(const AlignTrack *alignTrack, const std::vector< AlignModule * > &alignModules)
Gaudi::Property< bool > m_setMinIterations
reject track if exceed maximum number of iterations
Gaudi::Property< bool > m_doChi2VAlignParamMeasType
Gaudi::Property< bool > m_doResidualPlots
bool setResidualCovMatrix(AlignTrack *alignTrack) const
sets residual covariance matrix
Gaudi::Property< double > m_trackAlignParamCut
fit track with AlignModules shifted up and down in each extreme, find the number of iterations fitter...
ToolHandle< IGlobalTrackFitter > m_SLTrackFitterTool
std::vector< double *** > m_chi2VAlignParamVecMeasType
track chi2[idof][imeastype][ichambershift]
Gaudi::Property< double > m_traSize
Gaudi::Property< bool > m_runOutlierRemoval
std::vector< double ** > m_chi2VAlignParamXVec
chamber shift[idof][ichambershift]
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
uint32_t runNumber() const
The current event's run number.
uint64_t eventNumber() const
The current event's event number.
double chi2(TH1 *h0, TH1 *h1)
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Ensure that the ATLAS eigen extensions are properly loaded.
STL namespace.
EventInfo_v1 EventInfo
Definition of the latest event info version.
int m_minIterations
sets the minimum number of iterations to be used in the track fit.
int m_iterationsOfLastFit
returns the number of iterations used by the last fit (count starts at 1 for a single-iteration fit)
int run(int argc, char *argv[])