PandaRoot
PndFtsHoughSpace.h
Go to the documentation of this file.
1 
25 #ifndef PndFtsHoughSpace_H
26 #define PndFtsHoughSpace_H
27 
28 #include "PndFtsHoughTrackerTask.h"
29 #include "PndFtsHoughSpacePeak.h"
31 
32 #include "TH2.h"
33 #include <cmath>
34 #include <vector>
35 #include "Rtypes.h" // for Double_t, Int_t, etc
36 #include "FairLogger.h" // for FairLogger, MESSAGE_ORIGIN
37 
38 #include "PndTrackCandHit.h"
39 #include "TClonesArray.h"
40 
41 // magnetic field
42 #include "FairField.h"
43 #include "TVector3.h"
44 
45 #include "PndFtsHoughTracklet.h"
46 #include "PndFtsHoughTrackCand.h"
47 
48 // For error throwing
49 #include "TString.h"
50 #include <stdexcept>
51 
52 // for saving the path through the Hough space
53 typedef std::vector<Int_t> IdxPath; // helper -- path for one hit
54 typedef std::map<Int_t, IdxPath> HitIdxPathMap; // that is the one I need -- map of hit indices to path for the corresponding hits
55 typedef std::pair<Int_t, IdxPath> HitIdxPathPair; // helper for inserting one pair of hit index and path in map
56 
57 // cout for the above types
58 std::ostream &operator<<(std::ostream &os, const IdxPath &outVector);
59 std::ostream &operator<<(std::ostream &os, const HitIdxPathMap &outMap);
60 
61 class PndFtsHoughSpace : public TH2S {
62  public:
63  // Constructors/Destructors ---------
64  PndFtsHoughSpace(const char *name = nullptr, const Int_t refIndex = -1,
65 
67 
68  Double_t zRefPos = 0., Double_t interceptZx = 0.,
69 
70  PndFtsHoughTrackCand *associatedTrackCand = nullptr,
71 
72  PndFtsHoughTrackerTask *trackerTask = nullptr);
74 
75  // TH2S ExportTH2S();
76 
77  // General info for peak finders
78  // The peaks contain the following information
79  // peakTheta = theta for peak
80  // peakSecond = Q/pzx for peak (parabola HT)
81  // peakSecond = intercept for peak (line HT) (in z-x- or z-y-plane)
82  //
83  // peakThetaHw = half width of peak in theta
84  // peakSecondHw = half width of peak in second value (see above for what it stands for)
85  //
86  // actualHeight height of the peak in the histogram (in counts)
87 
93  std::vector<PndFtsHoughTracklet> FindAllPeaksScanPathsMergeBins(const UInt_t minHeight);
94 
100  std::vector<PndFtsHoughTracklet> FindAllPeaksScanPathsMergeBinsCalculatingPaths(const UInt_t minHeight);
101 
107  std::vector<PndFtsHoughTracklet> FindAllPeaksWithTSpectrum2(const UInt_t minHeight);
108 
114  std::vector<PndFtsHoughTracklet> FindAllPeaksBinsWoMergingWithSearchWindow(const UInt_t minHeight, const Int_t vicinityLength = 0);
115 
121  std::vector<PndFtsHoughTracklet> FindAllPeaksBlanko(const UInt_t minHeight);
122 
139  void FillHoughSpace();
140 
141  // operators
142  // PndFtsHoughSpace are the same if they contain the same hits, that means if the PndTrackCand are the same, therefore no need to implement that operator here
143 
144  // Accessors -----------------------
145  inline void Print() const;
146 
147  void setVerbose(Int_t verbose) { fVerbose = verbose; };
148 
149  Double_t getInterceptZx() const { return fInterceptZx; };
150 
151  Double_t getZRefPos() const { return fZRefPos; };
152 
153  inline UInt_t GetNHits() const { return fHitId.size(); };
154 
155  private:
156  // for PandaRoot input/output
157  PndFtsHoughTrackerTask *fTrackerTask;
158 
160  void throwError(const TString s) const { throw std::runtime_error(s.Data()); };
161 
162  Bool_t setParametersForHsOption(); // set parameters according to the kind of Hough transform I want to do
163  void filterInputHits(); // copies input hits (based on z coordinate and skewed/non-skewed) from fFtsHitArray (all FTS hits) to fHitId (only the hits that qualify for the specific
164  // Hough transform)
165  inline void AddHitToHS(UInt_t hitId, Double_t rho);
166  inline void AddHitToHS(FairLink link, Double_t rho);
167  inline Bool_t IsHitFromTubeIdAlreadyAdded(const Int_t tubeIdToAdd);
168  inline const PndFtsHit *getHitFromHS(UInt_t index) const; // gets the FTS hit corresponding to index
169  inline Int_t getHitIdFromHS(UInt_t index) const { return fHitId.at(index).GetHitId(); }; // gets the FTS hit Id corresponding to index
170  inline const TVector3 CalculateHitPosFromIntersectionsWithZxTrackModel(const PndFtsHit *const myHit) const;
171  inline const TVector3 GetRawOrCalculatedHitPos(const PndFtsHit *const myHit) const;
172 
173  void AddHitsToTrackletByCalculating(PndFtsHoughTracklet *currentTracklet, Int_t locmax);
174 
180  HitIdxPathMap fHitThetaYIdxPath;
181 
182  // Private Data Members ------------
183  Int_t fVerbose;
184  const Int_t fRefIndex;
185 
187  Int_t fFtsBranchId;
188  std::vector<PndTrackCandHit> fHitId;
189 
191  PndFtsHoughTrackCand *fAssociatedTrackCand;
192 
193  // only hits with a z value (in the laboratory system, zreal) between onlyusehitsfromz and onlyusehitsuptoz will be used for building the houghspace
194  Double_t fOnlyUseHitsFromZ;
195  Double_t fOnlyUseHitsUpToZ;
196  Bool_t fUseNonSkewedStraws; // if kTRUE, then hits from non-skewed straws are used for Hough transform
197  Bool_t fUseSkewedStraws; // if kTRUE, then hits from skewed straws are used for Hough transform
198 
199  Bool_t fKeepBConstant; // set only to kFALSE for testing
200  // If kTRUE the y-component of the B-field is not used in the parabola hough transform
201  // if kFALSE the parabola's shape will be adjusted based on the magnetic field maps
202 
203  // at which z value the values are calculated
204  Double_t fZRefPos; // is used to redefine an origin for the coordinate system (so that the angle definition gives meaningful theta values)
205  // Double_t interceptZx; // cannot be constant, because might need to be reset if set incorrectly (has to be 0 for line HT)
206  // is used to shift the true x values of hits so that they hit the point (zOffset|0) in z-x-plane (value is determined by line fit on chambers1+2)
207  // (zreal=zOffset, xreal=interceptZx) = (zshifted = 0, xshifted = 0)
208  // zshifted = zreal - zRefPos
209  // xshifted = xreal - interceptZx
210  // zreal = zshifted + zRefPos
211  // xreal = xshifted + interceptZx
212  // For the z-x-plane parabola, a shift in x (hitshiftinx) needs to be set (which should be the result of the straight line hough transform before the dipole field)
213  // For the straight line (stations before dipole field) hitshiftinx HAS TO BE ZERO
214 
215  // is used only for parabola in zx plane to shift the true x values of hits so that they hit the point (zOffset|0) in z-x-plane (value is determined by line fit on chambers1+2)
216  Double_t fInterceptZx;
217 
218  // for B field access
219  FairField *fField;
220 
221  // for HoughTransform
223  // if kTRUE will correct the pzx prediction according to values which should be obtained from a line fit mc truth momentum VS. reco momentum with high statistics
224  static const Bool_t fCorrectPzx = kFALSE;
225 
240  inline Bool_t FillHoles(const Int_t lastBinX, const Int_t lastBinY, const Int_t currentBinY, IdxPath *ptrThetaYIdxPathVec);
241 
242  inline Double_t equationParabola(Double_t thetaRad, Double_t hitZShifted, Double_t hitXShifted, Double_t By)
243  {
244  // for parabola equation
245  const Double_t n = 1.;
246  const Double_t e = 1.;
247  const Double_t c = n * e / 2.;
248 
249  Double_t yVal = 1. / c / By * (-hitZShifted * sin(thetaRad) + hitXShifted * cos(thetaRad)) / pow((hitZShifted * cos(thetaRad) + hitXShifted * sin(thetaRad)), 2);
250 
251  // next line is with rotation as in paper (I believe it is incorrect)
252  // value = 1. / c / By * (hitZshifted * sin(realtheta) - hitXshifted * cos(realtheta))/ pow((hitZshifted * cos(realtheta) + hitXshifted * sin(realtheta)), 2);
253  return yVal;
254  };
255 
256  inline Double_t equationParabolaPz(Double_t thetaRad, Double_t hitZShifted, Double_t hitXShifted, Double_t By)
257  {
258  // for parabola equation
259  const Double_t n = 1.;
260  const Double_t e = 1.;
261  const Double_t c = n * e / 2.;
262 
263  // Use shifted x and shifted z for parabola
264  Double_t yVal = c * By * pow((hitZShifted * cos(thetaRad) + hitXShifted * sin(thetaRad)), 2) / (-hitZShifted * sin(thetaRad) + hitXShifted * cos(thetaRad));
265 
266  // next line is with rotation as in paper (I believe it is incorrect)
267  // value = c*By*pow((hitZshifted * cos(realtheta) + hitXshifted * sin(realtheta)), 2)/(hitZshifted * sin(realtheta) - hitXshifted * cos(realtheta));
268 
269  return yVal;
270  };
271 
272  inline Double_t equationLineZxOrZy(Double_t thetaRad, Double_t hitZShifted, Double_t hitXLabSys)
273  { // TODO: Check if that also works in zy plane
274  // calculate b which is the distance of point on line at z = zOffset from z axis
275  Double_t yVal = -tan(thetaRad) * hitZShifted + hitXLabSys;
276  return yVal;
277  }
278 
279  //------
280  // DEBUG
281  //-----
284  inline TString GetDebugOutName(TString title = "", Int_t param = -1) const;
287  void WriteHistoOfHoughSpace() const;
290  TH2S MakeEmptyHistoOfSameDimensions(TString specifier = "", Int_t index = -1) const;
293  void WriteHistoOfAllPeaks(const std::vector<PndFtsHoughSpacePeak> &peaksToPlot) const;
296  void WriteHistoOfAllPaths() const;
300  void WriteHistoOfAllPathsForEachMcTruthTrack() const;
301  inline void PrintFoundTracklets(const std::vector<PndFtsHoughTracklet> &tracklets) const;
302  inline Double_t getByFromBField(Double_t hitXLabSys, Double_t hitYLabSys, Double_t hitZLabSys);
303 
304  public:
306 };
307 
308 // inline functions
310 {
311  std::cout << "=========== PndFtsHoughSpace::Print() ==========" << '\n';
312  std::cout << "fZRefPos = " << fZRefPos << '\n';
313  std::cout << "fInterceptZx = " << fInterceptZx << 'n';
314  TH2S::Print();
315 }
316 
317 void PndFtsHoughSpace::PrintFoundTracklets(const std::vector<PndFtsHoughTracklet> &tracklets) const
318 {
319  std::cout << tracklets.size() << " peaks found for " << GetName() << '\n';
320  if (10 < fVerbose) {
321  for (UInt_t i = 0; i < tracklets.size(); ++i) {
322  tracklets[i].Print();
323  }
324  }
325 }
326 
327 const PndFtsHit *PndFtsHoughSpace::getHitFromHS(UInt_t index) const
328 {
329  if (GetNHits() < index)
330  throwError("index too high");
331 
332  Int_t hitIndex = fHitId.at(index).GetHitId();
333  const PndFtsHit *const myHit = (PndFtsHit *)fTrackerTask->GetFtsHit(hitIndex);
334  return myHit;
335 }
336 
337 const TVector3 PndFtsHoughSpace::GetRawOrCalculatedHitPos(const PndFtsHit *const myHit) const
338 {
339  // get hit position
340  TVector3 hitPos;
341  if (kFALSE == myHit->GetSkewed()) {
342  myHit->Position(hitPos);
343  } else {
344  hitPos = CalculateHitPosFromIntersectionsWithZxTrackModel(myHit);
345  }
346  return hitPos;
347 }
348 
349 const TVector3 PndFtsHoughSpace::CalculateHitPosFromIntersectionsWithZxTrackModel(const PndFtsHit *const myHit) const
350 {
351  if (0 == fAssociatedTrackCand)
352  throwError("No track cand associated with Hough space. Cannot calculate possible hit pos. from track model.");
353 
354  const PndFtsTube *ftsTube = fTrackerTask->GetFtsTube(myHit);
355  const TVector3 wireDirection = ftsTube->GetWireDirection();
356  const TVector3 wireCenter = ftsTube->GetPosition();
357 
358  const Double_t hitZLabSys = wireCenter.Z();
359 
360  // calculate xTM according to track model at hitZLabSys
361  const Double_t xTM = fAssociatedTrackCand->getXLabSys(hitZLabSys);
362  // calculate param which is needed for xStraw = xTM
363  // xTM = wireCenter.X() + param*wireDirection.X()
364  const Double_t param = (xTM - wireCenter.X()) / wireDirection.X();
365  // calculate corresponding yStraw
366  const Double_t yStraw = wireCenter.Y() + param * wireDirection.Y();
367 
368  TVector3 crossingPosition(xTM, yStraw, hitZLabSys);
369  return crossingPosition;
370 }
371 
372 TString PndFtsHoughSpace::GetDebugOutName(TString title, Int_t param) const
373 {
374  TString debugOut = "/home/plots/";
375  debugOut += fTrackerTask->GetEventNr();
376  debugOut += title;
377  if (-1 != fRefIndex) {
378  debugOut += "-rId";
379  debugOut += fRefIndex;
380  }
381  if (-1 != param) {
382  debugOut += param;
383  }
384  debugOut += ".rtg"; // root textual graphics ;) -- actually just a macro // png does not work in this way
385  return debugOut;
386 }
387 
388 Double_t PndFtsHoughSpace::getByFromBField(Double_t hitXLabSys, Double_t hitYLabSys, Double_t hitZLabSys)
389 {
390  Double_t By = 0.;
391  // set y component of B field constant
392  if (kTRUE == fKeepBConstant) {
393  // do not take B field into account
394  By = 1.;
395  } else {
396  // Use B field information
397  Double_t po[3], BB[3];
398  po[0] = hitXLabSys; // Use magnetic field at real (not shifted) x position
399  po[1] = hitYLabSys;
400  po[2] = hitZLabSys;
401  fField->GetFieldValue(po, BB); // return value in KG (G3)
402  By = BB[1] / 10.; // By is y-component of magnetic field in Tesla
403  }
404  return By;
405 }
406 
407 #endif
void setVerbose(Int_t verbose)
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:119
std::vector< PndFtsHoughTracklet > FindAllPeaksWithTSpectrum2(const UInt_t minHeight)
Finds all peaks that satisfy the minimum height requirement minHeight.
const PndFtsTube * GetFtsTube(const PndFtsHit *const myHit) const
Returns pointer to the FTS tube corresponding to input FTS hit.
std::vector< PndFtsHoughTracklet > FindAllPeaksBinsWoMergingWithSearchWindow(const UInt_t minHeight, const Int_t vicinityLength=0)
Finds all peaks that satisfy the minimum height requirement minHeight.
Interface between PandaRoot (data input and output) and PndFtsHoughTrackFinder (implementation of PR ...
Double_t getZRefPos() const
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:118
TVector3 GetPosition() const
const PndFtsHit * GetFtsHit(UInt_t hitId) const
Returns pointer to the hit with index hitId in the FTS hit array.
std::vector< PndFtsHoughTracklet > FindAllPeaksScanPathsMergeBins(const UInt_t minHeight)
Finds all peaks that satisfy the minimum height requirement minHeight.
std::vector< PndFtsHoughTracklet > FindAllPeaksScanPathsMergeBinsCalculatingPaths(const UInt_t minHeight)
Finds all peaks that satisfy the minimum height requirement minHeight.
Int_t GetSkewed() const
Definition: PndFtsHit.h:74
unsigned int i
Definition: P4_F32vec4.h:21
UInt_t GetEventNr() const
Returns the save debug flag.
Class for saving the result of one Hough transform for FTS PR.
std::ostream & operator<<(std::ostream &os, const IdxPath &outVector)
Double_t getXLabSys(const Double_t zLabSys) const
Class for Hough space based on TH2S (for the moment). Saves the hits which enter this Hough space and...
UInt_t GetNHits() const
void Print() const
std::map< Int_t, IdxPath > HitIdxPathMap
Helper class for Hough space containing binning. Created: 09.02.2015.
PndFtsHoughSpace(const char *name=nullptr, const Int_t refIndex=-1, PndFtsHoughSpaceBinning binning=PndFtsHoughSpaceBinning(), Double_t zRefPos=0., Double_t interceptZx=0., PndFtsHoughTrackCand *associatedTrackCand=nullptr, PndFtsHoughTrackerTask *trackerTask=nullptr)
TVector3 GetWireDirection() const
Class for saving a FTS track cand. for Hough transform based FTS PR.
std::vector< PndFtsHoughTracklet > FindAllPeaksBlanko(const UInt_t minHeight)
Finds all peaks that satisfy the minimum height requirement minHeight.
ClassDef(PndFtsHoughSpace, 1)
Double_t getInterceptZx() const
std::pair< Int_t, IdxPath > HitIdxPathPair
void FillHoughSpace()
Fills the Hough space using the equation which corresponds to the name of the Hough space...
std::vector< Int_t > IdxPath