37#include <TClonesArray.h>
38#include <TGeoManager.h>
39#include <TGeoGlobalMagField.h>
40#include <TGraphErrors.h>
43#include <TMatrixDSym.h>
57const int Aligner::fgSNDetElemCh[
Aligner::fgNCh + 1] = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156};
60const int Aligner::fgNDetElemHalfCh[
Aligner::fgNHalfCh] = {2, 2, 2, 2, 2, 2, 2, 2, 9, 9, 9, 9, 13, 13, 13, 13, 13, 13, 13, 13};
65 {100, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
66 {101, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
68 {200, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
69 {201, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
71 {300, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
72 {301, 302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
74 {400, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
75 {401, 402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
77 {500, 501, 502, 503, 504, 514, 515, 516, 517, 0, 0, 0, 0},
78 {505, 506, 507, 508, 509, 510, 511, 512, 513, 0, 0, 0, 0},
80 {600, 601, 602, 603, 604, 614, 615, 616, 617, 0, 0, 0, 0},
81 {605, 606, 607, 608, 609, 610, 611, 612, 613, 0, 0, 0, 0},
83 {700, 701, 702, 703, 704, 705, 706, 720, 721, 722, 723, 724, 725},
84 {707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719},
86 {800, 801, 802, 803, 804, 805, 806, 820, 821, 822, 823, 824, 825},
87 {807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819},
89 {900, 901, 902, 903, 904, 905, 906, 920, 921, 922, 923, 924, 925},
90 {907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919},
92 {1000, 1001, 1002, 1003, 1004, 1005, 1006, 1020, 1021, 1022, 1023, 1024, 1025},
93 {1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019}
131 fRefitStraightTracks(false),
133 fResCutInitial(1000),
138 fGlobalParameterStatus(
std::vector<
int>(fNGlobal)),
139 fGlobalDerivatives(
std::vector<double>(fNGlobal)),
140 fLocalDerivatives(
std::vector<double>(fNLocal)),
142 mNEntriesAutoSave(10000),
143 mRecordWriter(new
o2::fwdalign::MilleRecordWriter()),
144 mWithConstraintsRecWriter(false),
145 mConstraintsRecWriter(nullptr),
146 mRecordReader(new
o2::fwdalign::MilleRecordReader()),
147 mWithConstraintsRecReader(false),
148 mConstraintsRecReader(nullptr),
150 fDoEvaluation(false),
151 fDisableRecordWriter(false),
172 for (
int iPar = 0; iPar <
fNGlobal; ++iPar) {
173 fGlobalParameterStatus[iPar] = kFreeParId;
178 fLocalDerivatives[
i] = 0.0;
182 fGlobalDerivatives[
i] = 0.0;
189 delete mRecordWriter;
190 delete mRecordReader;
205 LOG(fatal) <<
"Millepede already initialized";
209 if (!fDisableRecordWriter) {
214 if (mWithConstraintsRecWriter) {
226 if (DataRecFName.EndsWith(
".root")) {
227 ch->AddFile(DataRecFName);
229 int nent = ch->GetEntries();
232 LOG(fatal) <<
"Obtained chain is empty, please check your record ROOT file.";
238 if (mConstraintsRecReader) {
240 TChain* ch_cons =
new TChain(mConstraintsRecReader->
getDataTreeName());
241 if (ConsRecFName.EndsWith(
".root")) {
242 ch_cons->AddFile(ConsRecFName);
244 int nent_cons = ch_cons->GetEntries();
247 LOG(fatal) <<
"Obtained chain is empty, please check your record ROOT file.";
257 for (
int iPar = 0; iPar <
fNGlobal; ++iPar) {
259 if (fGlobalParameterStatus[iPar] == kFixedParId) {
263 }
else if (fGlobalParameterStatus[iPar] == kFreeParId || fGlobalParameterStatus[iPar] == kGroupBaseId) {
266 fGlobalParameterStatus[iPar] = nGlobal++;
269 }
else if (fGlobalParameterStatus[iPar] < kGroupBaseId) {
272 const int iDeBase(kGroupBaseId - 1 - fGlobalParameterStatus[iPar]);
273 const int iParBase = iPar %
fgNParCh;
276 if (iDeBase < 0 || iDeBase >= iPar /
fgNParCh) {
277 LOG(fatal) <<
"Group for parameter index " << iPar <<
" has wrong base detector element: " << iDeBase;
281 fGlobalParameterStatus[iPar] = fGlobalParameterStatus[iDeBase *
fgNParCh + iParBase];
282 LOG(info) <<
"Parameter " << iPar <<
" grouped to detector " << iDeBase <<
" (" << GetParameterMaskString(1 << iParBase).Data() <<
")";
285 LOG(fatal) <<
"Unrecognized parameter status for index " << iPar <<
": " << fGlobalParameterStatus[iPar];
289 LOG(info) <<
"Free Parameters: " << nGlobal <<
" out of " <<
fNGlobal;
295 if (!fDisableRecordWriter) {
296 mRecordWriter->
init();
305 for (
int iPar = 0; iPar <
fgNParCh; ++iPar) {
306 LOG(info) <<
"fAllowVar[" << iPar <<
"]= " << fAllowVar[iPar];
310 for (
int iDet = 0; iDet <
fgNDetElem; ++iDet) {
311 for (
int iPar = 0; iPar <
fgNParCh; ++iPar) {
323 string Path_file = Form(
"%s%s",
"Residual",
".root");
325 fTFile =
new TFile(Path_file.c_str(),
"RECREATE");
326 fTTree =
new TTree(
"TreeE",
"Evaluation");
328 const int kSplitlevel = 98;
329 const int kBufsize = 32000;
332 fTTree->Branch(
"fClDetElem", &(fTrkClRes->
fClDetElem),
"fClDetElem/I");
333 fTTree->Branch(
"fClDetElemNumber", &(fTrkClRes->
fClDetElemNumber),
"fClDetElemNumber/I");
334 fTTree->Branch(
"fClusterX", &(fTrkClRes->
fClusterX),
"fClusterX/F");
335 fTTree->Branch(
"fClusterY", &(fTrkClRes->
fClusterY),
"fClusterY/F");
336 fTTree->Branch(
"fTrackX", &(fTrkClRes->
fTrackX),
"fTrackX/F");
337 fTTree->Branch(
"fTrackY", &(fTrkClRes->
fTrackY),
"fTrackY/F");
338 fTTree->Branch(
"fClusterXloc", &(fTrkClRes->
fClusterXloc),
"fClusterXloc/F");
339 fTTree->Branch(
"fClusterYloc", &(fTrkClRes->
fClusterYloc),
"fClusterYloc/F");
340 fTTree->Branch(
"fTrackXloc", &(fTrkClRes->
fTrackXloc),
"fTrackXloc/F");
341 fTTree->Branch(
"fTrackYloc", &(fTrkClRes->
fTrackYloc),
"fTrackYloc/F");
342 fTTree->Branch(
"fTrackSlopeX", &(fTrkClRes->
fTrackSlopeX),
"fTrackSlopeX/F");
343 fTTree->Branch(
"fTrackSlopeY", &(fTrkClRes->
fTrackSlopeY),
"fTrackSlopeY/F");
344 fTTree->Branch(
"fBendingMomentum", &(fTrkClRes->
fBendingMomentum),
"fBendingMomentum/F");
345 fTTree->Branch(
"fResiduXGlobal", &(fTrkClRes->
fResiduXGlobal),
"fResiduXGlobal/F");
346 fTTree->Branch(
"fResiduYGlobal", &(fTrkClRes->
fResiduYGlobal),
"fResiduYGlobal/F");
347 fTTree->Branch(
"fResiduXLocal", &(fTrkClRes->
fResiduXLocal),
"fResiduXLocal/F");
348 fTTree->Branch(
"fResiduYLocal", &(fTrkClRes->
fResiduYLocal),
"fResiduYLocal/F");
349 fTTree->Branch(
"fCharge", &(fTrkClRes->
fCharge),
"fCharge/F");
350 fTTree->Branch(
"fClusterZ", &(fTrkClRes->
fClusterZ),
"fClusterZ/F");
351 fTTree->Branch(
"fTrackZ", &(fTrkClRes->
fTrackZ),
"fTrackZ/F");
352 fTTree->Branch(
"fBx", &(fTrkClRes->
fBx),
"fBx/F");
353 fTTree->Branch(
"fBy", &(fTrkClRes->
fBy),
"fBy/F");
354 fTTree->Branch(
"fBz", &(fTrkClRes->
fBz),
"fBz/F");
361 fInitialized = kFALSE;
363 LOG(info) <<
"Closing Evaluation TFile";
364 if (fTFile && fTTree) {
370 if (!fDisableRecordWriter) {
389 auto itTrackParam = track.
begin();
390 for (; itTrackParam != track.
end(); ++itTrackParam) {
393 const Cluster* cluster = itTrackParam->getClusterPtr();
401 FillTrackParamData(&*itTrackParam);
402 fTrackPos0[0] = fTrackPos[0];
403 fTrackPos0[1] = fTrackPos[1];
404 fTrackPos0[2] = fTrackPos[2];
405 fTrackSlope0[0] = fTrackSlope[0];
406 fTrackSlope0[1] = fTrackSlope[1];
413 if (fRefitStraightTracks) {
416 const LocalTrackParam trackParam(RefitStraightTrack(track, fTrackPos0[2]));
423 fTrackPos0[0] = trackParam.
fTrackX;
424 fTrackPos0[1] = trackParam.
fTrackY;
425 fTrackPos0[2] = trackParam.
fTrackZ;
432 itTrackParam = track.
begin();
433 for (; itTrackParam != track.
end(); ++itTrackParam) {
436 const Cluster* cluster = itTrackParam->getClusterPtr();
443 FillDetElemData(cluster);
444 FillRecPointData(cluster);
445 FillTrackParamData(&*itTrackParam);
451 TMatrixD transMat(3, 4);
452 trans.GetTransformMatrix(transMat);
455 r[0] = transMat(0, 0);
456 r[1] = transMat(0, 1);
457 r[2] = transMat(0, 2);
458 r[3] = transMat(1, 0);
459 r[4] = transMat(1, 1);
460 r[5] = transMat(1, 2);
461 r[6] = transMat(2, 0);
462 r[7] = transMat(2, 1);
463 r[8] = transMat(2, 2);
464 r[9] = transMat(0, 3);
465 r[10] = transMat(1, 3);
466 r[11] = transMat(2, 3);
471 fMeas[0] =
r[0] * (fClustPos[0] - fTrackPos[0]) +
r[1] * (fClustPos[1] - fTrackPos[1]);
472 fMeas[1] =
r[3] * (fClustPos[0] - fTrackPos[0]) +
r[4] * (fClustPos[1] - fTrackPos[1]);
476 fMeas[0] = (
r[0] * fClustPos[0] +
r[1] * fClustPos[1]);
477 fMeas[1] = (
r[3] * fClustPos[0] +
r[4] * fClustPos[1]);
483 const float InvBendingMom = itTrackParam->getInverseBendingMomentum();
484 const float TrackCharge = itTrackParam->getCharge();
486 double B[3] = {0.0, 0.0, 0.0};
487 double x[3] = {fTrackPos[0], fTrackPos[1], fTrackPos[2]};
488 TGeoGlobalMagField::Instance()->Field(
x,
B);
489 const float Bx =
B[0];
490 const float By =
B[1];
491 const float Bz =
B[2];
504 fTrkClRes->
fTrackX = fTrackPos[0];
505 fTrkClRes->
fTrackY = fTrackPos[1];
506 fTrkClRes->
fTrackZ = fTrackPos[2];
508 fTrkClRes->
fClusterXloc =
r[0] * fClustPos[0] +
r[1] * fClustPos[1];
509 fTrkClRes->
fClusterYloc =
r[3] * fClustPos[0] +
r[4] * fClustPos[1];
511 fTrkClRes->
fTrackXloc =
r[0] * fTrackPos[0] +
r[1] * fTrackPos[1];
512 fTrkClRes->
fTrackYloc =
r[3] * fTrackPos[0] +
r[4] * fTrackPos[1];
521 fTrkClRes->
fResiduXLocal =
r[0] * (fClustPos[0] - fTrackPos[0]) +
r[1] * (fClustPos[1] - fTrackPos[1]);
522 fTrkClRes->
fResiduYLocal =
r[3] * (fClustPos[0] - fTrackPos[0]) +
r[4] * (fClustPos[1] - fTrackPos[1]);
524 fTrkClRes->
fCharge = TrackCharge;
540 if (!fDisableRecordWriter) {
547 if (!fDisableRecordWriter) {
557 LOG(info) <<
"Fixing " << GetParameterMaskString(
mask).Data() <<
" for all detector elements";
582 if (iCh < 1 || iCh > 10) {
583 LOG(fatal) <<
"Invalid chamber index " << iCh;
589 for (
int i = iDetElemFirst;
i < iDetElemLast; ++
i) {
591 LOG(info) <<
"Fixing " << GetParameterMaskString(
mask).Data() <<
" for detector element " <<
i;
612 const int iDet(GetDetElemNumber(iDetElemId));
635 const int iCh(GetChamberId(
i));
636 if (!lChOnOff[iCh - 1]) {
645 if (iCh >= 1 && iCh <= 4) {
646 if (lDetElemNumber == 0 && !(sidesMask &
SideTopRight)) {
649 if (lDetElemNumber == 1 && !(sidesMask &
SideTopLeft)) {
661 if (iCh >= 5 && iCh <= 6) {
662 if (lDetElemNumber >= 0 && lDetElemNumber <= 4 && !(sidesMask &
SideTopRight)) {
665 if (lDetElemNumber >= 5 && lDetElemNumber <= 10 && !(sidesMask &
SideTopLeft)) {
668 if (lDetElemNumber >= 11 && lDetElemNumber <= 13 && !(sidesMask &
SideBottomLeft)) {
671 if (lDetElemNumber >= 14 && lDetElemNumber <= 17 && !(sidesMask &
SideBottomRight)) {
677 if (iCh >= 7 && iCh <= 10) {
678 if (lDetElemNumber >= 0 && lDetElemNumber <= 6 && !(sidesMask &
SideTopRight)) {
681 if (lDetElemNumber >= 7 && lDetElemNumber <= 13 && !(sidesMask &
SideTopLeft)) {
684 if (lDetElemNumber >= 14 && lDetElemNumber <= 19 && !(sidesMask &
SideBottomLeft)) {
687 if (lDetElemNumber >= 20 && lDetElemNumber <= 25 && !(sidesMask &
SideBottomRight)) {
703 LOG(fatal) <<
"Millepede already initialized";
706 fGlobalParameterStatus[iPar] = kFixedParId;
715 if (iCh < 1 || iCh > 10) {
716 LOG(fatal) <<
"Invalid chamber index " << iCh;
722 for (
int i = iDetElemFirst;
i < iDetElemLast; ++
i) {
724 LOG(info) <<
"Releasing " << GetParameterMaskString(
mask).Data() <<
" for detector element " <<
i;
745 const int iDet(GetDetElemNumber(iDetElemId));
766 LOG(fatal) <<
"Millepede already initialized";
769 fGlobalParameterStatus[iPar] = kFreeParId;
776 if (iCh < 1 || iCh >
fgNCh) {
777 LOG(fatal) <<
"Invalid chamber index " << iCh;
780 const int detElemMin = 100 * iCh;
781 const int detElemMax = 100 * iCh +
fgNDetElemCh[iCh] - 1;
789 if (iCh < 1 || iCh >
fgNCh) {
790 LOG(fatal) <<
"Invalid chamber index " << iCh;
793 if (iHalf < 0 || iHalf > 1) {
794 LOG(fatal) <<
"Invalid half chamber index " << iHalf;
797 const int iHalfCh = 2 * (iCh - 1) + iHalf;
806 const int nDetElem = detElemMax - detElemMin + 1;
808 LOG(fatal) <<
"Requested group of DEs " << detElemMin <<
"-" << detElemMax <<
" contains less than 2 DE's";
812 int* detElemList =
new int[nDetElem];
813 for (
int i = 0;
i < nDetElem; ++
i) {
814 detElemList[
i] = detElemMin +
i;
819 delete[] detElemList;
827 LOG(fatal) <<
"Millepede already initialized";
830 const int iDeBase(GetDetElemNumber(detElemList[0]));
831 for (
int i = 0;
i < nDetElem; ++
i) {
832 const int iDeCurrent(GetDetElemNumber(detElemList[
i]));
834 fGlobalParameterStatus[iDeCurrent *
fgNParCh + 0] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
837 fGlobalParameterStatus[iDeCurrent *
fgNParCh + 1] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
840 fGlobalParameterStatus[iDeCurrent *
fgNParCh + 2] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
843 fGlobalParameterStatus[iDeCurrent *
fgNParCh + 3] = (
i == 0) ? kGroupBaseId : (kGroupBaseId - iDeBase - 1);
847 LOG(info) <<
"Creating new group for detector " << detElemList[
i] <<
" and variable " << GetParameterMaskString(
mask).Data();
849 LOG(info) <<
"Adding detector element " << detElemList[
i] <<
" to current group";
860 for (
int i = iDetElemFirst;
i < iDetElemLast; ++
i) {
881 const int iDet(GetDetElemNumber(iDetElemId));
901 LOG(fatal) <<
"Millepede not initialized";
905 LOG(info) <<
"Parameter " << iPar <<
" set to non linear ";
921 const int iCh(GetChamberId(
i));
922 if (lChOnOff[iCh - 1]) {
925 fConstraintX.values[
i *
fgNParCh + 0] = 1.0;
928 fConstraintY.values[
i *
fgNParCh + 1] = 1.0;
931 fConstraintTZ.values[
i *
fgNParCh + 2] = 1.0;
934 fConstraintTZ.values[
i *
fgNParCh + 3] = 1.0;
940 AddConstraint(fConstraintX.values, 0.0);
943 AddConstraint(fConstraintY.values, 0.0);
946 AddConstraint(fConstraintTZ.values, 0.0);
949 AddConstraint(fConstraintZ.values, 0.0);
973 const int iCh(GetChamberId(
i));
976 if (lChOnOff[iCh - 1]) {
982 const int lDetElemId = iCh * 100 + lDetElemNumber;
986 if (iCh >= 1 && iCh <= 4) {
987 if (lDetElemNumber == 0 && !(sidesMask &
SideTopRight)) {
990 if (lDetElemNumber == 1 && !(sidesMask &
SideTopLeft)) {
1002 if (iCh >= 5 && iCh <= 6) {
1003 if (lDetElemNumber >= 0 && lDetElemNumber <= 4 && !(sidesMask &
SideTopRight)) {
1006 if (lDetElemNumber >= 5 && lDetElemNumber <= 10 && !(sidesMask &
SideTopLeft)) {
1009 if (lDetElemNumber >= 11 && lDetElemNumber <= 13 && !(sidesMask &
SideBottomLeft)) {
1012 if (lDetElemNumber >= 14 && lDetElemNumber <= 17 && !(sidesMask &
SideBottomRight)) {
1018 if (iCh >= 7 && iCh <= 10) {
1019 if (lDetElemNumber >= 0 && lDetElemNumber <= 6 && !(sidesMask &
SideTopRight)) {
1022 if (lDetElemNumber >= 7 && lDetElemNumber <= 13 && !(sidesMask &
SideTopLeft)) {
1025 if (lDetElemNumber >= 14 && lDetElemNumber <= 19 && !(sidesMask &
SideBottomLeft)) {
1028 if (lDetElemNumber >= 20 && lDetElemNumber <= 25 && !(sidesMask &
SideBottomRight)) {
1034 double lDetElemGloX = 0.;
1035 double lDetElemGloY = 0.;
1036 double lDetElemGloZ = 0.;
1038 auto fTransform = fTransformCreator(lDetElemId);
1042 fTransform.LocalToMaster(SlatPos, GlobalPos);
1043 lDetElemGloX = GlobalPos.x();
1044 lDetElemGloY = GlobalPos.y();
1045 lDetElemGloZ = GlobalPos.z();
1049 lMeanY += lDetElemGloY;
1050 lSigmaY += lDetElemGloY * lDetElemGloY;
1051 lMeanZ += lDetElemGloZ;
1052 lSigmaZ += lDetElemGloZ * lDetElemGloZ;
1057 lMeanY /= lNDetElem;
1058 lSigmaY /= lNDetElem;
1059 lSigmaY = TMath::Sqrt(lSigmaY - lMeanY * lMeanY);
1060 lMeanZ /= lNDetElem;
1061 lSigmaZ /= lNDetElem;
1062 lSigmaZ = TMath::Sqrt(lSigmaZ - lMeanZ * lMeanZ);
1063 LOG(info) <<
"Used " << lNDetElem <<
" DetElem, MeanZ= " << lMeanZ <<
", SigmaZ= " << lSigmaZ;
1066 Array fConstraintX[4];
1067 Array fConstraintY[4];
1068 Array fConstraintP[4];
1069 Array fConstraintXZ[4];
1070 Array fConstraintYZ[4];
1071 Array fConstraintPZ[4];
1074 Array fConstraintXY[4];
1075 Array fConstraintYY[4];
1076 Array fConstraintPY[4];
1080 lDetTLBR[0] = sidesMask &
SideTop;
1081 lDetTLBR[1] = sidesMask &
SideLeft;
1088 const int iCh(GetChamberId(
i));
1091 if (!lChOnOff[iCh - 1]) {
1097 const int lDetElemId = iCh * 100 + lDetElemNumber;
1100 double lDetElemGloX = 0.;
1101 double lDetElemGloY = 0.;
1102 double lDetElemGloZ = 0.;
1104 auto fTransform = fTransformCreator(lDetElemId);
1108 fTransform.LocalToMaster(SlatPos, GlobalPos);
1109 lDetElemGloX = GlobalPos.x();
1110 lDetElemGloY = GlobalPos.y();
1111 lDetElemGloZ = GlobalPos.z();
1115 for (
int iSide = 0; iSide < 4; iSide++) {
1118 if (!lDetTLBR[iSide]) {
1124 if (iCh >= 1 && iCh <= 4) {
1125 if (lDetElemNumber == 0 && !(iSide == 0 || iSide == 3)) {
1128 if (lDetElemNumber == 1 && !(iSide == 0 || iSide == 1)) {
1131 if (lDetElemNumber == 2 && !(iSide == 2 || iSide == 1)) {
1134 if (lDetElemNumber == 3 && !(iSide == 2 || iSide == 3)) {
1140 if (iCh >= 5 && iCh <= 6) {
1141 if (lDetElemNumber >= 0 && lDetElemNumber <= 4 && !(iSide == 0 || iSide == 3)) {
1144 if (lDetElemNumber >= 5 && lDetElemNumber <= 9 && !(iSide == 0 || iSide == 1)) {
1147 if (lDetElemNumber >= 10 && lDetElemNumber <= 13 && !(iSide == 2 || iSide == 1)) {
1150 if (lDetElemNumber >= 14 && lDetElemNumber <= 17 && !(iSide == 2 || iSide == 3)) {
1156 if (iCh >= 7 && iCh <= 10) {
1157 if (lDetElemNumber >= 0 && lDetElemNumber <= 6 && !(iSide == 0 || iSide == 3)) {
1160 if (lDetElemNumber >= 7 && lDetElemNumber <= 13 && !(iSide == 0 || iSide == 1)) {
1163 if (lDetElemNumber >= 14 && lDetElemNumber <= 19 && !(iSide == 2 || iSide == 1)) {
1166 if (lDetElemNumber >= 20 && lDetElemNumber <= 25 && !(iSide == 2 || iSide == 3)) {
1173 fConstraintX[iSide].values[
i *
fgNParCh + 0] = 1;
1178 fConstraintY[iSide].values[
i *
fgNParCh + 1] = 1;
1183 fConstraintP[iSide].values[
i *
fgNParCh + 2] = 1;
1188 fConstraintXZ[iSide].values[
i *
fgNParCh + 0] = (lDetElemGloZ - lMeanZ) / lSigmaZ;
1193 fConstraintYZ[iSide].values[
i *
fgNParCh + 1] = (lDetElemGloZ - lMeanZ) / lSigmaZ;
1198 fConstraintPZ[iSide].values[
i *
fgNParCh + 2] = (lDetElemGloZ - lMeanZ) / lSigmaZ;
1203 fConstraintXY[iSide].values[
i *
fgNParCh + 0] = (lDetElemGloY - lMeanY) / lSigmaY;
1208 fConstraintYY[iSide].values[
i *
fgNParCh + 1] = (lDetElemGloY - lMeanY) / lSigmaY;
1213 fConstraintPY[iSide].values[
i *
fgNParCh + 2] = (lDetElemGloY - lMeanY) / lSigmaY;
1219 for (
int iSide = 0; iSide < 4; iSide++) {
1221 if (!lDetTLBR[iSide]) {
1226 AddConstraint(fConstraintX[iSide].
values, 0.0);
1229 AddConstraint(fConstraintY[iSide].
values, 0.0);
1232 AddConstraint(fConstraintP[iSide].
values, 0.0);
1235 AddConstraint(fConstraintXZ[iSide].
values, 0.0);
1238 AddConstraint(fConstraintYZ[iSide].
values, 0.0);
1241 AddConstraint(fConstraintPZ[iSide].
values, 0.0);
1244 AddConstraint(fConstraintXY[iSide].
values, 0.0);
1247 AddConstraint(fConstraintYY[iSide].
values, 0.0);
1250 AddConstraint(fConstraintPY[iSide].
values, 0.0);
1259 if (!fInitialized) {
1260 LOG(fatal) <<
"Millepede is not initialized";
1272 LOG(fatal) <<
"Millepede already initialized";
1276 if (!(iPar >= 0 && iPar <
fgNParCh)) {
1277 LOG(fatal) <<
"Invalid index: " << iPar;
1280 fAllowVar[iPar] =
value;
1292 for (
int i = 0;
i < 2; ++
i) {
1293 LOG(info) <<
"fSigma[" <<
i <<
"] =" << fSigma[
i];
1298void Aligner::GlobalFit(std::vector<double>& parameters, std::vector<double>& errors, std::vector<double>& pulls)
1301 fMillepede->
GlobalFit(parameters, errors, pulls);
1303 LOG(info) <<
"Done fitting global parameters";
1304 for (
int iDet = 0; iDet <
fgNDetElem; ++iDet) {
1305 LOG(info) << iDet <<
" " << parameters[iDet *
fgNParCh + 0] <<
" " << parameters[iDet *
fgNParCh + 1] <<
" " << parameters[iDet *
fgNParCh + 3] <<
" " << parameters[iDet *
fgNParCh + 2];
1323 std::vector<o2::detectors::AlignParam>&
params,
1324 std::vector<double>& misAlignments)
1341 double lModuleMisAlignment[
fgNParCh] = {0};
1342 double lDetElemMisAlignment[
fgNParCh] = {0};
1345 for (
int hc = 0; hc < 20; hc++) {
1347 TGeoCombiTrans localDeltaTransform;
1348 localDeltaTransform = DeltaTransform(lModuleMisAlignment);
1350 std::string sname = fmt::format(
"MCH/HC{}", hc);
1353 double lPsi, lTheta, lPhi = 0.;
1354 if (!isMatrixConvertedToAngles(localDeltaTransform.GetRotationMatrix(),
1355 lPsi, lTheta, lPhi)) {
1356 LOG(error) <<
"Problem extracting angles!";
1363 params.emplace_back(lAP);
1368 if (DetElemIsValid(iDetElemId)) {
1370 const int iDetElemNumber(GetDetElemNumber(iDetElemId));
1373 lDetElemMisAlignment[
i] = 0.0;
1375 lDetElemMisAlignment[
i] = misAlignments[iDetElemNumber *
fgNParCh +
i];
1381 localDeltaTransform = DeltaTransform(lDetElemMisAlignment);
1383 if (!isMatrixConvertedToAngles(localDeltaTransform.GetRotationMatrix(),
1384 lPsi, lTheta, lPhi)) {
1385 LOG(error) <<
"Problem extracting angles for " << sname.c_str();
1390 params.emplace_back(lAP);
1395 LOG(info) << fmt::format(
"Keeping detElement {} unchanged\n", iDetElemId);
1409 TMatrixDSym mChCorrMatrix(6);
1410 mChCorrMatrix[0][0] = chResX * chResX;
1411 mChCorrMatrix[1][1] = chResY * chResY;
1413 TMatrixDSym mDECorrMatrix(6);
1414 mDECorrMatrix[0][0] = deResX * deResX;
1415 mDECorrMatrix[1][1] = deResY * deResY;
1419 for (
int chId = 0; chId <= 9; ++chId) {
1422 if (rChId > 0 && chId + 1 != rChId) {
1430 chName1 = Form(
"GM%d", chId);
1431 chName2 = Form(
"GM%d", chId);
1435 chName1 = Form(
"GM%d", 4 + (chId - 4) * 2);
1436 chName2 = Form(
"GM%d", 4 + (chId - 4) * 2 + 1);
1439 for (
int i = 0;
i < misAlignArray->GetEntries(); ++
i) {
1443 if ((volName.Contains(chName1) &&
1444 ((volName.Last(
'/') == volName.Index(chName1) + chName1.Length()) ||
1445 (volName.Length() == volName.Index(chName1) + chName1.Length()))) ||
1446 (volName.Contains(chName2) &&
1447 ((volName.Last(
'/') == volName.Index(chName2) + chName2.Length()) ||
1448 (volName.Length() == volName.Index(chName2) + chName2.Length())))) {
1450 volName.Remove(0, volName.Last(
'/') + 1);
1461 TMatrixD AtGASum(4, 4);
1464 TMatrixD AtGMSum(4, 1);
1468 for (
auto itTrackParam(track.
begin()); itTrackParam != track.
end(); ++itTrackParam) {
1471 const Cluster* cluster = itTrackParam->getClusterPtr();
1480 A(0, 2) = (cluster->
getZ() - z0);
1482 A(1, 3) = (cluster->
getZ() - z0);
1484 TMatrixD At(TMatrixD::kTransposed,
A);
1492 const TMatrixD AtG(At, TMatrixD::kMult, G);
1493 const TMatrixD AtGA(AtG, TMatrixD::kMult,
A);
1498 M(0, 0) = cluster->
getX();
1499 M(1, 0) = cluster->
getY();
1500 const TMatrixD AtGM(AtG, TMatrixD::kMult, M);
1505 TMatrixD AtGASumInv(TMatrixD::kInverted, AtGASum);
1506 TMatrixD X(AtGASumInv, TMatrixD::kMult, AtGMSum);
1509 LocalTrackParam out;
1510 out.fTrackX = X(0, 0);
1511 out.fTrackY = X(1, 0);
1513 out.fTrackSlopeX = X(2, 0);
1514 out.fTrackSlopeY = X(3, 0);
1520void Aligner::FillDetElemData(
const Cluster* cluster)
1525 const int detElemId = cluster->getDEId();
1526 fDetElemNumber = GetDetElemNumber(detElemId);
1530void Aligner::FillRecPointData(
const Cluster* cluster)
1534 fClustPos[0] = cluster->getX();
1535 fClustPos[1] = cluster->getY();
1536 fClustPos[2] = cluster->getZ();
1540void Aligner::FillTrackParamData(
const TrackParam* trackParam)
1544 fTrackPos[0] = trackParam->getNonBendingCoor();
1545 fTrackPos[1] = trackParam->getBendingCoor();
1546 fTrackPos[2] = trackParam->getZ();
1547 fTrackSlope[0] = trackParam->getNonBendingSlope();
1548 fTrackSlope[1] = trackParam->getBendingSlope();
1552void Aligner::LocalEquationX(
const double*
r)
1560 SetLocalDerivative(0,
r[0]);
1561 SetLocalDerivative(1,
r[0] * (fTrackPos[2] - fTrackPos0[2]));
1564 SetLocalDerivative(2,
r[1]);
1565 SetLocalDerivative(3,
r[1] * (fTrackPos[2] - fTrackPos0[2]));
1577 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 0, -
r[0]);
1578 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 1, -
r[1]);
1583 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 2, -
r[1] * fTrackPos[0] +
r[0] * fTrackPos[1]);
1586 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 3,
r[0] * fTrackSlope[0] +
r[1] * fTrackSlope[1]);
1591 const double trackPosX = fTrackPos0[0] + fTrackSlope0[0] * (fTrackPos[2] - fTrackPos0[2]);
1592 const double trackPosY = fTrackPos0[1] + fTrackSlope0[1] * (fTrackPos[2] - fTrackPos0[2]);
1595 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 2, -
r[1] * trackPosX +
r[0] * trackPosY);
1599 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 3,
r[0] * fTrackSlope0[0] +
r[1] * fTrackSlope0[1]);
1603 fMillepede->
SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, fMeas[0], fSigma[0]);
1607void Aligner::LocalEquationY(
const double*
r)
1615 SetLocalDerivative(0,
r[3]);
1616 SetLocalDerivative(1,
r[3] * (fTrackPos[2] - fTrackPos0[2]));
1619 SetLocalDerivative(2,
r[4]);
1620 SetLocalDerivative(3,
r[4] * (fTrackPos[2] - fTrackPos0[2]));
1624 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 0, -
r[3]);
1625 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 1, -
r[4]);
1630 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 2, -
r[4] * fTrackPos[0] +
r[3] * fTrackPos[1]);
1633 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 3,
r[3] * fTrackSlope[0] +
r[4] * fTrackSlope[1]);
1638 const double trackPosX = fTrackPos0[0] + fTrackSlope0[0] * (fTrackPos[2] - fTrackPos0[2]);
1639 const double trackPosY = fTrackPos0[1] + fTrackSlope0[1] * (fTrackPos[2] - fTrackPos0[2]);
1642 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 2, -
r[4] * trackPosX +
r[3] * trackPosY);
1645 SetGlobalDerivative(fDetElemNumber *
fgNParCh + 3,
r[3] * fTrackSlope0[0] +
r[4] * fTrackSlope0[1]);
1649 fMillepede->
SetLocalEquation(fGlobalDerivatives, fLocalDerivatives, fMeas[1], fSigma[1]);
1653TGeoCombiTrans Aligner::DeltaTransform(
const double* lMisAlignment)
const
1658 const TGeoTranslation deltaTrans(lMisAlignment[0], lMisAlignment[1], lMisAlignment[3]);
1661 TGeoRotation deltaRot;
1662 deltaRot.RotateZ(lMisAlignment[2] * 180. / TMath::Pi());
1665 return TGeoCombiTrans(deltaTrans, deltaRot);
1668bool Aligner::isMatrixConvertedToAngles(
const double* rot,
double& psi,
double& theta,
double& phi)
const
1675 if (std::abs(rot[0]) < 1e-7 || std::abs(rot[8]) < 1e-7) {
1676 LOG(error) <<
"Failed to extract roll-pitch-yall angles!";
1679 psi = std::atan2(-rot[5], rot[8]);
1680 theta = std::asin(rot[2]);
1681 phi = std::atan2(-rot[1], rot[0]);
1686void Aligner::AddConstraint(
double* par,
double value)
1689 if (!fInitialized) {
1690 LOG(fatal) <<
"Millepede is not initialized";
1693 std::vector<double> vpar(
fNGlobal);
1702bool Aligner::DetElemIsValid(
int iDetElemId)
const
1705 const int iCh = iDetElemId / 100;
1706 const int iDet = iDetElemId % 100;
1711int Aligner::GetDetElemNumber(
int iDetElemId)
const
1715 const int iCh = iDetElemId / 100;
1716 const int iDet = iDetElemId % 100;
1720 LOG(fatal) <<
"Invalid detector element id: " << iDetElemId;
1728int Aligner::GetChamberId(
int iDetElemNumber)
const
1732 for (iCh = 0; iCh <
fgNCh; iCh++) {
1742TString Aligner::GetParameterMaskString(
unsigned int mask)
const
1761TString Aligner::GetSidesMaskString(
unsigned int mask)
const
Definition of the base alignment parameters class.
Definition of the MCH track for internal use.
General class for alignment with large number of degrees of freedom, adapted from AliROOT.
Class to store the data of single track processing.
Definition of the MCH track parameters for internal use.
void setGlobalParams(double x, double y, double z, double psi, double theta, double phi)
================ methods for direct setting of delta params
void setSymName(const char *m)
set symbolic name of the volume
const std::string & getSymName() const
return symbolic name of the volume
bool applyToGeometry() const
apply object to geoemetry
void SetGlobalConstraint(const std::vector< double > &dergb, const double val, const double sigma=0, const bool doPrint=false)
define a constraint equation
void DisableRecordWriter()
Disable record writer for DPL process.
void SetNonLinear(int index, bool v=true)
int InitMille(int nGlo, const int nLoc, const int lNStdDev=-1, const double lResCut=-1., const double lResCutInit=-1., const std::vector< int > ®roup={})
init all
void SetParSigma(int i, double par)
void SetConstraintsRecWriter(o2::fwdalign::MilleRecordWriter *myP)
void SetConstraintsRecReader(o2::fwdalign::MilleRecordReader *myP)
double GetParError(int iPar) const
return error for parameter iPar
void SetLocalEquation(std::vector< double > &dergb, std::vector< double > &derlc, const double lMeas, const double lSigma)
assing derivs of loc.eq.
int SetIterations(const double lChi2CutFac)
Number of iterations is calculated from lChi2CutFac.
void SetRecord(o2::fwdalign::MillePedeRecord *aRecord)
int PrintGlobalParameters() const
print the final results into the logfile
int GlobalFit(std::vector< double > &par, std::vector< double > &error, std::vector< double > &pull)
performs a requested number of global iterations
void SetRecordWriter(o2::fwdalign::MilleRecordWriter *myP)
o2::fwdalign::MillePedeRecord * GetRecord() const
void SetRecordReader(o2::fwdalign::MilleRecordReader *myP)
void SetGlobalParameters(double *par)
TString getDataTreeName() const
return the name of record data tree
void connectToChain(TChain *ch)
connect to input TChain
void setCyclicAutoSave(const long nEntries)
Set the number of entries to be used by TTree::AutoSave()
void setDataFileName(TString fname)
choose data records filename
void init()
init output file and tree
void setRecordRun(int run)
assign run
void terminate()
write tree and close output file
void setRecordWeight(double wgh)
assign weight
void fillRecordTree(const bool doPrint=false)
fill tree
HMPID cluster implementation.
void ReleaseDetElem(int iDetElemId, unsigned int parameterMask=ParAll)
void SetAllowedVariation(int iPar, double value)
void ReAlign(std::vector< o2::detectors::AlignParam > ¶ms, std::vector< double > &misAlignments)
void SetDetElemNonLinear(int iSt, unsigned int parameterMask)
static const int fgNDetElemCh[fgNCh]
Number of detection elements per chamber.
void FixParameter(int iPar)
void SetAlignmentResolution(const TClonesArray *misAlignArray, int chId, double chResX, double chResY, double deResX, double deResY)
void GlobalFit(std::vector< double > ¶ms, std::vector< double > &errors, std::vector< double > &pulls)
perform global fit
static const int fgDetElemHalfCh[fgNHalfCh][fgNDetHalfChMax]
list of detection elements per tracking module
@ fNGlobal
Number of global parameters.
@ fgNDetHalfChMax
max number of detector elements per half chamber
@ fgNHalfCh
Number of half chambers.
@ fNLocal
Number of local parameters.
@ fgNCh
Number tracking chambers.
@ fgNParCh
Number of degrees of freedom per chamber.
void AddConstraints(const bool *bChOnOff, unsigned int parameterMask)
void SetParameterNonLinear(int iPar)
void FixHalfSpectrometer(const bool *bChOnOff, unsigned int sidesMask=AllSides, unsigned int parameterMask=ParAll)
void SetChamberNonLinear(int iCh, unsigned int parameterMask)
void init(TString DataRecFName="millerecords.root", TString ConsRecFName="milleconstraints.root")
void FixChamber(int iCh, unsigned int parameterMask=ParAll)
void PrintGlobalParameters(void) const
print global parameters
static const int fgSNDetElemCh[fgNCh+1]
Sum of detection elements up to this chamber.
void ProcessTrack(Track &track, const o2::mch::geo::TransformationCreator &transformation, Bool_t doAlignment, Double_t weight=1)
double GetParError(int iPar) const
get error on a given parameter
void ReleaseChamber(int iCh, unsigned int parameterMask=ParAll)
void GroupDetElems(int detElemMin, int detElemMax, unsigned int parameterMask=ParAll)
void InitGlobalParameters(double *par)
initialize global parameters to a give set of values
void FixDetElem(int iDetElemId, unsigned int parameterMask=ParAll)
void GroupChamber(int iCh, unsigned int parameterMask=ParAll)
void FixAll(unsigned int parameterMask=ParAll)
void SetSigmaXY(double sigmaX, double sigmaY)
void ReleaseParameter(int iPar)
void GroupHalfChamber(int iCh, int iHalf, unsigned int parameterMask=ParAll)
static const int fgNDetElemHalfCh[fgNHalfCh]
Number of detection element per tracking module.
self initialized array, used for adding constraints
local track residual, for tempoarary eval
local track parameters, for refit
auto end()
Return an iterator passing the track parameters at last cluster.
auto begin()
Return an iterator to the track parameters at clusters (point to the first one)
GLuint GLuint GLfloat weight
GLsizei const GLfloat * value
GLenum const GLfloat * params
GLenum GLsizei GLsizei GLint * values
int detElemId(Chamber chamber, Side side, int number)
std::function< o2::math_utils::Transform3D(int detElemId)> TransformationCreator
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.
cluster minimal structure
double getEx() const
Return the cluster resolution along x as double.
int getDEId() const
Return the detection element ID, part of the unique ID.
double getY() const
Return the cluster position along y as double.
double getX() const
Return the cluster position along x as double.
double getEy() const
Return the cluster resolution along y as double.
double getZ() const
Return the cluster position along z as double.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"