FairRoot/PandaRoot
PndFtsHoughTrackCand.cxx
Go to the documentation of this file.
1 #include "PndFtsHoughTrackCand.h"
2 
4 
5 
6 #include <iostream>
7 #include "math.h"
8 
9 #include "TClonesArray.h"
10 #include "FairRootManager.h"
11 #include "PndFtsHit.h"
12 #include "PndTrack.h"
13 #include "FairTrackParP.h"
14 #include "TVector3.h"
15 
17 
19  fTrackerTask(trackerTask),
20 
21  fVerbose(0),
22 
23  fZxLineBeforeDipole(0., trackerTask), // TODO: It could be a problem here that I set the z reference value to 0.
24 
25  fZxParabola(0., trackerTask),
26 
27  fZxLineBehindDipole(0., trackerTask),
28 
29  fZyLine(0., trackerTask),
30 
31  fIntTrackCand(),
32 
33  fZCoordLineParabola(0.),
34  fZCoordParabolaLine(0.)
35 {
36  if (0==fTrackerTask){
37  std::cout << "PndFtsHoughTrackCand FATAL ERROR Tracker task pointer not set.\n";
38  } else {
40  if(3<fVerbose) std::cout << "PndFtsHoughTrackCand called with tracker ptr " << fTrackerTask << '\n';
41  }
42 }
43 
45 {
46 
47 }
48 
49 
51  if (fZxLineBeforeDipole.isSet()) {
52  std::cerr << "WARNING from PndFtsHoughTrackCand: Line before dipole in zx plane is set more than once! Ignore new values! Potentially FATAL ERROR!\n";
53  return;
54  }
55  fZxLineBeforeDipole = zxLineParabola;
58 }
60  if (fZxParabola.isSet()) {
61  std::cerr << "WARNING from PndFtsHoughTrackCand: Parabola inside dipole in zx plane is set more than once! Ignore new values! Potentially FATAL ERROR!\n";
62  return;
63  }
64  // warn if line before dipole field and parabola within are not calculated wrt the same z reference value
65  if (zxParabola.getZRefLabSys() != fZCoordLineParabola){
66  std::cout << "WARNING from PndFtsHoughTrackCand: First line and parabola were not calculated wrt the same z position! Potentially FATAL ERROR!\n";
67  }
68  fZxParabola = zxParabola;
70 }
72  if (fZxLineBehindDipole.isSet()) {
73  std::cerr << "WARNING from PndFtsHoughTrackCand: Line behind dipole in zx plane is set more than once! Ignore new values! Potentially FATAL ERROR!\n";
74  return;
75  }
76  fZxLineBehindDipole = zxParabolaLine;
79 }
81  if (fZyLine.isSet()) {
82  std::cerr << "WARNING from PndFtsHoughTrackCand: Line in zy plane is set more than once! Ignore new values! Potentially FATAL ERROR!\n";
83  return;
84  }
85  fZyLine=zyLine;
87 }
88 
89 
90 
91 
92 
93 
95  std::cout << "=========== PndFtsHoughTrackCand::Print() ==========\n";
97  if (kTRUE==fZxLineBeforeDipole.isSet()){
98  std::cout << "zx plane\n\n";
99  std::cout << "1st line: ";
101  }
102  if (kTRUE==fZxParabola.isSet()){
103  std::cout << "parabola: ";
104  fZxParabola.Print();
105  }
106  if (kTRUE==fZxLineBehindDipole.isSet()){
107  std::cout << "2nd line: ";
109  }
110  if (kTRUE==fZyLine.isSet()){
111  std::cout << "zy plane\n\n";
112  std::cout << "Line: ";
113  fZyLine.Print();
114  }
115 }
116 
117 
118 
120 {
121  // add all the hits from the tracklet which are not already in the hitId vector
122  for (UInt_t iHit = 0; iHit < inTracklet.GetNHits(); ++iHit)
123  {
124  PndTrackCandHit inHit = inTracklet.GetSortedHit(iHit);
125  const Int_t inHitId = inHit.GetHitId();
126  const Int_t inDetId = inHit.GetDetId();
127  // if hit is NOT in track -1 is returned by HitInTrack, otherwise the index (>=0) in the HitId vector is returned
128  if (-1==fIntTrackCand.HitInTrack(inDetId,inHitId)){
129  // add hit to track cand
130  const Double_t inRho = inHit.GetRho();
131  fIntTrackCand.AddHit(inDetId, inHitId, inRho);
132  }
133  }
134 }
135 
136 
137 // TODO: Check this!
139  // does not take option of varying B field into account
140  // calculate x in lab sys for a given z position in lab sys for which the parabola assumption holds
141  // theta in radian in zx plane given at z = zRefLabSys
142  const Double_t thetaRad = fZxParabola.getThetaRadVal();
143  const Double_t qDivPzx = getQdivPzx(); // Q/pzx
144  const Double_t zRefLabSys = fZxParabola.getZRefLabSys();
145  const Double_t zshifted = zLabSys-zRefLabSys;
146 
147  const Double_t interceptLine = fZxLineBeforeDipole.getSecondVal();
148 
149  const Double_t By = 1.;
150 
151  if (0==thetaRad){
152  Double_t xParabolaSys = qDivPzx /2. * By * zshifted;
153  // go from local parabola system to the lab system
154  Double_t xLabSys = xParabolaSys + interceptLine;
155  return xLabSys;
156  }
157 
158 
159  const Double_t tantheta = tan(thetaRad);
160  const Double_t pzstuff = 1. / qDivPzx / By / sin(thetaRad);
161  const Double_t ztantheta = zshifted / tantheta;
162  const Double_t a = -ztantheta + pzstuff / tantheta;
163 
164  const Double_t wurzel = sqrt(a * a - 2. * pzstuff * zshifted - ztantheta * ztantheta);
165  const Double_t x1ParabolaSys = a - wurzel;
166  const Double_t x2ParabolaSys = a + wurzel;
167 
168  // go from local parabola system to the lab system
169  Double_t x1LabSys = x1ParabolaSys + interceptLine;
170  Double_t x2LabSys = x2ParabolaSys + interceptLine;
171 
172  // there are two analytical solutions, take the one closer to 0
173  if (fabs(x1LabSys)<fabs(x2LabSys)) {
174  return x1LabSys;
175  } else {
176  return x2LabSys;
177  }
178 }
179 
180 
181 
182 
183 
185  return fIntTrackCand;
186 
187  // // The following is what I used when I derived this class from PndTrackCand. Instead this class now contains a member of PndTrackCand
188  // // Maybe this is not necessary because PndFtsHoughTrackCand is derived from PndTrackCand
189  // PndTrackCand myCand;
190  // // copy all the hits from PndFtsHoughTrackCand *this to PndTrackCand myCand
191  // for (UInt_t iHit = 0; iHit < intTrackCand.GetNHits(); ++iHit)
192  // {
193  // PndTrackCandHit inHit = intTrackCand.GetSortedHit(iHit);
194  // const Int_t inHitId = inHit.GetHitId();
195  // const Int_t inDetId = inHit.GetDetId();
196  // const Double_t inRho = inHit.GetRho();
197  // myCand.AddHit(inDetId, inHitId, inRho);
198  // }
199  // return myCand;
200 }
201 
202 
203 
204 // for conversion to PndTrack, compare to tools/riemannfit/PndRiemannTrack.cxx, line 1104
205 //--------------------------------------------------------------------------------------------
206 // getNumHits is called getNHits in PndTrackCand (which I use to store the hits belonging to this track candidate)
207 // I don't need the B field to calculate the parameters
209  // calculates first and last parameter, but uses an empty PndTrackCand which has to be set lateron using SetTrackCandRef
210  FairTrackParP firstPar, lastPar;
211  PndTrackCand myCand;
212  if (fIntTrackCand.GetNHits() > 0){
213  firstPar = getTrackParPForHit(0);
215  }
216  return PndTrack(firstPar, lastPar, myCand);
217 }
218 
219 
220 FairTrackParP PndFtsHoughTrackCand::getTrackParPForHit(const UInt_t index) {
221  // index is the index of the hit in intTrackCand, not in the FTS hit array
222  // this method will sort the hitId vector of intTrackCand and therefore cannot be used for const track candidates
223 
224  // TODO: Check if all arguments are correct
225 
226  // Warn if we do not have a complete track candidate
227  if (!isComplete()) std::cout << "getHit: You try to access hits before we have a complete track candidate.\n";
228 
229  // not necessary, I check later if I get a hit or not
230  //if (index >= intTrackCand.GetNHits()) throwError("index in PndFtsHoughTrackCand::getTrackParPForHit is too large.");
231 
232  // Translate index in track candidate to hitId in FTS hit array
233  UInt_t hitId = fIntTrackCand.GetSortedHit(index).GetHitId();
234 
235  // get position of hit
236  const PndFtsHit *myHit = fTrackerTask->GetFtsHit(hitId);
237  if (0 == myHit) throwError("Cannot get hit, probably the tracking has not finished or the index is too large.");
238 
239  // Take z of hit and calculate the position and momentum for that z using the results from the Hough transforms and my track model
240  Double_t zLabSys = myHit->GetZ();
241 
242  // position should NOT come from hit, it should come from the pattern recognition track model
243  // position error can be large (like 1* or 2* tube size) as the Kalman filter will adjust it.
244  TVector3 hitPos = getPos(zLabSys);
245 
246 
247  TVector3 hitPosError = fTrackerTask->GetFtsHitPosErrors(myHit);
248 
249  // momentum comes from the pattern recognition track model
250  TVector3 mom = getP(zLabSys);
251  TVector3 momError = 0.1*mom; // TODO: add correct values here
252 
253  // set plane as detector plane in which the hit is, FTS planes are parallel to xy plane
254  TVector3 origin; // set origin of plane = position of hit
255  myHit->Position(origin);
256  TVector3 dj(1,0,0); // unit vector along x // TODO: Check if that is set correctly for FTS
257  TVector3 dk(0,1,0); // unit vector along y // TODO: Check if that is set correctly for FTS
258 
259  // ----- Constructor with track parameters in LAB -----------------------------------
260  // FairTrackParP::FairTrackParP(TVector3 pos, TVector3 Mom, TVector3 posErr, TVector3 MomErr, Int_t Q, TVector3 o, TVector3 dj, TVector3 dk)
261  FairTrackParP result(hitPos, mom, hitPosError, momError, getCharge(), origin, dj, dk);
262  return result;
263 }
264 
265 TVector3 PndFtsHoughTrackCand::getP(const Double_t zLabSys) const{
266  throwIfZOutOfRange(zLabSys);
267 
268  TVector3 mom;
269 
270  if (kFALSE == isComplete())
271  {
272  std::cout << "getPforHit: Track cand. is not complete yet. Momentum will be calculated for incomplete track cand.\n";
273  }
274 
275  Double_t pZLabSys;
276  Double_t pXLabSys;
277  std::pair<Double_t, Double_t> pZPXLabSys;
278 
279  // track model is assumed to be line+parabola+line in zx and line in zy
280  if ( zLabSys <= fZCoordLineParabola ){
281  // use 1st line in zx plane
282  pZPXLabSys = getPZPXLabLine(zLabSys, &fZxLineBeforeDipole);
283  } else if ( zLabSys < fZCoordParabolaLine ){
284  // use "tangent" to parabola in zx plane
285  pZPXLabSys = getPZPXLabParabola(zLabSys);
286  } else {
287  // use 2nd line in zx plane
288  pZPXLabSys = getPZPXLabLine(zLabSys, &fZxLineBehindDipole);
289  }
290 
291  pZLabSys = pZPXLabSys.first;
292  pXLabSys = pZPXLabSys.second;
293  const Double_t pYLabSys = getPYLab();
294  mom.SetXYZ(pXLabSys, pYLabSys, pZLabSys);
295  if (fVerbose > 10) std::cout << "P-Vector for z=" << zLabSys << " : " << mom.X() << " " << mom.Y() << " " << mom.Z() << '\n';
296  return mom;
297 }
298 
299 
301  // estimate angle by calculating 2 points (zLabSys1, xLabSys1) and (zLabSys2, xLabSys2) which are close together
302 
303  throwIfZOutOfRange(zLabSys);
304 
305  const Double_t epsilon = 0.5; // small positive number
306 
307  const Double_t xLabSys1 = getXLabSys(zLabSys-epsilon);
308  const Double_t xLabSys2 = getXLabSys(zLabSys+epsilon);
309 
310  return atan2(xLabSys2-xLabSys1, 2*epsilon);
311 }
312 
314  // calculates the corresponding x coordinate to a given z coordinate according to the track model
315 
316  throwIfZOutOfRange(zLabSys);
317 
318  if (zLabSys <= fZCoordLineParabola) {
319  // use 1st line in zx plane
320  return getXOrYLabForLine(zLabSys, &fZxLineBeforeDipole);
321  } else if (zLabSys < fZCoordParabolaLine) {
322  // use parabola in zx plane
323  return getXLabForParabola(zLabSys);
324  } else {
325  // use 2nd line in zx plane
326  return getXOrYLabForLine(zLabSys, &fZxLineBehindDipole);
327  }
328  throwError("Argument was not handled!");
329 }
330 
331 TVector3 PndFtsHoughTrackCand::getPos(const Double_t zLabSys) const{
332  // calculates the point on the track based on the results from the Hough transforms using my track model for the given z
333 
334  throwIfZOutOfRange(zLabSys);
335 
336  if (kFALSE == isComplete()) std::cout << "getPositionForHit: Track cand. is not complete yet. Position will be calculated for incomplete track cand.\n";
337 
338  TVector3 position;
339  // track model is assumed to be line+parabola+line in zx and line in zy
340  const Double_t yLabSys = getXOrYLabForLine(zLabSys, &fZyLine);
341 
342  Double_t xLabSys = getXLabSys(zLabSys);
343 
344  position.SetXYZ(xLabSys, yLabSys, zLabSys);
345  if (fVerbose > 10) std::cout << "Pos-Vector for z=" << zLabSys << " : " << position.X() << " " << position.Y() << " " << position.Z() << '\n';
346  return position;
347 }
348 
349 
350 
351 // end for conversion to PndTrack
353 
354 
355 
356 
357 
358 //Double_t PndFtsHoughTrackCand::getThetaZxComplicated(const Double_t zLabSys) const{
359 // throwIfZOutOfRange(zLabSys);
360 //
361 // if ( zLabSys <= fZCoordLineParabola ){
362 // // use 1st line in zx plane
363 // return fZxLineBeforeDipole.getThetaRadVal();
364 // } else if ( zLabSys < fZCoordParabolaLine ){
365 // // use parabola to calculate angle in zx plane
366 // return getThetaZxLabForParabolaUnused(zLabSys);
367 // } else {
368 // // use 2nd line in zx plane
369 // return fZxLineBehindDipole.getThetaRadVal();
370 // }
371 //}
372 
373 
374 // Double_t getThetaZxLabForParabolaComplicated(const Double_t &zLabSys) const {
375 // // calculate theta in radian in zx plane for parabola part of track model
376 // // go into local coordinate system and use derivation of parabola to calculate angles, then add rotation of coordinate systems
377 //
378 // // go from lab system into local parabola system
379 // // which is rotated with thetaRadVor
380 // // and shifted (compare to PndFtsHoughSpace)
381 // const Double_t thetaZxRadVor = fZxLineBeforeDipole.getThetaRadVal();
382 // const Double_t zRefPos = fZxLineBeforeDipole.getZRefLabSys();
383 // const Double_t interceptZx = fZxLineBeforeDipole.getSecondVal();
384 //
385 // const Double_t pZxInv = getQoverPzx()/getCharge();
386 //
387 // // is used to redefine an origin for the coordinate system (so that the angle definition gives meaningful theta values)
388 // // Double_t interceptZx; // 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)
389 // // (zreal=zOffset, xreal=interceptZx) = (zshifted = 0, xshifted = 0)
390 // // zshifted = zreal - zRefPos
391 // // xshifted = xreal - interceptZx
392 // // zreal = zshifted + zRefPos
393 // // xreal = xshifted + interceptZx
394 // // 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)
395 //
396 // // shifted origin between global and local coordinate system
397 // const Double_t zshifted = zLabSys - zRefPos;
398 // const Double_t xshifted = getXLabForParabola(zLabSys) - interceptZx;
399 //
400 // // rotation of local coordinate system wrt (shifted) global coordiate system
401 // const Double_t zShiftedRotated = zshifted * cos(thetaZxRadVor) + xshifted*sin(thetaZxRadVor);
402 //
403 //
404 // // for parabola equation
405 // const Double_t n = 1.;
406 // const Double_t e = 1.;
407 // const Double_t By = 1.;
408 //
409 //
410 // // calculate rotation angle (in zx plane) of parabola in shifted and rotated system
411 // const Double_t thetaZxLocal = atan(n*e*By*pZxInv*zShiftedRotated); // TODO: Maybe here I actually get 2 values
412 // // add rotation of local coordinate system wrt global coordinate system
413 // return thetaZxRadVor + thetaZxLocal;
414 // }
415 
416 
417 
418 
419 //inline std::pair<Double_t, Double_t> getPZPXLabParabolaApproximation(const Double_t &zLabSys) const {
420 // // theta in radian in zx plane given at z = zRefLabSys
421 // const Double_t thetaRadVor = fZxLineBeforeDipole.getThetaRadVal();
422 // const Double_t zRefLabVor = fZxLineBeforeDipole.getZRefLabSys();
423 //
424 // const Double_t thetaRadNach = fZxLineBehindDipole.getThetaRadVal();
425 // const Double_t zRefLabNach = fZxLineBehindDipole.getZRefLabSys();
426 //
427 // // assume that theta is rotated linearly along z which is (probably) true for a circle, but not for a parabola // TODO: Check if this is a good assumption
428 // const Double_t zDistTotal = zRefLabNach - zRefLabVor;
429 // const Double_t zDistTraveled = zLabSys - zRefLabVor;
430 //
431 // const Double_t currentThetaRad = thetaRadVor + zDistTraveled / zDistTotal * (thetaRadNach - thetaRadVor);
432 //
433 // const Double_t qDivPzx = fZxParabola.getSecondVal(); // Q/pzx
434 // const Double_t pZx = getCharge() / qDivPzx;
435 //
436 // const Double_t pZLabSys = pZx*cos(currentThetaRad);
437 // const Double_t pXLabSys = pZx*sin(currentThetaRad);
438 // std::pair<Double_t, Double_t> pZPXLabSys(pZLabSys, pXLabSys);
439 //
440 // return pZPXLabSys;
441 // }
int fVerbose
Definition: poormantracks.C:24
void SetZxParabola(const PndFtsHoughTracklet zxParabola)
void Print() const
FairTrackParP getTrackParPForHit(const UInt_t i)
Double_t getThetaRadVal() const
void SetZyLine(const PndFtsHoughTracklet zyLine)
Interface between PandaRoot (data input and output) and PndFtsHoughTrackFinder (implementation of PR ...
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
PndFtsHoughTracklet fZxLineBehindDipole
Double_t getXLabForParabola(const Double_t &zLabSys) const
std::pair< Double_t, Double_t > getPZPXLabLine(const Double_t &zLabSys, const PndFtsHoughTracklet *const lineTracklet) const
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
PndTrackCandHit GetSortedHit(UInt_t i)
Definition: PndTrackCand.h:54
Bool_t isComplete() const
std::pair< Double_t, Double_t > getPZPXLabParabola(const Double_t &zLabSys) const
void SetZxLineBeforeDipole(const PndFtsHoughTracklet zxLineParabola)
void addUniqueTrackletHits(const PndFtsHoughTracklet inTracklet)
PndFtsHoughTrackerTask * fTrackerTask
Double_t mom
Definition: plot_dirc.C:14
Double_t getZRefLabSys() const
TVector3 getPos(const Double_t zLabSys) const
void throwError(const TString s) const
For error reporting.
PndFtsHoughTracklet fZxParabola
Class for saving the result of one Hough transform for FTS PR.
Int_t a
Definition: anaLmdDigi.C:126
void AddHit(UInt_t detId, UInt_t hitId, Double_t rho)
Double_t getXOrYLabForLine(const Double_t &zLabSys, const PndFtsHoughTracklet *const lineTracklet) const
PndFtsHoughTrackCand(PndFtsHoughTrackerTask *trackerTask=0)
Set pointer to tracker task (super important as it provides an I/O interface to PandaRoot) ...
Double_t
Double_t GetRho() const
Double_t getSecondVal() const
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
TVector3 getP(const Double_t zLabSys) const
friend F32vec4 atan2(const F32vec4 &y, const F32vec4 &x)
Definition: P4_F32vec4.h:117
void throwIfZOutOfRange(const Double_t &zLabSys) const
void SetZxLineBehindDipole(const PndFtsHoughTracklet zxParabolaLine)
const PndFtsHit * GetFtsHit(UInt_t hitId) const
Returns pointer to the hit with index hitId in the FTS hit array.
PndFtsHoughTracklet fZxLineBeforeDipole
UInt_t GetNHits() const
Definition: PndTrackCand.h:59
Double_t getQdivPzx() const
ClassImp(PndAnaContFact)
Class for saving a FTS track cand. for Hough transform based FTS PR.
Double_t getPYLab() const
Double_t getXLabSys(const Double_t zLabSys) const
Int_t GetHitId() const
const TVector3 GetFtsHitPosErrors(const PndFtsHit *const ftsHit) const
Returns the position error (based on FTS straw geometry) for the hit with index hitId in the FTS hit ...
Int_t GetDetId() const
PndFtsHoughTracklet fZyLine
Int_t HitInTrack(UInt_t detId, UInt_t hitId) const
Double_t getThetaZxRad(const Double_t zLabSys) const