ATLAS Offline Software
Loading...
Searching...
No Matches
ShiftingDerivCalcTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TrkTrack/Track.h"
13
17
23
26
28
29#include "TGraph.h"
30#include "TF1.h"
31#include "TCanvas.h"
32#include "TPaveText.h"
33#include "TAxis.h"
34
35
36namespace Trk {
37
38 //________________________________________________________________________
40 const std::string& name,
41 const IInterface* parent)
42
43 : AthAlgTool(type,name,parent)
44 , m_trackFitterTool("Trk::GlobalChi2Fitter/MCTBFitter")
45 , m_SLTrackFitterTool("Trk::GlobalChi2Fitter/MCTBSLFitter")
46 //,m_fitter?
47 , m_residualCalculator("Trk::AlignResidualCalculator/ResidualCalculator")
48 , m_alignModuleTool("Trk::AlignModuleTool/AlignModuleTool")
49 , m_traSize(.1)
50 , m_rotSize(.1)
51 , m_runOutlierRemoval(false)
55 , m_nIterations(0)
56 , m_unshiftedResiduals(nullptr)
57 , m_unshiftedResErrors(nullptr)
58 //m_chi2VAlignParamVec
59 //m_chi2VAlignParamXVec
60 , m_tmpChi2VAlignParam(nullptr)
61 , m_tmpChi2VAlignParamX(nullptr)
63 //m_chi2VAlignParamVecMeasType
65 , m_unshiftedTrackChi2MeasType(new double [TrackState::NumberOfMeasurementTypes])
66 //m_trackAlignParamCut
67 //m_setMinIterations
68 //m_maxIter
69 //m_minIter
70 //m_removeScatteringBeforeRefit
82 , m_secPass{}
83 {
84 declareInterface<IDerivCalcTool>(this);
85
86 declareProperty("TrackFitterTool", m_trackFitterTool);
87 declareProperty("SLTrackFitterTool", m_SLTrackFitterTool);
88 declareProperty("TranslationSize", m_traSize);
89 declareProperty("RotationSize", m_rotSize);
90 declareProperty("RunOutlierRemoval", m_runOutlierRemoval);
91 declareProperty("ParticleNumber", m_particleNumber);
92 declareProperty("doChi2VChamberShiftsMeasType", m_doChi2VAlignParamMeasType = false);
93 declareProperty("doResidualFits", m_doFits = true);
94 declareProperty("NumberOfShifts", m_nFits=5);
95 declareProperty("ResidualCalculator", m_residualCalculator);
96 declareProperty("AlignModuleTool", m_alignModuleTool);
97 declareProperty("doResidualPlots", m_doResidualPlots=false);
98 declareProperty("TrackAlignParamCut", m_trackAlignParamCut=1e6);//.001
99 declareProperty("SetMinIterations", m_setMinIterations=false);
100 declareProperty("MaxIterations", m_maxIter=50);
101 declareProperty("MinIterations", m_minIter=10);
102
103 declareProperty("RemoveScatteringBeforeRefit", m_removeScatteringBeforeRefit=false);
104
105 m_logStream = nullptr;
106
107 }
108
109 //________________________________________________________________________
115
116 //________________________________________________________________________
118 {
119
120 msg(MSG::DEBUG) << "in ShiftingDerivCalcTool initialize()"<<endmsg;
121 ATH_CHECK(m_trackFitterTool.retrieve());
122 ATH_CHECK(m_SLTrackFitterTool.retrieve());
124 ATH_CHECK(m_alignModuleTool.retrieve());
125
127 msg(MSG::INFO) << "ParticleNumber: " << m_particleNumber << endmsg;
128 msg(MSG::INFO) << "ParticleHypothesis: " << m_particleHypothesis << endmsg;
129
130
131 if(!m_doFits){
132 m_nFits = 2;
133 }
134
136 m_traSize = 5.*m_traSize/(double)m_nFits;
137 m_rotSize = 5.*m_rotSize/(double)m_nFits;
138
139 msg(MSG::INFO) << "doFits: " << m_doFits << endmsg;
140 msg(MSG::INFO) << "nFits: " << m_nFits << endmsg;
141
142 return StatusCode::SUCCESS;
143 }
144
145 //________________________________________________________________________
147 {
148 ATH_MSG_INFO("number tracks processed: "<<m_ntracksProcessed<<
149 "\nnumber tracks passing initial scan: "<<m_ntracksPassInitScan<<
150 "\nnumber tracks passing setting unshifted residuals: "<< m_ntracksPassSetUnshiftedRes<<
151 "\nnumber tracks pass getting derivatives (1st pass): "<<m_ntracksPassGetDeriv<<
152 "\nnumber tracks pass getting derivatives (2nd pass): "<<m_ntracksPassGetDerivSecPass<<
153 "\nnumber tracks pass getting derivatives (3rd pass): "<<m_ntracksPassGetDerivLastPass<<
154 "\nnumber tracks pass setting derivatives: "<<m_ntracksPassDerivatives);
155 ATH_MSG_INFO("number tracks fail max iterations: "<<m_ntracksFailMaxIter<<
156 "\nnumber tracks fail track refit: "<<m_ntracksFailTrackRefit<<
157 "\nnumber tracks fail align param cut: "<<m_ntracksFailAlignParamCut<<
158 "\nnumber tracks fail final attempt: "<<m_ntracksFailFinalAttempt);
159
160 return StatusCode::SUCCESS;
161 }
162
163 //________________________________________________________________________
165 const std::vector<AlignModule*>& alignModules)
166 {
167 ATH_MSG_DEBUG("in scanShifts");
168
169 const Trk::Track* trackForRefit =
171 dynamic_cast<const Trk::Track*>(alignTrack);
172
173 // see whether straight track or not
174 m_fitter = alignTrack->isSLTrack() ?
176 ATH_MSG_DEBUG("refitting unshifted track with "<<m_fitter<<" (isSLTrack="
177 <<alignTrack->isSLTrack()<<")");
178
179 ATH_MSG_DEBUG("setting minNIterations to "<<m_nIterations);
180
181 // refit track
182
184 alignCache.m_minIterations = m_nIterations;
185 const Track* refittedTrack = m_fitter->alignmentFit(alignCache, *trackForRefit,
188 if (!refittedTrack) {
189 msg(MSG::WARNING) << "initial track refit failed" << endmsg;
190 return false;
191 }
192 else
193 ATH_MSG_DEBUG("initial track refit successful");
194
197 ATH_MSG_DEBUG("exceeded maximum number of iterations");
198 return false;
199 }
200 ATH_MSG_DEBUG("initial nIterations: "<<m_nIterations);
201
202 // loop over AlignModules
203 int imod(0);
204 for (std::vector<AlignModule*>::const_iterator moduleIt=alignModules.begin();
205 moduleIt!=alignModules.end(); ++moduleIt,imod++) {
206
207 // loop over AlignPar
208 int ipar(0);
209 DataVector<AlignPar>* alignPars=m_alignModuleTool->getAlignPars(*moduleIt);
210 for (DataVector<AlignPar>::iterator alignParIt=alignPars->begin();
211 alignParIt!=alignPars->end(); ++alignParIt,ipar++) {
212
213 for (int ishift=0;ishift<2;ishift++) {
214
215 double shiftsize = shiftSize(*alignParIt);
216 if (ishift>0) shiftsize*=-1.;
217 m_alignModuleTool->shiftModule(*moduleIt,alignTrack,(**alignParIt).paramType(),shiftsize);
218 refittedTrack = (m_fitter->fit(Gaudi::Hive::currentContext(),
219 *trackForRefit,m_runOutlierRemoval,
220 m_particleHypothesis)).release();
221 m_alignModuleTool->restoreModule(*moduleIt);
222 if (!refittedTrack) {
223 msg(MSG::WARNING) << "track refit failed!"<<endmsg;
225 return false;
226 }
227
228 int nIter=alignCache.m_iterationsOfLastFit;
229 ATH_MSG_DEBUG("nIter: "<<nIter);
230 if (nIter>m_maxIter) {
231 ATH_MSG_DEBUG("exceeded maximum number of iterations");
233 return false;
234 }
235
236 if (nIter>m_nIterations) m_nIterations=nIter;
237 }
238 } // loop over AlignPar
239 } // loop over AlignModules
240
241 ATH_MSG_DEBUG("done with scanShifts, m_nIterations="<<m_nIterations);
242 return true;
243 }
244
245 //________________________________________________________________________
247 {
248
249 // see whether straight track or not
250 m_fitter = alignTrack->isSLTrack() ?
252 ATH_MSG_DEBUG("refitting unshifted track with "<<m_fitter<<" (isSLTrack="
253 <<alignTrack->isSLTrack()<<")");
254
255 // refit track
256 ATH_MSG_DEBUG("\nsetting min number iterations to "<<m_nIterations);
258 alignCache.m_minIterations = m_nIterations;
259
260 const Trk::Track* trackForRefit =
262 dynamic_cast<const Trk::Track*>(alignTrack);
263 if (!trackForRefit) {
264 ATH_MSG_ERROR("no track for refit!");
265 return false;
266 }
267
268 const Track* refittedTrack = m_fitter->alignmentFit( alignCache,
269 *trackForRefit,
272
273 if (!refittedTrack) {
274 ATH_MSG_WARNING( "initial track refit failed" );
275 return false;
276 }
277 else
278 ATH_MSG_DEBUG("initial track refit successful");
279
280 // dump local track chi2 for debugging
281 double localChi2=m_residualCalculator->setResiduals(alignTrack,refittedTrack);
282 msg()<<MSG::DEBUG<<"local Chi2(unshifted) in setChi2VAlignParam="<<localChi2<<endmsg;
283 m_unshiftedTrackChi2 = localChi2;
284 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++) {
285 ATH_MSG_DEBUG("getting chi2 for measType "<<i);
287 }
288 ATH_MSG_DEBUG("done");
289
290 // create vector containing unshifted residuals and matrices containing errors
291 const int NMEAS=alignTrack->nAlignTSOSMeas();
292
293 // unshiftedResiduals owned by AlignTrack
295
296 // unshiftedResErrors owned by ShiftingDerivCalcTool
299
300 // loop over atsos and determine residuals and errors
301 int imeas=0;
302 AlignTSOSCollection::const_iterator atsosItr=alignTrack->firstAtsos();
303 for (; atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
304 if (!(**atsosItr).isValid()) continue;
305 for (std::vector<Residual>::const_iterator itRes=(**atsosItr).firstResidual();
306 itRes!=(**atsosItr).lastResidual();++itRes,++imeas) {
307 double residual = itRes->residual();
308 double errSq = itRes->errSq();
309 (*m_unshiftedResiduals)[imeas]=residual;
310 (*m_unshiftedResErrors)[imeas]=std::sqrt(errSq);
311 //ATH_MSG_DEBUG("weight: "<<1./errSq<<", unshiftedRes["<<imeas<<"]="
312 // <<(*m_unshiftedResiduals)[imeas]
313 // <<", resNorm="<<itRes->residualNorm());
314 }
315 }
316 if (imeas!=NMEAS) {
317 msg(MSG::ERROR)<<"problem with nmeas, imeas="<<imeas<<", NMEAS="<<NMEAS<<endmsg;
318 throw std::runtime_error("Error in ShiftingDerivCalcTool::setUnshiftedResiduals");
319 }
321
322 delete refittedTrack; refittedTrack=nullptr;
323
324 return true;
325 }
326
327//________________________________________________________________________
329{
330 ATH_MSG_DEBUG("in ShiftingDerivCalcTool setDerivatives");
332
333 // loop over AlignTSOSCollection,
334 // find modules that are in the AlignModuleList,
335 std::vector<AlignModule*> alignModules;
336 for (AlignTSOSCollection::iterator atsosItr=alignTrack->firstAtsos();
337 atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
338
339 ATH_MSG_VERBOSE("getting module");
340 AlignModule* module=(*atsosItr)->module();
341 if (module)
342 ATH_MSG_VERBOSE("have ATSOS for module "<<module->identify());
343 else
344 ATH_MSG_VERBOSE("no module!");
345
346 if (!(*atsosItr)->isValid() || !module) continue;
347 if (find(alignModules.begin(),alignModules.end(),module) == alignModules.end())
348 alignModules.push_back(module);
349 }
350
351 // find perigee of best track fit and use as starting perigee for all fits
353 if (m_setMinIterations && !scanShifts(alignTrack, alignModules)) {
354 return false;
355 };
356
358
359 // set unshifted residuals (this is done in AlignTrackDresser but redone here with track refit)
360 if (!setUnshiftedResiduals(alignTrack)) {
361 ATH_MSG_WARNING("problem with refitting track!");
362 return false;
363 };
364
366
367 // Determine derivatives from shifting these modules
368 std::vector<AlignModuleDerivatives> * derivatives = new std::vector<AlignModuleDerivatives>;
369 std::vector<AlignModuleDerivatives> * derivativeErr = new std::vector<AlignModuleDerivatives>;
370 std::vector<std::pair<AlignModule*, std::vector<double> > > * actualSecondDerivatives =
371 new std::vector<std::pair<AlignModule*, std::vector<double> > >;
373 for (auto *alignModule : alignModules) {
374
375 ATH_MSG_DEBUG("finding derivatives for module "<<(*alignModule).identify());
376
377 std::vector<Amg::VectorX> deriv_vec;
378 std::vector<Amg::VectorX> derivErr_vec;
379 std::vector<double> actualsecderiv_vec;
380
381 // get alignPars and create arrays to store chi2 vs. align pars
382 DataVector<AlignPar>* alignPars=m_alignModuleTool->getAlignPars(alignModule);
383 const int nAlignPar = alignPars->size();
384 m_tmpChi2VAlignParam = new double*[nAlignPar];
385 m_tmpChi2VAlignParamX = new double*[nAlignPar];
388 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++)
389 m_tmpChi2VAlignParamMeasType[i] = new double*[nAlignPar];
390 }
391
392
393 // get derivatives and arrays of chi2 vs. align params
394 bool resetIPar=false;
395 std::vector<Amg::VectorX> tmpderiv_vec;
396 std::vector<Amg::VectorX> tmpderivErr_vec;
397 std::vector<double> tmpactualsecderiv_vec;
398 m_secPass=false;
399
400 // first attempt with normal number of fitter iterations
401 bool success=getAllDerivatives(
402 alignTrack, alignModule,
403 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
404 resetIPar);
405 if (!success){
406 delete derivatives;
407 delete derivativeErr;
408 delete actualSecondDerivatives;
409 return false;
410 }
411
413
414 if (resetIPar) {
415 // second attempt with increased number of fitter iterations
416 m_secPass=true;
417 success=getAllDerivatives(alignTrack,alignModule,
418 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
419 resetIPar);
420 }
421
422 if (!success){
423 delete derivatives;
424 delete derivativeErr;
425 delete actualSecondDerivatives;
426 return false;
427 }
428
430
431 if (resetIPar) {
432 // third and last attempt with number of fitter iterations set to maximum
434 success=getAllDerivatives(alignTrack,alignModule,
435 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
436 resetIPar);
437 }
438
439 if (!success){
440 delete derivatives;
441 delete derivativeErr;
442 delete actualSecondDerivatives;
443 return false;
444 }
445
446
448
449 if (success && !resetIPar) {
450 for (int i=0;i<(int)tmpderiv_vec.size();i++) {
451 deriv_vec.push_back(tmpderiv_vec[i]);
452 derivErr_vec.push_back(tmpderivErr_vec[i]);
453 actualsecderiv_vec.push_back(tmpactualsecderiv_vec[i]);
454 }
455 }
456 else{
457 delete derivatives;
458 delete derivativeErr;
459 delete actualSecondDerivatives;
460 return false;
461 }
462 // set the chi2 vs. align param arrays
463 ATH_MSG_DEBUG("setting chi2 vs. align param arrays");
466 (*alignModule).setChi2VAlignParamArray (m_tmpChi2VAlignParam);
467 (*alignModule).setChi2VAlignParamXArray(m_tmpChi2VAlignParamX);
468
469 // arrays for measurement types
471 ATH_MSG_DEBUG("pushing back for measType");
473 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++)
474 (*alignModule).setChi2VAlignParamArrayMeasType(i,m_tmpChi2VAlignParamMeasType[i]);
475 }
476 ATH_MSG_DEBUG("done setting arrays");
477
478 derivatives->push_back(make_pair(alignModule,deriv_vec));
479 derivativeErr->push_back(make_pair(alignModule,derivErr_vec));
480 actualSecondDerivatives->push_back(make_pair(alignModule,actualsecderiv_vec));
481 }
482
484
485 alignTrack->setDerivatives(derivatives);
486 alignTrack->setDerivativeErr(derivativeErr);
487 alignTrack->setActualSecondDerivatives(actualSecondDerivatives);
488
489 // restore unshifted residuals in AlignTSOS
490 setUnshiftedResiduals(alignTrack);
491
492 return true;
493}
494
495//________________________________________________________________________
497 AlignTrack* alignTrack,
498 int ipar, AlignPar* alignPar,
499 Amg::VectorX& derivativeErr,
500 bool& resetIPar,
501 double& actualSecondDeriv)
502{
503 const Trk::Track* trackForRefit =
505 dynamic_cast<const Trk::Track*>(alignTrack);
506
507 ATH_MSG_DEBUG("m_nIterations: "<<m_nIterations);
508
509 // gets derivatives of residuals w.r.t. a specific alignment parameter given by alignPar
510 if (!m_fitter)
511 ATH_MSG_ERROR("set m_fitter before calling getDerivatives (by calling setUnshiftedResiduals)");
512
513 AlignModule* module=alignPar->alignModule();
514
515 // set derivatives for 2 shifts up and 2 shifts down
516 const int NFITS = m_nFits;
517 const int NMEAS = alignTrack->nAlignTSOSMeas();
518 module->setNChamberShifts(m_nFits);
519
520 ATH_MSG_DEBUG("NMEAS="<<NMEAS);
521 double** residuals=new double*[NFITS];
522 double** resErrors=new double*[NFITS];
523 double* chi2Array =new double[NFITS];
524 double* chi2ArrayX=new double[NFITS];
525
527 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++)
528 m_tmpChi2VAlignParamMeasType[i][ipar] =new double[NFITS];
529 }
530
531 for (int ifit=0;ifit<NFITS;ifit++) {
532 residuals[ifit]=new double[NMEAS];
533 resErrors[ifit]=new double[NMEAS];
534 }
535
536 // set the values for the unshifted track
537 const int unshiftedTrackIndex = m_doFits ? (m_nFits-1)/2 : 1;
538 chi2Array [unshiftedTrackIndex] = m_unshiftedTrackChi2;
539 ATH_MSG_DEBUG("chi2Array["<<unshiftedTrackIndex<<"]="<<chi2Array[unshiftedTrackIndex]);
540 chi2ArrayX[unshiftedTrackIndex] = 0.;
542 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++) {
543 m_tmpChi2VAlignParamMeasType[i][ipar][unshiftedTrackIndex]=
545 ATH_MSG_DEBUG("chi2ArrayMeasType["<<i<<"]["<<unshiftedTrackIndex<<"]="<<m_unshiftedTrackChi2MeasType[i]);
546 }
547 }
548
549
550 // get shift size
551 double shiftsize=shiftSize(alignPar);
552
554
555
556 ATH_MSG_VERBOSE("doing refits");
557 for (int ifit=0;ifit<NFITS;ifit++) {
558
559 ATH_MSG_VERBOSE("ifit="<<ifit);
560 int jfit=ifit;
561 if (ifit>unshiftedTrackIndex) {
562 jfit=NFITS-ifit+unshiftedTrackIndex;
563 }
564 if (m_doFits && ifit==unshiftedTrackIndex) {
565 for (int i=0;i<(int)m_unshiftedResiduals->rows();i++) {
566 residuals[ifit][i]=(*m_unshiftedResiduals)[i];
567 resErrors[ifit][i]=(*m_unshiftedResErrors)[i];
568 }
569 // change back in case it got changed on the other side of zero
570 shiftsize=shiftSize(alignPar);
571 continue;
572 }
573
574 // shift module and fit track
575 double currentshift = 0.;
576 if(m_doFits)
577 currentshift = shiftsize * (double)(jfit-unshiftedTrackIndex);
578 else
579 currentshift = (ifit==0) ? -1.*shiftsize : shiftsize;
580
581 ATH_MSG_DEBUG("current shift="<<currentshift<<" in getDerivatives");
582
583 m_alignModuleTool->shiftModule(module,alignTrack,
584 alignPar->paramType(),currentshift);
585
586
587 ATH_MSG_VERBOSE("fitting after shift");
588 const Track* refittedTrack=m_fitter->alignmentFit(alignCache,
589 *trackForRefit,
594 ATH_MSG_DEBUG("exceeded max number of iterations");
595 m_alignModuleTool->restoreModule(module);
596 resetIPar=false;
597 ATH_MSG_DEBUG("resetIPar set to false");
598 delete [] residuals; delete [] resErrors;
599 delete [] chi2Array; delete [] chi2ArrayX;
600 ATH_MSG_DEBUG("fail max iter");
602 Amg::VectorX derivatives(1);
603 return derivatives;
604 }
605 ATH_MSG_DEBUG("increasing m_nIterations to "<<m_nIterations<<" (not changing in fit yet)");
606 resetIPar=true;
607 ATH_MSG_DEBUG("resetIPar set to true");
608 }
609
610 // if resetIPar refit the rest of the tracks, but don't do anything with them until next pass
611 if (resetIPar) {
612 m_alignModuleTool->restoreModule(module);
613 continue;
614 }
615
616 if (!refittedTrack) {
617 msg(MSG::WARNING) << "track refit failed for jfit "<<jfit <<endmsg;
618 delete [] residuals; delete [] resErrors;
619 delete [] chi2Array; delete [] chi2ArrayX;
620 m_alignModuleTool->restoreModule(module);
621 if (!resetIPar || m_secPass) {
623 }
624 ATH_MSG_DEBUG("fail track refit, resetIPar "<<resetIPar<<", secPass "<<m_secPass);
625 Amg::VectorX derivatives(1);
626 return derivatives;
627 }
628 else
629 ATH_MSG_VERBOSE("track refit successful");
630
631 double chi2=refittedTrack->fitQuality()->chiSquared();
632
633 ATH_MSG_VERBOSE("jfit = "<<jfit);
634 double localChi2=m_residualCalculator->setResiduals(alignTrack,refittedTrack);
635 ATH_MSG_DEBUG("localChi2/fittedChi2="<<localChi2<<"/"<<chi2);
636
637 chi2ArrayX[jfit]= shiftsize * (double)(jfit-unshiftedTrackIndex);// / module->sigma(idof);
638 chi2Array[jfit]=localChi2;
639 ATH_MSG_DEBUG("chi2Array["<<jfit<<"]="<<chi2Array[jfit]);
641 for (int i=0;i<TrackState::NumberOfMeasurementTypes;i++) {
642 m_tmpChi2VAlignParamMeasType[i][ipar][jfit]= m_residualCalculator->chi2ForMeasType(i);
643 ATH_MSG_DEBUG("chi2ArrayMeasType["<<i<<"]["<<jfit<<"]="
644 <<m_tmpChi2VAlignParamMeasType[i][ipar][jfit]);
645 }
646 }
647
648 ATH_MSG_DEBUG("positions["<<jfit<<"]="<<chi2ArrayX[jfit]);
649
650 int imeas(0);
651 AlignTSOSCollection::const_iterator atsosItr=alignTrack->firstAtsos();
652 for (; atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
653 if (!(*atsosItr)->isValid()) continue;
654 for (std::vector<Residual>::const_iterator itRes=(**atsosItr).firstResidual();
655 itRes!=(**atsosItr).lastResidual();++itRes,++imeas) {
656
657 if (refittedTrack) {
658 residuals[jfit][imeas]=itRes->residual();
659 resErrors[jfit][imeas]=std::sqrt(itRes->errSq());
660 }
661 else {
662 residuals[jfit][imeas]=resErrors[jfit][imeas]=0.;
663 }
664 ATH_MSG_DEBUG("residuals["<<jfit<<"]["<<imeas<<"]="<<residuals[jfit][imeas]);
665 ATH_MSG_DEBUG("resErrors["<<jfit<<"]["<<imeas<<"]="<<resErrors[jfit][imeas]);
666 }
667 }
668
669 delete refittedTrack; refittedTrack=nullptr;
670 ATH_MSG_VERBOSE("calling restoreModule");
671 m_alignModuleTool->restoreModule(module);
672 } // NFITS
673
674 int iimeas(0);
675 AlignTSOSCollection::const_iterator aatsosItr=alignTrack->firstAtsos();
676 for (; aatsosItr != alignTrack->lastAtsos(); ++aatsosItr) {
677 if (!(*aatsosItr)->isValid()) continue;
678 for (std::vector<Residual>::const_iterator itRes=(**aatsosItr).firstResidual();
679 itRes!=(**aatsosItr).lastResidual();++itRes,++iimeas) {
680 for (int ifit=0;ifit<NFITS;ifit++) {
681 ATH_MSG_DEBUG("["<<ifit<<"]["<<iimeas<<"] res="<<residuals[ifit][iimeas]<<
682 ", resErr="<<resErrors[ifit][iimeas]);
683 }
684 }
685 }
686
687 if (resetIPar) {
688 //resetIPar=false;
689 delete [] residuals; delete [] resErrors;
690 delete [] chi2Array; delete [] chi2ArrayX;
691 if (m_secPass) ATH_MSG_WARNING("failed second pass!");
692 ATH_MSG_DEBUG("returning to reset IPar");
693 Amg::VectorX derivatives;
694 return derivatives;
695 }
696
697 // check chi2 vs. chamber pos to see if discontinuous
698 TGraph* gr = new TGraph(m_nFits,chi2ArrayX,chi2Array);
699 gr->Fit("pol2","QF");
700 TF1* fit=gr->GetFunction("pol2");
701 double chi2 =fit->GetChisquare()/double(m_nFits-3);
702 double slope=fit->GetParameter(1);
703 actualSecondDeriv=fit->GetParameter(2);
704 delete gr;
705
706 ATH_MSG_DEBUG("discontinuity check: chi2="<<chi2);
707 alignTrack->setTrackAlignParamQuality(alignPar->paramType(),chi2);
708
709 // EventInfo
710 if (chi2>1.e-6 || std::fabs(slope)<1.e-10) {
711 const xAOD::EventInfo* eventInfo;
712 StatusCode sc=evtStore()->retrieve(eventInfo);
713 if (sc.isFailure())
714 ATH_MSG_ERROR("Couldn't retrieve event info");
715 int run=eventInfo->runNumber();
716 int evt=eventInfo->eventNumber();
717 ATH_MSG_DEBUG("discontinuity check: chi2="<<chi2<<", run/evt "<<run<<"/"<<evt);
718 }
719
720 //reset in case it got changed somewhere
721 shiftsize = shiftSize(alignPar);
722
723 //-----------------------------------------//
724 //-- get derivatives from residuals --//
725 //-----------------------------------------//
726 ATH_MSG_VERBOSE("calculating residuals");
727 Amg::VectorX derivatives(alignTrack->nAlignTSOSMeas(),0);
728 ATH_MSG_DEBUG("created derivatives with "<<derivatives.rows()<<" rows");
729
730 // if bad fit or first derivative close to zero, replace derivatives with zeros
731 if (chi2>m_trackAlignParamCut) {// || std::fabs(slope)<1.e-10 ) {
732 ATH_MSG_DEBUG("chi2/"<<m_nFits-3<<"="<<chi2);
733 delete [] residuals; delete [] resErrors;
734 delete [] chi2Array; delete [] chi2ArrayX;
735
738 ATH_MSG_DEBUG("exceeded max number of iterations");
739 resetIPar=false;
740 }
741 ATH_MSG_DEBUG("increasing m_nIterations to "<<m_nIterations<<" (not changing in fit yet)");
742 resetIPar=true;
743 ATH_MSG_INFO("fail align param cut, secPass "<<m_secPass);
744 if (m_secPass) {
746 }
747 Amg::VectorX emptyDerivatives;
748 return emptyDerivatives;
749 }
750
751 int imeas(0);
752 TCanvas* canv(nullptr);
753 std::vector<TGraph*> vecGraphs;
754 AlignTSOSCollection::const_iterator atsosItr=alignTrack->firstAtsos();
755 for (; atsosItr != alignTrack->lastAtsos(); ++atsosItr) {
756 if (!(*atsosItr)->isValid()) continue;
757 for (int idim=0;idim<(*atsosItr)->nResDim();idim++) {
758
759 double* gr_x = new double[NFITS];
760 double* gr_y = new double[NFITS]; // residuals only have float precision if determined from ESD
761 int ngoodfits=0;
762 for (int ifit=0;ifit<NFITS;ifit++) {
763 double residual=residuals[ifit][imeas];
764 double resError=resErrors[ifit][imeas];
765 if (residual>-999.) {
766 gr_x[ngoodfits] =chi2ArrayX[ifit];
767 gr_y[ngoodfits] =residual/resError;
768 ngoodfits++;
769 }
770 }
771
772 if (!m_doFits && ngoodfits==2) {
773 derivatives[imeas]=(residuals[1][imeas]-residuals[0][imeas])/(2.*shiftsize)*
774 resErrors[unshiftedTrackIndex][imeas];
775 }
776 else if (m_doFits && ngoodfits>3) {
777 TGraph* gr=new TGraph(ngoodfits,gr_x,gr_y);
778
780 gr->Fit("pol2","VF");
781 else
782 gr->Fit("pol2","QF");
783 TF1* fit=gr->GetFunction("pol2");
784
785 //double derivRatio=fit->GetParameter(2)/fit->GetParameter(1);
786 ATH_MSG_DEBUG("deriv["<<imeas<<"]="<<fit->GetParameter(1)<<" +/- "<<fit->GetParError(1)
787 <<", chi2="<<fit->GetChisquare());
788 derivatives[imeas]=fit->GetParameter(1)*resErrors[unshiftedTrackIndex][imeas]; // first derivative at x=0
789 derivativeErr[imeas]=fit->GetParError(1)*resErrors[unshiftedTrackIndex][imeas];
790
791
792 // plot residuals vs. chamber position
793 if (m_doResidualPlots) {
794 if (!canv) canv=new TCanvas("resPlots","resPlots");
795 canv->cd();
796 gr->SetMarkerStyle(20);
797 gr->Draw("AP");
798
799 gr->GetXaxis()->SetTitle("shift in chamber pos. from nominal (CLHEP::mm)");
800 gr->GetYaxis()->SetTitle("residual (CLHEP::mm)");
801
802 TPaveText* pave=new TPaveText(.4,.65,.97,.92,"NDC");
803 pave->SetFillColor(0);
804 pave->SetBorderSize(1);
805 std::stringstream measType; measType<<"meas type: ";
806 if ((*atsosItr)->measType()==TrackState::MDT) measType<<" MDT";
807 else if ((*atsosItr)->measType()==TrackState::TGC) measType<<" TGC";
808 else if ((*atsosItr)->measType()==TrackState::RPC) measType<<" RPC";
809 else measType<<" undefined";
810
811 pave->AddText(measType.str().c_str());
812
813 std::stringstream firstderivtxt,secndderivtxt,aptxt,chi2txt;
814 firstderivtxt<<fit->GetParameter(1)<<" +/- "<<fit->GetParError(1);
815 secndderivtxt<<fit->GetParameter(2)<<" +/- "<<fit->GetParError(2);
816 aptxt <<"alignPar "<<alignPar->paramType()<<", RIO in "<<(*atsosItr)->identify();
817 chi2txt<<"chi2="<<fit->GetChisquare();
818
819 pave->AddText(firstderivtxt.str().c_str());
820 pave->AddText(secndderivtxt.str().c_str());
821 pave->AddText(aptxt.str().c_str());
822 pave->AddText(chi2txt.str().c_str());
823 pave->Draw();
824
825 std::stringstream canvName;
826 canvName<<"resPlots_ap"<<alignPar->paramType()<<"_measType"
827 <<(*atsosItr)->measType()<<"_"<<imeas<<".eps";
828 canv->Print(canvName.str().c_str());
829 canv->Clear();
830
831 delete pave;
832 }
833 vecGraphs.push_back(gr);
834 }
835 else {
836 derivatives[imeas]=-999.;
837 derivativeErr[imeas]=-999.;
838 }
839
840 delete [] gr_y;
841 delete [] gr_x;
842
843 ++imeas;
844 }
845 }
846
847 // delete TGraphs and TCanvas
848 for (auto & vecGraph : vecGraphs)
849 delete vecGraph;
850 delete canv;
851
852 delete [] residuals;
853 delete [] resErrors;
854
855 // set chi2 v alignparam
856 for (int ifit=0;ifit<NFITS;ifit++) {
857 m_tmpChi2VAlignParamX[ipar]=chi2ArrayX;
858 m_tmpChi2VAlignParam [ipar]=chi2Array;
859 }
860
861 ATH_MSG_DEBUG("derivativeErr: "<<derivativeErr);
862 return derivatives;
863}
864
865//________________________________________________________________________
866double ShiftingDerivCalcTool::shiftSize(const AlignPar* alignPar) const {
867 bool rotation =
868 alignPar->paramType() == AlignModule::RotX ||
869 alignPar->paramType() == AlignModule::RotY ||
870 alignPar->paramType() == AlignModule::RotZ;
871
872 double shift = rotation ? m_rotSize : m_traSize;
873
874 //ok... this is kind of ugly.
875 double sigma=alignPar->sigma();
876 return shift * sigma;
877}
878
879//________________________________________________________________________
881{
882 Amg::MatrixX W(alignTrack->nAlignTSOSMeas(),alignTrack->nAlignTSOSMeas());
883
884 if (alignTrack->localErrorMatrixInv()) {
885 ATH_MSG_ERROR("Need to assign this matrix correctly: ShiftingDerivCalcTool.cxx:888");
886 W = *(alignTrack->localErrorMatrixInv());
887 //W.assign(*(alignTrack->localErrorMatrixInv()));
888 } else{
889 return false;
890 }
891 ATH_MSG_DEBUG("W: "<<W);
892
893 bool Wisvalid(true);
894 const double epsilon=1e-10;
895 for( int irow=0; irow<W.rows(); ++irow) {
896 Wisvalid = Wisvalid && W(irow,irow)>0;
897 if( !(W(irow,irow)>0) )
898 msg(MSG::WARNING) << "matrix invalid: " << W(irow,irow) << endmsg;
899
900 for(int icol=0; icol<=irow; ++icol) {
901
902 // this one must be true if everything else succeeded
903 double Wcorr = W(irow,icol)/sqrt(W(irow,irow)*W(icol,icol));
904 bool Wcorrisvalid = Wcorr+epsilon>=-1 && Wcorr-epsilon<=1;
905 Wisvalid = Wisvalid && Wcorrisvalid;
906 if( !Wcorrisvalid )
907 msg(MSG::WARNING) << "matrix corr invalid: " << Wcorr-1 << " " << Wcorr+1 << endmsg;
908 }
909 }
910
911 if (Wisvalid)
912 alignTrack->setWeightMatrix(new Amg::MatrixX(W));
913
914 alignTrack->setWeightMatrixFirstDeriv(new Amg::MatrixX(std::move(W)));
915
916 return true;
917}
918
919//________________________________________________________________________
921{
922 for (int i=0;i<(int)m_chi2VAlignParamVec.size();i++) {
923 delete [] m_chi2VAlignParamVec[i]; m_chi2VAlignParamVec[i]=nullptr;
924 delete [] m_chi2VAlignParamXVec[i]; m_chi2VAlignParamXVec[i]=nullptr;
925 }
926 m_chi2VAlignParamVec.clear();
927 m_chi2VAlignParamXVec.clear();
928
929 for (auto & i : m_chi2VAlignParamVecMeasType) {
930 delete [] i; i=nullptr;
931 }
933}
934
935//________________________________________________________________________
937 AlignTrack* alignTrack,
938 const AlignModule* alignModule,
939 std::vector<Amg::VectorX>& deriv_vec,
940 std::vector<Amg::VectorX>& derivErr_vec,
941 std::vector<double>& actualsecderiv_vec,
942 bool& resetIPar)
943{
944 resetIPar=false;
945
946 deriv_vec.clear();
947 derivErr_vec.clear();
948 actualsecderiv_vec.clear();
949
950 setUnshiftedResiduals(alignTrack); // this will set the min number of iterations to the new value
951
952 int ipar(0);
953 DataVector<AlignPar>* alignPars=m_alignModuleTool->getAlignPars(alignModule);
954 for (DataVector<AlignPar>::iterator it=alignPars->begin(); it!=alignPars->end(); ++it,ipar++) {
955 ATH_MSG_DEBUG("ipar: "<<ipar);
956 Amg::VectorX derivErr(alignTrack->nAlignTSOSMeas());
957 double actualSecondDeriv(0.);
958 const Amg::VectorX vec=getDerivatives(alignTrack,ipar,*it,derivErr,resetIPar,actualSecondDeriv);
959 ATH_MSG_DEBUG("vec size: "<<vec.rows());
960
961 ATH_MSG_DEBUG("resetIPar="<<resetIPar);
962 if (resetIPar) continue; // continue with derivatives to find max iteration
963
964 if (vec.rows()<1) return false; // derivatives won't be set for alignTrack because it's a bad track
965
966 deriv_vec.push_back(vec);
967 derivErr_vec.push_back(derivErr);
968 actualsecderiv_vec.push_back(actualSecondDeriv);
969
970 for (int i=0;i<m_nFits;i++) {
971 ATH_MSG_DEBUG("m_tmpChi2VAlignParam["<<ipar<<"]["
972 <<i<<"]="<<m_tmpChi2VAlignParam[ipar][i]);
973 }
974 }
975
976 return true;
977}
978
979} // 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:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
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
int m_minIter
set minimum number of iterations for first track fits
std::vector< double ** > m_chi2VAlignParamVec
track chi2[idof][ichambershift]
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
int m_maxIter
reject track if exceed maximum number of iterations
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
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
bool m_removeScatteringBeforeRefit
flag to remove scattering before refitting track
ToolHandle< IAlignModuleTool > m_alignModuleTool
ParticleHypothesis m_particleHypothesis
bool m_setMinIterations
fit track with AlignModules shifted up and down in each extreme, find the number of iterations fitter...
bool scanShifts(const AlignTrack *alignTrack, const std::vector< AlignModule * > &alignModules)
bool setResidualCovMatrix(AlignTrack *alignTrack) const
sets residual covariance matrix
ToolHandle< IGlobalTrackFitter > m_SLTrackFitterTool
std::vector< double *** > m_chi2VAlignParamVecMeasType
track chi2[idof][imeastype][ichambershift]
double m_trackAlignParamCut
cut on value of track alignment parameter, determined from fit of chi2 vs.
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:138
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.
Definition run.py:1
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)