ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtGenfit.cxx
Go to the documentation of this file.
1 #include "AtGenfit.h"
2 
3 #include "AtHitCluster.h"
5 #include "AtTrack.h"
6 
7 #include <Math/Point3D.h>
8 #include <Math/Point3Dfwd.h> // for XYZPoint
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>
17 #include <TMath.h>
18 #include <TMatrixDSymfwd.h>
19 #include <TMatrixDfwd.h>
20 #include <TMatrixT.h>
21 #include <TMatrixTSym.h>
22 #include <TObjArray.h>
23 #include <TObject.h>
24 #include <TROOT.h>
25 #include <TVector3.h>
26 #include <TrackCand.h>
27 
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>
40 
41 #include <algorithm>
42 #include <iostream>
43 #include <tuple>
44 #include <utility>
45 constexpr auto cRED = "\033[1;31m";
46 constexpr auto cYELLOW = "\033[1;33m";
47 constexpr auto cNORMAL = "\033[0m";
48 constexpr auto cGREEN = "\033[1;32m";
49 
51 
52 AtFITTER::AtGenfit::AtGenfit(Float_t magfield, Float_t minbrho, Float_t maxbrho, std::string eLossFile,
53  Float_t gasMediumDensity, Int_t pdg, Int_t minit, Int_t maxit)
54  : fEnergyLossFile(std::move(eLossFile)),
55  fMeasurementProducer(
56  new genfit::MeasurementProducer<AtHitCluster, genfit::AtSpacepointMeasurement>(fHitClusterArray)),
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"))
60 {
61  fKalmanFitter = std::make_shared<genfit::KalmanFitterRefTrack>();
62  fKalmanFitter->setMinIterations(fMinIterations);
63  fKalmanFitter->setMaxIterations(fMaxIterations);
64  // fKalmanFitter->setDebugLvl();
65  fMeasurementFactory->addProducer(fTPCDetID, fMeasurementProducer);
66 
67  genfit::FieldManager::getInstance()->init(new genfit::ConstField(0., 0., fMagneticField)); // NOLINT TODO kGauss
68  genfit::MaterialEffects *materialEffects = genfit::MaterialEffects::getInstance();
69  materialEffects->setEnergyLossBrems(false);
70  materialEffects->setNoiseBrems(false);
71  materialEffects->useEnergyLossParam();
72  materialEffects->init(new genfit::TGeoMaterialInterface()); // NOLINT
73  // Parameteres set after initialization
74  materialEffects->setGasMediumDensity(gasMediumDensity);
75  materialEffects->setEnergyLossFile(fEnergyLossFile, fPDGCode);
76 
77  // fPDGCandidateArray = new std::vector<Int_t>; // TODO
78  // fPDGCandidateArray->push_back(2212);
79 
80  std::cout << " AtFITTER::AtGenfit::AtGenfit(): Checking materials that GENFIT will use "
81  << "\n";
82 
83  auto *gGeoMan = dynamic_cast<TGeoManager *>(gROOT->FindObject("FAIRGeom"));
84  TObjArray *volume_list = gGeoMan->GetListOfVolumes();
85  if (!volume_list) {
86  std::cout << cRED << " Warning! Null list of geometry volumes." << cNORMAL << "\n";
87  }
88 
89  int numVol = volume_list->GetEntries();
90 
91  for (int ivol = 0; ivol < numVol; ivol++) {
92  auto *volume = dynamic_cast<TGeoVolume *>(volume_list->At(ivol));
93  if (!volume) {
94 
95  std::cout << "Got a null geometry volume!! Skipping current list element"
96  << "\n";
97  continue;
98  }
99 
100  std::cout << cGREEN << " Volume name : " << volume->GetName() << cNORMAL << "\n";
101 
102  TGeoMaterial *mat = volume->GetMedium()->GetMaterial();
103 
104  // Int_t mat_indx = mat->GetIndex();
105  std::cout << cYELLOW << " - Material : " << mat->GetName() << cNORMAL << "\n";
106  }
107 
108  // PDG definitions
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;
114 
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);
125 }
126 
128 {
129  // delete fKalmanFitter;
130  delete fGenfitTrackArray;
131  delete fHitClusterArray;
132  delete fMeasurementProducer;
133  delete fMeasurementFactory;
134  delete fPDGCandidateArray;
135 }
136 
138 {
139  std::cout << cGREEN << " AtFITTER::AtGenfit::Init() " << cNORMAL << "\n";
140  // std::cout << cGREEN << " PDG : "<<fPDGCode<<"\n";
141  // std::cout << cGREEN << " Ion : "<<fIonName<<"\n";
142 
143  fHitClusterArray->Delete();
144  fGenfitTrackArray->Delete();
145 }
146 
148 {
149  return fGenfitTrackArray;
150 }
151 
157 {
158 
159  // std::vector<genfit::Track> genfitTrackArray;
160 
161  // std::vector<AtTrack> &patternTrackCand = patternEvent.GetTrackCand();
162 
163  // std::cout << cGREEN << " AtFITTER::AtGenfit::FitTracks - Number of candidate tracks : " << patternTrackCand.size()
164  //<< cNORMAL << "\n";
165 
166  // for (auto track : patternTrackCand) {
167  fHitClusterArray->Delete();
168  genfit::TrackCand trackCand;
169 
170  auto hitClusterArray = track->GetHitClusterArray();
171 
172  TVector3 pos_res;
173  TVector3 mom_res;
174  TMatrixDSym cov_res;
175 
176  std::cout << cYELLOW << " Track " << track->GetTrackID() << " with " << hitClusterArray->size() << " clusters "
177  << cNORMAL << "\n";
178 
179  if (hitClusterArray->size() < 3) //&& patternTrackCand.size()<5) { // TODO Check minimum number of clusters
180  return nullptr;
181 
182  if (fVerbosity > 0) {
183  std::cout << " Initial angles from PRA "
184  << "\n";
185  std::cout << " Theta : " << TMath::RadToDeg() * track->GetGeoTheta()
186  << " - Phi : " << TMath::RadToDeg() * track->GetGeoPhi() << "\n";
187  }
188 
189  // New angle convention
190  Double_t theta = 0.0;
191  Double_t phi = 0.0;
192 
193  // Variable for convention (simulation comes reversed)
194  Double_t thetaConv;
195  if (fSimulationConv) {
196  thetaConv = 180.0 * TMath::DegToRad() - track->GetGeoTheta();
197  } else {
198  thetaConv = track->GetGeoTheta();
199  }
200 
201  if (IsForwardTrack(thetaConv)) { // Forward (Backward) for experiment (simulation)
202 
203  if (fSimulationConv) {
204  theta = 180.0 * TMath::DegToRad() - track->GetGeoTheta();
205  phi = track->GetGeoPhi();
206  } else {
207  theta = track->GetGeoTheta();
208  phi = track->GetGeoPhi(); // 180.0 * TMath::DegToRad() - track->GetGeoPhi();
209  }
210 
211  // Needs to be reversed back for multifit
212  std::reverse(hitClusterArray->begin(), hitClusterArray->end());
213 
214  } else if (thetaConv > 90.0 * TMath::DegToRad()) { // Backward (Forward) for experiment (simulation)
215 
216  if (fSimulationConv) {
217  theta = track->GetGeoTheta();
218  phi = 180.0 * TMath::DegToRad() - track->GetGeoPhi(); // 180.0 * TMath::DegToRad() - track->GetGeoPhi();
219  } else {
220  theta = 180.0 * TMath::DegToRad() - track->GetGeoTheta();
221  phi = -track->GetGeoPhi();
222  }
223  } else {
224  std::cout << cRED << " AtGenfit::FitTracks - Warning! Undefined theta angle. Skipping event..." << cNORMAL
225  << "\n";
226  return nullptr;
227  }
228 
229  Double_t radius = track->GetGeoRadius() / 1000.0; // mm to m
230 
231  Double_t brho = (fMagneticField / 10.0) * radius / TMath::Sin(theta); // Tm
232 
233  Double_t p_mass = fMass;
234  Int_t p_Z = fAtomicNumber;
235  Int_t PDGCode = fPDGCode;
236 
237  if (fVerbosity > 0) {
238  std::cout << cYELLOW << " ---- AtGenfit : Initial parameters "
239  << "\n";
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";
245  }
246 
247  // hitClusterArray->resize(hitClusterArray->size() * 0.50);
248 
249  // Adding clusterized hits
250  // for (auto cluster : *hitClusterArray) {
251  for (auto iCluster = 0; iCluster < hitClusterArray->size(); ++iCluster) {
252  auto cluster = hitClusterArray->at(iCluster);
253  auto pos = cluster.GetPosition();
254  auto clusterClone(cluster);
255 
256  if (iCluster == 0) {
257  std::cout << cYELLOW << " First cluster : " << pos.X() << " - " << pos.Y() << " - " << pos.Z() << cNORMAL
258  << "\n";
259 
260  } else if (iCluster == (hitClusterArray->size() - 1)) {
261 
262  std::cout << cYELLOW << " Last cluster : " << pos.X() << " - " << pos.Y() << " - " << pos.Z() << cNORMAL
263  << "\n";
264  }
265 
266  if (IsForwardTrack(thetaConv)) { // Experiment forward
267  if (fSimulationConv)
268  clusterClone.SetPosition({pos.X(), pos.Y(), 1000.0 - pos.Z()});
269  else
270  clusterClone.SetPosition({-pos.X(), pos.Y(), 1000.0 - pos.Z()});
271  } else if (thetaConv > 90.0 * TMath::DegToRad()) {
272  if (fSimulationConv)
273  clusterClone.SetPosition({pos.X(), pos.Y(), pos.Z()});
274  else
275  clusterClone.SetPosition({-pos.X(), pos.Y(), pos.Z()});
276  }
277 
278  Int_t idx = fHitClusterArray->GetEntriesFast();
279  new ((*fHitClusterArray)[idx]) AtHitCluster(clusterClone);
280  trackCand.addHit(fTPCDetID, idx);
281  // std::cout<<" Adding cluster "<<idx<<"\n";
282  // std::cout<<pos.X()<<" "<<pos.Y()<<" "<<pos.Z()<<"\n";
283  // if(iCluster==0)
284  // iniPos = pos;
285  }
286 
287  // Initial cluster
288  // Last(first) one for tracks with angle >(<) 90
289  AtHitCluster iniCluster;
290  Double_t zIniCal = 0;
291  Double_t xIniCal = 0;
292 
293  XYZPoint iniPos;
294 
295  // Initial track position
296  if (IsForwardTrack(thetaConv)) {
297  iniCluster = hitClusterArray->front();
298  // iniCluster = hitClusterArray->back();
299  iniPos = iniCluster.GetPosition();
300  zIniCal = 1000.0 - iniPos.Z();
301 
302  if (fSimulationConv)
303  xIniCal = iniPos.X();
304  else
305  xIniCal = -iniPos.X();
306 
307  // Leave hit cluster array in its original state
308  std::reverse(hitClusterArray->begin(), hitClusterArray->end());
309 
310  } else if (thetaConv > 90.0 * TMath::DegToRad()) {
311  iniCluster = hitClusterArray->front();
312  // iniCluster = hitClusterArray->back();
313  iniPos = iniCluster.GetPosition();
314  zIniCal = iniPos.Z();
315 
316  if (fSimulationConv)
317  xIniCal = iniPos.X();
318  else
319  xIniCal = -iniPos.X();
320 
321  } else {
322  std::cout << cRED << " AtGenfit::FitTracks - Warning! Undefined theta angle. Skipping event..." << cNORMAL
323  << "\n";
324  }
325 
326  // Double_t dist = TMath::Sqrt(iniPos.X() * iniPos.X() + iniPos.Y() * iniPos.Y());
327 
328  // std::cout<<cRED<<" Distance to Z "<<dist<<cNORMAL<<"\n";
329  // if (dist > 70.0)
330  // return nullptr;
331 
332  // if(fVerbosity>1)
333  std::cout << " Initial position : " << xIniCal << " - " << iniPos.Y() << " - " << zIniCal << "\n";
334 
335  TVector3 posSeed(xIniCal / 10.0, iniPos.Y() / 10.0, zIniCal / 10.0);
336  posSeed.SetMag(posSeed.Mag());
337 
338  // Starting wih fit...
339 
340  TMatrixDSym covSeed(6); // TODO Check where COV matrix is defined, likely in AtPattern clusterize (hard coded
341  // in AtSpacePoint measurement)
342  TMatrixD covMatrix = iniCluster.GetCovMatrix();
343  for (Int_t iComp = 0; iComp < 3; iComp++)
344  covSeed(iComp, iComp) = covMatrix(iComp, iComp) / 100.; // unit conversion mm2 -> cm2
345 
346  for (Int_t iComp = 3; iComp < 6; iComp++)
347  covSeed(iComp, iComp) = covSeed(iComp - 3, iComp - 3);
348 
349  std::tuple<Double_t, Double_t> mom_ener =
350  GetMomFromBrho(p_mass, p_Z, brho); // TODO Change to structured bindings when C++17
351 
352  // Momentum calculation
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();
358 
359  if (fVerbosity > 0)
360  std::cout << cYELLOW << " Momentum from PRA- px : " << px << " - py : " << py << " - pz : " << pz << cNORMAL
361  << "\n";
362 
363  // Double_t momSeedMag = std::get<0>(mom_ener);
364  // TVector3 momSeed(0., 0., momSeedMag); //
365  TVector3 momSeed(px, py, pz);
366  momSeed.SetTheta(theta); // TODO: Check angle conventions
367  momSeed.SetPhi(phi); // TODO
368  trackCand.setCovSeed(covSeed);
369  trackCand.setPosMomSeed(posSeed, momSeed, p_Z);
370  trackCand.setPdgCode(fPDGCode);
371  // trackCand.Print();
372 
373  if (brho > fMaxBrho && brho < fMinBrho)
374  return nullptr;
375 
376  auto *gfTrack = new ((*fGenfitTrackArray)[fGenfitTrackArray->GetEntriesFast()]) // NOLINT
377  genfit::Track(trackCand, *fMeasurementFactory);
378  gfTrack->addTrackRep(new genfit::RKTrackRep(fPDGCode)); // NOLINT
379 
380  auto *trackRep = dynamic_cast<genfit::RKTrackRep *>(gfTrack->getTrackRep(0));
381  // trackRep->setPropDir(-1);
382 
383  try {
384  fKalmanFitter->processTrackWithRep(gfTrack, trackRep, false);
385  } catch (genfit::Exception &e) {
386  std::cout << " AtGenfit - Exception caught from Kalman Fitter : " << e.what() << "\n";
387  return nullptr;
388  }
389 
390  genfit::FitStatus *fitStatus;
391  try {
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";
398  fitStatus->Print();
399  }
400  } catch (genfit::Exception &e) {
401  return nullptr;
402  }
403 
404  genfit::MeasuredStateOnPlane fitState;
405  // genfit::TrackPoint* firstPoint;
406  // genfit::TrackPoint* lastPoint;
407  // genfit::KalmanFitterInfo* pointKFitterInfo;
408  try {
409  fitState = gfTrack->getFittedState();
410  if (fVerbosity > 0)
411  fitState.Print();
412  // Fit result
413  fitState.getPosMomCov(pos_res, mom_res, cov_res);
414  if (fVerbosity > 0)
415  std::cout << cYELLOW << " Total Momentum : " << mom_res.Mag() << " - Position : " << pos_res.X() << " "
416  << pos_res.Y() << " " << pos_res.Z() << cNORMAL << "\n";
417  // firstPoint = gfTrack->getPointWithMeasurement(0);
418  // lastPoint = gfTrack->getPointWithMeasurement(gfTrack->getNumPoints()-1);
419  // firstPoint->Print();
420  // lastPoint->Print();
421  // pointKFitterInfo = firstPoint->getKalmanFitterInfo();
422 
423  } catch (genfit::Exception &e) {
424  return nullptr;
425  }
426 
427  // TODO: Extrapolate back to Z axis (done in e20009 analysis for the moment)
428  /*TVector3 posVertex(0,0,pos_res.Z());
429  TVector3 normalVertex(0, 0, 1);
430 
431 
432  try {
433  for(auto iStep=0;iStep<20;++iStep){
434  trackRep -> extrapolateBy(fitState, -0.1*iStep);
435  //trackRep -> extrapolateToPlane(fitState,genfit::SharedPlanePtr(new
436  genfit::DetPlane(posVertex,normalVertex))); mom_res = fitState.getMom(); pos_res = fitState.getPos(); double
437  distance = TMath::Sqrt(pos_res.X()*pos_res.X() + pos_res.Y()*pos_res.Y()); if (fVerbosity > 0) std::cout <<
438  cYELLOW << " Extrapolation: Total Momentum : " << mom_res.Mag() << " - Position : " << pos_res.X() << " "
439  << pos_res.Y() << " " << pos_res.Z() <<" - POCA : "<<POCA<< cNORMAL << "\n";
440  }
441 
442  } catch (genfit::Exception &e) {
443  mom_res.SetXYZ(0, 0, 0);
444  pos_res.SetXYZ(0, 0, 0);
445  }*/
446 
447  // gfTrack ->Print();
448 
449  //} // iTrack
450 
451  std::cout << " End of GENFIT "
452  << "\n";
453  std::cout << " "
454  << "\n";
455 
456  return gfTrack;
457 }
458 
AtTrack::GetGeoPhi
Double_t GetGeoPhi() const
Definition: AtTrack.h:87
AtFITTER::AtGenfit::FitTracks
genfit::Track * FitTracks(AtTrack *track) override
Definition: AtGenfit.cxx:156
AtFITTER::AtGenfit::Init
void Init() override
Definition: AtGenfit.cxx:137
AtTrack::GetGeoRadius
Double_t GetGeoRadius() const
Definition: AtTrack.h:88
AtHitCluster
: Class representing a cluster of hits that arise from the same deposition of charge in space....
Definition: AtHitCluster.h:37
AtHitCluster.h
genfit
Definition: AtFitter.h:20
XYZPoint
ROOT::Math::XYZPoint XYZPoint
Definition: AtGenfit.cxx:50
ClassImp
ClassImp(AtFITTER::AtGenfit)
XYZPoint
ROOT::Math::XYZPoint XYZPoint
Definition: AtPatternCircle2D.h:18
hc::cluster
std::vector< size_t > cluster
Definition: hc.h:25
AtFITTER::AtGenfit::GetGenfitTrackArray
TClonesArray * GetGenfitTrackArray()
Definition: AtGenfit.cxx:147
AtFITTER::AtGenfit::AtGenfit
AtGenfit(Float_t magfield, Float_t minbrho, Float_t maxbrho, std::string eLossFile, Float_t gasMediumDensity, Int_t pdg=2212, Int_t minit=5, Int_t maxit=20)
Definition: AtGenfit.cxx:52
AtHit::GetPosition
const XYZPoint & GetPosition() const
Definition: AtHit.h:79
AtTrack::GetHitClusterArray
std::vector< AtHitCluster > * GetHitClusterArray()
Definition: AtTrack.h:90
AtTrack
Definition: AtTrack.h:25
AtSpacePointMeasurement.h
AtFITTER::AtGenfit
Definition: AtGenfit.h:34
AtTrack.h
cNORMAL
constexpr auto cNORMAL
Definition: AtGenfit.cxx:47
AtFITTER::AtGenfit::~AtGenfit
~AtGenfit()
Definition: AtGenfit.cxx:127
AtTrack::GetTrackID
Int_t GetTrackID() const
Definition: AtTrack.h:78
cYELLOW
constexpr auto cYELLOW
Definition: AtGenfit.cxx:46
AtTrack::GetGeoTheta
Double_t GetGeoTheta() const
Definition: AtTrack.h:86
cGREEN
constexpr auto cGREEN
Definition: AtGenfit.cxx:48
cRED
constexpr auto cRED
Definition: AtGenfit.cxx:45
AtHitCluster::GetCovMatrix
const TMatrixDSym & GetCovMatrix() const
Definition: AtHitCluster.h:75
AtGenfit.h