18#include "FairRootManager.h"
19#include "FairRunAna.h"
20#include "TClonesArray.h"
22#include "TGeoPhysicalNode.h"
43#include "TGeoPhysicalNode.h"
55std::pair<std::string, TGeoHMatrix>
AlignNode(std::string path,
double shiftX,
double shiftY,
double shiftZ,
56 double rotX,
double rotY,
double rotZ)
71 return std::pair<std::string, TGeoHMatrix>(path, result);
83 switch (n.fHitSystemId) {
97 : FairTask(name, iVerbose)
100 TFile* curFile = gFile;
101 TDirectory* curDirectory = gDirectory;
116 gDirectory = curDirectory;
127 const char* env = std::getenv(
"OMP_NUM_THREADS");
130 LOG(info) <<
"BBA: found environment variable OMP_NUM_THREADS = \"" << env
147 FairRootManager* ioman = FairRootManager::Instance();
150 LOG(error) <<
"CbmBbaAlignmentTask::Init :: RootManager not instantiated!";
160 LOG(error) <<
"CbmBbaAlignmentTask::Init: Global track array not found!";
167 LOG(error) <<
"CbmBbaAlignmentTask::Init: Global track matches array not found!";
172 fInputStsTracks =
static_cast<TClonesArray*
>(ioman->GetObject(
"StsTrack"));
174 LOG(error) <<
"CbmBbaAlignmentTask::Init: Sts track array not found!";
181 LOG(error) <<
"CbmBbaAlignmentTask::Init: Sts track matches array not found!";
186 fInputMcTracks =
static_cast<TClonesArray*
>(ioman->GetObject(
"MCTrack"));
188 Warning(
"CbmBbaAlignmentTask::Init",
"mc track array not found!");
201 TDirectory* curDirectory = gDirectory;
206 const char* n1 = Form(
"Station%d", i);
207 const char* n2 = Form(
", station %d", i);
234 if (i == 0 || i == 1) {
259 new TH1F(Form(
"ResBeforeAli%s_X", n1), Form(
"X-Residuals Before Alignment%s", n2), nBins, -sizeX, sizeX));
261 new TH1F(Form(
"ResBeforeAli%s_Y", n1), Form(
"Y-Residuals Before Alignment%s", n2), nBins, -sizeY, sizeY));
263 new TH1F(Form(
"ResAfterAli%s_X", n1), Form(
"X-Residuals After Alignment%s", n2), nBins, -sizeX, sizeX));
265 new TH1F(Form(
"ResAfterAli%s_Y", n1), Form(
"Y-Residuals After Alignment%s", n2), nBins, -sizeY, sizeY));
268 new TH1F(Form(
"PullBeforeAli%s_X", n1), Form(
"X-Pulls Before Alignment%s", n2), nBins, -sizePX, sizePX));
270 new TH1F(Form(
"PullBeforeAli%s_Y", n1), Form(
"Y-Pulls Before Alignment%s", n2), nBins, -sizePY, sizePY));
272 new TH1F(Form(
"PullAfterAli%s_X", n1), Form(
"X-Pulls After Alignment%s", n2), nBins, -sizePX, sizePX));
274 new TH1F(Form(
"PullAfterAli%s_Y", n1), Form(
"Y-Pulls After Alignment%s", n2), nBins, -sizePY, sizePY));
284 gDirectory = curDirectory;
292 LOG(info) <<
"BBA: exec event N " <<
fNEvents;
306 unsigned num_rejected_fit = 0;
316 if (!stsTrack)
continue;
322 n.fIsTimeSet =
false;
330 LOG(debug) <<
"failed to fit the track! ";
338 if (!std::isfinite(par.GetQp()))
continue;
339 if (fabs(par.GetQp()) > 1.)
continue;
356 LOG(fatal) <<
"BBA: null pointer to the global track!";
361 LOG(fatal) <<
"BBA: can not create the global track for the fit! ";
367 n.fIsTimeSet =
false;
369 if (n.fMxy.Dx2() < n.fMxy.Dy2()) {
382 LOG(debug) <<
"failed to fit the track! ";
391 if (num_rejected_fit != 0) {
392 LOG(warn) <<
"failed to fit " << num_rejected_fit <<
" tracks";
397 unsigned num_fix_rad_max = 0;
398 unsigned num_fix_rad_min = 0;
399 unsigned num_rejected_fit2 = 0;
401 if (!t.fIsActive)
continue;
402 for (
unsigned int in = 0; in < t.fUnalignedTrack.fNodes.size(); in++) {
411 LOG(debug) <<
"CbmBbaAlignmentTask: radiation thickness is too large: " << node.
fRadThick;
416 LOG(debug) <<
"CbmBbaAlignmentTask: radiation thickness is too small: " << node.
fRadThick;
422 if (num_fix_rad_max != 0) {
423 LOG(warn) <<
"CbmBbaAlignmentTask: radiation thickness is too large " << num_fix_rad_max <<
" times";
425 if (num_fix_rad_min != 0) {
426 LOG(warn) <<
"CbmBbaAlignmentTask: radiation thickness is too small " << num_fix_rad_min <<
" times";
428 if (num_rejected_fit2 != 0) {
429 LOG(warn) <<
"Rejected fit 2 " << num_rejected_fit2 <<
" tracks";
434 unsigned num_rejected_traj = 0;
436 if (!t.fIsActive)
continue;
437 const double cutX = 8.;
438 const double cutY = 8.;
439 for (
unsigned int in = 0; in < t.fUnalignedTrack.fNodes.size(); in++) {
456 || (node.
fMxy.
NdfY() > 0. && fabs(y_pull) > cutY)) {
463 if (num_rejected_traj != 0) {
464 LOG(warn) <<
"Rejected " << num_rejected_traj <<
" tracks for hits deviating from the trajectory";
467 TClonesArray* inputTracks =
nullptr;
474 static int statTracks = 0;
475 statTracks += inputTracks->GetEntriesFast();
477 unsigned active_tracks = 0;
479 if (t.fIsActive) active_tracks++;
482 LOG(info) <<
"Bba: " << inputTracks->GetEntriesFast() <<
" tracks in event, " << statTracks <<
" tracks in total, "
483 <<
fTracks.size() <<
" tracks selected for alignment, " << active_tracks <<
" tracks active";
495 mean += par[3 * i + ixyz];
503 par[3 * i + ixyz] -= mean;
522 std::vector<double> parConstrained = par;
528 for (
unsigned int in = 0; in < t.fUnalignedTrack.fNodes.size(); in++) {
535 assert(iSensor >= 0 && iSensor < (
int)
fSensors.size());
548 nodeAligned.
fZ = node.
fZ + dz;
553 p.
SetX(p.X() + p.Tx() * dz);
554 p.SetY(p.Y() + p.Ty() * dz);
555 p.SetZ(nodeAligned.
fZ);
559 p.
SetX(p.X() + p.Tx() * dz);
560 p.SetY(p.Y() + p.Ty() * dz);
561 p.SetZ(nodeAligned.
fZ);
566 static int statNCalls = 0;
568 if (statNCalls % 100 == 0) {
569 std::vector<double>& r = parConstrained;
570 LOG(info) <<
"Current parameters: ";
573 LOG(info) <<
"Body " << is <<
" sta " << b.fTrackingStation <<
": x " << r[3 * is + 0] <<
" y " << r[3 * is + 1]
574 <<
" z " << r[3 * is + 2];
585 t.fAlignedTrack = t.fUnalignedTrack;
590 std::vector<double> chi2Thread(
fNthreads, 0.);
591 std::vector<long> ndfThread(
fNthreads, 0);
593 auto fitThread = [&](
int iThread) {
600 if (!t.fIsActive)
continue;
604 for (
unsigned int in = 0; in < t.fAlignedTrack.fNodes.size(); in++) {
607 LOG(fatal) <<
"BBA: Cost function: aligned node is not fitted! ";
611 double chi2 = t.fAlignedTrack.fNodes.back().fParamDn.GetChiSq();
612 double ndf = t.fAlignedTrack.fNodes.back().fParamDn.GetNdf();
613 if (!ok || !std::isfinite(chi2) || chi2 <= 0. || ndf <= 0.) {
615 LOG(fatal) <<
"BBA: fit failed! ";
619 chi2Thread[iThread] += chi2;
620 ndfThread[iThread] += (int) ndf;
624 std::vector<std::thread> threads(
fNthreads);
628 threads[i] = std::thread(fitThread, i);
632 for (
auto& th : threads) {
657 LOG(info) <<
"BBA: start the alignment procedure with " <<
fTracks.size() <<
" tracks ...";
666 std::set<Sensor> sensorSet;
668 for (
auto& n : t.fUnalignedTrack.fNodes) {
686 s.
fNodePath =
"/cave_1/trd_v22h_mcbm_0/layer01_20101/module9_101001001";
689 s.
fNodePath =
"/cave_1/trd_v22h_mcbm_0/layer02_10202/module8_101002001";
692 s.
fNodePath =
"/cave_1/trd_v22h_mcbm_0/layer03_11303/module8_101303001";
704 for (
auto& s : sensorSet) {
710 for (
auto& n : t.fUnalignedTrack.fNodes) {
729 auto iter = std::lower_bound(
733 int iSensor = std::distance(
fSensors.begin(), iter);
734 n.fReference1 = iSensor;
736 t.fAlignedTrack = t.fUnalignedTrack;
747 s.fAlignmentBody = s.fTrackingStation;
754 for (
int unsigned i = 0; i <
fSensors.size(); i++) {
762 LOG(info) <<
"\n Sensors: ";
764 for (
unsigned int is = 0; is <
fSensors.size(); is++) {
766 LOG(info) <<
"Sensor " << is <<
" sys " << s.fSystemId <<
" sta " << s.fTrackingStation <<
" body "
771 LOG(info) <<
"\n Alignment bodies: ";
781 std::vector<bba::Parameter> par(nParameters);
783 for (
int ip = 0; ip < nParameters; ip++) {
784 bba::Parameter& p = par[ip];
787 p.SetBoundaryMin(-20.);
788 p.SetBoundaryMax(20.);
805 par[3 * ib + 0].SetActive(0);
806 par[3 * ib + 1].SetActive(1);
807 par[3 * ib + 2].SetActive(0);
810 par[3 * ib + 0].SetActive(1);
811 par[3 * ib + 1].SetActive(1);
812 par[3 * ib + 2].SetActive(1);
818 int ib = s.fAlignmentBody;
821 for (
int j = 0; j < 3; j++) {
822 bba::Parameter& p = par[ib * 3 + j];
825 p.SetStepMin(10.e-4);
828 p.SetStepMin(10.e-4);
836 bba::Parameter& px = par[3 * is + 0];
837 bba::Parameter& py = par[3 * is + 1];
838 bba::Parameter& pz = par[3 * is + 2];
843 px.SetValue(gRandom->Uniform(2. * d) - d);
846 py.SetValue(gRandom->Uniform(2. * d) - d);
849 pz.SetValue(gRandom->Uniform(2. * d) - d);
854 LOG(info) <<
"STS sensor paths: ";
861 LOG(error) <<
"Element not found: " << s.fSensorId;
867 LOG(info) <<
"Node: ";
875 alignment.setParameters(par);
877 auto lambdaCostFunction = [
this](
const std::vector<double>& p) {
return CostFunction(p); };
879 alignment.setChi2(lambdaCostFunction);
880 alignment.printInfo();
882 std::vector<double> parIdeal;
883 std::vector<double> parMisaligned;
885 const std::vector<double>& r = alignment.getResult();
886 for (
unsigned int i = 0; i < r.size(); i++) {
887 parMisaligned.push_back(r[i]);
888 parIdeal.push_back(0.);
893 std::cout <<
"initial cost function..." << std::endl;
897 unsigned tracks_rejected = 0;
899 double ndf = t.fAlignedTrack.fNodes.back().fParamDn.GetNdf();
900 double chi2 = t.fAlignedTrack.fNodes.back().fParamDn.GetChiSq();
901 if (ndf < 0. || chi2 < 0. || !std::isfinite(ndf) || !std::isfinite(chi2)) {
906 std::cout <<
"reject " << tracks_rejected <<
" bad tracks and recalculate the initial cost function..."
913 for (
const auto& t :
fTracks) {
914 if (!t.fIsActive)
continue;
916 for (
unsigned int in = 0; in < t.fAlignedTrack.fNodes.size(); in++) {
956 std::cout <<
"calculate ideal cost function..." << std::endl;
960 LOG(info) <<
" Cost function for the true parameters: " <<
fCostIdeal;
961 LOG(info) <<
" Cost function for the initial parameters: " <<
fCostInitial;
966 double costResult =
CostFunction(alignment.getResult());
972 std::vector<double> result = alignment.getResult();
973 std::map<std::string, TGeoHMatrix> alignmentMatrices;
976 int i = s.fAlignmentBody;
985 LOG(error) <<
"Element not found: " << s.fSensorId;
989 LOG(info) <<
"Node: ";
990 LOG(info) << n->GetName();
991 alignmentMatrices.insert(
992 AlignNode(n->GetName(), result[i * 3 + 0], result[i * 3 + 1], result[i * 3 + 2], 0., 0., 0.));
996 LOG(info) <<
"Node: ";
997 LOG(info) << s.fNodePath;
998 alignmentMatrices.insert(
999 AlignNode(s.fNodePath, result[i * 3 + 0], result[i * 3 + 1], result[i * 3 + 2], 0., 0., 0.));
1003 LOG(info) <<
"Node: ";
1004 LOG(info) << s.fNodePath;
1005 alignmentMatrices.insert(
1006 AlignNode(s.fNodePath, result[i * 3 + 0], result[i * 3 + 1], result[i * 3 + 2], 0., 0., 0.));
1018 TFile* misalignmentMatrixRootfile =
1019 new TFile(
"AlignmentMatrices_mcbm_beam_2022_05_23_nickel_finetuning.root",
"RECREATE");
1020 if (misalignmentMatrixRootfile->IsOpen()) {
1021 gDirectory->WriteObject(&alignmentMatrices,
"AlignmentMatrices");
1022 misalignmentMatrixRootfile->Write();
1023 misalignmentMatrixRootfile->Close();
1027 LOG(info) <<
" Cost function for the true parameters: " <<
fCostIdeal;
1028 LOG(info) <<
" Cost function for the initial parameters: " <<
fCostInitial;
1029 LOG(info) <<
" Cost function for the aligned parameters: " << costResult;
1031 LOG(info) <<
"\n Misaligned parameters: ";
1033 const std::vector<double>& r = parMisaligned;
1034 LOG(info) <<
"Body " << is <<
": x " << r[3 * is + 0] <<
" y " << r[3 * is + 1] <<
" z " << r[3 * is + 2];
1037 LOG(info) <<
"\n Alignment results: ";
1039 const std::vector<double>& r = alignment.getResult();
1042 LOG(info) <<
"Body " << is <<
" sta " << b.
fTrackingStation <<
": x " << r[3 * is + 0] <<
" y " << r[3 * is + 1]
1043 <<
" z " << r[3 * is + 2];
1049 LOG(info) <<
" Cost function for the true parameters: " <<
fCostIdeal;
1050 LOG(info) <<
" Cost function for the initial parameters: " <<
fCostInitial;
1051 LOG(info) <<
" Cost function for the aligned parameters: " << costResult;
1053 LOG(info) <<
"\n Alignment results, constrained: ";
1055 std::vector<double> r = alignment.getResult();
1059 LOG(info) <<
"Body " << is <<
" sta " << b.
fTrackingStation <<
": x " << r[3 * is + 0] <<
" y " << r[3 * is + 1]
1060 <<
" z " << r[3 * is + 2];
1064 unsigned active_tracks = 0;
1066 if (t.fIsActive) active_tracks++;
1071 LOG(info) <<
"Bba: " <<
fTracks.size() <<
" tracks used for alignment\n";
1072 LOG(info) <<
" " << active_tracks <<
" tracks active\n";
1074 LOG(info) <<
" Cost function for the true parameters: " <<
fCostIdeal;
1075 LOG(info) <<
" Cost function for the initial parameters: " <<
fCostInitial;
1076 LOG(info) <<
" Cost function for the aligned parameters: " << costResult;
1079 if (!t.fIsActive)
continue;
1082 for (
unsigned int in = 0; in < t.fAlignedTrack.fNodes.size(); in++) {
1117 TDirectory* curr = gDirectory;
1118 TFile* currentFile = gFile;
1127 gFile = currentFile;
1133 if (!obj->IsFolder())
1136 TDirectory* cur = gDirectory;
1137 TFile* currentFile = gFile;
1139 TDirectory* sub = cur->GetDirectory(obj->GetName());
1141 TList* listSub = (
static_cast<TDirectory*
>(obj))->GetList();
1143 while (TObject* obj1 = it()) {
1147 gFile = currentFile;
ClassImp(CbmBbaAlignmentTask)
std::pair< std::string, TGeoHMatrix > AlignNode(std::string path, double shiftX, double shiftY, double shiftZ, double rotX, double rotY, double rotZ)
Task class for alignment.
Time-slice/event reader for CA tracker in CBM (header)
@ 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.
Data class for a reconstructed hit in the STS.
Data class for STS tracks.
friend fvec sqrt(const fvec &a)
TClonesArray * fInputGlobalTrackMatches
void WriteHistosCurFile(TObject *obj)
std::vector< TrackContainer > fTracks
TrackingMode fTrackingMode
CbmBbaAlignmentTask(const char *name="CbmBbaAlignmentTask", Int_t iVerbose=0, TString histoFileName="CbmBbaAlignmentHisto.root")
std::vector< TH1F * > hPullsBeforeAlignmentX
TClonesArray * fInputStsTrackMatches
std::vector< TH1F * > hPullsAfterAlignmentX
double fSimulatedMisalignmentRange
TClonesArray * fInputMcTracks
TClonesArray * fInputStsTracks
std::vector< TH1F * > hResidualsAfterAlignmentX
std::vector< AlignmentBody > fAlignmentBodies
std::vector< TH1F * > hPullsBeforeAlignmentY
void ApplyAlignment(const std::vector< double > &par)
void ApplyConstraints(std::vector< double > &par)
TClonesArray * fInputGlobalTracks
std::vector< TH1F * > hResidualsAfterAlignmentY
std::vector< Sensor > fSensors
std::vector< TH1F * > hResidualsBeforeAlignmentX
std::vector< TH1F * > hResidualsBeforeAlignmentY
std::vector< TH1F * > hPullsAfterAlignmentY
double CostFunction(const std::vector< double > &par)
void ConstrainStation(std::vector< double > &par, int iSta, int ixyz)
void SetSkipUnmeasuredCoordinates(bool skip=true)
skip unmeasured coordinates
bool CreateMvdStsTrack(Trajectory &kfTrack, int stsTrackIndex)
set the input data arrays
bool CreateGlobalTrack(Trajectory &kfTrack, int globalTrackIndex)
void FixMomentumForMs(bool fix=true)
fix the inverse momentum for the Multiple Scattering calculation
void SetDefaultMomentumForMs(double p)
set the default inverse momentum for the Multiple Scattering calculation
void SetDoSmooth(bool doSmooth)
do the KF-smoothing to define track pars at all the nodes
bool FitTrajectory(CbmKfTrackFitter::Trajectory &t)
fit the track
void SetNoMultipleScattering()
set the default inverse momentum for the Multiple Scattering calculation
static CbmL1 * Instance()
Pointer to CbmL1 instance.
ca::Framework * fpAlgo
Pointer to the L1 track finder algorithm.
Class representing an element of the STS setup.
TGeoPhysicalNode * GetPnode() const
virtual void Print(Option_t *opt="") const
CbmStsElement * GetElement(Int_t address, Int_t level)
static CbmStsSetup * Instance()
static CbmStsTrackingInterface * Instance()
Gets pointer to the instance of the CbmStsTrackingInterface class.
int GetTrackingStationIndex(const CbmHit *hit) const override
Gets a tracking station of a CbmHit.
static int32_t GetRpcFullId(uint32_t address)
int GetNtrackingStations() const
Gets actual number of stations, provided by the current geometry setup.
const Parameters< fvec > & GetParameters() const
Gets a pointer to the Framework parameters object.
A container for all external parameters of the CA tracking algorithm.
int GetNstationsActive() const
Gets total number of active stations.
T X() const
Gets x position [cm].
T Y() const
Gets y position [cm].
void SetX(T v)
Sets x position [cm].
T GetCovariance(int i, int j) const
Get covariance matrix element.
CbmKfTrackFitter::Trajectory fUnalignedTrack
CbmKfTrackFitter::Trajectory fAlignedTrack
cbm::algo::kf::TrackParamD fParamUp
fitted track parameters upstream the node
double fZ
Z coordinate of the node.
bool fIsFitted
true if the track parameters at the node are fitted
cbm::algo::kf::MeasurementXy< double > fMxy
== Hit information ( if present )
int fReference1
some reference can be set by the user
cbm::algo::kf::TrackParamD fParamDn
fitted track parameters downstream the node
bool fIsXySet
== Flags etc
bool fIsRadThickFixed
true if the radiation thickness is fixed to the fRadThick value
A trajectory to be fitted.
std::vector< TrajectoryNode > fNodes
nodes on the trajectory