HighLAND
TruthUtils.cxx
1 #include "TruthUtils.hxx"
2 #include "ConstituentsUtils.hxx"
3 
4 
5 //**************************************************
7  //**************************************************
8 
9  // out of FV
10  if ( ! InFiducialVolume(det, trueVertex.Position)) return -999;
11 
12  /// particles coming out the vertex
13  Int_t NMich=0;
14 
15  for (int tit = 0; tit < trueVertex.nTrueParticles; tit++) {
16  AnaTrueParticleB* true_track = trueVertex.TrueParticles[tit];
17 
18  //if not a pi+/-, a e+/-, a mu+/-
19  if( abs(true_track->GParentPDG)!=211) continue;
20  if( abs(true_track->ParentPDG)!=13 ) continue;
21  if( abs(true_track->PDG)!=11 ) continue;
22 
23  NMich++;
24  }
25 
26  // std::cout<<" nb of michel electrons "<<NMich << " " << trueVertex.nTrueParticles <<std::endl;
27 
28  return NMich;
29 }
30 
31 //**************************************************
32 Float_t anaUtils::GetTrueLinearLengthInTPC(const AnaTrueParticleB& trueTrack, Float_t& distz){
33  //**************************************************
34 
35  Float_t dist = -9999999;
36  distz = -999;
37  for (Int_t idet = 0; idet < trueTrack.nDetCrossings; idet++) {
38  //i.e crossing the active part of the tpc
39  if (!trueTrack.DetCrossings[idet]->Detector)
40  continue;
41  if (SubDetId::GetDetectorUsed(trueTrack.DetCrossings[idet]->Detector, SubDetId::kTPC) && trueTrack.DetCrossings[idet]->InActive) {
42  Float_t dist_temp = anaUtils::GetSeparationSquared(trueTrack.DetCrossings[idet]->ExitPosition, trueTrack.DetCrossings[idet]->EntrancePosition);
43  Float_t distz_temp = fabs(trueTrack.DetCrossings[idet]->ExitPosition[2] - trueTrack.DetCrossings[idet]->EntrancePosition[2]);
44  if (dist_temp > dist)
45  dist = dist_temp;
46  if (distz_temp > distz)
47  distz = distz_temp;
48 
49  }
50  }
51 
52  return sqrt(dist);
53 }
54 
55 //********************************************************************
57  //********************************************************************
58  int count = 0;
59 
60  if (!SubDetId::IsFGDDetector(det))
61  return false;
62 
63  AnaTrueParticleB* tracks[NMAXTRUEPARTICLES];
64  int ntracks = anaUtils::GetAllChargedTrajInBunch(event, tracks);
65  if((UInt_t)ntracks>NMAXTRUEPARTICLES) ntracks = NMAXTRUEPARTICLES;
66 
67  for (int i=0; i<ntracks; i++){
68  AnaTrueParticleB* track = tracks[i];
69  if (!track) continue;
70 
71  //should satisfy some minimum criteria in FGD and ECal
72  if (anaUtils::TrueParticleEntersDet(track, det) && anaUtils::TrueParticleEntersDet(track, SubDetId::kTECAL) && !anaUtils::TrueParticleCrossesTPC(track))
73  outTraj[count++] = track;
74 
75  }
76 
77  return count;
78 }
79 
80 
81 //********************************************************************
83  //********************************************************************
84  int count = 0;
85 
86 
87  for(Int_t i = 0; i < event.nTrueParticles;i++){
88 
89  AnaTrueParticleB* track = event.TrueParticles[i];
90 
91  if (!track) continue;
92 
93  if(!track->TrueVertex) continue;
94  if(track->TrueVertex->Bunch != event.Bunch) continue;
95 
96  SubDetId::SubDetEnum ecal_det[20];
97 
98  int necal_det = anaUtils::GetECalDetCrossed(track, ecal_det);
99 
100  if (necal_det > 0)
101  outTraj[count++] = track;
102  }
103 
104  return count;
105 }
106 
107 //********************************************************************
109  //********************************************************************
110 
111  if(!track)
112  return false;
113 
114 
115  //this is a check to account for no splitting of truth into sub-detectors for SMRD and ECa
116  if (det > SubDetId::kDSECAL && det < SubDetId::kTPC){
117  std::cout<< "anaUtils::TrueParticleEntersDet() WARNING: " << det << " is not available from true info " << std::endl;
118  }
119 
120  //check that a trajectory crosses volume
121  for(Int_t idet=0;idet<track->nDetCrossings;idet++){
122 
123  if(!SubDetId::GetDetectorUsed(track->DetCrossings[idet]->Detector, det)) continue;
124 
125  return true;
126 
127  }
128 
129  return false;
130 
131 }
132 
133 //********************************************************************
134 bool anaUtils::TrueParticleCrossesTECal(const AnaTrueParticleB* track, Float_t min_sep){
135  //********************************************************************
136 
137  if(!track)
138  return false;
139 
140  Float_t surf_pos[4] = {
141  DetDef::tecalTLmin[1],
142  DetDef::tecalBLmax[1],
143  DetDef::tecalLmin[0],
144  DetDef::tecalRmax[0]
145  };
146 
147  //check that a trajectory crosses BarrelECal active volume
148  for(Int_t idet=0;idet<track->nDetCrossings;idet++){
149 
150  AnaDetCrossingB* cross = track->DetCrossings[idet];
151  if(!cross)
152  continue;
153 
154  if(!(cross->Detector & (1<<SubDetId::kTECAL)) || !cross->InActive) continue;
155 
156  //since truth info does not allow splitting the ecal sub-volumes --> use hard-coded values
157 
158  // top
159  Float_t sep = 0.;
160  if (cross->ExitPosition[1]>1265.){
161  sep = cross->ExitPosition[1]-surf_pos[0];
162  }
163  //bottom
164  else if (cross->ExitPosition[1]<-1265.){
165  sep = surf_pos[1]-cross->ExitPosition[1];
166  }
167  //left
168  else if (cross->ExitPosition[0]>1300.){
169  sep = cross->ExitPosition[0]-surf_pos[2];
170  }
171  //right
172  else if (cross->ExitPosition[0]<-1300.){
173  sep = surf_pos[3]-cross->ExitPosition[0];
174  }
175 
176  if(sep>min_sep)
177  return true;
178  }
179 
180  return false;
181 
182 }
183 
184 
185 //********************************************************************
186 bool anaUtils::TrueParticleCrossesSMRD(const AnaTrueParticleB* track, Float_t min_sep){
187  //********************************************************************
188 
189  if(!track)
190  return false;
191 
192  Float_t surf_pos[4] = {
193  DetDef::smrdTLmin[1],
194  DetDef::smrdBLmax[1],
195  DetDef::smrd6Lmin[0],
196  DetDef::smrd6Rmax[0]
197  };
198 
199  //loop through det crossings
200  for(Int_t idet=0;idet<track->nDetCrossings;idet++){
201 
202  AnaDetCrossingB* cross = track->DetCrossings[idet];
203  if(!cross)
204  continue;
205 
206  //InActive flag is not set for SMRD in oaAnalysis
207  if(!(cross->Detector & (1<<SubDetId::kSMRD)))
208  continue;
209 
210  // top
211  Float_t sep = 0.;
212  if (cross->ExitPosition[1]>2010.){
213  sep = cross->ExitPosition[1]-surf_pos[0];
214  }
215  //bottom
216  else if (cross->ExitPosition[1]<-2010.){
217  sep = surf_pos[1]-cross->ExitPosition[1];
218  }
219  //left
220  else if (cross->ExitPosition[0]>1830.){
221  sep = cross->ExitPosition[0]-surf_pos[2];
222  }
223  //right
224  else if (cross->ExitPosition[0]<-1830.){
225  sep = surf_pos[3]-cross->ExitPosition[0];
226  }
227 
228  if(sep>min_sep)
229  return true;
230  }
231 
232  return false;
233 
234 }
235 
236 //********************************************************************
238  //********************************************************************
239 
240  if(!track)
241  return false;
242 
243  //for the moment consider the minimum separation in the direction perpendicular to the beam as:
244  // 48 mm (iron) mm (we are intersted for tracks that come from inside, so should cross the first iron block)
245  // as it comes from oaAnalysis only one point is saved for SMRD, as I understand the code it should be the exit point
246  // so make a cut in X/Y distance between the point and particular surface inner border
247 
248  if (det!=SubDetId::kFGD && !SubDetId::IsFGDDetector(det))
249  return false;
250 
251 
252  //loop through det crossings
253  for(Int_t idet=0;idet<track->nDetCrossings;idet++){
254 
255  AnaDetCrossingB* cross = track->DetCrossings[idet];
256  if(!cross)
257  continue;
258 
259  // i.e crossing the active part of the FGD
260  if (!SubDetId::GetDetectorUsed(track->DetCrossings[idet]->Detector, det) || !track->DetCrossings[idet]->InActive)
261  continue;
262 
263  //the separation should be done using the z position, since the fgd is separated by layer in z,
264  //making the z position the reconstructed quantity to be cut on
265  Float_t sep = fabs(track->DetCrossings[idet]->EntrancePosition[2] - track->DetCrossings[idet]->ExitPosition[2]);
266 
267  //should be at least two layers
268  if(sep>DetDef::fgdXYModuleWidth)
269  return true;
270 
271  }
272 
273  return false;
274 
275 }
276 
277 //********************************************************************
279  //********************************************************************
280 
281  if(!track)
282  return false;
283 
284  if (det!=SubDetId::kTPC && !SubDetId::IsTPCDetector(det))
285  return false;
286 
287  Float_t dist=-999999.;
288 
289  //loop through det crossings
290  for(Int_t idet=0;idet<track->nDetCrossings;idet++){
291 
292  AnaDetCrossingB* cross = track->DetCrossings[idet];
293  if(!cross)
294  continue;
295 
296  // i.e crossing the active part of the FGD
297  if (!SubDetId::GetDetectorUsed(track->DetCrossings[idet]->Detector, det) || !track->DetCrossings[idet]->InActive)
298  continue;
299 
300  //i.e crossing the active part of the tpc
301  if(SubDetId::GetDetectorUsed(track->DetCrossings[idet]->Detector, det) && track->DetCrossings[idet]->InActive){
302  Float_t sep = anaUtils::GetSeparationSquared(track->DetCrossings[idet]->EntrancePosition, track->DetCrossings[idet]->ExitPosition);
303  if(sep>dist) dist=sep;
304  }
305  }
306 
307  if(dist>62500)//bigger than the ~1/4 of the width of the TPC
308  return true;
309 
310  return false;
311 
312 }
313 
314 //**************************************************
316  //**************************************************
317 
318  int count = 0;
319 
320  if (!track)
321  return count;
322 
323  for (Int_t idet = 0; idet < track->nDetCrossings; idet++){
324 
325  if((track->DetCrossings[idet]->Detector & (1<<SubDetId::kTECAL)) && track->DetCrossings[idet]->InActive) {
326 
327  //use geometry info to split between sub-detectors
328  if (track->DetCrossings[idet]->EntrancePosition[1] > 1265. || track->DetCrossings[idet]->ExitPosition[1] > 1265)
329  det[count++] = SubDetId::kTopTECAL;
330 
331  else if (track->DetCrossings[idet]->EntrancePosition[1] < -1265. || track->DetCrossings[idet]->ExitPosition[1] < -1265.)
332  det[count++] = SubDetId::kBottomTECAL;
333 
334  else if (track->DetCrossings[idet]->EntrancePosition[0] > 1300. || track->DetCrossings[idet]->ExitPosition[0] > 1300.)
335  det[count++] = SubDetId::kLeftTECAL;
336 
337  else if (track->DetCrossings[idet]->EntrancePosition[0] < -1300. || track->DetCrossings[idet]->ExitPosition[0] < -1300.)
338  det[count++] = SubDetId::kRightTECAL;
339 
340  }
341 
342  else if((track->DetCrossings[idet]->Detector & (1<<SubDetId::kPECAL)) && track->DetCrossings[idet]->InActive) {
343 
344  //use geometry info to split between sub-detectors
345  if (track->DetCrossings[idet]->EntrancePosition[1] > 1265. || track->DetCrossings[idet]->ExitPosition[1] > 1265)
346  det[count++] = SubDetId::kTopPECAL;
347 
348  else if (track->DetCrossings[idet]->EntrancePosition[1 ] < -1265. || track->DetCrossings[idet]->ExitPosition[1] < -1265.)
349  det[count++] = SubDetId::kBottomPECAL;
350 
351  else if (track->DetCrossings[idet]->EntrancePosition[0] > 1300. || track->DetCrossings[idet]->ExitPosition[0] > 1300.)
352  det[count++] = SubDetId::kLeftPECAL;
353 
354  else if (track->DetCrossings[idet]->EntrancePosition[0] < -1300. || track->DetCrossings[idet]->ExitPosition[0] < -1300.)
355  det[count++] = SubDetId::kRightPECAL;
356  }
357  else if((track->DetCrossings[idet]->Detector & (1<<SubDetId::kDSECAL)) && track->DetCrossings[idet]->InActive) {
358  det[count++] = SubDetId::kDSECAL;
359  }
360  }
361  return count;
362 }
363 
364 
365 
366 //**************************************************
368  //**************************************************
369  int count = 0;
370 
371  if (!track)
372  return count;
373 
374  for(Int_t idet=0;idet<track->nDetCrossings;idet++){
375  //InActive flag is not set for SMRD in oaAnalysis
376 
377  if(!(track->DetCrossings[idet]->Detector & (1<<SubDetId::kSMRD)))
378  continue;
379 
380  //use geometry info to split between sub-detectors
381  if (track->DetCrossings[idet]->EntrancePosition[1]>2010.)
382  det[count++] = SubDetId::kTopSMRD;
383 
384  if (track->DetCrossings[idet]->EntrancePosition[1]<-2010.)
385  det[count++] = SubDetId::kBottomSMRD;
386 
387  if (track->DetCrossings[idet]->EntrancePosition[0]>1830.)
388  det[count++] = SubDetId::kLeftSMRD;
389 
390  if (track->DetCrossings[idet]->EntrancePosition[0]<-1830.)
391  det[count++] = SubDetId::kRightSMRD;
392  }
393 
394  return count;
395 }
396 
397 //**************************************************
399  //**************************************************
400  int count = 0;
401 
402  if (!track)
403  return count;
404 
405  for(Int_t idet=0;idet<track->nDetCrossings;idet++){
406 
407  // i.e crossing the active part of the FGD
408  if (SubDetId::GetDetectorUsed(track->DetCrossings[idet]->Detector, SubDetId::kFGD1)
409  && track->DetCrossings[idet]->InActive)
410  det[count++] = SubDetId::kFGD1;
411 
412  if (SubDetId::GetDetectorUsed(track->DetCrossings[idet]->Detector, SubDetId::kFGD2)
413  && track->DetCrossings[idet]->InActive)
414  det[count++] = SubDetId::kFGD2;
415 
416  }
417 
418  return count;
419 }
420 
421 //**************************************************
423  //**************************************************
424 
425  AnaDetCrossingB* cross = NULL;
426 
427 
428  if (!track) return cross;
429 
430  for (int i = 0; i < track->nDetCrossings; i++){
431 
432  if (!track->DetCrossings[i]) continue;
433 
435 
436  if (det_bit == SubDetId::kInvalid) continue;
437 
438  if (det_bit != det) continue;
439 
440  if (!track->DetCrossings[i]->InActive) continue;
441 
442  cross = track->DetCrossings[i];
443 
444  }
445 
446  return cross;
447 
448 }
449 
450 //**************************************************
452  //**************************************************
453  return sqrt(pow(cross.EntranceMomentum[0],2) +
454  pow(cross.EntranceMomentum[1],2) +
455  pow(cross.EntranceMomentum[2],2));
456 }
457 
458 //**************************************************
460  //**************************************************
461 
462  return sqrt(pow(cross.ExitMomentum[0],2) +
463  pow(cross.ExitMomentum[1],2) +
464  pow(cross.ExitMomentum[2],2));
465 }
bool TrueParticleCrossesTECal(const AnaTrueParticleB *track, Float_t min_sep=50.)
Definition: TruthUtils.cxx:134
bool InActive
If the particle passes through an active part of the subdetector.
AnaTrueVertexB * TrueVertex
Pointer to the AnaTrueVertexB of the interaction that created this AnaTrueParticleB.
bool TrueParticleEntersDet(const AnaTrueParticleB *track, SubDetId::SubDetEnum det)
Whether a true track enters a given sub-detector.
Definition: TruthUtils.cxx:108
unsigned long Detector
int nDetCrossings
The number of DetCrossing objects.
int nTrueParticles
How many true particles are associated with this vertex.
Float_t ExitPosition[4]
for each subdetector tell the exit position
static bool IsFGDDetector(SubDetId::SubDetEnum det)
Check if a detector enumeration refers to a FGD or not.
Definition: SubDetId.cxx:126
int GetECalDetCrossed(const AnaTrueParticleB *track, SubDetId::SubDetEnum det[])
ECal detectors crossed: split based on geom info PECal and TECal sub-detectors, this may not be very ...
Definition: TruthUtils.cxx:315
Int_t GetNMichelElectrons(const AnaTrueVertexB &trueVertex, SubDetId::SubDetEnum det=SubDetId::kFGD1)
Get the number of true michel electrons.
Definition: TruthUtils.cxx:6
Representation of a true Monte Carlo vertex.
Float_t GetExitMomentum(const AnaDetCrossingB &cross)
Get the momentum value from AnaDetCrossing.
Definition: TruthUtils.cxx:459
Int_t GParentPDG
The PDG code of this particle&#39;s grandparent, or 0 if there is no grandparent.
bool TrueParticleCrossesTPC(const AnaTrueParticleB *track, SubDetId::SubDetEnum det=SubDetId::kTPC)
Whether a true track crosses a TPC so to be able to reconstruct an object.
Definition: TruthUtils.cxx:278
int GetAllChargedTrajsInFgdECalInBunch(const AnaEventB &event, AnaTrueParticleB *outTraj[], SubDetId::SubDetEnum det)
Definition: TruthUtils.cxx:56
static bool GetDetectorUsed(unsigned long BitField, SubDetId::SubDetEnum det)
Method to see if a certain subdetector or subdetector system is used.
Definition: SubDetId.cxx:40
AnaTrueParticleB ** TrueParticles
The true particles associated with this vertex.
float GetSeparationSquared(const Float_t *pos1, const Float_t *pos2)
Calculate the distance between two points.
int GetAllChargedTrajInBunch(const AnaEventB &event, AnaTrueParticleB *traj[])
Definition: SubDetUtils.cxx:26
bool TrueParticleCrossesFGD(const AnaTrueParticleB *track, SubDetId::SubDetEnum det=SubDetId::kFGD)
Whether a true track crosses a FGD so to be able to deposit charge in at least two layers...
Definition: TruthUtils.cxx:237
Representation of a true Monte Carlo trajectory/particle.
Float_t GetEntranceMomentum(const AnaDetCrossingB &cross)
Get the momentum value from AnaDetCrossing.
Definition: TruthUtils.cxx:451
Float_t Position[4]
The position the true interaction happened at.
int GetSMRDDetCrossed(const AnaTrueParticleB *track, SubDetId::SubDetEnum det[])
SMRD detectors crossed.
Definition: TruthUtils.cxx:367
bool TrueParticleCrossesSMRD(const AnaTrueParticleB *track, Float_t min_sep=48.)
Definition: TruthUtils.cxx:186
Float_t EntrancePosition[4]
for each subdetector tell the entrance position
static bool IsTPCDetector(SubDetId::SubDetEnum det)
Check if a detector enumeration refers to a TPC or not.
Definition: SubDetId.cxx:122
AnaDetCrossingB ** DetCrossings
Representation of a detector crossing info for a true particle (G4 trajectory).
SubDetEnum
Enumeration of all detector systems and subdetectors.
Definition: SubDetId.hxx:25
Int_t PDG
The PDG code of this particle.
Int_t ParentPDG
The PDG code of this particle&#39;s immediate parent, or 0 if there is no parent.
Int_t Bunch
The index of this bunch (0-7).
AnaDetCrossingB * GetAnaDetCrossing(const AnaTrueParticleB *track, SubDetId::SubDetEnum det)
Definition: TruthUtils.cxx:422
static SubDetId::SubDetEnum GetSubdetectorEnum(unsigned long BitField)
Get the single subdetector that this track is from.
Definition: SubDetId.cxx:165
Float_t ExitMomentum[3]
for each subdetector tell the exit momentum
int GetAllTrajsInECalInBunch(const AnaEventB &event, AnaTrueParticleB *outTraj[])
Definition: TruthUtils.cxx:82
int GetFGDDetCrossed(const AnaTrueParticleB *track, SubDetId::SubDetEnum det[])
FGD detectors crossed.
Definition: TruthUtils.cxx:398
Float_t GetTrueLinearLengthInTPC(const AnaTrueParticleB &trueTrack, Float_t &distz)
Return the true linear length traversed in the TPC.
Definition: TruthUtils.cxx:32
bool InFiducialVolume(SubDetId::SubDetEnum det, const Float_t *pos, const Float_t *FVdefmin, const Float_t *FVdefmax)
Float_t EntranceMomentum[3]
for each subdetector tell the entrance momentum