32 #include "TPaveText.h"
40 const std::string&
name,
44 , m_trackFitterTool(
"Trk::GlobalChi2Fitter/MCTBFitter")
45 , m_SLTrackFitterTool(
"Trk::GlobalChi2Fitter/MCTBSLFitter")
47 , m_residualCalculator(
"Trk::AlignResidualCalculator/ResidualCalculator")
48 , m_alignModuleTool(
"Trk::AlignModuleTool/AlignModuleTool")
51 , m_runOutlierRemoval(false)
52 , m_particleHypothesis(
Trk::
muon)
56 , m_unshiftedResiduals(
nullptr)
57 , m_unshiftedResErrors(
nullptr)
60 , m_tmpChi2VAlignParam(
nullptr)
61 , m_tmpChi2VAlignParamX(
nullptr)
62 , m_tmpChi2VAlignParamMeasType(
nullptr)
64 , m_unshiftedTrackChi2{}
71 , m_ntracksProcessed(0)
72 , m_ntracksPassInitScan(0)
73 , m_ntracksPassSetUnshiftedRes(0)
74 , m_ntracksPassDerivatives(0)
75 , m_ntracksPassGetDeriv(0)
76 , m_ntracksPassGetDerivSecPass(0)
77 , m_ntracksPassGetDerivLastPass(0)
78 , m_ntracksFailMaxIter(0)
79 , m_ntracksFailTrackRefit(0)
80 , m_ntracksFailAlignParamCut(0)
81 , m_ntracksFailFinalAttempt(0)
84 declareInterface<IDerivCalcTool>(
this);
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);
99 declareProperty(
"SetMinIterations", m_setMinIterations=
false);
100 declareProperty(
"MaxIterations", m_maxIter=50);
101 declareProperty(
"MinIterations", m_minIter=10);
103 declareProperty(
"RemoveScatteringBeforeRefit", m_removeScatteringBeforeRefit=
false);
105 m_logStream =
nullptr;
142 return StatusCode::SUCCESS;
160 return StatusCode::SUCCESS;
165 const std::vector<AlignModule*>& alignModules)
185 const Track* refittedTrack =
m_fitter->alignmentFit(alignCache, *trackForRefit,
188 if (!refittedTrack) {
189 msg(MSG::WARNING) <<
"initial track refit failed" <<
endmsg;
204 for (std::vector<AlignModule*>::const_iterator moduleIt=alignModules.begin();
205 moduleIt!=alignModules.end(); ++moduleIt,imod++) {
211 alignParIt!=alignPars->
end(); ++alignParIt,ipar++) {
213 for (
int ishift=0;ishift<2;ishift++) {
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(),
222 if (!refittedTrack) {
223 msg(MSG::WARNING) <<
"track refit failed!"<<
endmsg;
263 if (!trackForRefit) {
268 const Track* refittedTrack =
m_fitter->alignmentFit( alignCache,
273 if (!refittedTrack) {
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);
317 msg(MSG::ERROR)<<
"problem with nmeas, imeas="<<imeas<<
", NMEAS="<<NMEAS<<
endmsg;
318 throw std::runtime_error(
"Error in ShiftingDerivCalcTool::setUnshiftedResiduals");
322 delete refittedTrack; refittedTrack=
nullptr;
335 std::vector<AlignModule*> alignModules;
337 atsosItr != alignTrack->
lastAtsos(); ++atsosItr) {
346 if (!(*atsosItr)->isValid() || !
module)
continue;
347 if (
find(alignModules.begin(),alignModules.end(),
module) == alignModules.end())
348 alignModules.push_back(
module);
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) {
375 ATH_MSG_DEBUG(
"finding derivatives for module "<<(*alignModule).identify());
377 std::vector<Amg::VectorX> deriv_vec;
378 std::vector<Amg::VectorX> derivErr_vec;
379 std::vector<double> actualsecderiv_vec;
383 const int nAlignPar = alignPars->
size();
394 bool resetIPar=
false;
395 std::vector<Amg::VectorX> tmpderiv_vec;
396 std::vector<Amg::VectorX> tmpderivErr_vec;
397 std::vector<double> tmpactualsecderiv_vec;
402 alignTrack, alignModule,
403 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
407 delete derivativeErr;
408 delete actualSecondDerivatives;
418 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
424 delete derivativeErr;
425 delete actualSecondDerivatives;
435 tmpderiv_vec,tmpderivErr_vec,tmpactualsecderiv_vec,
441 delete derivativeErr;
442 delete actualSecondDerivatives;
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]);
458 delete derivativeErr;
459 delete actualSecondDerivatives;
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));
501 double& actualSecondDeriv)
511 ATH_MSG_ERROR(
"set m_fitter before calling getDerivatives (by calling setUnshiftedResiduals)");
521 double** residuals=
new double*[NFITS];
522 double** resErrors=
new double*[NFITS];
523 double* chi2Array =
new double[NFITS];
524 double* chi2ArrayX=
new double[NFITS];
531 for (
int ifit=0;ifit<NFITS;ifit++) {
532 residuals[ifit]=
new double[NMEAS];
533 resErrors[ifit]=
new double[NMEAS];
539 ATH_MSG_DEBUG(
"chi2Array["<<unshiftedTrackIndex<<
"]="<<chi2Array[unshiftedTrackIndex]);
540 chi2ArrayX[unshiftedTrackIndex] = 0.;
557 for (
int ifit=0;ifit<NFITS;ifit++) {
561 if (ifit>unshiftedTrackIndex) {
562 jfit=NFITS-ifit+unshiftedTrackIndex;
564 if (
m_doFits && ifit==unshiftedTrackIndex) {
566 residuals[ifit][
i]=(*m_unshiftedResiduals)[
i];
567 resErrors[ifit][
i]=(*m_unshiftedResErrors)[
i];
575 double currentshift = 0.;
577 currentshift = shiftsize * (
double)(jfit-unshiftedTrackIndex);
579 currentshift = (ifit==0) ? -1.*shiftsize : shiftsize;
581 ATH_MSG_DEBUG(
"current shift="<<currentshift<<
" in getDerivatives");
588 const Track* refittedTrack=
m_fitter->alignmentFit(alignCache,
598 delete [] residuals;
delete [] resErrors;
599 delete [] chi2Array;
delete [] chi2ArrayX;
616 if (!refittedTrack) {
617 msg(MSG::WARNING) <<
"track refit failed for jfit "<<jfit <<
endmsg;
618 delete [] residuals;
delete [] resErrors;
619 delete [] chi2Array;
delete [] chi2ArrayX;
637 chi2ArrayX[jfit]= shiftsize * (
double)(jfit-unshiftedTrackIndex);
638 chi2Array[jfit]=localChi2;
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) {
658 residuals[jfit][imeas]=itRes->residual();
659 resErrors[jfit][imeas]=std::sqrt(itRes->errSq());
662 residuals[jfit][imeas]=resErrors[jfit][imeas]=0.;
664 ATH_MSG_DEBUG(
"residuals["<<jfit<<
"]["<<imeas<<
"]="<<residuals[jfit][imeas]);
665 ATH_MSG_DEBUG(
"resErrors["<<jfit<<
"]["<<imeas<<
"]="<<resErrors[jfit][imeas]);
669 delete refittedTrack; refittedTrack=
nullptr;
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]);
689 delete [] residuals;
delete [] resErrors;
690 delete [] chi2Array;
delete [] chi2ArrayX;
698 TGraph*
gr =
new TGraph(
m_nFits,chi2ArrayX,chi2Array);
699 gr->Fit(
"pol2",
"QF");
700 TF1*
fit=
gr->GetFunction(
"pol2");
702 double slope=
fit->GetParameter(1);
703 actualSecondDeriv=
fit->GetParameter(2);
710 if (
chi2>1.
e-6 || std::fabs(slope)<1.
e-10) {
715 int run=eventInfo->runNumber();
716 int evt=eventInfo->eventNumber();
728 ATH_MSG_DEBUG(
"created derivatives with "<<derivatives.rows()<<
" rows");
733 delete [] residuals;
delete [] resErrors;
734 delete [] chi2Array;
delete [] chi2ArrayX;
748 return emptyDerivatives;
752 TCanvas*
canv(
nullptr);
753 std::vector<TGraph*> vecGraphs;
755 for (; atsosItr != alignTrack->
lastAtsos(); ++atsosItr) {
756 if (!(*atsosItr)->isValid())
continue;
757 for (
int idim=0;idim<(*atsosItr)->nResDim();idim++) {
759 double* gr_x =
new double[NFITS];
760 double* gr_y =
new double[NFITS];
762 for (
int ifit=0;ifit<NFITS;ifit++) {
763 double residual=residuals[ifit][imeas];
764 double resError=resErrors[ifit][imeas];
766 gr_x[ngoodfits] =chi2ArrayX[ifit];
773 derivatives[imeas]=(residuals[1][imeas]-residuals[0][imeas])/(2.*shiftsize)*
774 resErrors[unshiftedTrackIndex][imeas];
777 TGraph*
gr=
new TGraph(ngoodfits,gr_x,gr_y);
780 gr->Fit(
"pol2",
"VF");
782 gr->Fit(
"pol2",
"QF");
783 TF1*
fit=
gr->GetFunction(
"pol2");
787 <<
", chi2="<<
fit->GetChisquare());
788 derivatives[imeas]=
fit->GetParameter(1)*resErrors[unshiftedTrackIndex][imeas];
789 derivativeErr[imeas]=
fit->GetParError(1)*resErrors[unshiftedTrackIndex][imeas];
794 if (!
canv)
canv=
new TCanvas(
"resPlots",
"resPlots");
796 gr->SetMarkerStyle(20);
799 gr->GetXaxis()->SetTitle(
"shift in chamber pos. from nominal (CLHEP::mm)");
800 gr->GetYaxis()->SetTitle(
"residual (CLHEP::mm)");
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: ";
809 else measType<<
" undefined";
811 pave->AddText(measType.str().c_str());
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();
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());
825 std::stringstream canvName;
826 canvName<<
"resPlots_ap"<<alignPar->
paramType()<<
"_measType"
827 <<(*atsosItr)->measType()<<
"_"<<imeas<<
".eps";
828 canv->Print(canvName.str().c_str());
833 vecGraphs.push_back(
gr);
836 derivatives[imeas]=-999.;
837 derivativeErr[imeas]=-999.;
848 for (
auto & vecGraph : vecGraphs)
856 for (
int ifit=0;ifit<NFITS;ifit++) {
876 return shift *
sigma;
885 ATH_MSG_ERROR(
"Need to assign this matrix correctly: ShiftingDerivCalcTool.cxx:888");
894 const double epsilon=1
e-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;
904 bool Wcorrisvalid = Wcorr+epsilon>=-1 && Wcorr-epsilon<=1;
905 Wisvalid = Wisvalid && Wcorrisvalid;
907 msg(MSG::WARNING) <<
"matrix corr invalid: " << Wcorr-1 <<
" " << Wcorr+1 <<
endmsg;
930 delete []
i;
i=
nullptr;
939 std::vector<Amg::VectorX>& deriv_vec,
940 std::vector<Amg::VectorX>& derivErr_vec,
941 std::vector<double>& actualsecderiv_vec,
947 derivErr_vec.clear();
948 actualsecderiv_vec.clear();
957 double actualSecondDeriv(0.);
962 if (resetIPar)
continue;
964 if (
vec.rows()<1)
return false;
966 deriv_vec.push_back(
vec);
967 derivErr_vec.push_back(derivErr);
968 actualsecderiv_vec.push_back(actualSecondDeriv);