FairRoot/PandaRoot
PndFtsTrackerIdeal.cxx
Go to the documentation of this file.
1 #include "PndFtsTrackerIdeal.h"
2 
3 //#include "PndDetectorList.h"
4 #include "PndMCTrack.h"
5 #include "PndTrackCand.h"
6 #include "PndTrack.h"
7 
8 #include "FairTrackParP.h"
9 #include "FairMCPoint.h"
10 #include "FairHit.h"
11 //#include "FairMCApplication.h"
12 #include "FairTask.h"
13 //#include "FairRunAna.h"
14 //#include "FairGeoNode.h"
15 //#include "FairGeoVector.h"
16 //#include "FairGeoMedium.h"
17 #include "FairRootManager.h"
18 
19 #include "TObjectTable.h"
20 #include "TClonesArray.h"
21 #include "TParticlePDG.h"
22 #include "TRandom3.h"
23 #include <iostream>
24 
25 // fts
26 #include "PndFtsPoint.h"
27 #include "PndFtsHit.h"
28 #include "PndFtsTube.h"
29 #include "PndFtsMapCreator.h"
30 // fairroot
31 #include "FairRootManager.h"
32 #include "FairRunAna.h"
33 #include "FairRuntimeDb.h"
34 
35 using namespace std;
36 //________________________________________________________________
38  FairTask("FTSTrackfinderIdeal"), fMCTracks(0), fTrackCands(0), fTracks(0),
39  fTrackIds(0), fMinFtsHitsPerTrack(5), fMomSigma(0,0,0), fDPoP(0.), fRelative (kFALSE), fVtxSigma(0,0,0), fEfficiency(1.), fPersistence(kTRUE),
40  fTracksArrayName("FTSTrkIdeal"), pdg(0)
41 {
42  //---
43  fTrackCands = new TClonesArray("PndTrackCand");
44  fTracks = new TClonesArray("PndTrack");
45  fVerbose = 0;
46  fMomSigma.SetXYZ(0.,0.,0.);
47  fVtxSigma.SetXYZ(0.,0.,0.);
49  fBranchActive[0]=kTRUE;
50  for (int i=1;i<4;i++) fBranchActive[i]=kFALSE;
51 }
52 
53 //_________________________________________________________________
55 {
56  FairRootManager *fManager =FairRootManager::Instance();
57  fManager->Write();
58 }
59 
60 //_________________________________________________________________
62 {
63  //---
64  FairRootManager::Instance()->Register(fTracksArrayName,"FTSTrk", fTracks, fPersistence);
65  FairRootManager::Instance()->Register(fTracksArrayName+"Cand","FTSTrk", fTrackCands, fPersistence);
66  if(fVerbose>3) Info("Register","Done.");
67 }
68 
69 
71  FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb();
72  fFtsParameters = (PndGeoFtsPar*) rtdb->getContainer("PndGeoFtsPar");
73 }
74 
75 //________________________________________________________________
77  // ---
78  if(fVerbose>3) Info("Init","Start initialisation.");
79 
80  FairRootManager *fManager = FairRootManager::Instance();
81 
82  // Get MC arrays
83  fMCTracks = dynamic_cast<TClonesArray *>(fManager->GetObject("MCTrack"));
84  if ( ! fMCTracks ) {
85  std::cout << "-W- PndFtsTrackerIdeal::Init: No MCTrack array! Needed for MC Truth" << std::endl;
86  return kERROR;
87  }
88 
89  //FTS
90  fMCPoints[0] = dynamic_cast<TClonesArray *> (fManager->GetObject("FTSPoint"));
91  if ( ! fMCPoints[0] ) {
92  std::cout << "-W- PndFtsTrackerIdeal::Init: No FTSPoint array!" << std::endl;
93  return kERROR;
94  }
95  fHits[0] = dynamic_cast<TClonesArray *> (fManager->GetObject("FTSHit"));
96  if ( ! fHits[0] ) {
97  std::cout << "-W- PndFtsTrackerIdeal::Init: No FTSHit array!" << std::endl;
98  return kERROR;
99  }
100  fBranchIDs[0] = FairRootManager::Instance()->GetBranchId("FTSHit");
101 
102 
103  //GEM
104  fMCPoints[1] = dynamic_cast<TClonesArray *> (fManager->GetObject("GEMPoint"));
105  if ( ! fMCPoints[1] ) {
106  std::cout << "-W- PndFtsTrackerIdeal::Init: No GEMPoint array!" << std::endl;
107  fMCPoints[1]=new TClonesArray("FairMCPoint");
108  }
109  fHits[1] = dynamic_cast<TClonesArray *> (fManager->GetObject("GEMHit"));
110  if ( ! fHits[1] ) {
111  std::cout << "-W- PndFtsTrackerIdeal::Init: No GEMHit array!" << std::endl;
112  fHits[1]=new TClonesArray("FairHit");
113  }
114  fBranchIDs[1] = FairRootManager::Instance()->GetBranchId("GEMHit");
115 
116  //MVD Pixel
117  fMCPoints[2] = dynamic_cast<TClonesArray *> (fManager->GetObject("MVDPoint"));
118  if ( ! fMCPoints[2] ) {
119  std::cout << "-W- PndFtsTrackerIdeal::Init: No MVDPoint array!" << std::endl;
120  fMCPoints[1]=new TClonesArray("FairMCPoint");
121  }
122  fHits[2] = dynamic_cast<TClonesArray *> (fManager->GetObject("MVDHitsPixel"));
123  if ( ! fHits[2] ) {
124  std::cout << "-W- PndFtsTrackerIdeal::Init: No MVDHitsPixel array!" << std::endl;
125  fHits[2]=new TClonesArray("FairHit");
126  }
127  fBranchIDs[2] = FairRootManager::Instance()->GetBranchId("MVDHitsPixel");
128 
129  fMCPoints[3] = fMCPoints[2];
130  fHits[3] = dynamic_cast<TClonesArray *> (fManager->GetObject("MVDHitsStrip"));
131  if ( ! fHits[3] ) {
132  std::cout << "-W- PndFtsTrackerIdeal::Init: No MVDHitsStrip array!" << std::endl;
133  fMCPoints[3]=new TClonesArray("FairHit");
134  }
135  fBranchIDs[3] = FairRootManager::Instance()->GetBranchId("MVDHitsStrip");
136 
137  if(fVerbose>3) Info("Init","Fetched all arrays.");
138 
139  Register();
140 
141  pdg = new TDatabasePDG();
142  if(fVerbose>3) Info("Init","End initialisation.");
143 
144 
146  fTubeArrayFts = mapperFts->FillTubeArray();
147 
148  return kSUCCESS;
149 }
150 
151 //_________________________________________________________________
152 void PndFtsTrackerIdeal::Exec(Option_t * )
153 {
154  Reset();
155  if(fVerbose>3) Info("Exec","Start eventloop.");
156  if(fVerbose>4){
157  Info("Exec","Print some array properties");
158  for(int iii=0;iii<4;iii++){
159  std::cout<<"fHits["<<iii<<"] is branchID "<<fBranchIDs[iii]<<" with the name "<<fHits[iii]->GetName()<<" and contains "<<fHits[iii]->GetEntriesFast()<<" entries."<<std::endl;
160  std::cout<<"fMCPoints["<<iii<<"] with the name "<<fMCPoints[iii]->GetName()<<" and contains "<<fMCPoints[iii]->GetEntriesFast()<<" entries."<<std::endl;
161  }
162  }
163 
164  // Do we have enough hits in the FTS in this particular event?
166  if(fVerbose>3) Info("Exec","Skip the event, since we have less than %i hits in FTS", fMinFtsHitsPerTrack);
167  return;
168  }
169 
170 
171  FairHit* ghit = NULL;
172  std::map<Int_t, FairHit*> firstHit;
173  std::map<Int_t, FairHit*> lastHit;
174  FairMCPoint* myPoint=NULL;
175  std::map<Int_t, FairMCPoint*> firstPoint;
176  std::map<Int_t, FairMCPoint*> lastPoint;
177  std::map<Int_t, PndTrackCand*> candlist;
178 
179  // Loop over all hits from FTS first (later other detectors, too)
180  // When looping over FTS hits create a PndTrackCand with the same index as the MC truth track if we find at least one FTS hit
181  // After the FTS Hit Loop remove all candidates which do not have at least fMinFtsHitsPerTrack hits (from FTS)
182  // and remove all tracks which are bent in the dipole so much that they turn around and fly towards the barrel again (this leads to problems in the fitter)
183  // I will remove such tracks at the end of the loop on FTS hits. I plan to check all (MC truth) time-ordered FTS hits associated to a given PndTrackCand and check if the z-component is increasing. If not, I will remove the PndTrackCand.
184  // When looping over the other detectors only hits are added to PndTrackCand objects which were created in the loop over FTS hits and NOT removed afterwards
185 
186  // Detector loop
187  for(Int_t iDet=0;iDet<4;iDet++){
188  if (kFALSE == fBranchActive[iDet]) continue; //skip manually switched off detector
189  if(fVerbose>4) Info("Exec","Use detector %i",iDet);
190  // Hit loop
191  for (Int_t ih = 0; ih < fHits[iDet]->GetEntriesFast(); ih++) {
192  ghit = (FairHit*) fHits[iDet]->At(ih);
193  if(!ghit) {
194  if(fVerbose>3) Error("Exec","Have no ghit %i, array size: %i",ih,fHits[iDet]->GetEntriesFast());
195  continue;
196  }
197  if(iDet==0)
198  {
199  if(fStationsDisabled.size() > 0)
200  {
201  PndFtsHit* myhit = (PndFtsHit*) fHits[iDet]->At(ih);
202  if(fStationsDisabled.find(myhit->GetLayerID()) != fStationsDisabled.end()) continue;
203  }
204  }
205  Int_t mchitid=ghit->GetRefIndex();
206  if(mchitid<0) {
207  if(fVerbose>3) Error("Exec","Have a negative mcHit %i",mchitid);
208  continue;
209  }
210  myPoint = (FairMCPoint*)(fMCPoints[iDet]->At(mchitid));
211  if(!myPoint) continue;
212  Int_t trackID = myPoint->GetTrackID();
213  if(trackID<0) continue;
214 
215  if(fVerbose>5) Info("Exec","Have a Hit %i at Track index %i",ih,trackID);
216 
217  // Continue Construction of a track candidate (start with FTS hits)
218  // Track candidates and corresponding MC track index are saved in a map
219  PndTrackCand* cand=candlist[trackID];
220  if(NULL==cand){
221  if(0!=iDet){
222  if(fVerbose>5) Info("Exec","Skip Hit %i, it's not connected to a Track in FTS",ih);
223  continue; // skip Tracks in MVD/GEM not going to FTS
224  }
225  if(fVerbose>5) Info("Exec","Create new PndTrack object %i",trackID);
226  cand=new PndTrackCand();
227  cand->setMcTrackId(trackID);
228  if(fVerbose>5) Info("Exec","Creating new PndTrack object finished %i",trackID);
229  }
230  if(fVerbose>5) Info("Exec","add the hit %i to trackcand %i",ih,trackID);
231  cand->AddHit(fBranchIDs[iDet],ih,myPoint->GetTime());
232  // Figure out if the current hit is the earliest in the event
233  if(!firstHit[trackID] || firstPoint[trackID]->GetTime() > myPoint->GetTime()) {
234  firstHit[trackID]=ghit;
235  firstPoint[trackID]=myPoint;
236  }
237  // or the latest one
238  if(!lastHit[trackID] || lastPoint[trackID]->GetTime() < myPoint->GetTime()) {
239  lastHit[trackID]=ghit;
240  lastPoint[trackID]=myPoint;
241  }
242 
243  candlist[trackID] = cand; // set
244  }// end loop over hits
245 
246 
247 
248 
249 
250  // TODO: Check if the following loops work
251  // After the FTS Hit Loop remove all candidates which do not have at least fMinFtsHitsPerTrack hits (from FTS)
252  // and remove all tracks which are bent in the dipole so much that they turn around and fly towards the barrel again (this leads to problems in the fitter)
253  if(0==iDet){ // only needed after PndTrkCand contain only FTS hits
254  if(fVerbose>5) Info("Exec","Remove all PndTrkCand which are not realistic to be found by FTS Pattern Recognition");
255 
256  // re-iterate over candlist and save key values for PndTrkCand which are not realisitic to be found by FTS PR in a vector
257  // these will be deleted after the clean loop
258  std::map<Int_t, PndTrackCand*>::iterator candit;
259  std::vector<Int_t> keysToDeleteFromCandList;
260 
261  if(fVerbose>10){
262  cout << "print the map keys BEFORE cleaning\n";
263  for(candit=candlist.begin(); candit!=candlist.end(); ++candit) {
264  cout << "trackID == " << candit->first << endl;
265  }
266  }
267 
268 
269  for(candit=candlist.begin(); candit!=candlist.end(); ++candit) {
270  Int_t trackID=candit->first;
271  PndTrackCand* tcand=candit->second;
272  if(!tcand) {
273  if(fVerbose>3) Warning("Exec","Have no candidate at %i",trackID);
274  continue;
275  }
276  // remove tcand if it does not have enough hits from FTS (after run with iDet == 0 only FTS hits are filled)
277  if( (int)tcand->GetNHits() < fMinFtsHitsPerTrack ){ // TODO: Make this criterion more realistic
278  if(fVerbose>9){
279  Info("Exec","Mark candlist[%i] for deletion because it has only %i FTS hits which is not enough.", trackID, tcand->GetNHits());
280  }
281  keysToDeleteFromCandList.push_back(trackID);
282  continue;
283  }
284 
285  // check if tcand is deflected too much in dipole and turns around again
286  tcand->Sort();
287 
288  // Go through all hits of the PndTrkCand and check if their z values are increasing.
289  // If not, remove the PndTrkCand from candlist
290  Double_t lastz = -100.; // saves the z-position of the last hit
291  for( size_t iSortedHit=0; iSortedHit<tcand->GetNHits(); ++iSortedHit ) {
292  // TODO: This needs to be checked
293  if(fVerbose>11) Info("Exec","Look at hit iSortedHit == %i", (int)iSortedHit);
294  PndTrackCandHit candhit = tcand->GetSortedHit(iSortedHit);
295  Int_t hitID = candhit.GetHitId();
296  Int_t detID = candhit.GetDetId();
297  if(fVerbose > 11) {
298  cout << "PndFtsTrackerIdeal at cleaning loop\n";
299  cout << "candhit = " << candhit << endl;
300  cout << "hitID = " << hitID << endl;
301  cout << "detID = " << detID << endl;
302  }
303  FairHit *hit = NULL;
304  // check if it really comes from the FTS (should always be true)
305  if(detID == FairRootManager::Instance()->GetBranchId("FTSHit")) {
306  hit = (PndFtsHit*) fHits[iDet]->At(hitID);
307  Int_t tubeID = ((PndFtsHit*) hit)->GetTubeID();
308  PndFtsTube *tube = (PndFtsTube*) fTubeArrayFts->At(tubeID);
309  if( tube->IsSkew() ){ // only check and count non-skewed hits
310  if(hit->GetRefIndex() == -1) {
311  Error("Exec","Cleaning loop found a hit which was not caused by any MC truth track at iSortedHit == %i",(int)iSortedHit);
312  }
313  else {
314  PndFtsPoint *pnt = (PndFtsPoint*) fMCPoints[0]->At(hit->GetRefIndex());
315  //if(tube->IsSkew()) nofFtsSkewPoints++;
316  //else nofFtsSkewPoints++;
317  // TODO: count if I have enough non-skewed hits from layers 1+2 and 3-5
318 
319  // determine if z-coordinates are increasing
320  if ( pnt->GetZ() < lastz ){
321  if(fVerbose>9){
322  Info("Exec","Mark candlist[%i] for deletion because the track turns around in the dipole field (its time-sorted hits have decreasing z values at some point).", trackID);
323  }
324  // delete candlist[trackID] check if this works
325  keysToDeleteFromCandList.push_back(trackID);
326  break; // do not look at further hits from that track, look at next track
327  }
328  else {
329  lastz = pnt->GetZ();
330  }
331  }
332  } // if IsSkew
333  } else Error("Exec","Cleaning loop found a hit from a detector other than FTS at iSortedHit == %i",(int)iSortedHit);
334 
335 
336 
337  } // sorted hit loop
338  if(fVerbose>3) Info("Exec","Ended cleaning loop for candidate with trackID %i",trackID);
339  } // for candidate cleaning loop
340 
341 
342  // now delete all keys from candlist that have previously been saved in the vector keysToDeleteFromCandList
343  for (size_t iKey=0; iKey<keysToDeleteFromCandList.size(); ++iKey){
344  if(fVerbose>10){
345  std::cout << "Delete key " << keysToDeleteFromCandList[iKey] << std::endl;
346  }
347  candlist.erase(keysToDeleteFromCandList[iKey]);
348  }
349  keysToDeleteFromCandList.clear();
350 
351  if(fVerbose>10){
352  cout << "print the map keys AFTER cleaning\n";
353  for(candit=candlist.begin(); candit!=candlist.end(); ++candit) {
354  cout << "trackID == " << candit->first << endl;
355  }
356  }
357 
358  } // if only FTS hits filled
359 
360 
361  }// end loop over detectors
362  // now we have track candidates
363  if(fVerbose>3) Info("Exec","Insert to TCA (depending on efficiency)");
364 
365  // re-iterate and select by efficiency & number of hits
366  std::map<Int_t, PndTrackCand*>::iterator candit;
367  //FairTrackParP* firstPar=NULL;
368  //FairTrackParP* lastPar=NULL;
369  PndMCTrack *mc=NULL;
370  TVector3 svtx, smom;
371  Int_t charge=0, trackID=-1;
372 
373  for(candit=candlist.begin(); candit!=candlist.end(); ++candit) {
374  PndTrackCand* tcand=candit->second;
375  trackID=candit->first;
376  if(!tcand) {
377  if(fVerbose>3) Warning("Exec","Have no candidate at %i",trackID);
378  continue;
379  }
380  if( tcand->GetNHits() < 3 ) continue; // Here the total number of hits in the candidate are considered, not just the FTS hits. Note that this is obsolete in case fMinFtsHitsPerTrack is set to 3 or more
381  if(0 < fEfficiency && fEfficiency < 1){
382  if(gRandom->Rndm() > fEfficiency) continue;
383  }
384  tcand->Sort();
385  mc = (PndMCTrack*)fMCTracks->At(trackID);
386  if (mc->GetPdgCode()<100000000) charge = (Int_t)TMath::Sign(1.0, ((TParticlePDG*)pdg->GetParticle(mc->GetPdgCode()))->Charge());
387  else charge = 1;
388  tcand->setMcTrackId(trackID);
389  // prepare track parameters
390  firstPoint[trackID]->Position(svtx); // set position to first hit
391  SmearFWD(svtx, fVtxSigma);
392  firstPoint[trackID]->Momentum(smom);
393  if (fRelative) fMomSigma.SetXYZ(fDPoP*smom.Mag(),fDPoP*smom.Mag(),fDPoP*smom.Mag());
394  SmearFWD(smom, fMomSigma);
395  FairTrackParP* firstPar=new FairTrackParP(svtx, smom,
397  charge, svtx,
398  TVector3(1.,0.,0.), TVector3(0.,1.,0.));
399 
400  lastPoint[trackID]->Position(svtx);
401  SmearFWD(svtx, fVtxSigma);
402  lastPoint[trackID]->Momentum(smom);
403  SmearFWD(smom, fMomSigma);
404  FairTrackParP* lastPar=new FairTrackParP(svtx, smom,
406  charge, svtx,
407  TVector3(1.,0.,0.), TVector3(0.,1.,0.));
408 
409  if(fVerbose>3) Info("Exec","Store candidate at %i",trackID);
410  // Creates a new track in the TClonesArray.
411  if(fVerbose>3) Info("AddTrack","Adding a Track.");
412  TClonesArray &pndtracks = *fTracks;
413  TClonesArray &pndtrackcands = *fTrackCands;
414  // TClonesArray &pndtrackids = *fTrackIds;
415  Int_t size = pndtrackcands.GetEntriesFast();
416  if(pndtracks.GetEntriesFast() != size) {
417  Error("Exec","Arrays out of synchronisation: %i tracks, %i cands. Abort event."
418  ,pndtracks.GetEntriesFast(),pndtrackcands.GetEntriesFast());
419  return;
420  }
421 
422  new(pndtrackcands[size]) PndTrackCand(*tcand);
423  new(pndtracks[size]) PndTrack(*firstPar, *lastPar, *tcand,0,0,1,mc->GetPdgCode(),trackID,FairRootManager::Instance()->GetBranchId("MCTrack"));
424  //delete(tcand);
425  delete(firstPar);
426  delete(lastPar);
427  }
428 
429  if(fVerbose>3) Info("Exec","End eventloop.");
430 }
431 
432 //_________________________________________________________________
434 {
435  std::cout << " Found "<< fTracks->GetEntriesFast() << " tracks\n";
436 }
437 
438 //________________________________________________________________
440  //---
441  if (fTracks->GetEntriesFast() != 0) fTracks->Delete();
442  if (fTrackCands->GetEntriesFast() != 0) fTrackCands->Delete();
443 }
444 
445 
446 //_________________________________________________________________
447 Int_t PndFtsTrackerIdeal::SetMinFtsHitsPerTrack(Int_t minFtsHitsPerTrack)
448 {
449  // check that the argument is >= 1
450  if (minFtsHitsPerTrack<1)
451  {
452  minFtsHitsPerTrack=1;
453  }
454  fMinFtsHitsPerTrack=minFtsHitsPerTrack;
455  return fMinFtsHitsPerTrack;
456 }
457 
458 
459 
460 //_________________________________________________________________
461 void PndFtsTrackerIdeal::SmearFWD(TVector3 &vec, const TVector3 &sigma)
462 {
463  // gaussian smearing
464  Double_t rannn=0.;
465  rannn = gRandom->Gaus(vec.X(),sigma.X());
466  vec.SetX(rannn);
467 
468  rannn = gRandom->Gaus(vec.Y(),sigma.Y());
469  vec.SetY(rannn);
470 
471  rannn = gRandom->Gaus(vec.Z(),sigma.Z());
472  vec.SetZ(rannn);
473 
474  return;
475 }
476 
478 
virtual void Exec(Option_t *option)
int fVerbose
Definition: poormantracks.C:24
Int_t fMinFtsHitsPerTrack
Array of track IDs (Links)
Int_t i
Definition: run_full.C:25
void SetTrackOutput(TString name="FTSTrkIdeal")
Int_t GetPdgCode() const
Definition: PndMCTrack.h:73
PndTrackCandHit GetSortedHit(UInt_t i)
Definition: PndTrackCand.h:54
void setMcTrackId(int i)
Definition: PndTrackCand.h:72
TClonesArray * pnt
Double_t sigma[nsteps]
Definition: dedx_bands.C:65
cout<< "POINTs for new FwEndCap == "<< tsim-> GetEntriesFast()
Bool_t fBranchActive[4]
Array of Branch IDs.
Int_t GetLayerID() const
Definition: PndFtsHit.h:74
TClonesArray * fHits[4]
Array of event&#39;s points.
void SmearFWD(TVector3 &vec, const TVector3 &sigma)
void AddHit(UInt_t detId, UInt_t hitId, Double_t rho)
TClonesArray * fMCTracks
Double_t
TClonesArray * fTubeArrayFts
FairRuntimeDb * rtdb
Definition: hit_dirc.C:66
virtual InitStatus Init()
TClonesArray * fTrackCands
Array of disabled stations.
Int_t fBranchIDs[4]
Array of event&#39;s hits.
PndGeoFtsPar * fFtsParameters
Particle DB.
bool IsSkew() const
Definition: PndFtsTube.h:32
Int_t SetMinFtsHitsPerTrack(Int_t minFtsHitsPerTrack=5)
TClonesArray * fTracks
Array of found track candidates.
UInt_t GetNHits() const
Definition: PndTrackCand.h:59
ClassImp(PndAnaContFact)
TClonesArray * FillTubeArray()
this function will be used in PndFtsHitProducesRealFast
TClonesArray * fMCPoints[4]
Array of PndMCTrack.
std::map< int, bool > fStationsDisabled
Array of Branch Activeness.
PndSdsMCPoint * hit
Definition: anasim.C:70
Int_t GetHitId() const
cout<<"the Event No is "<< i<< endl;{{if(hit_array->GetEntriesFast()!=mc_array->GetEntriesFast()) continue;PndSdsHit *hit=(PndSdsHit *) hit_array-> At(j)
Definition: anaLmdCluster.C:71
dble_vec_t vec[12]
Definition: ranlxd.cxx:380
Int_t GetDetId() const