14#include "FairRootManager.h"
15#include "FairRunAna.h"
16#include "TClonesArray.h"
18#include "TGeoManager.h"
21#include "bba/Parameter.h"
25#include <TGeoManager.h>
26#include <TGeoMatrix.h>
38 constexpr double shiftToRotFactor = 10.;
39 constexpr bool kMultipleScatteringInCostFunction =
41 constexpr bool kMultipleScatteringInTrackSelection =
47 : FairTask(name, iVerbose)
51 TFile* curFile = gFile;
52 TDirectory* curDirectory = gDirectory;
66 gDirectory = curDirectory;
72 std::cout <<
"CbmBbaAlignTask::Init()" << std::endl;
76 const char* env = std::getenv(
"OMP_NUM_THREADS");
84 LOG(info) <<
"BBA: running with " <<
fNthreads <<
" threads";
89 LOG(info) <<
"BBA: OpenMP not available, running with single thread";
94 FairRootManager* ioman = FairRootManager::Instance();
96 LOG(fatal) <<
"CbmBbaAlignTask: no FairRootManager";
101 fInputStsTracks =
static_cast<TClonesArray*
>(ioman->GetObject(
"StsTrack"));
103 LOG(error) <<
"CbmBbaAlignTask::Init: STS track array not found!";
107 LOG(info) <<
"CbmBbaAlignTask::Init: STS track array found.";
112 fFitter.SetIgnorePoorCoordinates(
true);
115 fFitter.SetIgnoreMultipleScattering(!kMultipleScatteringInTrackSelection);
122 LOG(fatal) <<
"CbmBbaAlignTask::Init: STS RecoSetupUnit not found! Initialize "
123 "CbmSetup::Instance()->LoadSetup(setup) before running the alignment task.";
128 LOG(info) <<
"CbmBbaAlignTask::Init: Number of STS tracking stations from interface: " <<
fNtrackingStations;
136 std::cout <<
"CbmBbaAlignTask::Exec()" << std::endl;
138 LOG(info) <<
"BBA: exec event N " <<
fNevents;
141 LOG(info) <<
"CbmBbaAlignTask::Exec: STS track array found with size: " <<
fInputStsTracks->GetEntries();
152 std::cout <<
"CbmBbaAlignTask::Finish()" << std::endl;
153 LOG(info) <<
"BBA: start the global alignment procedure with " <<
fTracks.size() <<
" tracks ...";
167 LOG(debug) <<
"\n Sensors: ";
168 for (
unsigned int is = 0; is <
fSensors.size(); is++) {
170 LOG(debug) <<
"Sensor " << is <<
" sys " << s.fSystemId <<
" sta " << s.fTrackingStation <<
" body "
173 LOG(info) <<
"\n Alignment bodies: ";
176 LOG(info) <<
"Body: " << ib <<
" station: " << b.GetTrackingStation();
184 LOG(info) <<
"no simulated misalignment";
194 alignment.setParameters(par);
195 alignment.setChi2([
this](
const std::vector<double>& p) {
return CostFunction(p); });
196 alignment.printInfo();
204 LOG(debug) <<
"calculate initial cost function first time ...";
209 unsigned tracks_rejected = 0;
210 for (
unsigned int itr = 0; itr < tracksCopy.size(); itr++) {
211 auto& t = tracksCopy[itr];
212 double ndf = t.fFittedTrackParam.GetNdf();
213 double chi2 = t.fFittedTrackParam.GetChiSq();
214 if (ndf < 0. || chi2 < 0. || !std::isfinite(ndf) || !std::isfinite(chi2)) {
215 fTracks[itr].fIsActive =
false;
219 LOG(info) <<
"reject " << tracks_rejected <<
" bad tracks and recalculate the initial cost function...";
230 LOG(debug) <<
"calculate ideal cost function second time...";
234 LOG(info) <<
"BBA: start the alignment procedure ...";
237 LOG(info) <<
" Cost function for the true parameters: " <<
fCostIdeal;
238 LOG(info) <<
" Cost function for the initial parameters: " <<
fCostInitial;
246 LOG(info) <<
"BBA: alignment procedure finished ...";
249 LOG(info) <<
"BBA: alignment results: ";
250 LOG(info) <<
" aligned parameters: " <<
PrintParameters(alignment.getResult());
252 LOG(info) <<
" RMSE to MC parameters: " <<
PrintRMSE(par,
fParMC, alignment.getResult());
253 LOG(info) <<
" Number of cost function calls: " <<
fNcallsCost;
254 LOG(info) <<
" Cost function for the initial parameters: " <<
fCostInitial;
255 LOG(info) <<
" Cost function for the true parameters: " <<
fCostIdeal;
256 LOG(info) <<
" Cost function for the final parameters: " << costResult
257 <<
", diff to true cost: " << costResult -
fCostIdeal
258 <<
", diff to initial cost: " << costResult -
fCostInitial;
267 LOG(info) <<
"BBA: creating alignment matrices for the output ...";
272 if (misalignmentMatrixRootfile->IsOpen()) {
273 gDirectory->WriteObject(&alignmentMatrices,
"AlignmentMatrices");
274 misalignmentMatrixRootfile->Write();
275 misalignmentMatrixRootfile->Close();
279 TDirectory* curr = gDirectory;
280 TFile* currentFile = gFile;
298 unsigned num_accepted = 0;
299 unsigned num_rejected_create_failed = 0;
300 unsigned num_rejected_fit = 0;
301 unsigned num_rejected_hitNumber = 0;
302 unsigned num_rejected_infiniteQp = 0;
303 unsigned num_rejected_momentum = 0;
304 unsigned num_fix_rad_max = 0;
305 unsigned num_fix_rad_min = 0;
306 unsigned num_rejected_fit_node = 0;
307 unsigned num_rejected_traj = 0;
308 int numPosMomentum = 0;
309 int numNegMomentum = 0;
314 for (
int iTr = 0; iTr < inputTracks->GetEntriesFast(); iTr++) {
321 num_rejected_create_failed++;
340 num_rejected_hitNumber++;
343 if (!std::isfinite(par.GetQp())) {
344 num_rejected_infiniteQp++;
347 if (fabs(par.GetQp()) > 3) {
348 num_rejected_momentum++;
357 num_rejected_fit_node++;
360 if (n.radThick > 0.01) {
361 LOG(debug) <<
"CbmBbaAlignTask: radiation thickness is too large: " << n.radThick;
365 if (n.radThick < 0.001) {
366 LOG(debug) <<
"CbmBbaAlignTask: radiation thickness is too small: " << n.radThick;
376 const double cutX = 8.;
377 const double cutY = 8.;
385 t_copy.DisableMeasurementAtNode(i);
386 if (!
fFitter.FitTrajectory(t_copy)) {
391 double x_residual = n.measurementXY.X() - n.paramDn.X();
392 double y_residual = n.measurementXY.Y() - n.paramDn.Y();
393 double x_pull = x_residual /
sqrt(n.measurementXY.Dx2() + n.paramDn.GetCovariance(0, 0));
394 double y_pull = y_residual /
sqrt(n.measurementXY.Dy2() + n.paramDn.GetCovariance(1, 1));
395 if (!n.isFitted || (n.measurementXY.NdfX() > 0. && fabs(x_pull) > cutX)
396 || (n.measurementXY.NdfY() > 0. && fabs(y_pull) > cutY)) {
406 Tracks.back().StoreOriginalHitPositions();
407 if (par.GetQp() > 0.) {
418 if (num_rejected_create_failed != 0) {
419 LOG(warn) <<
"failed to create " << num_rejected_create_failed <<
" tracks";
421 if (num_rejected_fit != 0) {
422 LOG(warn) <<
"failed to fit " << num_rejected_fit <<
" tracks";
424 if (num_rejected_hitNumber != 0) {
425 LOG(info) <<
"rejected " << num_rejected_hitNumber <<
" tracks for insufficient number of hits";
427 if (num_rejected_infiniteQp != 0) {
428 LOG(warn) <<
"rejected " << num_rejected_infiniteQp <<
" tracks for infinite Q/p";
430 if (num_rejected_momentum != 0) {
431 LOG(info) <<
"rejected " << num_rejected_momentum <<
" tracks for low momentum";
433 if (num_fix_rad_max != 0) {
434 LOG(warn) <<
"CbmBbaAlignTask: radiation thickness is too large " << num_fix_rad_max <<
" times";
436 if (num_fix_rad_min != 0) {
437 LOG(warn) <<
"CbmBbaAlignTask: radiation thickness is too small " << num_fix_rad_min <<
" times";
439 if (num_rejected_fit_node != 0) {
440 LOG(warn) <<
"Rejected fit node " << num_rejected_fit_node <<
" tracks";
442 if (num_rejected_traj != 0) {
443 LOG(warn) <<
"Rejected " << num_rejected_traj <<
" tracks for hits deviating from the trajectory";
446 LOG(info) <<
"BBA: selected " << num_accepted <<
" (" << Tracks.size() <<
" total) tracks for alignment, "
447 << numPosMomentum <<
" positive and " << numNegMomentum <<
" negative momentum tracks";
457 std::set<Sensor> sensorSet;
460 for (
auto& n : t.fTrack.GetNodes()) {
468 if (n.materialLayer < 0) {
469 LOG(fatal) <<
"CbmBbaAlignTask::SensorsFromTracks: negative material layer in track node! for "
480 std::vector<Sensor> sensors(sensorSet.begin(), sensorSet.end());
483 std::sort(sensors.begin(), sensors.end(), [](
const Sensor& a,
const Sensor& b) { return a < b; });
485 LOG(info) <<
"BBA: found " << sensors.size() <<
" sensors used by selected tracks:";
492 std::vector<Sensor>& sensors)
const
494 std::vector<cbm::bba::AlignmentBody> alignmentBodies;
503 case 0: z = -14.;
break;
504 case 1: z = -4.;
break;
505 case 2: z = 6.;
break;
506 case 3: z = 16.;
break;
507 case 4: z = 26.;
break;
508 case 5: z = 36.;
break;
509 case 6: z = 46.;
break;
510 case 7: z = 56.;
break;
511 default: z = 0.;
break;
514 alignmentBodies.back().SetTrackingStation(i);
516 for (
auto& s : sensors) {
517 s.fAlignmentBody = s.fTrackingStation;
521 alignmentBodies.clear();
522 alignmentBodies.reserve(sensors.size());
524 for (
unsigned int i = 0; i < sensors.size(); i++) {
525 auto& s = sensors[i];
527 s.fAlignmentBody = i;
528 alignmentBodies.back().SetTrackingStation(s.fTrackingStation);
533 return alignmentBodies;
542 for (
unsigned int i = 0; i < t.fTrack.GetNofNodes(); i++) {
543 const auto& n = t.fTrack.GetNode(i);
550 if (n.materialLayer < 0) {
551 LOG(fatal) <<
"CbmBbaAlignTask::SetReferences: negative material layer in track node! for "
560 std::lower_bound(sensors.begin(), sensors.end(), s, [](
const Sensor& a,
const Sensor& b) { return a < b; });
561 assert(iter != sensors.end());
563 int iSensor = std::distance(sensors.begin(), iter);
564 t.fTrack.SetSensorId(i, iSensor);
565 t.fTrack.SetAlignmentBodyId(i,
566 sensors.at(iSensor).fAlignmentBody);
574 std::vector<bba::Parameter> par(nParameters);
577 for (
int ip = 0; ip < nParameters; ip++) {
578 bba::Parameter& p = par[ip];
582 if (ip % kNdfBody < 3) {
590 if (ip % kNdfBody < 3) {
605 if (b.GetTrackingStation() == 0) {
606 par[kNdfBody * ib + 0].SetActive(0);
607 par[kNdfBody * ib + 1].SetActive(0);
608 par[kNdfBody * ib + 2].SetActive(0);
609 par[kNdfBody * ib + 3].SetActive(0);
610 par[kNdfBody * ib + 4].SetActive(0);
611 par[kNdfBody * ib + 5].SetActive(0);
615 par[kNdfBody * ib + 0].SetActive(0);
616 par[kNdfBody * ib + 1].SetActive(0);
617 par[kNdfBody * ib + 2].SetActive(0);
618 par[kNdfBody * ib + 3].SetActive(0);
619 par[kNdfBody * ib + 4].SetActive(0);
620 par[kNdfBody * ib + 5].SetActive(0);
623 if (b.GetTrackingStation() == 4) {
624 par[kNdfBody * ib + 0].SetActive(0);
625 par[kNdfBody * ib + 1].SetActive(0);
626 par[kNdfBody * ib + 2].SetActive(0);
627 par[kNdfBody * ib + 3].SetActive(0);
628 par[kNdfBody * ib + 4].SetActive(0);
629 par[kNdfBody * ib + 5].SetActive(0);
639 for (
unsigned int i = 0; i < par.size(); i++) {
646 const std::vector<double>& par2)
const
648 if (par1.size() != par2.size()) {
649 LOG(fatal) <<
"CbmBbaAlignTask::DiffParameters: parameter vectors have different sizes!";
651 std::vector<double> diff(par1.size(), 0.);
652 for (
unsigned int i = 0; i < par1.size(); i++) {
653 diff[i] = par1[i] - par2[i];
660 std::stringstream ss;
661 ss <<
"BBA: alignment parameters:";
664 ss <<
"\nBody " << is <<
" sta " << b.GetTrackingStation() <<
": x " << std::setprecision(10)
665 << par[kNdfBody * is + 0] <<
" y " << par[kNdfBody * is + 1] <<
" z " << par[kNdfBody * is + 2]
666 <<
" alpha: " << par[kNdfBody * is + 3] <<
" beta: " << par[kNdfBody * is + 4]
667 <<
" gamma: " << par[kNdfBody * is + 5];
673 const std::vector<double>& parValues)
const
675 std::vector<double> rmse(kNdfBody, 0.);
676 std::vector<unsigned int> active(kNdfBody, 0);
678 unsigned int indexX = kNdfBody * is + 0;
679 unsigned int indexY = kNdfBody * is + 1;
680 unsigned int indexZ = kNdfBody * is + 2;
681 unsigned int indexA = kNdfBody * is + 3;
682 unsigned int indexB = kNdfBody * is + 4;
683 unsigned int indexC = kNdfBody * is + 5;
684 if (par[indexX].IsActive()) {
685 double dx = parValues[indexX] - parMC[indexX];
689 if (par[indexY].IsActive()) {
690 double dy = parValues[indexY] - parMC[indexY];
694 if (par[indexZ].IsActive()) {
695 double dz = parValues[indexZ] - parMC[indexZ];
699 if (par[indexA].IsActive()) {
700 double da = parValues[indexA] - parMC[indexA];
704 if (par[indexB].IsActive()) {
705 double db = parValues[indexB] - parMC[indexB];
709 if (par[indexC].IsActive()) {
710 double dc = parValues[indexC] - parMC[indexC];
715 for (
unsigned int i = 0; i < kNdfBody; i++) {
716 rmse[i] =
sqrt(rmse[i] / active[i]);
718 std::stringstream ss;
719 ss <<
"BBA: RMSE of alignment parameters:";
720 for (
unsigned int i = 0; i < kNdfBody; i++) {
721 const char* label =
"xyzabc";
722 ss <<
"\n" << label[i] <<
": " << std::setprecision(10) << rmse[i] <<
" (" << active[i] <<
" active)";
728 std::vector<TrackContainer>&
tracks,
729 std::vector<cbm::bba::AlignmentBody>& AlignmentBodies)
const
733 double dRot = d * shiftToRotFactor;
734 std::vector<double> par_misaligned(kNdfBody * AlignmentBodies.size(), 0.);
736 for (
unsigned int is = 0; is < AlignmentBodies.size(); is++) {
737 const bba::Parameter& px = par[kNdfBody * is + 0];
738 const bba::Parameter& py = par[kNdfBody * is + 1];
739 const bba::Parameter& pz = par[kNdfBody * is + 2];
740 const bba::Parameter& pa = par[kNdfBody * is + 3];
741 const bba::Parameter& pb = par[kNdfBody * is + 4];
742 const bba::Parameter& pc = par[kNdfBody * is + 5];
746 par_misaligned.at(kNdfBody * is + 0) = gRandom->Uniform(2. * d) - d;
749 par_misaligned.at(kNdfBody * is + 1) = gRandom->Uniform(2. * d) - d;
752 par_misaligned.at(kNdfBody * is + 2) = gRandom->Uniform(2. * d) - d;
755 par_misaligned.at(kNdfBody * is + 3) = gRandom->Uniform(2. * (dRot)) - (dRot);
758 par_misaligned.at(kNdfBody * is + 4) = gRandom->Uniform(2. * (dRot)) - (dRot);
761 par_misaligned.at(kNdfBody * is + 5) = gRandom->Uniform(2. * (dRot)) - (dRot);
768 t.StoreOriginalHitPositions();
770 return par_misaligned;
775 TDirectory* curDirectory = gDirectory;
779 for (
int i = -1; i < nHistos; i++) {
780 const char* histName = Form(
"Station%d", i);
781 const char* histTitle = Form(
", Station %d", i);
784 histTitle =
", all Stations";
796 Form(
"%s_X_Res_BeforeAli", histName), Form(
"X-Residuals Before Alignment%s", histTitle), nBins, -sizeRX, sizeRX));
798 Form(
"%s_Y_Res_BeforeAli", histName), Form(
"Y-Residuals Before Alignment%s", histTitle), nBins, -sizeRY, sizeRY));
801 Form(
"%s_X_Pull_BeforeAli", histName), Form(
"X-Pulls Before Alignment%s", histTitle), nBins, -sizePX, sizePX));
803 Form(
"%s_Y_Pull_BeforeAli", histName), Form(
"Y-Pulls Before Alignment%s", histTitle), nBins, -sizePY, sizePY));
807 Form(
"%s_X_Res_AfterAli", histName), Form(
"X-Residuals After Alignment%s", histTitle), nBins, -sizeRX, sizeRX));
809 Form(
"%s_Y_Res_AfterAli", histName), Form(
"Y-Residuals After Alignment%s", histTitle), nBins, -sizeRY, sizeRY));
812 Form(
"%s_X_Pull_AfterAli", histName), Form(
"X-Pulls After Alignment%s", histTitle), nBins, -sizePX, sizePX));
814 Form(
"%s_Y_Pull_AfterAli", histName), Form(
"Y-Pulls After Alignment%s", histTitle), nBins, -sizePY, sizePY));
817 for (
int i = 0; i < nHistos + 1; i++) {
836 gDirectory = curDirectory;
841 if (!obj->IsFolder())
844 TDirectory* cur = gDirectory;
845 TFile* currentFile = gFile;
847 TDirectory* sub = cur->GetDirectory(obj->GetName());
849 TList* listSub = (
dynamic_cast<TDirectory*
>(obj))->GetList();
851 while (TObject* obj1 = it()) {
863 for (
const auto& t :
tracks) {
864 if (!t.fIsActive)
continue;
865 for (
unsigned int in = 0; in < t.fTrack.GetNofNodes(); in++) {
868 const auto& node = tr.GetNode(in);
872 tr.DisableMeasurementAtNode(in);
876 if (!node.isFitted) {
882 double x_residual = node.measurementXY.X() - node.paramDn.X();
883 double y_residual = node.measurementXY.Y() - node.paramDn.Y();
884 double x_pull = x_residual /
sqrt(node.measurementXY.Dx2() + node.paramDn.GetCovariance(0, 0));
885 double y_pull = y_residual /
sqrt(node.measurementXY.Dy2() + node.paramDn.GetCovariance(1, 1));
887 if (node.measurementXY.NdfX() > 0) {
889 histo.
fPullsX[0]->Fill(x_pull);
891 if (node.measurementXY.NdfY() > 0) {
893 histo.
fPullsY[0]->Fill(y_pull);
897 histo.
fResidualsX[alignmentBody + 1]->Fill(x_residual);
898 histo.
fResidualsY[alignmentBody + 1]->Fill(y_residual);
900 histo.
fPullsX[alignmentBody + 1]->Fill(x_pull);
901 histo.
fPullsY[alignmentBody + 1]->Fill(y_pull);
907 std::vector<cbm::bba::AlignmentBody>& AlignmentBodies)
const
910 for (
unsigned int ib = 0; ib < AlignmentBodies.size(); ib++) {
911 double dx = par[kNdfBody * ib + 0];
912 double dy = par[kNdfBody * ib + 1];
913 double dz = par[kNdfBody * ib + 2];
914 double da = par[kNdfBody * ib + 3];
915 double db = par[kNdfBody * ib + 4];
916 double dc = par[kNdfBody * ib + 5];
917 AlignmentBodies[ib].SetParameters(dx, dy, dz, da, db, dc);
922 std::vector<cbm::bba::AlignmentBody>& AlignmentBodies,
bool invert =
false)
const
927 for (
unsigned int in = 0; in < t.fTrack.GetNofNodes(); in++) {
928 auto& node = t.fTrack.GetNodeReference(in);
934 if (AlignmentBodyIdx < 0) {
935 LOG(fatal) <<
"BBA: ApplyAlignment: node has no alignment body! ";
938 std::array<double, 3> alignedHit;
940 alignedHit = AlignmentBodies[AlignmentBodyIdx].ApplyAlignmentToHit(t.fOriginalHitPositions[in]);
943 alignedHit = AlignmentBodies[AlignmentBodyIdx].ApplyInverseAlignmentToHit(t.fOriginalHitPositions[in]);
947 double dz = alignedHit[2] - node.z;
949 node.measurementXY.SetX(alignedHit[0]);
950 node.measurementXY.SetY(alignedHit[1]);
951 node.z = alignedHit[2];
955 auto& p = node.paramDn;
956 p.SetX(p.X() + p.Tx() * dz);
957 p.SetY(p.Y() + p.Ty() * dz);
961 auto& p = node.paramUp;
962 p.SetX(p.X() + p.Tx() * dz);
963 p.SetY(p.Y() + p.Ty() * dz);
980 double chi2Total = 0.;
986#pragma omp parallel for firstprivate(fit) reduction(+ : chi2Total, ndfTotal) num_threads(fNthreads)
987 for (
unsigned int itr = 0; itr <
tracks.size(); itr++) {
989 if (!t.fIsActive)
continue;
993 for (
unsigned int in = 0; in < t.fTrack.GetNofNodes(); in++) {
994 const auto& node = t.fTrack.GetNode(in);
995 if (!node.isFitted) {
996 LOG(fatal) <<
"BBA: Cost function: aligned node is not fitted! ";
1000 double chi2 = t.fFittedTrackParam.GetChiSq();
1001 double ndf = t.fFittedTrackParam.GetNdf();
1002 if (!ok || !std::isfinite(chi2) || chi2 <= 0. || ndf <= 0.) {
1004 LOG(fatal) <<
"BBA: fit failed! ";
1009 ndfTotal += (int) ndf;
1012 double cost = chi2Total / (ndfTotal + 1);
1019 LOG(info) <<
"Cost function called " <<
fNcallsCost <<
" times, current cost: " << cost
1020 <<
", diff to ideal cost: " << cost -
fCostIdeal <<
", ndf: " << ndfTotal <<
", chi2: " << chi2Total;
1030 double shiftZ,
double rotX,
double rotY,
1034 LOG(fatal) <<
"Alignment node path is empty!";
1036 if (path[0] !=
'/') {
1042 TGeoHMatrix alignmentMatrix;
1043 alignmentMatrix.SetDx(shiftX);
1044 alignmentMatrix.SetDy(shiftY);
1045 alignmentMatrix.SetDz(shiftZ);
1046 alignmentMatrix.RotateX(rotX);
1047 alignmentMatrix.RotateY(rotY);
1048 alignmentMatrix.RotateZ(rotZ);
1051 if (!gGeoManager->cd(path.c_str())) {
1052 LOG(fatal) <<
"Failed to cd to path " << path;
1054 const TGeoNode* node = gGeoManager->GetCurrentNode();
1056 LOG(fatal) <<
"Failed to find TGeoNode at path " << path;
1058 TGeoHMatrix nominalGlobal = *(gGeoManager->GetCurrentMatrix());
1059 TGeoHMatrix alignedGlobal =
1064 gGeoManager->CdUp();
1065 TGeoHMatrix motherGlobal = *(gGeoManager->GetCurrentMatrix());
1068 TGeoHMatrix alignedLocal = motherGlobal.Inverse() * alignedGlobal;
1072 TGeoHMatrix origLocal = *node->GetMatrix();
1076 TObjArray* pNodes = gGeoManager->GetListOfPhysicalNodes();
1077 for (
int i = 0; i < pNodes->GetEntriesFast(); i++) {
1078 const TGeoPhysicalNode* pnode =
dynamic_cast<const TGeoPhysicalNode*
>(pNodes->At(i));
1079 if (pnode->GetNode() == node) {
1082 origLocal = *pnode->GetOriginalMatrix();
1087 LOG(debug) <<
"Failed to find physical node for node " << path;
1090 LOG(debug) <<
"Found physical node for node " << path;
1096 TGeoHMatrix alignmentLocal = alignedLocal * origLocal.Inverse();
1097 alignmentLocal.SetName(
"aligned with bba (local)");
1098 origLocal.SetName(
"original local matrix of sensor");
1099 alignmentMatrix.SetName(
"alignment matrix (global)");
1101 if (fair::Logger::GetConsoleSeverity() == fair::Severity::debug) {
1102 LOG(debug) <<
"Write alignment matrix for the node " << path <<
":";
1103 alignmentMatrix.Print();
1105 alignmentLocal.Print();
1108 return {path, alignmentLocal};
1115 std::map<std::string, TGeoHMatrix> alignmentMatrices;
1118 int i = s.fAlignmentBody;
1120 if (i < 0)
continue;
1121 if (s.fNodePath.empty())
continue;
1122 alignmentMatrices.insert(
CreateAlignmentNode(s.fNodePath, par[i * kNdfBody + 0], par[i * kNdfBody + 1],
1123 par[i * kNdfBody + 2], 0., 0., 0.));
1125 return alignmentMatrices;
1137 for (
const auto& n :
fTrack.GetNodes()) {
1153 for (
const auto& n :
fTrack.GetNodes()) {
Task class for alignment.
Alignment body class for the BBA alignment.
@ kMvd
Micro-Vertex Detector.
@ kTrd
Transition Radiation Detector.
@ kTof
Time-of-flight Detector.
@ kSts
Silicon Tracking System.
@ kTrd2d
TRD-FASP Detector (FIXME)
@ kMuch
Muon detection system.
friend fvec sqrt(const fvec &a)
static int GetAlignmentBodyId(const Node &node)
std::vector< double > fParStart
std::vector< cbm::bba::AlignmentBody > CreateAndSetAlignmentBodies(AlignmentMode mode, std::vector< Sensor > &sensors) const
TClonesArray * fInputStsTracks
void ApplyAlignment(const std::vector< double > &par, std::vector< TrackContainer > &tracks, std::vector< cbm::bba::AlignmentBody > &AlignmentBodies, bool invert) const
double CostFunction(const std::vector< double > &par, std::vector< TrackContainer > &tracks)
std::vector< bba::Parameter > CreateAlignmentParameters() const
std::vector< double > fParMC
std::vector< Sensor > fSensors
TString fMatrixOutFileName
unsigned SelectTracks(TClonesArray *inputTracks, std::vector< TrackContainer > &tracks)
void SetAlignment(const std::vector< double > &par, std::vector< cbm::bba::AlignmentBody > &AlignmentBodies) const
std::vector< double > InvertParameters(std::vector< double > par) const
AlignmentMode fAlignmentMode
std::vector< double > DiffParameters(const std::vector< double > &par1, const std::vector< double > &par2) const
Histograms fHistoBeforeAlignment
std::string PrintParameters(const std::vector< double > &par) const
void SetReferences(const std::vector< Sensor > &sensors, std::vector< TrackContainer > &tracks) const
std::vector< double > SimulateMisalignment(const std::vector< bba::Parameter > &par, std::vector< TrackContainer > &tracks, std::vector< cbm::bba::AlignmentBody > &AlignmentBodies) const
std::vector< TrackContainer > fTracks
std::vector< cbm::bba::AlignmentBody > fAlignmentBodies
void InitializeHistograms()
std::pair< std::string, TGeoHMatrix > CreateAlignmentNode(std::string path, double shiftX, double shiftY, double shiftZ, double rotX, double rotY, double rotZ) const
CbmKfTrackFitter< cbm::algo::kf::DoFitTime::N > fFitter
double fSimulatedMisalignmentRange
CbmBbaAlignTask(const char *name="CbmBbaAlignTask", Int_t iVerbose=0, TString histoFileName="./CbmBbaAlignmentHisto.root", size_t nMaxTracks=1000)
void WriteObjectsCurFile(TObject *obj)
void FillHistograms(const std::vector< TrackContainer > &tracks, Histograms &histo)
std::map< std::string, TGeoHMatrix > CreateAlignmentMatrices(const std::vector< double > &par) const
Histograms fHistoAfterAlignment
std::string PrintRMSE(const std::vector< bba::Parameter > &par, const std::vector< double > &parMC, const std::vector< double > &parValues) const
std::vector< Sensor > SensorsFromTracks(const std::vector< TrackContainer > &tracks) const
static ECbmModuleId GetHitSystemId(const Node &node)
static int GetHitAddress(const Node &node)
bool FitTrajectoryUpstream(const cbm::algo::kf::Trajectory< double > &t, cbm::algo::kf::TrackParamD &parUp)
fit the trajectory upstream and return the track parameters at the first measurement node
void SetIgnoreMultipleScattering(bool ignore=true)
ignore the multiple scattering effects in the fit
const algo::RecoSetup & GetSetup() const
Setup accessor.
static RecoSetupManager * Instance()
Instance access.
std::shared_ptr< const GeoNodeMap > GetGeoNodeMap() const
Access to geo node map.
const sts::RecoSetupUnit * GetSts() const
Access to STS reconstruction setup unit.
size_t GetNofNodes() const
Get number of nodes on the trajectory.
Node & GetNodeReference(const size_t index)
Get reference to the node by its index.
const Node & GetNode(const size_t index) const
Get const reference to the node by its index.
alignment body accessor and property handler
std::vector< std::unique_ptr< TH1F > > fResidualsY
std::vector< std::unique_ptr< TH1F > > fPullsY
std::vector< std::unique_ptr< TH1F > > fResidualsX
std::vector< std::unique_ptr< TH1F > > fPullsX
cbm::algo::kf::TrackParamD fFittedTrackParam
std::vector< std::array< double, 3 > > fOriginalHitPositions
void StoreOriginalHitPositions()