TrdMCClusterR Fit Classifier
EventGeneratorTRD.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <TH1F.h>
4 #include <TROOT.h>
5 #include <TError.h>
6 #include <TCanvas.h>
7 #include <TProfile.h>
8 #include <TRandom3.h>
9 
10 #include "AMSTrdMCTrack.h"
11 #include "EventGenTRDConsts.h"
12 
13 #include <cmath>
14 #include <vector>
15 #include <iostream>
16 
17 
19 {
20  //______________________________________________________________________________________
21  std::vector<AMSTrdMCTrack::Track> GenerateTRDEvent(const TH1F * hFittedTRDtrksinMC, const bool& debugMode = false, const double& SIGMA_TRACK_CLUSTERS = 1)
22  {
36  TRandom3 * r3 = new TRandom3();
37  r3->SetSeed(0);
38 
44  };
45 
47  // int N = r3->Integer(51); /// Generates integer between 0 and 50
48  int N = hFittedTRDtrksinMC->GetRandom();
49  if (debugMode)
50  N = 5;
51  if (N == 1) N = 2;
52 
53 
55  std::vector<AMSTrdMCTrack::Track> vTracks(N);
56  unsigned int nSimClustersInEvent = 0;
57 
58 
61  for(int i = 0; i < N; i++)
62  {
63  vTracks[i].trkID = i+1;
64 
66  if(i == 0)
67  vTracks[i].g3PID = 14;
68  else
69  vTracks[i].g3PID = r3->Integer(101) - 50;
70 
76  };
77 
78 
80  int M = r3->Integer(99) + 2;
81 
83  double dx = (Pn.x - P0.x) / M;
84  double dy = (Pn.y - P0.y) / M;
85  double dz = (Pn.z - P0.z) / M;
86 
88  for(int j = 0; j < M; j++)
89  {
90  ++nSimClustersInEvent;
91 
92  vTracks[i].clusters.push_back(
93  {
94  P0.x + j * dx + r3->Gaus(0, SIGMA_TRACK_CLUSTERS),
95  P0.y + j * dy + r3->Gaus(0, SIGMA_TRACK_CLUSTERS),
96  P0.z + j * dz + r3->Gaus(0, SIGMA_TRACK_CLUSTERS)
97  });
98  }
99  }
100 
101 
103  if (debugMode)
104  printf("Generated %d tracks in sim event, containing %d sim clusters.", N, nSimClustersInEvent);
105 
108 
109  delete r3;
110  return vTracks;
111  }
112 
113 
114  //______________________________________________________________________________________
115  std::vector<int> EstimateLayerLadderTube(double x, double y, double z, const bool debugMode = false)
116  {
122  static const TH2F * const TRDModuleMap_XZ = new TH2F ("TRDModuleMap_XZ", ";x (cm);z (cm);", 18, EventGenTRDConsts::SIM_TRD_XMIN, EventGenTRDConsts::SIM_TRD_XMAX, 20, EventGenTRDConsts::SIM_TRD_ZMIN, EventGenTRDConsts::SIM_TRD_ZMAX);
123  static const TH2F * const TRDModuleMap_YZ = new TH2F ("TRDModuleMap_YZ", ";y (cm);z (cm);", 18, EventGenTRDConsts::SIM_TRD_YMIN, EventGenTRDConsts::SIM_TRD_YMAX, 20, EventGenTRDConsts::SIM_TRD_ZMIN, EventGenTRDConsts::SIM_TRD_ZMAX);
124 
126  int layerXZ = TRDModuleMap_XZ->GetYaxis()->FindBin(z) - 1;
127  int layerYZ = TRDModuleMap_YZ->GetYaxis()->FindBin(z) - 1;
128 
130  if (layerXZ != layerYZ)
131  {
132  std::cerr<<"\n[ERROR] z: "<<z<<". layerXZ: "<<layerXZ<<" and layerYZ: "<<layerYZ<<"\n";
133  throw std::runtime_error("Layer mismatch between XZ and YZ maps");
134  }
135  int layer = layerXZ;
136 
138  int ladder = 0;
139  double leftEdge, rightEdge;
140  double pos = 0;
141 
143  if (layer >= 0 && layer <= 3) {
144  ladder = TRDModuleMap_YZ->GetXaxis()->FindBin(y) - 3;
145  pos = y;
146  leftEdge = TRDModuleMap_YZ->GetXaxis()->GetBinLowEdge(ladder + 3);
147  rightEdge = TRDModuleMap_YZ->GetXaxis()->GetBinUpEdge(ladder + 3);
148  } else if (layer >= 4 && layer <= 11) {
149  ladder = TRDModuleMap_XZ->GetXaxis()->FindBin(x) - 2;
150  pos = x;
151  leftEdge = TRDModuleMap_XZ->GetXaxis()->GetBinLowEdge(ladder + 2);
152  rightEdge = TRDModuleMap_XZ->GetXaxis()->GetBinUpEdge(ladder + 2);
153  } else if (layer >= 12 && layer <= 15) {
154  ladder = TRDModuleMap_XZ->GetXaxis()->FindBin(x) - 1;
155  pos = x;
156  leftEdge = TRDModuleMap_XZ->GetXaxis()->GetBinLowEdge(ladder + 1);
157  rightEdge = TRDModuleMap_XZ->GetXaxis()->GetBinUpEdge(ladder + 1);
158  } else if (layer >= 16 && layer <= 19) {
159  ladder = TRDModuleMap_YZ->GetXaxis()->FindBin(y) - 1;
160  pos = y;
161  leftEdge = TRDModuleMap_YZ->GetXaxis()->GetBinLowEdge(ladder + 1);
162  rightEdge = TRDModuleMap_YZ->GetXaxis()->GetBinUpEdge(ladder + 1);
163  } else {
164  throw std::runtime_error("Layer index out of allowed range");
165  }
166 
168  double partitionWidth = (rightEdge - leftEdge) / 16;
169  int tube = static_cast<int>((pos - leftEdge) / partitionWidth);
170  //tube = (tube + 0) % 16; /// This adds 0/3/etc/ to tube and then uses modulo 16 to handle overflow. Found to be not needed.
171 
172  if (tube < 0 || tube >= 16)
173  {
174  std::cerr<<"\n\nz: "<<z<<". leftEdge: "<<leftEdge<<" and rightEdge: "<<rightEdge<<"\n";
175  throw std::runtime_error("Tube calculation out of range");
176  }
177 
178  if (ladder < 0 || ladder > 17)
179  {
180  if (debugMode)
181  std::cerr<<"\n\nSkipping cluster x: "<<x<<", y: "<<y<<", z: "<<z<<". Layer, Ladder = "<<layer<<", "<<ladder<<"\n";
182  // throw std::runtime_error("Ladder calculation out of range");
183  }
184 
185  std::vector<int> result = {layer, ladder, tube};
186  return result;
187  }
188 
189 
190  //______________________________________________________________________________________
191  double GetRandomSampledEdep(const TH1F * hTRDEkinMaxZPrMC, const TH2F * h2D_TRDEkinMaxZPrMC_Edep, const bool debugMode = false)
192  {
194  if (!hTRDEkinMaxZPrMC || !h2D_TRDEkinMaxZPrMC_Edep)
195  throw std::runtime_error("\n\nUnable to open Ekin and Edep histograms\n\n");
196 
198  double sampledEkin = hTRDEkinMaxZPrMC->GetRandom();
199 
201  int binX = h2D_TRDEkinMaxZPrMC_Edep->GetXaxis()->FindBin(sampledEkin);
202 
204  TH1D * hProjectionY = h2D_TRDEkinMaxZPrMC_Edep->ProjectionY("_py", binX, binX, "e"); // "e" option to use bin errors for weighting
205 
207  double sampledEdep = hProjectionY->GetRandom();
208 
210  delete hProjectionY;
211 
212  if (debugMode)
213  printf("\nFrom GetRandomSampledEdep(): Sampled Ekin = %8.3f, binX = %8d, Sampled Edep = %8.3f.", sampledEkin, binX, sampledEdep);
214 
216  return sampledEdep;
217  }
218 
219 
220  //______________________________________________________________________________________
221  double generateNearEdge(double min, double max, TRandom3& r3)
222  {
224 
225  double width = (max - min) * 0.02;
226  if (r3.Uniform() < 0.5)
227  return r3.Uniform(min, min + width);
228  else
229  return r3.Uniform(max - width, max);
230  }
231 
232 
233  //______________________________________________________________________________________
235  {
237 
238  AMSTrdMCTrack::Cluster cluster;
239  cluster.z = r3.Uniform(EventGenTRDConsts::SIM_TRD_ZMIN + 10, EventGenTRDConsts::SIM_TRD_ZMAX - 10);
240 
241  if (cluster.z <= 96.6)
242  {
243  cluster.x = r3.Uniform(-77.0, 77.0);
244  cluster.y = generateNearEdge(-72.0, 72.0, r3);
245  }
246 
247  else if (cluster.z > 96.6 && cluster.z <= 119.8)
248  {
249  cluster.x = generateNearEdge(-81.0, 81.0, r3);
250  cluster.y = r3.Uniform(-84.0, 84.0);
251  }
252 
253  else if (cluster.z > 119.8 && cluster.z <= 130.0)
254  {
255  cluster.x = generateNearEdge(-91.0, 91.0, r3);
256  cluster.y = r3.Uniform(-92.0, 92.0);
257  }
258 
259  else if (cluster.z > 130.0 && cluster.z <= 143.0)
260  {
261  cluster.x = r3.Uniform(-97.0, 97.0);
262  cluster.y = generateNearEdge(-92.0, 92.0, r3);
263  }
264  else
265  throw std::runtime_error("generated cluster.z value from r3.Uniform > 143.0!");
266 
267  return cluster;
268  }
269 
270 
271  //______________________________________________________________________________________
273  {
289  const AMSTrdMCTrack::Cluster fixedPoint = {r3.Gaus(0.0, 20),
290  r3.Gaus(0.0, 20),
291  r3.Gaus(P0.z, 20)}; //r3.Uniform(70, 160)
293 
295  double dirX = fixedPoint.x - P0.x;
296  double dirY = fixedPoint.y - P0.y;
297  double dirZ = fixedPoint.z - P0.z;
298 
300  double length = std::sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
301  dirX /= length;
302  dirY /= length;
303  dirZ /= length;
304 
306  // double minDistance = minDistance + r3.Uniform(0.0, 10.0); // Ensure it is at least minDistance away
307  const double minDistance = EventGenTRDConsts::MIN_SIDE_TRACK_LENGTH + r3.Gaus(20, 5);
308 
310  int N = 1;
311  double distance = 0.0;
312  while (distance < 2 * minDistance)
313  {
314  Pn.x = P0.x + N * minDistance * dirX;
315  Pn.y = P0.y + N * minDistance * dirY;
316  Pn.z = P0.z + N * minDistance * dirZ;
317 
319  distance = AMSTrdMCTrack::GetDistance(P0, Pn);
320  N++;
321  }
322 
323  return Pn;
324  }
325 
326 
327  //______________________________________________________________________________________
329  {
331  Pn.z = 2 * 110 - P0.z;
332 
333  if (r3.Uniform() < 0.3333)
334  {
335  Pn.x = r3.Gaus(-1*P0.x, 20);
336  Pn.y = r3.Gaus( 1*P0.y, 20);
337  }
338  else if (r3.Uniform() >= 0.3333 && r3.Uniform() < 0.6666)
339  {
340  Pn.x = r3.Gaus( 1*P0.x, 20);
341  Pn.y = r3.Gaus(-1*P0.y, 20);
342  }
343  else
344  {
345  Pn.x = r3.Gaus(0, 40);
346  Pn.y = r3.Gaus(0, 40);
347  }
348 
349  return Pn;
350  }
351 
352 
353 
354 
355  //______________________________________________________________________________________
356  std::vector<AMSTrdMCTrack::TRDTrack> GenerateTRDEvent(const TH1F * hTRDEkinMaxZPrMC,
357  const TH2F * h2D_TRDEkinMaxZPrMC_Edep,
358  const TH2F * h2D_TRDMap_XZ,
359  const TH2F * h2D_TRDMap_YZ,
360  const TH2F * h2D_TRDMap_XY,
361  const int nFakeTracksPerEvent = 1,
362  const bool debugMode = false,
363  TH1D * hQA_nAttemptsPerFakeEvent = NULL,
364  TH2D * hQA_FakeAngleVSLength = NULL,
365  double SIGMA_TRACK_CLUSTERS = 0.001)
366  {
371  if (!hTRDEkinMaxZPrMC || !h2D_TRDEkinMaxZPrMC_Edep || !h2D_TRDMap_XZ || !h2D_TRDMap_YZ || !h2D_TRDMap_XY)
372  throw std::runtime_error("std::vector<AMSTrdMCTrack::TRDTrack> GenerateTRDEvent(): Histograms not be loaded.");
373 
375  TRandom3 r3;
376  r3.SetSeed(0);
377 
379  std::vector<AMSTrdMCTrack::TRDTrack> vTracks;
380  vTracks.reserve(nFakeTracksPerEvent);
381 
382  unsigned int nSimClustersInEvent = 0;
383  int attempts = 0;
384 
387  if (debugMode)
388  printf("\nP0 = (%8.3f, %8.3f, %8.3f) cm", P0.x, P0.y, P0.z);
389 
390 
391  while (int(vTracks.size()) < nFakeTracksPerEvent && attempts < EventGenTRDConsts::MAX_ATTEMPTS_PER_EVENT * nFakeTracksPerEvent)
392  {
393  attempts++;
394  if (debugMode)
395  printf("\nnAttepts to find Pn = %d", attempts);
396 
397 
399  // AMSTrdMCTrack::Cluster Pn = GenerateClusterNearTRDEdge(r3); /// --> Is working okay, but perhaps with some issues.
400  // AMSTrdMCTrack::Cluster Pn = GenerateClusterOppositeP0(P0, r3); /// --> Is not working efficiently. Too make events with no clusters.
402 
404  double dx = Pn.x - P0.x;
405  double dy = Pn.y - P0.y;
406  double dz = Pn.z - P0.z;
407  double magnitude = AMSTrdMCTrack::GetDistance(P0, Pn);
408  double cosTheta = fabs(dz / magnitude);
409 
411  double radians = acos(cosTheta); // acos() returns the angle in radians
412  double degrees = radians * (180.0 / M_PI);
413  if (debugMode)
414  {
415  printf("\nCheck Pn = (%8.3f, %8.3f, %8.3f) cm", Pn.x, Pn.y, Pn.z);
416  printf("\nAngle = %5.2f radians or %6.1f degrees.\nLength = %5.1f cm", radians, degrees, magnitude);
417  }
418 
421  continue;
423  continue;
425  continue;
426 
427  if (debugMode)
428  printf("\nInitial good line found! Set Pn = (%8.3f, %8.3f, %8.3f) cm", Pn.x, Pn.y, Pn.z);
429 
432  track.trkID = vTracks.size() + 1;
433  track.g3PID = (track.trkID == 1) ? 14 : r3.Integer(101) - 50;
434 
436  int M = r3.Gaus(20) + 20;
437 
438 
440  for (int j = 0; j < M; j++)
441  {
442  double x = P0.x + j * dx / M + r3.Gaus(0, SIGMA_TRACK_CLUSTERS);
443  double y = P0.y + j * dy / M + r3.Gaus(0, SIGMA_TRACK_CLUSTERS);
444  double z = P0.z + j * dz / M + r3.Gaus(0, SIGMA_TRACK_CLUSTERS);
445 
447  if (x < EventGenTRDConsts::SIM_TRD_XMIN || x > EventGenTRDConsts::SIM_TRD_XMAX ||
448  y < EventGenTRDConsts::SIM_TRD_YMIN || y > EventGenTRDConsts::SIM_TRD_YMAX ||
449  z < EventGenTRDConsts::SIM_TRD_ZMIN || z > EventGenTRDConsts::SIM_TRD_ZMAX)
450  continue;
451 
452  bool isInside = AMSTrdMCTrack::IsClusterInsideTRD(h2D_TRDMap_XZ, h2D_TRDMap_YZ, h2D_TRDMap_XY, x, y, z);
453  if (isInside == false)
454  continue;
455 
457  std::vector<int> estLLT = EstimateLayerLadderTube(x, y, z, debugMode);
458  if (estLLT[1] < 0 || estLLT[1] > 17)
459  continue;
460 
462  double Edep = GetRandomSampledEdep(hTRDEkinMaxZPrMC, h2D_TRDEkinMaxZPrMC_Edep);
463 
465  track.clusters.push_back({x, y, z, estLLT[0], estLLT[1], estLLT[2], Edep});
466  ++nSimClustersInEvent;
467  }
468 
469  if (!track.clusters.empty())
470  vTracks.push_back(track);
471 
472  if (track.clusters.size() >= 2)
473  {
474  double distance = AMSTrdMCTrack::GetDistance(track.clusters.front(), track.clusters.back());
475 
476  if (debugMode)
477  printf("\nActual length of fake track: %8.2f cm.", distance);
478 
479  if (hQA_FakeAngleVSLength)
480  hQA_FakeAngleVSLength->Fill(degrees, distance);
481  }
482  }
483 
484 
486  if (debugMode)
487  {
488  printf("\nGenerated %d fake track(s) in this event, containing %d synthetic/fake clusters.", int(vTracks.size()), nSimClustersInEvent);
490  printf("\n");
491  }
492 
494  if (hQA_nAttemptsPerFakeEvent)
495  hQA_nAttemptsPerFakeEvent->Fill(attempts);
496 
497  static int nCalls = 0;
498  nCalls++;
499  if (vTracks.empty())
500  printf("\n\n[WARNING]: For nCall = %d, vTracks generated by GenerateTRDEvent() is empty. | nAttempts = %d\n", nCalls, attempts);
501 
502  return vTracks;
503  }
504 
505 
506 
507 
508  //______________________________________________________________________________________
510  TH2F * GetModuleHistogramFakeTracks(const std::vector<AMSTrdMCTrack::TRDTrack>& fake_tracks, const bool debugMode = false, TH2F * hTRDEventMap_XZ = NULL, TH2F * hTRDEventMap_YZ = NULL)
511  {
512  if (fake_tracks.empty())
513  {
514  std::cerr<<"\n[WARNING]: In GetModuleHistogramFakeTracks(), provided std::vector<AMSTrdMCTrack::TRDTrack> is empty.\n\n";
515  return nullptr;
516  }
517 
520  TH2F * hTRDModuleMap = new TH2F("hTRDModuleMap_FakeTracks", ";Ladder;Layer;Edep", 18, 0, 18, 20, 0, 20);
521 
522  // Fill the histogram using the tracks data
523  for (const auto& track : fake_tracks)
524  {
525  for (const auto& cluster : track.clusters)
526  {
527  int ladder_hist = cluster.Ladder;
528  int layer = cluster.Layer;
529 
530  // Determine ladder value based on layer
531  if (layer >= 0 && layer <= 3)
532  ladder_hist = ladder_hist + 2;
533  else if (layer >= 4 && layer <= 11)
534  ladder_hist = ladder_hist + 1;
535  else if (layer >= 12 && layer <= 15)
536  ladder_hist = ladder_hist + 0;
537  else if (layer >= 16 && layer <= 19)
538  ladder_hist = ladder_hist + 0;
539  else
540  throw std::runtime_error("Layer index out of allowed range 0-19");
541 
542  hTRDModuleMap->Fill(ladder_hist, layer, cluster.Edep);
543 
544  if (hTRDEventMap_XZ) hTRDEventMap_XZ->Fill(cluster.x, cluster.z, cluster.Edep);
545  if (hTRDEventMap_YZ) hTRDEventMap_YZ->Fill(cluster.y, cluster.z, cluster.Edep);
546  }
547  }
548 
549  return hTRDModuleMap;
550  }
551 }
double GetDistance(const T &P1, const T &P2)
Definition: AMSTrdMCTrack.h:67
void printTRDTrackInfo(const std::vector< TRDTrack > &vTracks)
Definition: AMSTrdMCTrack.h:170
bool IsClusterInsideTRD(const TH2F *h2D_TRDMap_XZ, const TH2F *h2D_TRDMap_YZ, const TH2F *h2D_TRDMap_XY, double x, double y, double z)
Definition: AMSTrdMCTrack.h:77
const double SIM_TRD_XYMAX
cm
Definition: EventGenTRDConsts.h:13
const double MAX_ATTEMPTS_PER_EVENT
cm
Definition: EventGenTRDConsts.h:17
const double MAX_Z_ANGLE_THETA
Angle of tracl from the vertical Z-axis in radians. | (0.2 rad ~ 11 degrees) (0.8 rad ~ 45 degrees)
Definition: EventGenTRDConsts.h:22
const double SIM_TRD_XYMIN
--— Some physical detector constants
Definition: EventGenTRDConsts.h:12
const double SIM_TRD_ZMIN
Definition: EventGenTRDConsts.h:28
const double SIM_TRD_YMAX
Definition: EventGenTRDConsts.h:27
const double SIM_TRD_YMIN
Definition: EventGenTRDConsts.h:26
const double SIM_TRD_XMAX
Definition: EventGenTRDConsts.h:25
const double MIN_SIDE_TRACK_LENGTH
Definition: EventGenTRDConsts.h:19
const double MIN_Z_ANGLE_THETA
cm
Definition: EventGenTRDConsts.h:21
const double SIM_TRD_ZMAX
Definition: EventGenTRDConsts.h:29
const double SIM_TRD_XMIN
Angle of track from the vertical Z-axis in radians. | (1.0 rad ~ 57 degrees) (1.3 rad ~ 75 degrees)
Definition: EventGenTRDConsts.h:24
Definition: EventGeneratorTRD.h:19
TH2F * GetModuleHistogramFakeTracks(const std::vector< AMSTrdMCTrack::TRDTrack > &fake_tracks, const bool debugMode=false, TH2F *hTRDEventMap_XZ=NULL, TH2F *hTRDEventMap_YZ=NULL)
Function to process fake tracks and return a filled histogram.
Definition: EventGeneratorTRD.h:510
double generateNearEdge(double min, double max, TRandom3 &r3)
Definition: EventGeneratorTRD.h:221
std::vector< int > EstimateLayerLadderTube(double x, double y, double z, const bool debugMode=false)
Definition: EventGeneratorTRD.h:115
std::vector< AMSTrdMCTrack::Track > GenerateTRDEvent(const TH1F *hFittedTRDtrksinMC, const bool &debugMode=false, const double &SIGMA_TRACK_CLUSTERS=1)
Definition: EventGeneratorTRD.h:21
AMSTrdMCTrack::Cluster GenerateClusterNearTRDEdge(TRandom3 &r3)
Definition: EventGeneratorTRD.h:234
AMSTrdMCTrack::Cluster GenerateClusterAtMinDistance(const AMSTrdMCTrack::Cluster &P0, TRandom3 &r3)
Definition: EventGeneratorTRD.h:272
AMSTrdMCTrack::Cluster GenerateClusterOppositeP0(const AMSTrdMCTrack::Cluster &P0, TRandom3 &r3)
Definition: EventGeneratorTRD.h:328
double GetRandomSampledEdep(const TH1F *hTRDEkinMaxZPrMC, const TH2F *h2D_TRDEkinMaxZPrMC_Edep, const bool debugMode=false)
Definition: EventGeneratorTRD.h:191
Definition: AMSTrdMCTrack.h:27
double y
Definition: AMSTrdMCTrack.h:29
double z
Definition: AMSTrdMCTrack.h:30
double x
Definition: AMSTrdMCTrack.h:28
Definition: AMSTrdMCTrack.h:58
std::vector< TRDHitCluster > clusters
Definition: AMSTrdMCTrack.h:61
int g3PID
Definition: AMSTrdMCTrack.h:60
int trkID
Definition: AMSTrdMCTrack.h:59