24#include "MCHAlign/Alignment.h"
25#include "MCHAlign/MillePede2.h"
26#include "MCHAlign/MillePedeRecord.h"
31#include "MCHTracking/Cluster.h"
32#include "TGeoManager.h"
46#include "TGeoManager.h"
56#include <TMatrixDSym.h>
58#include <TClonesArray.h>
59#include <TGraphErrors.h>
71const Int_t Alignment::fgNDetElemCh[Alignment::fgNCh] = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26};
72const Int_t Alignment::fgSNDetElemCh[Alignment::fgNCh + 1] = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156};
75const Int_t Alignment::fgNDetElemHalfCh[Alignment::fgNHalfCh] = {2, 2, 2, 2, 2, 2, 2, 2, 9, 9, 9, 9, 13, 13, 13, 13, 13, 13, 13, 13};
78const Int_t Alignment::fgDetElemHalfCh[Alignment::fgNHalfCh][Alignment::fgNDetHalfChMax] =
80 {100, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
81 {101, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
83 {200, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
84 {201, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
86 {300, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
87 {301, 302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
89 {400, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
90 {401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
92 {500, 501, 502, 503, 504, 514, 515, 516, 517, 0, 0, 0, 0},
93 {505, 506, 507, 508, 509, 510, 511, 512, 513, 0, 0, 0, 0},
95 {600, 601, 602, 603, 604, 614, 615, 616, 617, 0, 0, 0, 0},
96 {605, 606, 607, 608, 609, 610, 611, 612, 613, 0, 0, 0, 0},
98 {700, 701, 702, 703, 704, 705, 706, 720, 721, 722, 723, 724, 725},
99 {707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719},
101 {800, 801, 802, 803, 804, 805, 806, 820, 821, 822, 823, 824, 825},
102 {807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819},
104 {900, 901, 902, 903, 904, 905, 906, 920, 921, 922, 923, 924, 925},
105 {907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919},
107 {1000, 1001, 1002, 1003, 1004, 1005, 1006, 1020, 1021, 1022, 1023, 1024, 1025},
108 {1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019}
121 for (Int_t
i = 0;
i < Alignment::fNGlobal; ++
i) {
141Alignment::Alignment()
143 fInitialized(kFALSE),
146 fRefitStraightTracks(kFALSE),
156 fGeoCombiTransInverse(),
157 fDoEvaluation(kFALSE),
174 fMillepede =
new MillePede2();
179 for (Int_t iPar = 0; iPar < fNGlobal; ++iPar) {
180 fGlobalParameterStatus[iPar] = kFreeParId;
184 for (
int i = 0;
i < fNLocal; ++
i) {
185 fLocalDerivatives[
i] = 0.0;
188 for (
int i = 0;
i < fNGlobal; ++
i) {
189 fGlobalDerivatives[
i] = 0.0;
200void Alignment::init(
void)
210 LOG(fatal) <<
"Millepede already initialized";
215 for (Int_t iPar = 0; iPar < fNGlobal; ++iPar) {
217 if (fGlobalParameterStatus[iPar] == kFixedParId) {
221 }
else if (fGlobalParameterStatus[iPar] == kFreeParId || fGlobalParameterStatus[iPar] == kGroupBaseId) {
224 fGlobalParameterStatus[iPar] = nGlobal++;
227 }
else if (fGlobalParameterStatus[iPar] < kGroupBaseId) {
230 const Int_t iDeBase(kGroupBaseId - 1 - fGlobalParameterStatus[iPar]);
231 const Int_t iParBase = iPar % fgNParCh;
234 if (iDeBase < 0 || iDeBase >= iPar / fgNParCh) {
235 LOG(fatal) <<
"Group for parameter index " << iPar <<
" has wrong base detector element: " << iDeBase;
239 fGlobalParameterStatus[iPar] = fGlobalParameterStatus[iDeBase * fgNParCh + iParBase];
240 LOG(info) <<
"Parameter " << iPar <<
" grouped to detector " << iDeBase <<
" (" << GetParameterMaskString(1 << iParBase).Data() <<
")";
243 LOG(fatal) <<
"Unrecognized parameter status for index " << iPar <<
": " << fGlobalParameterStatus[iPar];
246 LOG(info) <<
"Free Parameters: " << nGlobal <<
" out of " << fNGlobal;
250 fMillepede->InitMille(fNGlobal, fNLocal, fNStdDev, fResCut, fResCutInitial);
252 fInitialized = kTRUE;
255 for (Int_t iPar = 0; iPar < fgNParCh; ++iPar) {
256 LOG(info) <<
"fAllowVar[" << iPar <<
"]= " << fAllowVar[iPar];
260 for (Int_t iDet = 0; iDet < fgNDetElem; ++iDet) {
261 for (Int_t iPar = 0; iPar < fgNParCh; ++iPar) {
262 fMillepede->SetParSigma(iDet * fgNParCh + iPar, fAllowVar[iPar]);
268 fMillepede->SetIterations(fStartFac);
271 if (fDoEvaluation && fRefitStraightTracks) {
272 fTFile =
new TFile(
"Alignment.root",
"RECREATE");
273 fTTree =
new TTree(
"TreeE",
"Evaluation");
275 const Int_t kSplitlevel = 98;
276 const Int_t kBufsize = 32000;
278 fTrackParamOrig =
new LocalTrackParam();
279 fTTree->Branch(
"fTrackParamOrig",
"LocalTrackParam", &fTrackParamOrig, kBufsize, kSplitlevel);
281 fTrackParamNew =
new LocalTrackParam();
282 fTTree->Branch(
"fTrackParamNew",
"LocalTrackParam", &fTrackParamNew, kBufsize, kSplitlevel);
287void Alignment::terminate(
void)
289 LOG(info) <<
"Closing Evaluation TFile";
290 if (fTFile && fTTree) {
298MillePedeRecord* Alignment::ProcessTrack(Track& track, Bool_t doAlignment, Double_t
weight)
307 fTrackRecord.Reset();
308 if (fMillepede->GetRecord()) {
309 fMillepede->GetRecord()->Reset();
316 for (
auto itTrackParam(track.begin()); itTrackParam != track.end(); ++itTrackParam) {
327 FillTrackParamData(&*itTrackParam);
328 fTrackPos0[0] = fTrackPos[0];
329 fTrackPos0[1] = fTrackPos[1];
330 fTrackPos0[2] = fTrackPos[2];
331 fTrackSlope0[0] = fTrackSlope[0];
332 fTrackSlope0[1] = fTrackSlope[1];
339 if (fRefitStraightTracks) {
342 const LocalTrackParam trackParam(RefitStraightTrack(track, fTrackPos0[2]));
345 if (fTrackParamOrig) {
346 fTrackParamOrig->fTrackX = fTrackPos0[0];
347 fTrackParamOrig->fTrackY = fTrackPos0[1];
348 fTrackParamOrig->fTrackZ = fTrackPos0[2];
349 fTrackParamOrig->fTrackSlopeX = fTrackSlope[0];
350 fTrackParamOrig->fTrackSlopeY = fTrackSlope[1];
354 if (fTrackParamNew) {
355 fTrackParamNew->fTrackX = trackParam.fTrackX;
356 fTrackParamNew->fTrackY = trackParam.fTrackY;
357 fTrackParamNew->fTrackZ = trackParam.fTrackZ;
358 fTrackParamNew->fTrackSlopeX = trackParam.fTrackSlopeX;
359 fTrackParamNew->fTrackSlopeY = trackParam.fTrackSlopeY;
370 fTrackPos0[0] = trackParam.fTrackX;
371 fTrackPos0[1] = trackParam.fTrackY;
372 fTrackPos0[2] = trackParam.fTrackZ;
373 fTrackSlope[0] = trackParam.fTrackSlopeX;
374 fTrackSlope[1] = trackParam.fTrackSlopeY;
379 for (
auto itTrackParam(track.begin()); itTrackParam != track.end(); ++itTrackParam) {
386 const Cluster* cluster = itTrackParam->getClusterPtr();
391 FillDetElemData(cluster);
392 FillRecPointData(cluster);
393 FillTrackParamData(&*itTrackParam);
396 const Double_t*
r(fGeoCombiTransInverse.GetRotationMatrix());
402 fMeas[0] =
r[0] * (fClustPos[0] - fTrackPos[0]) +
r[1] * (fClustPos[1] - fTrackPos[1]);
403 fMeas[1] =
r[3] * (fClustPos[0] - fTrackPos[0]) +
r[4] * (fClustPos[1] - fTrackPos[1]);
408 fMeas[0] = (
r[0] * fClustPos[0] +
r[1] * fClustPos[1]);
409 fMeas[1] = (
r[3] * fClustPos[0] +
r[4] * fClustPos[1]);
418 fMillepede->SetRecordRun(fRunNumber);
419 fMillepede->SetRecordWeight(
weight);
420 fTrackRecord = *fMillepede->GetRecord();
424 fMillepede->SaveRecordData();
425 fMillepede->CloseDataRecStorage();
429 return &fTrackRecord;
433void Alignment::ProcessTrack(MillePedeRecord* trackRecord)
435 LOG(fatal) << __PRETTY_FUNCTION__ <<
" is disabled";
442 if (!fMillepede->GetRecord()) {
443 fMillepede->InitDataRecStorage(kFalse);
446 *fMillepede->GetRecord() = *trackRecord;
449 fMillepede->SaveRecordData();
451 fMillepede->CloseDataRecStorage();
457void Alignment::FixAll(UInt_t
mask)
460 LOG(info) <<
"Fixing " << GetParameterMaskString(
mask).Data() <<
" for all detector elements";
463 for (Int_t
i = 0;
i < fgNDetElem; ++
i) {
476void Alignment::FixChamber(Int_t iCh, UInt_t
mask)
481 if (iCh < 1 || iCh > 10) {
482 LOG(fatal) <<
"Invalid chamber index " << iCh;
488 for (Int_t
i = iDetElemFirst;
i < iDetElemLast; ++
i) {
490 LOG(info) <<
"Fixing " << GetParameterMaskString(
mask).Data() <<
" for detector element " <<
i;
504void Alignment::FixDetElem(Int_t iDetElemId, UInt_t
mask)
507 const Int_t iDet(GetDetElemNumber(iDetElemId));
509 FixParameter(iDet, 0);
511 FixParameter(iDet, 1);
513 FixParameter(iDet, 2);
515 FixParameter(iDet, 3);
519void Alignment::FixHalfSpectrometer(
const Bool_t* lChOnOff, UInt_t sidesMask, UInt_t
mask)
523 for (Int_t
i = 0;
i < fgNDetElem; ++
i) {
526 const Int_t iCh(GetChamberId(
i));
527 if (!lChOnOff[iCh - 1])
535 if (iCh >= 1 && iCh <= 4) {
536 if (lDetElemNumber == 0 && !(sidesMask & SideTopRight))
538 if (lDetElemNumber == 1 && !(sidesMask & SideTopLeft))
540 if (lDetElemNumber == 2 && !(sidesMask & SideBottomLeft))
542 if (lDetElemNumber == 3 && !(sidesMask & SideBottomRight))
547 if (iCh >= 5 && iCh <= 6) {
548 if (lDetElemNumber >= 0 && lDetElemNumber <= 4 && !(sidesMask & SideTopRight))
550 if (lDetElemNumber >= 5 && lDetElemNumber <= 10 && !(sidesMask & SideTopLeft))
552 if (lDetElemNumber >= 11 && lDetElemNumber <= 13 && !(sidesMask & SideBottomLeft))
554 if (lDetElemNumber >= 14 && lDetElemNumber <= 17 && !(sidesMask & SideBottomRight))
559 if (iCh >= 7 && iCh <= 10) {
560 if (lDetElemNumber >= 0 && lDetElemNumber <= 6 && !(sidesMask & SideTopRight))
562 if (lDetElemNumber >= 7 && lDetElemNumber <= 13 && !(sidesMask & SideTopLeft))
564 if (lDetElemNumber >= 14 && lDetElemNumber <= 19 && !(sidesMask & SideBottomLeft))
566 if (lDetElemNumber >= 20 && lDetElemNumber <= 25 && !(sidesMask & SideBottomRight))
576void Alignment::FixParameter(Int_t iPar)
581 LOG(fatal) <<
"Millepede already initialized";
584 fGlobalParameterStatus[iPar] = kFixedParId;
588void Alignment::ReleaseChamber(Int_t iCh, UInt_t
mask)
593 if (iCh < 1 || iCh > 10) {
594 LOG(fatal) <<
"Invalid chamber index " << iCh;
600 for (Int_t
i = iDetElemFirst;
i < iDetElemLast; ++
i) {
602 LOG(info) <<
"Releasing " << GetParameterMaskString(
mask).Data() <<
" for detector element " <<
i;
605 ReleaseParameter(
i, 0);
607 ReleaseParameter(
i, 1);
609 ReleaseParameter(
i, 2);
611 ReleaseParameter(
i, 3);
616void Alignment::ReleaseDetElem(Int_t iDetElemId, UInt_t
mask)
619 const Int_t iDet(GetDetElemNumber(iDetElemId));
621 ReleaseParameter(iDet, 0);
623 ReleaseParameter(iDet, 1);
625 ReleaseParameter(iDet, 2);
627 ReleaseParameter(iDet, 3);
631void Alignment::ReleaseParameter(Int_t iPar)
636 LOG(fatal) <<
"Millepede already initialized";
639 fGlobalParameterStatus[iPar] = kFreeParId;
643void Alignment::GroupChamber(Int_t iCh, UInt_t
mask)
646 if (iCh < 1 || iCh >
fgNCh) {
647 LOG(fatal) <<
"Invalid chamber index " << iCh;
650 const Int_t detElemMin = 100 * iCh;
651 const Int_t detElemMax = 100 * iCh +
fgNDetElemCh[iCh] - 1;
652 GroupDetElems(detElemMin, detElemMax,
mask);
656void Alignment::GroupHalfChamber(Int_t iCh, Int_t iHalf, UInt_t
mask)
659 if (iCh < 1 || iCh >
fgNCh) {
660 LOG(fatal) <<
"Invalid chamber index " << iCh;
663 if (iHalf < 0 || iHalf > 1) {
664 LOG(fatal) <<
"Invalid half chamber index " << iHalf;
667 const Int_t iHalfCh = 2 * (iCh - 1) + iHalf;
668 GroupDetElems(&fgDetElemHalfCh[iHalfCh][0], fgNDetElemHalfCh[iHalfCh],
mask);
672void Alignment::GroupDetElems(Int_t detElemMin, Int_t detElemMax, UInt_t
mask)
676 const Int_t nDetElem = detElemMax - detElemMin + 1;
678 LOG(fatal) <<
"Requested group of DEs " << detElemMin <<
"-" << detElemMax <<
" contains less than 2 DE's";
682 Int_t* detElemList =
new int[nDetElem];
683 for (Int_t
i = 0;
i < nDetElem; ++
i) {
684 detElemList[
i] = detElemMin +
i;
688 GroupDetElems(detElemList, nDetElem,
mask);
689 delete[] detElemList;
693void Alignment::GroupDetElems(
const Int_t* detElemList, Int_t nDetElem, UInt_t
mask)
697 LOG(fatal) <<
"Millepede already initialized";
700 const Int_t iDeBase(GetDetElemNumber(detElemList[0]));
701 for (Int_t
i = 0;
i < nDetElem; ++
i) {
702 const Int_t iDeCurrent(GetDetElemNumber(detElemList[
i]));
704 fGlobalParameterStatus[iDeCurrent * fgNParCh + 0] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
706 fGlobalParameterStatus[iDeCurrent * fgNParCh + 1] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
708 fGlobalParameterStatus[iDeCurrent * fgNParCh + 2] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
710 fGlobalParameterStatus[iDeCurrent * fgNParCh + 3] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
713 LOG(info) <<
"Creating new group for detector " << detElemList[
i] <<
" and variable " << GetParameterMaskString(
mask).Data();
715 LOG(info) <<
"Adding detector element " << detElemList[
i] <<
" to current group";
720void Alignment::SetChamberNonLinear(Int_t iCh, UInt_t
mask)
725 for (Int_t
i = iDetElemFirst;
i < iDetElemLast; ++
i) {
728 SetParameterNonLinear(
i, 0);
730 SetParameterNonLinear(
i, 1);
732 SetParameterNonLinear(
i, 2);
734 SetParameterNonLinear(
i, 3);
739void Alignment::SetDetElemNonLinear(Int_t iDetElemId, UInt_t
mask)
742 const Int_t iDet(GetDetElemNumber(iDetElemId));
744 SetParameterNonLinear(iDet, 0);
746 SetParameterNonLinear(iDet, 1);
748 SetParameterNonLinear(iDet, 2);
750 SetParameterNonLinear(iDet, 3);
754void Alignment::SetParameterNonLinear(Int_t iPar)
758 LOG(fatal) <<
"Millepede not initialized";
761 fMillepede->SetNonLinear(iPar);
762 LOG(info) <<
"Parameter " << iPar <<
" set to non linear ";
766void Alignment::AddConstraints(
const Bool_t* lChOnOff, UInt_t
mask)
775 for (Int_t
i = 0;
i < fgNDetElem; ++
i) {
778 const Int_t iCh(GetChamberId(
i));
779 if (lChOnOff[iCh - 1]) {
782 fConstraintX.values[
i * fgNParCh + 0] = 1.0;
784 fConstraintY.values[
i * fgNParCh + 1] = 1.0;
786 fConstraintTZ.values[
i * fgNParCh + 2] = 1.0;
788 fConstraintTZ.values[
i * fgNParCh + 3] = 1.0;
793 AddConstraint(fConstraintX.values, 0.0);
795 AddConstraint(fConstraintY.values, 0.0);
797 AddConstraint(fConstraintTZ.values, 0.0);
799 AddConstraint(fConstraintZ.values, 0.0);
803void Alignment::AddConstraints(
const Bool_t* lChOnOff,
const Bool_t* lVarXYT, UInt_t sidesMask)
813 Double_t lMeanY = 0.;
814 Double_t lSigmaY = 0.;
815 Double_t lMeanZ = 0.;
816 Double_t lSigmaZ = 0.;
819 for (Int_t
i = 0;
i < fgNDetElem; ++
i) {
822 const Int_t iCh(GetChamberId(
i));
825 if (lChOnOff[iCh - 1])
830 const Int_t lDetElemId = iCh * 100 + lDetElemNumber;
834 if (iCh >= 1 && iCh <= 4) {
835 if (lDetElemNumber == 0 && !(sidesMask & SideTopRight))
837 if (lDetElemNumber == 1 && !(sidesMask & SideTopLeft))
839 if (lDetElemNumber == 2 && !(sidesMask & SideBottomLeft))
841 if (lDetElemNumber == 3 && !(sidesMask & SideBottomRight))
846 if (iCh >= 5 && iCh <= 6) {
847 if (lDetElemNumber >= 0 && lDetElemNumber <= 4 && !(sidesMask & SideTopRight))
849 if (lDetElemNumber >= 5 && lDetElemNumber <= 10 && !(sidesMask & SideTopLeft))
851 if (lDetElemNumber >= 11 && lDetElemNumber <= 13 && !(sidesMask & SideBottomLeft))
853 if (lDetElemNumber >= 14 && lDetElemNumber <= 17 && !(sidesMask & SideBottomRight))
858 if (iCh >= 7 && iCh <= 10) {
859 if (lDetElemNumber >= 0 && lDetElemNumber <= 6 && !(sidesMask & SideTopRight))
861 if (lDetElemNumber >= 7 && lDetElemNumber <= 13 && !(sidesMask & SideTopLeft))
863 if (lDetElemNumber >= 14 && lDetElemNumber <= 19 && !(sidesMask & SideBottomLeft))
865 if (lDetElemNumber >= 20 && lDetElemNumber <= 25 && !(sidesMask & SideBottomRight))
870 Double_t lDetElemGloX = 0.;
871 Double_t lDetElemGloY = 0.;
872 Double_t lDetElemGloZ = 0.;
874 auto fTransform = fTransformCreator(lDetElemId);
878 fTransform.LocalToMaster(SlatPos, GlobalPos);
879 lDetElemGloX = GlobalPos.x();
880 lDetElemGloY = GlobalPos.y();
881 lDetElemGloZ = GlobalPos.z();
885 lMeanY += lDetElemGloY;
886 lSigmaY += lDetElemGloY * lDetElemGloY;
887 lMeanZ += lDetElemGloZ;
888 lSigmaZ += lDetElemGloZ * lDetElemGloZ;
894 lSigmaY /= lNDetElem;
895 lSigmaY = TMath::Sqrt(lSigmaY - lMeanY * lMeanY);
897 lSigmaZ /= lNDetElem;
898 lSigmaZ = TMath::Sqrt(lSigmaZ - lMeanZ * lMeanZ);
899 LOG(info) <<
"Used " << lNDetElem <<
" DetElem, MeanZ= " << lMeanZ <<
", SigmaZ= " << lSigmaZ;
902 Array fConstraintX[4];
903 Array fConstraintY[4];
904 Array fConstraintP[4];
905 Array fConstraintXZ[4];
906 Array fConstraintYZ[4];
907 Array fConstraintPZ[4];
910 Array fConstraintXY[4];
911 Array fConstraintYY[4];
912 Array fConstraintPY[4];
916 lDetTLBR[0] = sidesMask & SideTop;
917 lDetTLBR[1] = sidesMask & SideLeft;
918 lDetTLBR[2] = sidesMask & SideBottom;
919 lDetTLBR[3] = sidesMask & SideRight;
921 for (Int_t
i = 0;
i < fgNDetElem; ++
i) {
924 const Int_t iCh(GetChamberId(
i));
927 if (!lChOnOff[iCh - 1])
932 const Int_t lDetElemId = iCh * 100 + lDetElemNumber;
935 Double_t lDetElemGloX = 0.;
936 Double_t lDetElemGloY = 0.;
937 Double_t lDetElemGloZ = 0.;
939 auto fTransform = fTransformCreator(lDetElemId);
943 fTransform.LocalToMaster(SlatPos, GlobalPos);
944 lDetElemGloX = GlobalPos.x();
945 lDetElemGloY = GlobalPos.y();
946 lDetElemGloZ = GlobalPos.z();
950 for (Int_t iSide = 0; iSide < 4; iSide++) {
953 if (!lDetTLBR[iSide])
958 if (iCh >= 1 && iCh <= 4) {
959 if (lDetElemNumber == 0 && !(iSide == 0 || iSide == 3))
961 if (lDetElemNumber == 1 && !(iSide == 0 || iSide == 1))
963 if (lDetElemNumber == 2 && !(iSide == 2 || iSide == 1))
965 if (lDetElemNumber == 3 && !(iSide == 2 || iSide == 3))
970 if (iCh >= 5 && iCh <= 6) {
971 if (lDetElemNumber >= 0 && lDetElemNumber <= 4 && !(iSide == 0 || iSide == 3))
973 if (lDetElemNumber >= 5 && lDetElemNumber <= 9 && !(iSide == 0 || iSide == 1))
975 if (lDetElemNumber >= 10 && lDetElemNumber <= 13 && !(iSide == 2 || iSide == 1))
977 if (lDetElemNumber >= 14 && lDetElemNumber <= 17 && !(iSide == 2 || iSide == 3))
982 if (iCh >= 7 && iCh <= 10) {
983 if (lDetElemNumber >= 0 && lDetElemNumber <= 6 && !(iSide == 0 || iSide == 3))
985 if (lDetElemNumber >= 7 && lDetElemNumber <= 13 && !(iSide == 0 || iSide == 1))
987 if (lDetElemNumber >= 14 && lDetElemNumber <= 19 && !(iSide == 2 || iSide == 1))
989 if (lDetElemNumber >= 20 && lDetElemNumber <= 25 && !(iSide == 2 || iSide == 3))
995 fConstraintX[iSide].values[
i * fgNParCh + 0] = 1;
999 fConstraintY[iSide].values[
i * fgNParCh + 1] = 1;
1003 fConstraintP[iSide].values[
i * fgNParCh + 2] = 1;
1007 fConstraintXZ[iSide].values[
i * fgNParCh + 0] = (lDetElemGloZ - lMeanZ) / lSigmaZ;
1011 fConstraintYZ[iSide].values[
i * fgNParCh + 1] = (lDetElemGloZ - lMeanZ) / lSigmaZ;
1015 fConstraintPZ[iSide].values[
i * fgNParCh + 2] = (lDetElemGloZ - lMeanZ) / lSigmaZ;
1019 fConstraintXY[iSide].values[
i * fgNParCh + 0] = (lDetElemGloY - lMeanY) / lSigmaY;
1023 fConstraintYY[iSide].values[
i * fgNParCh + 1] = (lDetElemGloY - lMeanY) / lSigmaY;
1027 fConstraintPY[iSide].values[
i * fgNParCh + 2] = (lDetElemGloY - lMeanY) / lSigmaY;
1032 for (Int_t iSide = 0; iSide < 4; iSide++) {
1034 if (!lDetTLBR[iSide])
1038 AddConstraint(fConstraintX[iSide].
values, 0.0);
1040 AddConstraint(fConstraintY[iSide].
values, 0.0);
1042 AddConstraint(fConstraintP[iSide].
values, 0.0);
1044 AddConstraint(fConstraintXZ[iSide].
values, 0.0);
1046 AddConstraint(fConstraintYZ[iSide].
values, 0.0);
1048 AddConstraint(fConstraintPZ[iSide].
values, 0.0);
1050 AddConstraint(fConstraintXY[iSide].
values, 0.0);
1052 AddConstraint(fConstraintYY[iSide].
values, 0.0);
1054 AddConstraint(fConstraintPY[iSide].
values, 0.0);
1059void Alignment::InitGlobalParameters(Double_t* par)
1062 if (!fInitialized) {
1063 LOG(fatal) <<
"Millepede is not initialized";
1066 fMillepede->SetGlobalParameters(par);
1070void Alignment::SetAllowedVariation(Int_t iPar, Double_t
value)
1075 LOG(fatal) <<
"Millepede already initialized";
1079 if (!(iPar >= 0 && iPar < fgNParCh)) {
1080 LOG(fatal) <<
"Invalid index: " << iPar;
1083 fAllowVar[iPar] =
value;
1087void Alignment::SetSigmaXY(Double_t sigmaX, Double_t sigmaY)
1095 for (Int_t
i = 0;
i < 2; ++
i) {
1096 LOG(info) <<
"fSigma[" <<
i <<
"] =" << fSigma[
i];
1101void Alignment::GlobalFit(Double_t* parameters, Double_t* errors, Double_t* pulls)
1105 fMillepede->GlobalFit(parameters, errors, pulls);
1107 LOG(info) <<
"Done fitting global parameters";
1108 for (
int iDet = 0; iDet < fgNDetElem; ++iDet) {
1109 LOG(info) << iDet <<
" " << parameters[iDet * fgNParCh + 0] <<
" " << parameters[iDet * fgNParCh + 1] <<
" " << parameters[iDet * fgNParCh + 3] <<
" " << parameters[iDet * fgNParCh + 2];
1114void Alignment::PrintGlobalParameters()
const
1116 fMillepede->PrintGlobalParameters();
1120Double_t Alignment::GetParError(Int_t iPar)
const
1122 return fMillepede->GetParError(iPar);
1297void Alignment::SetAlignmentResolution(
const TClonesArray* misAlignArray, Int_t rChId, Double_t chResX, Double_t chResY, Double_t deResX, Double_t deResY)
1302 TMatrixDSym mChCorrMatrix(6);
1303 mChCorrMatrix[0][0] = chResX * chResX;
1304 mChCorrMatrix[1][1] = chResY * chResY;
1306 TMatrixDSym mDECorrMatrix(6);
1307 mDECorrMatrix[0][0] = deResX * deResX;
1308 mDECorrMatrix[1][1] = deResY * deResY;
1312 for (Int_t chId = 0; chId <= 9; ++chId) {
1315 if (rChId > 0 && chId + 1 != rChId)
1322 chName1 = Form(
"GM%d", chId);
1323 chName2 = Form(
"GM%d", chId);
1327 chName1 = Form(
"GM%d", 4 + (chId - 4) * 2);
1328 chName2 = Form(
"GM%d", 4 + (chId - 4) * 2 + 1);
1331 for (
int i = 0;
i < misAlignArray->GetEntries(); ++
i) {
1335 if ((volName.Contains(chName1) &&
1336 ((volName.Last(
'/') == volName.Index(chName1) + chName1.Length()) ||
1337 (volName.Length() == volName.Index(chName1) + chName1.Length()))) ||
1338 (volName.Contains(chName2) &&
1339 ((volName.Last(
'/') == volName.Index(chName2) + chName2.Length()) ||
1340 (volName.Length() == volName.Index(chName2) + chName2.Length())))) {
1342 volName.Remove(0, volName.Last(
'/') + 1);
1354LocalTrackParam Alignment::RefitStraightTrack(Track& track, Double_t z0)
const
1358 TMatrixD AtGASum(4, 4);
1361 TMatrixD AtGMSum(4, 1);
1365 for (
auto itTrackParam(track.begin()); itTrackParam != track.end(); ++itTrackParam) {
1368 if (!&*itTrackParam)
1372 const Cluster* cluster = itTrackParam->getClusterPtr();
1380 A(0, 2) = (cluster->getZ() - z0);
1382 A(1, 3) = (cluster->getZ() - z0);
1384 TMatrixD At(TMatrixD::kTransposed,
A);
1389 G(0, 0) = 1.0 /
Square(cluster->getEx());
1390 G(1, 1) = 1.0 /
Square(cluster->getEy());
1392 const TMatrixD AtG(At, TMatrixD::kMult, G);
1393 const TMatrixD AtGA(AtG, TMatrixD::kMult,
A);
1398 M(0, 0) = cluster->getX();
1399 M(1, 0) = cluster->getY();
1400 const TMatrixD AtGM(AtG, TMatrixD::kMult, M);
1405 TMatrixD AtGASumInv(TMatrixD::kInverted, AtGASum);
1406 TMatrixD X(AtGASumInv, TMatrixD::kMult, AtGMSum);
1415 LocalTrackParam out;
1416 out.fTrackX = X(0, 0);
1417 out.fTrackY = X(1, 0);
1419 out.fTrackSlopeX = X(2, 0);
1420 out.fTrackSlopeY = X(3, 0);
1426void Alignment::FillDetElemData(
const Cluster* cluster)
1429 LOG(info) << __PRETTY_FUNCTION__ <<
" is enabled";
1433 const Int_t
detElemId = cluster->getDEId();
1434 fDetElemNumber = GetDetElemNumber(detElemId);
1438 auto fTransform = fTransformCreator(detElemId);
1448void Alignment::FillRecPointData(
const Cluster* cluster)
1452 fClustPos[0] = cluster->getX();
1453 fClustPos[1] = cluster->getY();
1454 fClustPos[2] = cluster->getZ();
1458void Alignment::FillTrackParamData(
const TrackParam* trackParam)
1462 fTrackPos[0] = trackParam->getNonBendingCoor();
1463 fTrackPos[1] = trackParam->getBendingCoor();
1464 fTrackPos[2] = trackParam->getZ();
1465 fTrackSlope[0] = trackParam->getNonBendingSlope();
1466 fTrackSlope[1] = trackParam->getBendingSlope();
1470void Alignment::LocalEquationX(
void)
1475 const Double_t*
r(fGeoCombiTransInverse.GetRotationMatrix());
1478 SetLocalDerivative(0,
r[0]);
1479 SetLocalDerivative(1,
r[0] * (fTrackPos[2] - fTrackPos0[2]));
1480 SetLocalDerivative(2,
r[1]);
1481 SetLocalDerivative(3,
r[1] * (fTrackPos[2] - fTrackPos0[2]));
1492 SetGlobalDerivative(fDetElemNumber * fgNParCh + 0, -
r[0]);
1493 SetGlobalDerivative(fDetElemNumber * fgNParCh + 1, -
r[1]);
1498 SetGlobalDerivative(fDetElemNumber * fgNParCh + 2, -
r[1] * fTrackPos[0] +
r[0] * fTrackPos[1]);
1501 SetGlobalDerivative(fDetElemNumber * fgNParCh + 3,
r[0] * fTrackSlope[0] +
r[1] * fTrackSlope[1]);
1506 const Double_t trackPosX = fTrackPos0[0] + fTrackSlope0[0] * (fTrackPos[2] - fTrackPos0[2]);
1507 const Double_t trackPosY = fTrackPos0[1] + fTrackSlope0[1] * (fTrackPos[2] - fTrackPos0[2]);
1510 SetGlobalDerivative(fDetElemNumber * fgNParCh + 2, -
r[1] * trackPosX +
r[0] * trackPosY);
1513 SetGlobalDerivative(fDetElemNumber * fgNParCh + 3,
r[0] * fTrackSlope0[0] +
r[1] * fTrackSlope0[1]);
1517 fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, fMeas[0], fSigma[0]);
1521void Alignment::LocalEquationY(
void)
1526 const Double_t*
r(fGeoCombiTransInverse.GetRotationMatrix());
1529 SetLocalDerivative(0,
r[3]);
1530 SetLocalDerivative(1,
r[3] * (fTrackPos[2] - fTrackPos0[2]));
1531 SetLocalDerivative(2,
r[4]);
1532 SetLocalDerivative(3,
r[4] * (fTrackPos[2] - fTrackPos0[2]));
1535 SetGlobalDerivative(fDetElemNumber * fgNParCh + 0, -
r[3]);
1536 SetGlobalDerivative(fDetElemNumber * fgNParCh + 1, -
r[4]);
1541 SetGlobalDerivative(fDetElemNumber * fgNParCh + 2, -
r[4] * fTrackPos[0] +
r[3] * fTrackPos[1]);
1544 SetGlobalDerivative(fDetElemNumber * fgNParCh + 3,
r[3] * fTrackSlope[0] +
r[4] * fTrackSlope[1]);
1549 const Double_t trackPosX = fTrackPos0[0] + fTrackSlope0[0] * (fTrackPos[2] - fTrackPos0[2]);
1550 const Double_t trackPosY = fTrackPos0[1] + fTrackSlope0[1] * (fTrackPos[2] - fTrackPos0[2]);
1553 SetGlobalDerivative(fDetElemNumber * fgNParCh + 2, -
r[4] * trackPosX +
r[3] * trackPosY);
1556 SetGlobalDerivative(fDetElemNumber * fgNParCh + 3,
r[3] * fTrackSlope0[0] +
r[4] * fTrackSlope0[1]);
1560 fMillepede->SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, fMeas[1], fSigma[1]);
1564TGeoCombiTrans Alignment::DeltaTransform(
const double* lMisAlignment)
const
1569 const TGeoTranslation deltaTrans(lMisAlignment[0], lMisAlignment[1], lMisAlignment[3]);
1572 TGeoRotation deltaRot;
1573 deltaRot.RotateZ(lMisAlignment[2] * 180. / TMath::Pi());
1576 return TGeoCombiTrans(deltaTrans, deltaRot);
1580void Alignment::AddConstraint(Double_t* par, Double_t
value)
1583 if (!fInitialized) {
1584 LOG(fatal) <<
"Millepede is not initialized";
1587 fMillepede->SetGlobalConstraint(par,
value);
1591Bool_t Alignment::DetElemIsValid(Int_t iDetElemId)
const
1594 const Int_t iCh = iDetElemId / 100;
1595 const Int_t iDet = iDetElemId % 100;
1600Int_t Alignment::GetDetElemNumber(Int_t iDetElemId)
const
1604 const Int_t iCh = iDetElemId / 100;
1605 const Int_t iDet = iDetElemId % 100;
1609 LOG(fatal) <<
"Invalid detector element id: " << iDetElemId;
1617Int_t Alignment::GetChamberId(Int_t iDetElemNumber)
const
1621 for (iCh = 0; iCh <
fgNCh; iCh++) {
1630TString Alignment::GetParameterMaskString(UInt_t
mask)
const
1645TString Alignment::GetSidesMaskString(UInt_t
mask)
const
1650 if (
mask & SideLeft)
1652 if (
mask & SideBottom)
1654 if (
mask & SideRight)
Definition of the base alignment parameters class.
const int fgSNDetElemCh[fgNCh+1]
const int fgNDetElemCh[fgNCh]
Definition of the MCH track for internal use.
Interface for MCH geometry creation.
Definition of the MCH track parameters for internal use.
const std::string & getSymName() const
return symbolic name of the volume
HMPID cluster implementation.
self initialized array, used for adding constraints
GLuint GLuint GLfloat weight
GLsizei const GLfloat * value
GLenum GLsizei GLsizei GLint * values
int detElemId(Chamber chamber, Side side, int number)
Double_t Square(Double_t x)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"