CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CTPPSFastTrackingProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FastSimulation/CTPPSFastTrackingProducer
4 // Class: CTPPSFastTrackingProducer
5 //
13 //
14 // Original Author: Sandro Fonseca De Souza
15 // Created: Thu, 29 Sep 2016 16:13:41 GMT
16 //
17 //
18 
19 #include <memory>
20 
41 
42 #include "TLorentzVector.h"
43 
44 // hector includes
45 #include "H_Parameters.h"
46 #include "H_BeamLine.h"
47 #include "H_RecRPObject.h"
48 #include "H_BeamParticle.h"
49 
51 public:
53 
54 private:
55  void produce(edm::Event&, const edm::EventSetup&) override;
56 
57  // ----------member data ---------------------------
58 
59  typedef std::vector<CTPPSFastRecHit> CTPPSFastRecHitContainer;
62  void FastReco(int Direction, H_RecRPObject* station);
63  void Reconstruction();
64  void ReconstructArm(
65  H_RecRPObject* pps_station, double x1, double y1, double x2, double y2, double& tx, double& ty, double& eloss);
66  void MatchCellId(int cellId, std::vector<int> vrecCellId, std::vector<double> vrecTof, bool& match, double& recTof);
67  bool SearchTrack(int,
68  int,
69  int Direction,
70  double& xi,
71  double& t,
72  double& partP,
73  double& pt,
74  double& thx,
75  double& thy,
76  double& x0,
77  double& y0,
78  double& xt,
79  double& yt,
80  double& X1d,
81  double& Y1d,
82  double& X2d,
83  double& Y2d);
84  void TrackerStationClear();
86  void ProjectToToF(const double x1, const double y1, const double x2, const double y2, double& xt, double& yt) {
87  xt = ((fz_timing - fz_tracker2) * (x2 - x1) / (fz_tracker2 - fz_tracker1)) + x2;
88  yt = ((fz_timing - fz_tracker2) * (y2 - y1) / (fz_tracker2 - fz_tracker1)) + y2;
89  };
90  // Hector objects
91  bool SetBeamLine();
92 
93  std::unique_ptr<H_BeamLine> m_beamlineCTPPS1;
94  std::unique_ptr<H_BeamLine> m_beamlineCTPPS2;
95  std::unique_ptr<H_RecRPObject> pps_stationF;
96  std::unique_ptr<H_RecRPObject> pps_stationB;
97 
100 
101  // Defaults
102  double lengthctpps;
104  double fBeamEnergy;
110  std::unique_ptr<CTPPSTrkStation> TrkStation_F; // auxiliary object with the tracker geometry
111  std::unique_ptr<CTPPSTrkStation> TrkStation_B;
112  std::unique_ptr<CTPPSTrkDetector> det1F;
113  std::unique_ptr<CTPPSTrkDetector> det1B;
114  std::unique_ptr<CTPPSTrkDetector> det2F;
115  std::unique_ptr<CTPPSTrkDetector> det2B;
116  std::unique_ptr<CTPPSToFDetector> detToF_F;
117  std::unique_ptr<CTPPSToFDetector> detToF_B;
118 
119  std::vector<CTPPSFastTrack> theCTPPSFastTrack;
120 
122 
123  std::vector<int> recCellId_F, recCellId_B;
124  std::vector<double> recTof_F, recTof_B;
125 
128  std::vector<double> fToFCellWidth;
132 };
134 // constructors and destructor
135 //
137  : m_verbosity(false), fBeamMomentum(0.), fCrossAngleCorr(false), fCrossingAngleBeam1(0.), fCrossingAngleBeam2(0.) {
138  //register your products
139  produces<edm::CTPPSFastTrackContainer>("CTPPSFastTrack");
140  using namespace edm;
141  _recHitToken = consumes<CTPPSFastRecHitContainer>(iConfig.getParameter<edm::InputTag>("recHitTag"));
142  m_verbosity = iConfig.getParameter<bool>("Verbosity");
143  // User definitons
144 
145  // Read beam parameters needed for Hector reconstruction
146  lengthctpps = iConfig.getParameter<double>("BeamLineLengthCTPPS");
147  beam1filename = iConfig.getParameter<string>("Beam1");
148  beam2filename = iConfig.getParameter<string>("Beam2");
149  fBeamEnergy = iConfig.getParameter<double>("BeamEnergy"); // beam energy in GeV
151  fCrossingAngleBeam1 = iConfig.getParameter<double>("CrossingAngleBeam1");
152  fCrossingAngleBeam2 = iConfig.getParameter<double>("CrossingAngleBeam2");
153 
154  if (fCrossingAngleBeam1 != 0 || fCrossingAngleBeam2 != 0)
155  fCrossAngleCorr = true;
156  //Read detectors positions and parameters
157 
158  fz_tracker1 = iConfig.getParameter<double>("Z_Tracker1");
159  fz_tracker2 = iConfig.getParameter<double>("Z_Tracker2");
160  fz_timing = iConfig.getParameter<double>("Z_Timing");
161  //
162  fTrackerWidth = iConfig.getParameter<double>("TrackerWidth");
163  fTrackerHeight = iConfig.getParameter<double>("TrackerHeight");
164  fTrackerInsertion = iConfig.getParameter<double>("TrackerInsertion");
165  fBeamXRMS_Trk1 = iConfig.getParameter<double>("BeamXRMS_Trk1");
166  fBeamXRMS_Trk2 = iConfig.getParameter<double>("BeamXRMS_Trk2");
167  fTrk1XOffset = iConfig.getParameter<double>("Trk1XOffset");
168  fTrk2XOffset = iConfig.getParameter<double>("Trk2XOffset");
169  fToFCellWidth = iConfig.getUntrackedParameter<std::vector<double> >("ToFCellWidth");
170  fToFCellHeight = iConfig.getParameter<double>("ToFCellHeight");
171  fToFPitchX = iConfig.getParameter<double>("ToFPitchX");
172  fToFPitchY = iConfig.getParameter<double>("ToFPitchY");
173  fToFNCellX = iConfig.getParameter<int>("ToFNCellX");
174  fToFNCellY = iConfig.getParameter<int>("ToFNCellY");
175  fToFInsertion = iConfig.getParameter<double>("ToFInsertion");
176  fBeamXRMS_ToF = iConfig.getParameter<double>("BeamXRMS_ToF");
177  fToFXOffset = iConfig.getParameter<double>("ToFXOffset");
178  fTimeSigma = iConfig.getParameter<double>("TimeSigma");
179  fImpParcut = iConfig.getParameter<double>("ImpParcut");
180 
181  if (!SetBeamLine()) {
182  if (m_verbosity)
183  LogDebug("CTPPSFastTrackingProducer") << "CTPPSFastTrackingProducer: WARNING: lengthctpps= " << lengthctpps;
184  return;
185  }
186 
187  // Create a particle to get the beam energy from the beam file
188  // Take care: the z inside the station is in meters
189  //
190  //Tracker Detector Description
191  det1F = std::make_unique<CTPPSTrkDetector>(
193  det2F = std::make_unique<CTPPSTrkDetector>(
195  det1B = std::make_unique<CTPPSTrkDetector>(
197  det2B = std::make_unique<CTPPSTrkDetector>(
199 
200  //Timing Detector Description
201  std::vector<double> vToFCellWidth;
202  vToFCellWidth.reserve(8);
203  for (int i = 0; i < 8; i++) {
204  vToFCellWidth.push_back(fToFCellWidth[i]);
205  }
206  double pos_tof = fToFInsertion * fBeamXRMS_ToF + fToFXOffset;
207  detToF_F = std::make_unique<CTPPSToFDetector>(
208  fToFNCellX, fToFNCellY, vToFCellWidth, fToFCellHeight, fToFPitchX, fToFPitchY, pos_tof, fTimeSigma);
209  detToF_B = std::make_unique<CTPPSToFDetector>(
210  fToFNCellX, fToFNCellY, vToFCellWidth, fToFCellHeight, fToFPitchX, fToFPitchY, pos_tof, fTimeSigma);
211  //
212 }
213 
214 // ------------ method called to produce the data ------------
216  using namespace edm;
220  recCellId_F.clear();
221  recCellId_B.clear();
222  recTof_F.clear();
223  recTof_B.clear();
225  Reconstruction();
227 
228  std::unique_ptr<CTPPSFastTrackContainer> output_tracks(new CTPPSFastTrackContainer);
229  int n = 0;
230  for (std::vector<CTPPSFastTrack>::const_iterator i = theCTPPSFastTrack.begin(); i != theCTPPSFastTrack.end(); i++) {
231  output_tracks->push_back(*i);
232  n += 1;
233  }
234 
235  iEvent.put(std::move(output_tracks), "CTPPSFastTrack");
236 } //end
237 
240  TrkStation_F->first.clear();
241  TrkStation_F->second.clear();
242  TrkStation_B->first.clear();
243  TrkStation_B->second.clear();
244 }
247  det1F->clear();
248  det1B->clear();
249  det2F->clear();
250  det2B->clear();
251  detToF_F->clear();
252  detToF_B->clear();
253 }
254 
257  // DetId codification for PSimHit taken from CTPPSPixel- It will be replaced by CTPPSDetId
258  // 2014314496 -> Tracker1 zPositive
259  // 2014838784 -> Tracker2 zPositive
260  // 2046820352 -> Timing zPositive
261  // 2031091712 -> Tracker1 zNegative
262  // 2031616000 -> Tracker2 zNegative
263  // 2063597568 -> Timing zNegative
264 
265  for (unsigned int irecHits = 0; irecHits < recHits->size(); ++irecHits) {
266  const CTPPSFastRecHit* recHitDet = &(*recHits)[irecHits];
267  unsigned int detlayerId = recHitDet->detUnitId();
268  double x = recHitDet->entryPoint().x();
269  double y = recHitDet->entryPoint().y();
270  double z = recHitDet->entryPoint().z();
271  float tof = recHitDet->tof();
272  if (detlayerId == 2014314496)
273  det1F->AddHit(detlayerId, x, y, z);
274  else if (detlayerId == 2014838784)
275  det2F->AddHit(detlayerId, x, y, z);
276  else if (detlayerId == 2031091712)
277  det1B->AddHit(detlayerId, x, y, z);
278  else if (detlayerId == 2031616000)
279  det2B->AddHit(detlayerId, x, y, z);
280  else if (detlayerId == 2046820352) {
281  detToF_F->AddHit(x, y, tof);
282  recCellId_F.push_back(detToF_F->findCellId(x, y));
283  recTof_F.push_back(tof);
284  } else if (detlayerId == 2063597568) {
285  detToF_B->AddHit(x, y, tof);
286  recCellId_B.push_back(detToF_B->findCellId(x, y));
287  recTof_B.push_back(tof);
288  }
289 
290  } //LOOP TRK
291  //creating Stations
292  TrkStation_F = std::make_unique<CTPPSTrkStation>(*det1F, *det2F);
293  TrkStation_B = std::make_unique<CTPPSTrkStation>(*det1B, *det2B);
294 } // end function
295 
297  theCTPPSFastTrack.clear();
298  int Direction;
299  Direction = 1; //cms positive Z / forward
300  FastReco(Direction, &*pps_stationF);
301  Direction = -1; //cms negative Z / backward
302  FastReco(Direction, &*pps_stationB);
303 } //end Reconstruction
304 
306  int j,
307  int Direction,
308  double& xi,
309  double& t,
310  double& partP,
311  double& pt,
312  double& thx,
313  double& thy,
314  double& x0,
315  double& y0,
316  double& xt,
317  double& yt,
318  double& X1d,
319  double& Y1d,
320  double& X2d,
321  double& Y2d) {
322  // Given 1 hit in Tracker1 and 1 hit in Tracker2 try to make a track with Hector
323  xi = 0;
324  t = 0;
325  partP = 0;
326  pt = 0;
327  x0 = 0.;
328  y0 = 0.;
329  xt = 0.;
330  yt = 0.;
331  X1d = 0.;
332  Y1d = 0.;
333  X2d = 0.;
334  Y2d = 0.;
335  CTPPSTrkDetector* det1 = nullptr;
336  CTPPSTrkDetector* det2 = nullptr;
337  H_RecRPObject* station = nullptr;
338  // Separate in forward and backward stations according to direction
339  if (Direction > 0) {
340  det1 = &(TrkStation_F->first);
341  det2 = &(TrkStation_F->second);
342  station = &*pps_stationF;
343  } else {
344  det1 = &(TrkStation_B->first);
345  det2 = &(TrkStation_B->second);
346  station = &*pps_stationB;
347  }
348  if (det1->ppsNHits_ <= i || det2->ppsNHits_ <= j)
349  return false;
350  //
351  double x1 = det1->ppsX_.at(i);
352  double y1 = det1->ppsY_.at(i);
353  double x2 = det2->ppsX_.at(j);
354  double y2 = det2->ppsY_.at(j);
355  double eloss;
356 
357  //thx and thy are returned in microrad
359  station, Direction * x1, y1, Direction * x2, y2, thx, thy, eloss); // Pass the hits in the LHC ref. frame
360  thx *= -Direction; // invert to the CMS ref frame
361 
362  // Protect for unphysical results
363  if (edm::isNotFinite(eloss) || edm::isNotFinite(thx) || edm::isNotFinite(thy))
364  return false;
365  //
366 
367  if (m_verbosity)
368  LogDebug("CTPPSFastTrackingProducer::SearchTrack:") << "thx " << thx << " thy " << thy << " eloss " << eloss;
369 
370  // Get the start point of the reconstructed track near the origin made by Hector in the CMS ref. frame
371  x0 = -Direction * station->getX0() * um_to_cm;
372  y0 = station->getY0() * um_to_cm;
373  double ImpPar = sqrt(x0 * x0 + y0 * y0);
374  if (ImpPar > fImpParcut)
375  return false;
376  if (eloss < 0. || eloss > fBeamEnergy)
377  return false;
378  //
379  // Calculate the reconstructed track parameters
380  double theta = sqrt(thx * thx + thy * thy) * urad;
381  xi = eloss / fBeamEnergy;
382  double energy = fBeamEnergy * (1. - xi);
383  partP = sqrt(energy * energy - PPSTools::ProtonMassSQ);
384  t = -2. * (PPSTools::ProtonMassSQ - fBeamEnergy * energy + fBeamMomentum * partP * cos(theta));
385  pt = partP * theta;
386  if (xi < 0. || xi > 1. || t < 0. || t > 10. || pt <= 0.) {
387  xi = 0.;
388  t = 0.;
389  partP = 0.;
390  pt = 0.;
391  x0 = 0.;
392  y0 = 0.;
393  return false; // unphysical values
394  }
395  //Try to include the timing detector in the track
396  ProjectToToF(x1, y1, x2, y2, xt, yt); // the projections is done in the CMS ref frame
397  X1d = x1;
398  Y1d = y1;
399  X2d = x2;
400  Y2d = y2;
401  return true;
402 } //end SearchTrack
403 
405  H_RecRPObject* pps_station, double x1, double y1, double x2, double y2, double& tx, double& ty, double& eloss) {
406  tx = 0.;
407  ty = 0.;
408  eloss = 0.;
409  if (!pps_station)
410  return;
411  x1 *= mm_to_um;
412  x2 *= mm_to_um;
413  y1 *= mm_to_um;
414  y2 *= mm_to_um;
415  pps_station->setPositions(x1, y1, x2, y2);
416  double energy = pps_station->getE(AM); // dummy call needed to calculate some Hector internal parameter
417  if (edm::isNotFinite(energy))
418  return;
419  tx = pps_station->getTXIP(); // change orientation to CMS
420  ty = pps_station->getTYIP();
421  eloss = pps_station->getE();
422 }
423 
425  int cellId, std::vector<int> vrecCellId, std::vector<double> vrecTof, bool& match, double& recTof) {
426  for (unsigned int i = 0; i < vrecCellId.size(); i++) {
427  if (cellId == vrecCellId.at(i)) {
428  match = true;
429  recTof = vrecTof.at(i);
430  continue;
431  }
432  }
433 }
434 
435 void CTPPSFastTrackingProducer::FastReco(int Direction, H_RecRPObject* station) {
436  double theta = 0.;
437  double xi, t, partP, pt, phi, x0, y0, thx, thy, xt, yt, X1d, Y1d, X2d, Y2d;
438  CTPPSTrkDetector* Trk1 = nullptr;
439  CTPPSTrkDetector* Trk2 = nullptr;
440  double pos_tof = fToFInsertion * fBeamXRMS_ToF + fToFXOffset;
441  int cellId = 0;
442  std::vector<double> vToFCellWidth;
443  vToFCellWidth.reserve(8);
444  for (int i = 0; i < 8; i++) {
445  vToFCellWidth.push_back(fToFCellWidth[i]);
446  }
448  fToFNCellX, fToFNCellY, vToFCellWidth, fToFCellHeight, fToFPitchX, fToFPitchY, pos_tof, fTimeSigma);
449  if (Direction > 0) {
450  Trk1 = &(TrkStation_F->first);
451  Trk2 = &(TrkStation_F->second);
452  } else {
453  Trk1 = &(TrkStation_B->first);
454  Trk2 = &(TrkStation_B->second);
455  }
456  // Make a track from EVERY pair of hits combining Tracker1 and Tracker2.
457  // The tracks may not be independent as 1 hit may belong to more than 1 track.
458  for (int i = 0; i < (int)Trk1->ppsNHits_; i++) {
459  for (int j = 0; j < (int)Trk2->ppsNHits_; j++) {
460  if (SearchTrack(i, j, Direction, xi, t, partP, pt, thx, thy, x0, y0, xt, yt, X1d, Y1d, X2d, Y2d)) {
461  // Check if the hitted timing cell matches the reconstructed track
462  cellId = ToF->findCellId(xt, yt);
463  double recTof = 0.;
464  bool matchCellId = false;
465  if (Direction > 0) {
466  theta = sqrt(thx * thx + thy * thy) * urad;
467  MatchCellId(cellId, recCellId_F, recTof_F, matchCellId, recTof);
468  } else if (Direction < 0) {
469  theta = TMath::Pi() - sqrt(thx * thx + thy * thy) * urad;
470  MatchCellId(cellId, recCellId_B, recTof_B, matchCellId, recTof);
471  }
472  phi = atan2(thy, thx); // at this point, thx is already in the cms ref. frame
473 
474  double px = partP * sin(theta) * cos(phi);
475  double py = partP * sin(theta) * sin(phi);
476  double pz = partP * cos(theta);
477  double e = sqrt(partP * partP + PPSTools::ProtonMassSQ);
478  TLorentzVector p(px, py, pz, e);
479  // Invert the Lorentz boost made to take into account the crossing angle during simulation
480  if (fCrossAngleCorr) {
482  }
483  //Getting the Xi and t (squared four momentum transferred) of the reconstructed track
484  PPSTools::Get_t_and_xi(const_cast<TLorentzVector*>(&p), t, xi, {fBeamMomentum, fBeamEnergy});
485  double pxx = p.Px();
486  double pyy = p.Py();
487  double pzz = p.Pz();
488  math::XYZVector momentum(pxx, pyy, pzz);
489  math::XYZPoint vertex(x0, y0, 0);
490 
491  track.setp(momentum);
492  track.setvertex(vertex);
493  track.sett(t);
494  track.setxi(xi);
495  track.setx1(X1d);
496  track.sety1(Y1d);
497  track.setx2(X2d);
498  track.sety2(Y2d);
499  if (matchCellId) {
500  track.setcellid(cellId);
501  track.settof(recTof);
502  } else {
503  track.setcellid(0);
504  track.settof(0.);
505  }
506  theCTPPSFastTrack.push_back(track);
507  }
508  }
509  }
510 } //end FastReco
511 
515  if (lengthctpps <= 0)
516  return false;
517  m_beamlineCTPPS1 = std::make_unique<H_BeamLine>(-1, lengthctpps + 0.1); // (direction, length)
518  m_beamlineCTPPS1->fill(b2.fullPath(), 1, "IP5");
519  m_beamlineCTPPS2 = std::make_unique<H_BeamLine>(1, lengthctpps + 0.1); //
520  m_beamlineCTPPS2->fill(b1.fullPath(), 1, "IP5");
521  m_beamlineCTPPS1->offsetElements(120, 0.097);
522  m_beamlineCTPPS2->offsetElements(120, -0.097);
523  pps_stationF = std::make_unique<H_RecRPObject>(fz_tracker1, fz_tracker2, *m_beamlineCTPPS1);
524  pps_stationB = std::make_unique<H_RecRPObject>(fz_tracker1, fz_tracker2, *m_beamlineCTPPS2);
525  return true;
526 }
527 //define this as a plug-in
void LorentzBoost(H_BeamParticle &h_p, int dir, const std::string &frame, FullBeamInfo const &bi)
void sett(float t)
const double Pi
T getUntrackedParameter(std::string const &, T const &) const
std::vector< double > ppsX_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
std::unique_ptr< CTPPSTrkDetector > det2B
int findCellId(double x, double y)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::unique_ptr< H_BeamLine > m_beamlineCTPPS1
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
void FastReco(int Direction, H_RecRPObject *station)
Geom::Theta< T > theta() const
T y() const
Definition: PV3DBase.h:60
void setvertex(const Point &vertex)
static const double urad
void sety1(float y1)
void setx2(float x2)
void ReconstructArm(H_RecRPObject *pps_station, double x1, double y1, double x2, double y2, double &tx, double &ty, double &eloss)
std::unique_ptr< H_RecRPObject > pps_stationB
std::unique_ptr< CTPPSToFDetector > detToF_F
float tof() const
deprecated name for timeOfFlight()
std::unique_ptr< CTPPSTrkDetector > det2F
std::unique_ptr< H_RecRPObject > pps_stationF
void setp(const Vector &momentum)
int iEvent
Definition: GenABIO.cc:224
void setx1(float x1)
CTPPSFastTrackingProducer(const edm::ParameterSet &)
std::unique_ptr< CTPPSTrkDetector > det1B
T sqrt(T t)
Definition: SSEVec.h:19
unsigned int detUnitId() const
T z() const
Definition: PV3DBase.h:61
std::unique_ptr< CTPPSTrkStation > TrkStation_B
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
def move
Definition: eostools.py:511
void setxi(float xi)
const double ProtonMassSQ
Definition: PPSUtilities.h:31
std::unique_ptr< CTPPSToFDetector > detToF_B
std::vector< CTPPSFastRecHit > CTPPSFastRecHitContainer
std::unique_ptr< H_BeamLine > m_beamlineCTPPS2
void ProjectToToF(const double x1, const double y1, const double x2, const double y2, double &xt, double &yt)
std::vector< double > ppsY_
void MatchCellId(int cellId, std::vector< int > vrecCellId, std::vector< double > vrecTof, bool &match, double &recTof)
std::unique_ptr< CTPPSTrkStation > TrkStation_F
std::vector< CTPPSFastTrack > theCTPPSFastTrack
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
static const double um_to_cm
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
Local3DPoint entryPoint() const
Entry point in the local Det frame.
std::unique_ptr< CTPPSTrkDetector > det1F
void settof(float tof)
void sety2(float y2)
static const double mm_to_um
edm::EDGetTokenT< CTPPSFastRecHitContainer > _recHitToken
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
static constexpr float b2
void Get_t_and_xi(const TLorentzVector *proton, double &t, double &xi, LimitedBeamInfo const &bi)
Definition: PPSUtilities.cc:72
T x() const
Definition: PV3DBase.h:59
const GeomDet * recHitDet(const TrackingRecHit &hit, const TrackingGeometry *geom)
void produce(edm::Event &, const edm::EventSetup &) override
std::vector< CTPPSFastTrack > CTPPSFastTrackContainer
void setcellid(unsigned int cellid)
void ReadRecHits(edm::Handle< CTPPSFastRecHitContainer > &)
static constexpr float b1
#define LogDebug(id)
bool SearchTrack(int, int, int Direction, double &xi, double &t, double &partP, double &pt, double &thx, double &thy, double &x0, double &y0, double &xt, double &yt, double &X1d, double &Y1d, double &X2d, double &Y2d)