7 #include <Math/Point3D.h>
8 #include <Math/Point3Dfwd.h>
9 #include <RKTrackRep.h>
10 #include <TClonesArray.h>
11 #include <TDatabasePDG.h>
12 #include <TGeoManager.h>
13 #include <TGeoMaterial.h>
14 #include <TGeoMaterialInterface.h>
15 #include <TGeoMedium.h>
16 #include <TGeoVolume.h>
18 #include <TMatrixDSymfwd.h>
19 #include <TMatrixDfwd.h>
21 #include <TMatrixTSym.h>
22 #include <TObjArray.h>
26 #include <TrackCand.h>
28 #include <AbsKalmanFitter.h>
29 #include <AbsMeasurement.h>
30 #include <AbsTrackRep.h>
31 #include <ConstField.h>
32 #include <Exception.h>
33 #include <FieldManager.h>
34 #include <FitStatus.h>
35 #include <KalmanFitterRefTrack.h>
36 #include <MaterialEffects.h>
37 #include <MeasuredStateOnPlane.h>
38 #include <MeasurementFactory.h>
39 #include <MeasurementProducer.h>
45 constexpr
auto cRED =
"\033[1;31m";
48 constexpr
auto cGREEN =
"\033[1;32m";
53 Float_t gasMediumDensity, Int_t pdg, Int_t minit, Int_t maxit)
54 : fEnergyLossFile(std::move(eLossFile)),
57 fMeasurementFactory(new
genfit::MeasurementFactory<
genfit::AbsMeasurement>()), fMinIterations(minit),
58 fMaxIterations(maxit), fMinBrho(minbrho), fMaxBrho(maxbrho), fMagneticField(10.0 * magfield), fPDGCode(pdg),
59 fGenfitTrackArray(new TClonesArray(
"genfit::Track")), fHitClusterArray(new TClonesArray(
"AtHitCluster"))
61 fKalmanFitter = std::make_shared<genfit::KalmanFitterRefTrack>();
62 fKalmanFitter->setMinIterations(fMinIterations);
63 fKalmanFitter->setMaxIterations(fMaxIterations);
65 fMeasurementFactory->addProducer(fTPCDetID, fMeasurementProducer);
67 genfit::FieldManager::getInstance()->init(
new genfit::ConstField(0., 0., fMagneticField));
68 genfit::MaterialEffects *materialEffects = genfit::MaterialEffects::getInstance();
69 materialEffects->setEnergyLossBrems(
false);
70 materialEffects->setNoiseBrems(
false);
71 materialEffects->useEnergyLossParam();
72 materialEffects->init(
new genfit::TGeoMaterialInterface());
74 materialEffects->setGasMediumDensity(gasMediumDensity);
75 materialEffects->setEnergyLossFile(fEnergyLossFile, fPDGCode);
80 std::cout <<
" AtFITTER::AtGenfit::AtGenfit(): Checking materials that GENFIT will use "
83 auto *gGeoMan =
dynamic_cast<TGeoManager *
>(gROOT->FindObject(
"FAIRGeom"));
84 TObjArray *volume_list = gGeoMan->GetListOfVolumes();
86 std::cout <<
cRED <<
" Warning! Null list of geometry volumes." <<
cNORMAL <<
"\n";
89 int numVol = volume_list->GetEntries();
91 for (
int ivol = 0; ivol < numVol; ivol++) {
92 auto *volume =
dynamic_cast<TGeoVolume *
>(volume_list->At(ivol));
95 std::cout <<
"Got a null geometry volume!! Skipping current list element"
100 std::cout <<
cGREEN <<
" Volume name : " << volume->GetName() <<
cNORMAL <<
"\n";
102 TGeoMaterial *mat = volume->GetMedium()->GetMaterial();
105 std::cout <<
cYELLOW <<
" - Material : " << mat->GetName() <<
cNORMAL <<
"\n";
109 const Double_t kAu2Gev = 0.9314943228;
110 const Double_t khSlash = 1.0545726663e-27;
111 const Double_t kErg2Gev = 1 / 1.6021773349e-3;
112 const Double_t khShGev = khSlash * kErg2Gev;
113 const Double_t kYear2Sec = 3600 * 24 * 365.25;
115 TDatabasePDG *db = TDatabasePDG::Instance();
116 db->AddParticle(
"Deuteron",
"Deuteron", 1.875612928, kTRUE, 0, 3,
"Ion", 1000010020);
117 db->AddParticle(
"Triton",
"Triton", 2.80943211, kFALSE, khShGev / (12.33 * kYear2Sec), 3,
"Ion", 1000010030);
118 db->AddParticle(
"Alpha",
"Alpha", 3.7284, kTRUE, 0, 6,
"Ion", 1000020040);
119 db->AddParticle(
"He3",
"He3", 2.80941352, kTRUE, 0, 6,
"Ion", 1000020030);
120 db->AddParticle(
"He6",
"He6", 5.60655972, kFALSE, khShGev / 0.806, 6,
"Ion", 1000020060);
121 db->AddParticle(
"Be10",
"Be10", 9.3275477, kFALSE, khShGev / (1.51E6 * kYear2Sec), 12,
"Ion", 1000040100);
122 db->AddParticle(
"Be11",
"Be11", 10.2666092, kFALSE, khShGev / (13.76), 12,
"Ion", 1000040110);
123 db->AddParticle(
"C12",
"C12", 11.18, kTRUE, 0, 18,
"Ion", 1000060120);
124 db->AddParticle(
"O16",
"O16", 14.8991686, kTRUE, 0, 24,
"Ion", 1000080160);
130 delete fGenfitTrackArray;
131 delete fHitClusterArray;
132 delete fMeasurementProducer;
133 delete fMeasurementFactory;
134 delete fPDGCandidateArray;
139 std::cout <<
cGREEN <<
" AtFITTER::AtGenfit::Init() " <<
cNORMAL <<
"\n";
143 fHitClusterArray->Delete();
144 fGenfitTrackArray->Delete();
149 return fGenfitTrackArray;
167 fHitClusterArray->Delete();
168 genfit::TrackCand trackCand;
176 std::cout <<
cYELLOW <<
" Track " << track->
GetTrackID() <<
" with " << hitClusterArray->size() <<
" clusters "
179 if (hitClusterArray->size() < 3)
182 if (fVerbosity > 0) {
183 std::cout <<
" Initial angles from PRA "
185 std::cout <<
" Theta : " << TMath::RadToDeg() * track->
GetGeoTheta()
186 <<
" - Phi : " << TMath::RadToDeg() * track->
GetGeoPhi() <<
"\n";
190 Double_t theta = 0.0;
195 if (fSimulationConv) {
196 thetaConv = 180.0 * TMath::DegToRad() - track->
GetGeoTheta();
201 if (IsForwardTrack(thetaConv)) {
203 if (fSimulationConv) {
204 theta = 180.0 * TMath::DegToRad() - track->
GetGeoTheta();
212 std::reverse(hitClusterArray->begin(), hitClusterArray->end());
214 }
else if (thetaConv > 90.0 * TMath::DegToRad()) {
216 if (fSimulationConv) {
218 phi = 180.0 * TMath::DegToRad() - track->
GetGeoPhi();
220 theta = 180.0 * TMath::DegToRad() - track->
GetGeoTheta();
224 std::cout <<
cRED <<
" AtGenfit::FitTracks - Warning! Undefined theta angle. Skipping event..." <<
cNORMAL
231 Double_t brho = (fMagneticField / 10.0) * radius / TMath::Sin(theta);
233 Double_t p_mass = fMass;
234 Int_t p_Z = fAtomicNumber;
235 Int_t PDGCode = fPDGCode;
237 if (fVerbosity > 0) {
238 std::cout <<
cYELLOW <<
" ---- AtGenfit : Initial parameters "
240 std::cout <<
" PDG : " << PDGCode <<
" - Mass : " << p_mass <<
" - Atomic number : " << p_Z <<
"\n";
241 std::cout <<
" B field : " << fMagneticField / 10.0 <<
" - Min. Bhro : " << fMinBrho
242 <<
" - Max. Brho : " << fMaxBrho <<
"\n";
243 std::cout <<
" Theta : " << theta * TMath::RadToDeg() <<
" - Phi : " << phi * TMath::RadToDeg()
244 <<
" - Brho (geo) : " << brho <<
cNORMAL <<
"\n";
251 for (
auto iCluster = 0; iCluster < hitClusterArray->size(); ++iCluster) {
252 auto cluster = hitClusterArray->at(iCluster);
253 auto pos =
cluster.GetPosition();
257 std::cout <<
cYELLOW <<
" First cluster : " << pos.X() <<
" - " << pos.Y() <<
" - " << pos.Z() <<
cNORMAL
260 }
else if (iCluster == (hitClusterArray->size() - 1)) {
262 std::cout <<
cYELLOW <<
" Last cluster : " << pos.X() <<
" - " << pos.Y() <<
" - " << pos.Z() <<
cNORMAL
266 if (IsForwardTrack(thetaConv)) {
268 clusterClone.SetPosition({pos.X(), pos.Y(), 1000.0 - pos.Z()});
270 clusterClone.SetPosition({-pos.X(), pos.Y(), 1000.0 - pos.Z()});
271 }
else if (thetaConv > 90.0 * TMath::DegToRad()) {
273 clusterClone.SetPosition({pos.X(), pos.Y(), pos.Z()});
275 clusterClone.SetPosition({-pos.X(), pos.Y(), pos.Z()});
278 Int_t idx = fHitClusterArray->GetEntriesFast();
279 new ((*fHitClusterArray)[idx])
AtHitCluster(clusterClone);
280 trackCand.addHit(fTPCDetID, idx);
290 Double_t zIniCal = 0;
291 Double_t xIniCal = 0;
296 if (IsForwardTrack(thetaConv)) {
297 iniCluster = hitClusterArray->front();
300 zIniCal = 1000.0 - iniPos.Z();
303 xIniCal = iniPos.X();
305 xIniCal = -iniPos.X();
308 std::reverse(hitClusterArray->begin(), hitClusterArray->end());
310 }
else if (thetaConv > 90.0 * TMath::DegToRad()) {
311 iniCluster = hitClusterArray->front();
314 zIniCal = iniPos.Z();
317 xIniCal = iniPos.X();
319 xIniCal = -iniPos.X();
322 std::cout <<
cRED <<
" AtGenfit::FitTracks - Warning! Undefined theta angle. Skipping event..." <<
cNORMAL
333 std::cout <<
" Initial position : " << xIniCal <<
" - " << iniPos.Y() <<
" - " << zIniCal <<
"\n";
335 TVector3 posSeed(xIniCal / 10.0, iniPos.Y() / 10.0, zIniCal / 10.0);
336 posSeed.SetMag(posSeed.Mag());
340 TMatrixDSym covSeed(6);
343 for (Int_t iComp = 0; iComp < 3; iComp++)
344 covSeed(iComp, iComp) = covMatrix(iComp, iComp) / 100.;
346 for (Int_t iComp = 3; iComp < 6; iComp++)
347 covSeed(iComp, iComp) = covSeed(iComp - 3, iComp - 3);
349 std::tuple<Double_t, Double_t> mom_ener =
350 GetMomFromBrho(p_mass, p_Z, brho);
353 Double_t px = 0, py = 0, pz = 0;
354 TVector3 mom_dir(TMath::Sin(theta) * TMath::Cos(phi), TMath::Sin(theta) * TMath::Sin(phi), TMath::Cos(theta));
355 px = std::get<0>(mom_ener) * mom_dir.X();
356 py = std::get<0>(mom_ener) * mom_dir.Y();
357 pz = std::get<0>(mom_ener) * mom_dir.Z();
360 std::cout <<
cYELLOW <<
" Momentum from PRA- px : " << px <<
" - py : " << py <<
" - pz : " << pz <<
cNORMAL
365 TVector3 momSeed(px, py, pz);
366 momSeed.SetTheta(theta);
368 trackCand.setCovSeed(covSeed);
369 trackCand.setPosMomSeed(posSeed, momSeed, p_Z);
370 trackCand.setPdgCode(fPDGCode);
373 if (brho > fMaxBrho && brho < fMinBrho)
376 auto *gfTrack =
new ((*fGenfitTrackArray)[fGenfitTrackArray->GetEntriesFast()])
377 genfit::Track(trackCand, *fMeasurementFactory);
378 gfTrack->addTrackRep(
new genfit::RKTrackRep(fPDGCode));
380 auto *trackRep =
dynamic_cast<genfit::RKTrackRep *
>(gfTrack->getTrackRep(0));
384 fKalmanFitter->processTrackWithRep(gfTrack, trackRep,
false);
385 }
catch (genfit::Exception &e) {
386 std::cout <<
" AtGenfit - Exception caught from Kalman Fitter : " << e.what() <<
"\n";
390 genfit::FitStatus *fitStatus;
392 if (fVerbosity > 0) {
393 fitStatus = gfTrack->getFitStatus(trackRep);
394 std::cout <<
cYELLOW <<
" Is fitted? " << fitStatus->isFitted() <<
"\n";
395 std::cout <<
" Is Converged ? " << fitStatus->isFitConverged() <<
"\n";
396 std::cout <<
" Is Converged Partially? " << fitStatus->isFitConvergedPartially() <<
"\n";
397 std::cout <<
" Is pruned ? " << fitStatus->isTrackPruned() <<
cNORMAL <<
"\n";
400 }
catch (genfit::Exception &e) {
404 genfit::MeasuredStateOnPlane fitState;
409 fitState = gfTrack->getFittedState();
413 fitState.getPosMomCov(pos_res, mom_res, cov_res);
415 std::cout <<
cYELLOW <<
" Total Momentum : " << mom_res.Mag() <<
" - Position : " << pos_res.X() <<
" "
416 << pos_res.Y() <<
" " << pos_res.Z() <<
cNORMAL <<
"\n";
423 }
catch (genfit::Exception &e) {
451 std::cout <<
" End of GENFIT "