HighLAND
numuCC4piMultiPiSelection.cxx
1 #include "numuCC4piMultiPiSelection.hxx"
2 #include "baseSelection.hxx"
3 #include "SystematicTuning.hxx"
4 #include "CutUtils.hxx"
5 #include "EventBoxUtils.hxx"
6 #include "Parameters.hxx"
7 #include "SubDetId.hxx"
8 #include "SystId.hxx"
9 #include "SystematicUtils.hxx"
10 
11 //********************************************************************
12 numuCC4piMultiPiSelection::numuCC4piMultiPiSelection(bool forceBreak): SelectionBase(forceBreak,EventBoxId::kEventBoxTracker) {
13  //********************************************************************
14 
15  // Initialize systematic tuning parameters
16  systTuning::Initialize();
17 }
18 
19 //********************************************************************
21  //********************************************************************
22 
23  AddStep(StepBase::kCut, "event quality", new EventQualityCut(), true); //if passed accum_level=1
24  AddStep(StepBase::kCut, "> 0 tracks ", new numuCC4pi::TotalMultiplicityCut(), true); //if passed accum_level=2
25  AddStep(StepBase::kAction, "Sort TPC tracks", new numuCC4pi::SortTracksAction());
26  AddStep(StepBase::kCut, "quality+fiducial", new numuCC4pi::TrackGQandFVCut(), true); //if passed accum_level=3
27  AddStep(StepBase::kAction, "veto Action", new numuCC4pi::VetoAction());
28  AddStep(StepBase::kAction, "muon PID Action", new numuCC4pi::PIDAction());
29  AddStep(StepBase::kAction, "find vertex", new numuCC4pi::FindVertexAction());
30  AddStep(StepBase::kAction, "fill summary", new FillSummaryAction_numuCC4piMultiPi());
31  AddStep(StepBase::kAction, "find_pions", new numuCC4piMultiPi::FindPionsAction());
32  AddStep(StepBase::kAction, "find ECal photons", new numuCC4piMultiPi::FindEcalPhotonsAction());
33 
34  AddSplit(4);
35 
36  AddStep(0, StepBase::kCut, "Fwd Quality Cut", new numuCC4pi::Fwd_Quality()); //if passed accum_level=4
37  AddStep(0, StepBase::kCut, "Fwd Veto Cut", new numuCC4pi::Fwd_Veto()); //if passed accum_level=5
38  AddStep(0, StepBase::kCut, "Fwd PID Cut", new numuCC4pi::Fwd_PID()); //if passed accum_level=6
39  AddStep(0, StepBase::kCut, "Fwd 4piMultiPi Cut", new numuCC4pi::Fwd()); //if passed accum_level=7
40 
41  AddSplit(3,0);
42  AddStep(0,0, StepBase::kCut, "Fwd CC-0pi", new numuCC4piMultiPi::NoPionCut());
43  AddStep(0,0, StepBase::kCut, "Fwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
44 
45  AddStep(0,1, StepBase::kCut, "Fwd CC-1pi", new numuCC4piMultiPi::OnePionCut());
46  AddStep(0,1, StepBase::kCut, "Fwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
47 
48  AddStep(0,2, StepBase::kCut, "Fwd CC-Other", new numuCC4piMultiPi::OthersCut());
49 
50  AddStep(1, StepBase::kCut, "Bwd Quality Cut", new numuCC4pi::Bwd_Quality());
51  AddStep(1, StepBase::kCut, "Bwd Veto Cut", new numuCC4pi::Bwd_Veto());
52  AddStep(1, StepBase::kCut, "Bwd PID Cut", new numuCC4pi::Bwd_PID());
53  AddStep(1, StepBase::kCut, "Bwd 4piMultiPi Cut", new numuCC4pi::Bwd());
54 
55  AddSplit(3,1);
56  AddStep(1,0, StepBase::kCut, "Bwd CC-0pi", new numuCC4piMultiPi::NoPionCut());
57  AddStep(1,0, StepBase::kCut, "Bwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
58 
59  AddStep(1,1, StepBase::kCut, "Bwd CC-1pi", new numuCC4piMultiPi::OnePionCut());
60  AddStep(1,1, StepBase::kCut, "Bwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
61 
62  AddStep(1,2, StepBase::kCut, "Bwd CC-Other", new numuCC4piMultiPi::OthersCut());
63 
64  AddStep(2, StepBase::kCut, "HAFwd Quality Cut", new numuCC4pi::HAFwd_Quality());
65  AddStep(2, StepBase::kCut, "HAFwd Veto Cut", new numuCC4pi::HAFwd_Veto());
66  AddStep(2, StepBase::kCut, "HAFwd PID Cut", new numuCC4pi::HAFwd_PID());
67  AddStep(2, StepBase::kCut, "HAFwd 4piMultiPi Cut", new numuCC4pi::HAFwd());
68 
69  AddSplit(3,2);
70  AddStep(2,0, StepBase::kCut, "HAFwd CC-0pi", new numuCC4piMultiPi::NoPionCut());
71  AddStep(2,0, StepBase::kCut, "HAFwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
72 
73  AddStep(2,1, StepBase::kCut, "HAFwd CC-1pi", new numuCC4piMultiPi::OnePionCut());
74  AddStep(2,1, StepBase::kCut, "HAFwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
75 
76  AddStep(2,2, StepBase::kCut, "HAFwd CC-Other", new numuCC4piMultiPi::OthersCut());
77 
78  AddStep(3, StepBase::kCut, "HABwd Quality Cut", new numuCC4pi::HABwd_Quality());
79  AddStep(3, StepBase::kCut, "HABwd Veto Cut", new numuCC4pi::HABwd_Veto());
80  AddStep(3, StepBase::kCut, "HABwd PID Cut", new numuCC4pi::HABwd_PID());
81  AddStep(3, StepBase::kCut, "HABwd 4piMultiPi Cut", new numuCC4pi::HABwd());
82 
83  AddSplit(3,3);
84  AddStep(3,0, StepBase::kCut, "HABwd CC-0pi", new numuCC4piMultiPi::NoPionCut());
85  AddStep(3,0, StepBase::kCut, "HABwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
86 
87  AddStep(3,1, StepBase::kCut, "HABwd CC-1pi", new numuCC4piMultiPi::OnePionCut());
88  AddStep(3,1, StepBase::kCut, "HABwd ECal Pi0 veto", new numuCC4piMultiPi::EcalPi0VetoCut());
89 
90  AddStep(3,2, StepBase::kCut, "HABwd CC-Other", new numuCC4piMultiPi::OthersCut());
91 
92  SetBranchAlias(0, "Fwd CC0pi", 0, 0);
93  SetBranchAlias(1, "Fwd CC1pi", 0, 1);
94  SetBranchAlias(2, "Fwd CCOther", 0, 2);
95 
96  SetBranchAlias(3, "Bwd CC0pi", 1,0);
97  SetBranchAlias(4, "Bwd CC1pi", 1,1);
98  SetBranchAlias(5, "Bwd CCOther", 1,2);
99 
100  SetBranchAlias(6, "HAFwd CC0pi", 2,0);
101  SetBranchAlias(7, "HAFwd CC1pi", 2,1);
102  SetBranchAlias(8, "HAFwd CCOther", 2,2);
103 
104  SetBranchAlias(9, "HABwd CC0pi", 3,0);
105  SetBranchAlias(10, "HABwd CC1pi", 3,1);
106  SetBranchAlias(11, "HABwd CCOther",3,2);
107 
108  SetPreSelectionAccumLevel(2);
109 
110 }
111 
112 //********************************************************************
114  //********************************************************************
115 
116  // Change FV definition to take all thickness
117  // Note! this will affect all downstream stuff
118  FVDef::FVdefminFGD1[2] = 0;
119  FVDef::FVdefmaxFGD1[2] = 0;
120 
121  // The detector in which the selection is applied
122  SetDetectorFV(SubDetId::kFGD1);
123 
124 }
125 
126 
127 //**************************************************
129 //**************************************************
130 
131  AnaEventB& event = *static_cast<AnaEventB*>(&eventBB);
132 
133  // Create the appropriate EventBox if it does not exist yet
134  if (!event.EventBoxes[EventBoxId::kEventBoxTracker]) event.EventBoxes[EventBoxId::kEventBoxTracker] = new EventBoxTracker();
135 
136  boxUtils::FillTracksWithTPC(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
137  boxUtils::FillTracksWithFGD(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
138  boxUtils::FillTracksWithECal(event);
139 
140  boxUtils::FillTrajsChargedInTPC(event);
141  boxUtils::FillTrajsChargedInFGDAndNoTPC(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
142  boxUtils::FillTrajsChargedHATracker(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
143  boxUtils::FillTrajsInECal(event);
144 
145 }
146 
147 //********************************************************************
148 bool numuCC4piMultiPiSelection::FillEventSummary(AnaEventC& event, Int_t allCutsPassed[]){
149  //********************************************************************
150 
151  if(allCutsPassed[0]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
152  if(allCutsPassed[1]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
153  if(allCutsPassed[2]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
154 
155  if(allCutsPassed[3]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
156  if(allCutsPassed[4]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
157  if(allCutsPassed[5]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
158 
159  if(allCutsPassed[6]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
160  if(allCutsPassed[7]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
161  if(allCutsPassed[8]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
162 
163  if(allCutsPassed[9]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC0Pi;
164  if(allCutsPassed[10]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCC1Pi;
165  if(allCutsPassed[11]) static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuMuCCOther;
166 
167  return (static_cast<AnaEventSummaryB*>(event.Summary)->EventSample != SampleId::kUnassigned);
168 }
169 
170 //********************************************************************
172  //********************************************************************
173 
174  // Cast the ToyBox to the appropriate type
175  ToyBoxCC4piMultiPi* cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&boxB);
176 
177  if(!cc4piMultiPibox->MainTrack) return 1;
178 
179  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD1NuMuCC0Pi] = cc4piMultiPibox->MainTrack;
180  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD1NuMuCC1Pi] = cc4piMultiPibox->MainTrack;
181  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD1NuMuCCOther] = cc4piMultiPibox->MainTrack;
182 
183  anaUtils::CopyArray( cc4piMultiPibox->MainTrack->PositionStart, static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD1NuMuCC0Pi], 4);
184  anaUtils::CopyArray( cc4piMultiPibox->MainTrack->PositionStart, static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD1NuMuCC1Pi], 4);
185  anaUtils::CopyArray( cc4piMultiPibox->MainTrack->PositionStart, static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD1NuMuCCOther], 4);
186 
187  if(cc4piMultiPibox->MainTrack->GetTrueParticle()) static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD1NuMuCC0Pi] = cc4piMultiPibox->MainTrack->GetTrueParticle()->TrueVertex;
188  if(cc4piMultiPibox->MainTrack->GetTrueParticle()) static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD1NuMuCC1Pi] = cc4piMultiPibox->MainTrack->GetTrueParticle()->TrueVertex;
189  if(cc4piMultiPibox->MainTrack->GetTrueParticle()) static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD1NuMuCCOther] = cc4piMultiPibox->MainTrack->GetTrueParticle()->TrueVertex;
190 
191  return true;
192 }
193 
194 //*********************************************************************
196 //*********************************************************************
197 
198  SubDetId::SubDetEnum det = static_cast<SubDetId::SubDetEnum>(box.DetectorFV);
199 
200  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
201  EventBoxTracker* EventBox = static_cast<EventBoxTracker*>(event.EventBoxes[EventBoxId::kEventBoxTracker]);
202 
203  if (useTPCPions) numuCC4piMultiPiUtils::FindTPCPions(event, box, det, useOldSecondaryPID);
204  if (useME) numuCC4piMultiPiUtils::FindMEPions(event,det, prod5Cut);
205  if (useFGDPions) numuCC4piMultiPiUtils::FindIsoFGDPions(event, box, det);
206 
207  int nnegpions = cc4piMultiPibox->nNegativePionTPCtracks;
208  int npospions = cc4piMultiPibox->nPositivePionTPCtracks;
209  int nisofgdpions = cc4piMultiPibox->nIsoFGDPiontracks;
210  int nmichelelectrons = EventBox->nFGDMichelElectrons[det];
211  int npi0 = cc4piMultiPibox->nPosPi0TPCtracks+ cc4piMultiPibox->nElPi0TPCtracks;
212 
213  int pionFGD = nmichelelectrons;
214  if (!nmichelelectrons && nisofgdpions>0) pionFGD = 1;
215 
216  cc4piMultiPibox->nPosPions = npospions+pionFGD;
217  cc4piMultiPibox->nOtherPions = nnegpions+npi0;
218  return true;
219 }
220 
221 //*********************************************************************
223 //*********************************************************************
224  // Find whether there is a pi0 track in the ECal or not
225  // In order to apply a pi0 veto cut later
226  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
227  SubDetId::SubDetEnum det = static_cast<SubDetId::SubDetEnum>(box.DetectorFV);
228 
229  // Get all Ecal objects
230  EventBoxTracker::RecObjectGroupEnum groupID;
231  groupID = EventBoxTracker::kTracksWithECal;
232  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
233 
234  AnaTrackB *highestObject = NULL;
235  double higherEnergyObject = 0;
236 
237  //loop over all ECal objects
238  for(int i = 0; i < EventBox->nRecObjectsInGroup[groupID]; i++ ) {
239  AnaTrackB *allECALObjects = static_cast<AnaTrackB*>(EventBox->RecObjectsInGroup[groupID][i]);
240  if(!(allECALObjects->nECALSegments)) continue;
241  // Check for isolated ecal object
242  if(!(anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kDSECAL) ||
243  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kTopTECAL) ||
244  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kBottomTECAL) ||
245  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kLeftTECAL) ||
246  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kRightTECAL))
247  ) continue;
248 
249  AnaECALParticleB* ecalBase = allECALObjects->ECALSegments[0];
250  AnaTrackB* object = allECALObjects;
251  cc4piMultiPibox->ISOEcal.push_back(object);
252 
253  // Find the most energetic object in ECal
254  if(ecalBase->EMEnergy > higherEnergyObject){
255  higherEnergyObject = ecalBase->EMEnergy;
256  highestObject = object;
257  }
258  }// end of loop on allECALTracks
259 
260  // Save the highest energetic ecal object in the box and the pi0 track
261  if (highestObject){
262  cc4piMultiPibox->HObject = highestObject;
263  // Check if the highest energetic ecal object is shower-like
264  if( numuCC4piMultiPiUtils::ECALPi0Selection(event, box, highestObject, MostUpstreamLayerHitCut, det) ) {
265  cc4piMultiPibox->Pi0Ecaltrack = highestObject;
266  cc4piMultiPibox->nPi0Ecaltracks = cc4piMultiPibox->nPi0Ecaltracks+1;
267  }
268  }
269  return true;
270 }
271 
272 //*********************************************************************
274 //*********************************************************************
275 
276  (void)event;
277 
278  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
279 
280  // no positive and no other pions
281  if( cc4piMultiPibox->nPosPions + cc4piMultiPibox->nOtherPions == 0 ) {
282  return true;
283  }
284  return false;
285 }
286 
287 
288 //*********************************************************************
290 //*********************************************************************
291 
292  (void)event;
293 
294  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
295 
296  // one Positive pion and no other pions
297  if( cc4piMultiPibox->nOtherPions != 0 ) return false;
298  if( cc4piMultiPibox->nPosPions == 1 ){
299  return true;
300  }
301  return false;
302 }
303 
304 
305 //*********************************************************************
307 //*********************************************************************
308 
309  (void)event;
310 
311  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
312 
313  // More than one positive pion or more than zero other pions or event doesn't pass the pi0 veto
314  if( cc4piMultiPibox->nOtherPions != 0 ){
315  return true;
316  }
317  if( cc4piMultiPibox->nPosPions > 1 ){
318  return true;
319  }
320  if( cc4piMultiPibox->nPi0Ecaltracks > 0){
321  return true;
322  }
323  return false;
324 }
325 
326 //*********************************************************************
327 void numuCC4piMultiPiUtils::FindTPCPions(AnaEventC& event, ToyBoxB& box, SubDetId::SubDetEnum det, bool useOldSecondaryPID){
328 //*********************************************************************
329 
330  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
331 
332  cc4piMultiPibox->nPositivePionTPCtracks = 0;
333  cc4piMultiPibox->nPosPi0TPCtracks = 0;
334  cc4piMultiPibox->nNegativePionTPCtracks = 0;
335  cc4piMultiPibox->nElPi0TPCtracks = 0;
336 
337  EventBoxTracker::RecObjectGroupEnum groupID;
338  if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD1FV;
339  else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD2FV;
340  else return;
341 
342  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
343 
344  // Look for pions in positive tracks
345  for(int i = 0; i < EventBox->nRecObjectsInGroup[groupID]; i++ ) {
346  AnaTrackB *ptrack = static_cast<AnaTrackB*>(EventBox->RecObjectsInGroup[groupID][i]);
347 
348  if (ptrack->Charge>0){
349  if(useOldSecondaryPID){
350  if ( numuCC4piMultiPiUtils::TPCpionSelection(ptrack) ) {
351  cc4piMultiPibox->PositivePionTPCtracks[cc4piMultiPibox->nPositivePionTPCtracks] = ptrack;
352  cc4piMultiPibox->nPositivePionTPCtracks++;
353  }
354  else if ( numuCC4piMultiPiUtils::TPCElPi0Selection(ptrack) ) {
355  cc4piMultiPibox->PosPi0TPCtracks[cc4piMultiPibox->nPosPi0TPCtracks] = ptrack;
356  cc4piMultiPibox->nPosPi0TPCtracks++;
357  }
358  }
359  else {
360  Float_t PIDLikelihood[4];
361  anaUtils::GetPIDLikelihood(*ptrack, PIDLikelihood);
362 
363  // For Positive tracks we distinguish pions, electrons and protons.
364  double ElLklh = PIDLikelihood[1];
365  double ProtonLklh = PIDLikelihood[2];
366  double PionLklh = PIDLikelihood[3];
367  double norm = ElLklh+ProtonLklh+PionLklh;
368  ProtonLklh /= norm;
369  ElLklh /= norm;
370  PionLklh /= norm;
371 
372  if( ProtonLklh > ElLklh && ProtonLklh > PionLklh ) continue; // If the highest probability is a proton continue.
373 
374  // Id associated to the largest of the two probabilities.
375  if( PionLklh > ElLklh ){
376  cc4piMultiPibox->PositivePionTPCtracks[cc4piMultiPibox->nPositivePionTPCtracks] = ptrack;
377  cc4piMultiPibox->nPositivePionTPCtracks++;
378  }
379  else {
380  if( ptrack->Momentum > 900. ) continue; // This is mainly protons.
381  cc4piMultiPibox->PosPi0TPCtracks[cc4piMultiPibox->nPosPi0TPCtracks] = ptrack;
382  cc4piMultiPibox->nPosPi0TPCtracks++;
383  }
384  }
385  }
386  else{
387  if( cc4piMultiPibox->MainTrack == ptrack ) continue; // Same as the leading track.
388 
389  if(useOldSecondaryPID) {
390  if ( numuCC4piMultiPiUtils::TPCpionSelection(ptrack) ) {
391  cc4piMultiPibox->NegativePionTPCtracks[cc4piMultiPibox->nNegativePionTPCtracks] = ptrack;
392  cc4piMultiPibox->nNegativePionTPCtracks++;
393  }
394  else if ( numuCC4piMultiPiUtils::TPCElPi0Selection(ptrack) ) {
395  cc4piMultiPibox->ElPi0TPCtracks[cc4piMultiPibox->nElPi0TPCtracks] = ptrack;
396  cc4piMultiPibox->nElPi0TPCtracks++;
397  }
398  }
399  else {
400  // For Negative tracks we distinguish pions, electrons and protons.
401  Float_t PIDLikelihood[4];
402  anaUtils::GetPIDLikelihood(*ptrack, PIDLikelihood);
403 
404  // For Positive tracks we distinguish pions, electrons and protons.
405  double ElLklh = PIDLikelihood[1];
406  double PionLklh = PIDLikelihood[3];
407  double norm = ElLklh+PionLklh;
408  ElLklh /= norm;
409  PionLklh /= norm;
410 
411  if( PionLklh > 0.8 ){ // Id associated to the largest of the two probabilities.
412  cc4piMultiPibox->NegativePionTPCtracks[cc4piMultiPibox->nNegativePionTPCtracks] = ptrack;
413  cc4piMultiPibox->nNegativePionTPCtracks++;
414  }
415  else{
416  cc4piMultiPibox->ElPi0TPCtracks[cc4piMultiPibox->nElPi0TPCtracks] = ptrack;
417  cc4piMultiPibox->nElPi0TPCtracks++;
418  }
419  }
420  }
421  }
422 }
423 
424 //*********************************************************************
425 void numuCC4piMultiPiUtils::FindIsoFGDPions(AnaEventC& event, ToyBoxB& box, SubDetId::SubDetEnum det){
426 //*********************************************************************
427 
428  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
429  cc4piMultiPibox->nIsoFGDPiontracks = 0;
430  cc4piMultiPibox->nIsoFGDElPi0tracks = 0;
431 
432  EventBoxTracker::RecObjectGroupEnum groupID;
433  if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithFGD1AndNoTPC;
434  else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithFGD2AndNoTPC;
435  else return;
436 
437  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
438 
439  //loop over tracks
440  for (int i=0;i<EventBox->nRecObjectsInGroup[groupID]; i++ ){
441  AnaTrackB* track = static_cast<AnaTrackB*>(EventBox->RecObjectsInGroup[groupID][i]);
442  // Apply the fiducial cut and PID
443  if( numuCC4piMultiPiUtils::FGDpionSelection(track,det) ){
444  cc4piMultiPibox->IsoFGDPiontracks[cc4piMultiPibox->nIsoFGDPiontracks] = track;
445  cc4piMultiPibox->nIsoFGDPiontracks++;
446  }
447  else if( numuCC4piMultiPiUtils::FGDElPi0Selection(event,box,track,det) ){
448  cc4piMultiPibox->IsoFGDElPi0tracks[cc4piMultiPibox->nIsoFGDElPi0tracks] = track;
449  cc4piMultiPibox->nIsoFGDElPi0tracks++;
450  }
451  }
452 }
453 
454 //*********************************************************************
455 void numuCC4piMultiPiUtils::FindMEPions(AnaEventC& eventBB, SubDetId::SubDetEnum det, bool prod5Cut){
456 //*********************************************************************
457 
458  AnaEventB& event = *static_cast<AnaEventB*>(&eventBB);
459 
460  EventBoxTracker* EventBox = static_cast<EventBoxTracker*>(event.EventBoxes[EventBoxId::kEventBoxTracker]);
461 
462  // Fill the box only the first time this is used
463  if (EventBox->FGDMichelElectrons[det]) return;
464 
465  anaUtils::CreateArray(EventBox->FGDMichelElectrons[det], NMAXFGDTIMEBINS);
466  EventBox->nFGDMichelElectrons[det] = anaUtils::GetFGDMichelElectrons(event, det, EventBox->FGDMichelElectrons[det], prod5Cut);
467  anaUtils::ResizeArray(EventBox->FGDMichelElectrons[det], EventBox->nFGDMichelElectrons[det]);
468 
469 }
470 
471 //*********************************************************************
472 bool numuCC4piMultiPiUtils::TPCpionSelection(AnaTrackB *track){
473 //*********************************************************************
474 
475  Float_t PIDLikelihood[4];
476  anaUtils::GetPIDLikelihood(*track, PIDLikelihood);
477 
478  if ( PIDLikelihood[3] < 0.3 ) return false;
479 
480  double cut1 = (PIDLikelihood[0]+PIDLikelihood[3])/(1.-PIDLikelihood[2]);
481 
482  if( track->Momentum < 500. && cut1 < 0.8 ) return false;
483 
484  return true;
485 
486 
487 }
488 
489 //*********************************************************************
490 bool numuCC4piMultiPiUtils::TPCElPi0Selection(AnaTrackB *track){
491 //*********************************************************************
492 
493  if( track->nTPCSegments == 0 ) return false; // There is no TPC segment
494 
495  bool seltrack = false;
496 
497  // if (!cutUtils::TrackQualityCut(*track)) return seltrack;
498 
499  if( track->Momentum < 50. ) return seltrack;
500 
501  // if( track->Charge > 0. && track->Momentum > 800.) return seltrack;
502 
503  Float_t pulls[4];
504 
505  for(int i = 0; i < track->nTPCSegments ; i++ ){
506 
507  AnaTPCParticleB *tpcTrack = track->TPCSegments[i];
508 
509  if( !tpcTrack ) continue; // Extra protection.
510 
511  // Pulls are: Muon, Electron, Proton, Pion
512  anaUtils::ComputeTPCPull(*tpcTrack,pulls);
513 
514  if (TMath::Abs(pulls[0]) > 1.e+6 // muon pull
515  || TMath::Abs(pulls[1]) > 1.e+6 // electron pull
516  || TMath::Abs(pulls[2]) > 1.e+6 // proton pull
517  || TMath::Abs(pulls[3]) > 1.e+6) continue; // pion pull
518 
519  if( pulls[1] < -2.0 || pulls[1] > 2.0 ) break;
520 
521  if( track->Charge > 0. && ( pulls[2] > -4.0 && pulls[2] < 8.0 ) ) break;
522 
523  seltrack = true;
524 
525  }
526  return seltrack;
527 }
528 
529 //*********************************************************************
530 bool numuCC4piMultiPiUtils::FGDpionSelection(AnaTrackB *track, SubDetId::SubDetEnum det){
531 //*********************************************************************
532  if( track->nFGDSegments != 1 ) return false; // There is no FGD segment or it has more than one FGD
533 
534  AnaFGDParticleB *fgdTrack = track->FGDSegments[0];
535 
536  if( !fgdTrack ) return false; // Extra protection.
537 
538  if( TMath::Abs(fgdTrack->Pullp) > 1.e+6 || TMath::Abs(fgdTrack->Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->Pullpi) > 1.e+6 ) return false;
539 
540  // Check the pullnotset variable.
541  // This tells us if the pull was calculated by the algorithm.
542  // If it was not calculated this variable will be 1, so for calculated pulls fgdpulls!=1.
543  if( fgdTrack->Pullno == 1 ) return false;
544 
545  // This tell us something about the geometry.
546  // If the algorithm says the particle started and stopped in 1st/ 2nd fgd this is equal 1 or 2.
547  // If the particle stopped in 1st/2nd fgd, this is equal -1/-2. Other cases: 0.
548  if( fgdTrack->Containment == 0 ) return false;
549  if ( det == SubDetId::kFGD1 && fgdTrack->Containment != 1 ) return false;
550  else if( det == SubDetId::kFGD2 && fgdTrack->Containment != 2 ) return false;
551  else if( det == SubDetId::kFGD && fgdTrack->Containment != 1 && fgdTrack->Containment != 2) return false;
552 
553  double cosFGDpion = fgdTrack->DirectionStart[2];
554 
555  if(cosFGDpion > -0.3 && cosFGDpion < 0.3) return false;/// only for systematics issues. Must be remove in the future!!
556 
557  if( fgdTrack->Pullpi < 2.5 && fgdTrack->Pullpi > -2.0 ) return true;
558 
559  return false;
560 
561 
562 }
563 
564 //*********************************************************************
565 bool numuCC4piMultiPiUtils::FGDElPi0Selection(AnaEventC& event, ToyBoxB& box, AnaTrackB *track, SubDetId::SubDetEnum det){
566 //*********************************************************************
567 
568  (void)box;
569 
570  if( track->nFGDSegments != 1 ) return false; // There is no FGD segment or it has more than one FGD
571 
572  // ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
573 
574  AnaFGDParticleB *fgdTrack = track->FGDSegments[0];
575 
576  if( !fgdTrack ) return false; // Extra protection.
577 
578  if( TMath::Abs(fgdTrack->Pullp) > 1.e+6 || TMath::Abs(fgdTrack->Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->Pullpi) > 1.e+6 ) return false;
579 
580  // Check the pullnotset variable.
581  // This tells us if the pull was calculated by the algorithm.
582  // If it was not calculated this variable will be 1, so for calculated pulls fgdpulls!=1.
583  if( fgdTrack->Pullno == 1 ) return false;
584 
585  // This tell us something about the geometry.
586  // If the algorithm says the particle started and stopped in 1st/ 2nd fgd this is equal 1 or 2.
587  // If the particle stopped in 1st/2nd fgd, this is equal -1/-2. Other cases: 0.
588  if( fgdTrack->Containment == 0 ) return false;
589  if ( det == SubDetId::kFGD1 && fgdTrack->Containment != 1 ) return false;
590  else if( det == SubDetId::kFGD2 && fgdTrack->Containment != 2 ) return false;
591  else if( det == SubDetId::kFGD && fgdTrack->Containment != 1 && fgdTrack->Containment != 2) return false;
592 
593  EventBoxTracker* EventBox = static_cast<EventBoxTracker*>(event.EventBoxes[EventBoxId::kEventBoxTracker]);
594 
595  if(EventBox->nFGDMichelElectrons[det] > 0 && fgdTrack->Pullpi < -3.0 ) return true;
596  if(EventBox->nFGDMichelElectrons[det] == 0 && fgdTrack->Pullpi < -1.5 ) return true;
597 
598 
599  return false;
600 }
601 
602 //*********************************************************************
604 //*********************************************************************
605 
606  (void)event;
607 
608  // Select event without pi0 track (see FindEcalPhotonsAction)
609  ToyBoxCC4piMultiPi * cc4piMultiPibox = static_cast<ToyBoxCC4piMultiPi*>(&box);
610  if(cc4piMultiPibox->nPi0Ecaltracks > 0) return false;
611  else return true;
612 }
613 
614 //***********************************************************************
615 bool numuCC4piMultiPiUtils::ECALPi0Selection(AnaEventC& event, ToyBoxB& box, AnaTrackB *HO, int MostUpstreamLayerHitCut, SubDetId::SubDetEnum det){
616 //***********************************************************************
617 
618  (void)event;
619  (void)box;
620  (void)det;
621 
622  // Identify if the highest ECal object comes from a TPC positive track
623  // or the muon candidate.
624  // If not, then the ecal object might comes from a pi0 (if the object is shower like)
625 
626  bool Ecalpi0 = false;
627 
628  double EMENERGY = -9999.;
629  double MIPEM = -9999.;
630  double EM_UPSTREAM = -9999;
631  AnaECALParticleB* EcalSegment = HO->ECALSegments[0];
632  if( !EcalSegment ) return false;
633 
634  // Check that the Highest energetic ecal obj is actually shower-like (MIPEM>0)
635  // Cut on EMEnergy because of big spike around 26 MeV (feature of the reconstruction)
636  MIPEM = EcalSegment->PIDMipEm;
637  EMENERGY = EcalSegment->EMEnergy;
638  if (EMENERGY > 30. && MIPEM > 0.) Ecalpi0 = true;
639 
640  // This is the cut on MostUpstreamLayerHit variable.
641  // The cut threshold has to be set in the parameter file
642  // For more information on this variable, see slide 10: http://www.t2k.org/nd280/physics/convener/2015/November2/ECal_pi0_veto
643  EM_UPSTREAM = EcalSegment->MostUpStreamLayerHit;
644  if(EM_UPSTREAM > MostUpstreamLayerHitCut ) Ecalpi0 = false;
645 
646  return Ecalpi0;
647 }
648 
649 //**************************************************
650 bool numuCC4piMultiPiSelection::IsRelevantSystematic(const AnaEventC& event, const ToyBoxB& box, SystId_h systId, Int_t branch) const{
651  //**************************************************
652 
653  (void)event;
654  (void)branch;
655  (void)box;
656  (void)systId;
657 
658  return true;
659 
660 }
661 
662 //**************************************************
663 bool numuCC4piMultiPiSelection::IsRelevantRecObjectForSystematic(const AnaEventC& event, AnaRecObjectC* recObj, SystId_h systId, Int_t branch) const{
664  //**************************************************
665 
666  (void)event;
667  (void)branch;
668  (void)systId;
669 
670  AnaTrackB* track = static_cast<AnaTrackB*>(recObj);
671 
672  if (!track) return false;
673  if (!track->TrueObject) return false;
674 
675  return true;
676 
677 }
678 
679 //**************************************************
680 bool numuCC4piMultiPiSelection::IsRelevantTrueObjectForSystematic(const AnaEventC& event, AnaTrueObjectC* trueObj, SystId_h systId, Int_t branch) const{
681  //**************************************************
682 
683  (void)event;
684  (void)branch;
685  (void)systId;
686 
687  AnaTrueParticleB* trueTrack = static_cast<AnaTrueParticleB*>(trueObj);
688 
689  if (!trueTrack) return false;
690 
691  return true;
692 
693 }
694 
695 //**************************************************
696 bool numuCC4piMultiPiSelection::IsRelevantRecObjectForSystematicInToy(const AnaEventC& event, const ToyBoxB& boxB, AnaRecObjectC* recObj, SystId_h systId, Int_t branch) const{
697 //**************************************************
698 
699  (void)event;
700  (void)branch;
701 
702  const ToyBoxCC4piMultiPi& cc4piMultiPibox = *static_cast<const ToyBoxCC4piMultiPi*>(&boxB);
703 
704  AnaTrackB* track = static_cast<AnaTrackB*>(recObj);
705 
706  if(systId == SystId::kTpcClusterEff){
707  if (track->nTPCSegments > 0) {
709  if (tpcTrack) {
710  if (tpcTrack->NNodes > 16 && tpcTrack->NNodes < 19) return true;
711  }
712  }
713  return false;
714  }
715  if(systId == SystId::kChargeIDEff){
716  if (track == cc4piMultiPibox.MainTrack) return true;
717  return false;
718  }
719  if(systId == SystId::kTpcFgdMatchEff){
720  if (track == cc4piMultiPibox.MainTrack) return true;
721  return false;
722  }
723  if(systId == SystId::kECalPID){
724  if (track == cc4piMultiPibox.MainTrack) {
725  if (branch==2 || branch==3) return true;
726  else if (branch==0 || branch==4 || branch==5) {
727  if ( anaUtils::TrackUsesDet(*track,SubDetId::kTECAL) ) return true;
728  if ( anaUtils::InFiducialVolume(SubDetId::kDSECAL, track->PositionEnd, numuCC4pi_utils::_FVdefminDsECal, numuCC4pi_utils::_FVdefmaxDsECal) ) return true;
729  }
730  }
731  return false;
732  }
733 
734  return true;
735 
736 }
737 
738 //**************************************************
739 bool numuCC4piMultiPiSelection::IsRelevantTrueObjectForSystematicInToy(const AnaEventC& event, const ToyBoxB& boxB, AnaTrueObjectC* trueObj, SystId_h systId, Int_t branch) const{
740 //**************************************************
741 
742  (void)event;
743  (void)branch;
744 
745  const ToyBoxCC4piMultiPi& cc4piMultiPibox = *static_cast<const ToyBoxCC4piMultiPi*>(&boxB);
746 
747  AnaTrueParticleB* trueTrack = static_cast<AnaTrueParticleB*>(trueObj);
748 
749  if ( !cc4piMultiPibox.MainTrack->GetTrueParticle() ) return false;
750 
751  if(systId == SystId::kTpcTrackEff){
752  if (trueTrack->PDG == 13 && cc4piMultiPibox.MainTrack->GetTrueParticle()->PDG!=13) return true;
753  if (branch!=2 && branch!=3) { if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID) return true; }
754  return false;
755  }
756  if(systId == SystId::kECalTrackEff){
757  if (trueTrack->PDG == 13 && cc4piMultiPibox.MainTrack->GetTrueParticle()->PDG!=13) return true;
758  if (branch==2 || branch==3) { if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID) return true; }
759  return false;
760  }
761  if(systId == SystId::kTpcP0dMatchEff){
762  if (branch==1) { if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID) return true; }
763  return false;
764  }
765  if(systId == SystId::kTpcECalMatchEff){
766  if (branch>-1 && branch<6) { if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID) return true; }
767  return false;
768  }
769  if(systId == SystId::kFgdECalMatchEff){
770  if (branch==2 || branch==3) { if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID) return true; }
771  return false;
772  }
773  if(systId == SystId::kFgdECalSmrdMatchEff){
774  if (branch==2 || branch==3) { if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID) return true; }
775  return false;
776  }
777  if(systId == SystId::kSIPion){
778  // If this trueTrack is associated to the MainTrack
779  if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID){
780  if (abs(cc4piMultiPibox.MainTrack->GetTrueParticle()->PDG) == 211) return true;
781  if (abs(cc4piMultiPibox.MainTrack->GetTrueParticle()->ParentPDG) == 211) return true;
782  if (abs(cc4piMultiPibox.MainTrack->GetTrueParticle()->GParentPDG) == 211) return true;
783  return false;
784  }
785  // If this trueTrack is NOT associated to the MainTrack, consider the posibility of this trueTrack to become the MainTrack and be identified as muon
786  // For the moment assume a negative pion may become the MainTrack if its momentum its above 90% of the current MainTrack momentum.
787  // Ideally we should check that this true pion is not associated to any reconstructed track, but this is not possible now without looping.
788  // Multiply by the charge of the MainTrack such that it can be use for antiNumu selection
789  if (trueTrack->PDG == 211*((Int_t)cc4piMultiPibox.MainTrack->Charge) && trueTrack->Momentum > 0.9*cc4piMultiPibox.MainTrack->Momentum) return true;
790  return false;
791  }
792  if(systId == SystId::kSIProton){
793  // If this trueTrack is associated to the MainTrack
794  if (trueTrack->ID == cc4piMultiPibox.MainTrack->GetTrueParticle()->ID){
795  if (cc4piMultiPibox.MainTrack->GetTrueParticle()->PDG == 2212) return true;
796  if (cc4piMultiPibox.MainTrack->GetTrueParticle()->ParentPDG == 2212) return true;
797  if (cc4piMultiPibox.MainTrack->GetTrueParticle()->GParentPDG == 2212) return true;
798  return false;
799  }
800  // If this trueTrack is NOT associated to the MainTrack, consider the posibility of this trueTrack to become the MainTrack
801  if (trueTrack->PDG == 2212 && trueTrack->Momentum > 0.9*cc4piMultiPibox.MainTrack->Momentum) return true;
802  return false;
803  }
804 
805  return true;
806 
807 }
808 
809 //********************************************************************
810 bool numuCC4piMultiPiSelection::CheckRedoSelection(const AnaEventC& eventC, const ToyBoxB& PreviousToyBoxB, Int_t& redoFromStep){
811  //********************************************************************
812 
813  (void)eventC;
814  (void)PreviousToyBoxB;
815  (void)redoFromStep;
816 
817  return true;
818 
819 }
820 
AnaTrueVertexB * TrueVertex
Pointer to the AnaTrueVertexB of the interaction that created this AnaTrueParticleB.
bool Apply(AnaEventC &event, ToyBoxB &box) const
Float_t PositionStart[4]
The reconstructed start position of the particle.
bool IsRelevantTrueObjectForSystematicInToy(const AnaEventC &, const ToyBoxB &, AnaTrueObjectC *, SystId_h systId, Int_t branch=0) const
Is this true track relevant for a given systematic (after selection, called for each toy) ...
bool Apply(AnaEventC &event, ToyBoxB &box) const
void InitializeEvent(AnaEventC &event)
Fill the EventBox with the objects needed by this selection.
int GetFGDMichelElectrons(const AnaEventB &event, const SubDetId::SubDetEnum det, AnaFgdTimeBinB **arr, bool prod5Cut=0)
Get all delayed time bins as Michel Electron candidates.
AnaECALParticleB * ECALSegments[NMAXECALS]
The ECAL segments that contributed to this global track.
int nECALSegments
How many ECAL tracks are associated with this track.
Float_t Pullp
Proton pull, according to FGD information.
void DefineDetectorFV()
Define the detector Fiducial Volume in which this selection is applied.
Float_t Pullno
Dummy pull. If the FGD pulls weren&#39;t set, this is set to 1.
Int_t NNodes
The number of nodes in the reconstructed object.
SubDetId_h DetectorFV
Indicate the FV we are interested in.
Definition: ToyBoxB.hxx:52
Int_t GParentPDG
The PDG code of this particle&#39;s grandparent, or 0 if there is no grandparent.
Representation of an ECAL segment of a global track.
Float_t Pullpi
Pion pull, according to FGD information.
AnaTPCParticleB * TPCSegments[NMAXTPCS]
The TPC segments that contributed to this global track.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool IsRelevantSystematic(const AnaEventC &event, const ToyBoxB &box, SystId_h systId, Int_t branch) const
Is this systematic relevant for this selection.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool CheckRedoSelection(const AnaEventC &event, const ToyBoxB &PreviousToyBox, Int_t &redoFromStep)
AnaTrueObjectC * TrueObject
The link to the true oject that most likely generated this reconstructed object.
Float_t Momentum
The initial momentum of the true particle.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool TrackUsesDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
Float_t Pullmu
Muon pull, according to FGD information.
Float_t Charge
The reconstructed charge of the particle.
Int_t ID
The ID of the trueObj, which corresponds to the ID of the TTruthParticle that created it...
void DefineSteps()
Define all steps in the selection.
Float_t GetPIDLikelihood(const AnaTrackB &track, Int_t hypo, bool prod5Cut=0)
Definition: PIDUtils.cxx:180
Int_t nRecObjectsInGroup[NMAXRECOBJECTGROUPS]
----—— RecObjects and TrueRecObjects used in the selection and systematics ------------—— ...
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
int nTPCSegments
How many TPC tracks are associated with this track.
Representation of a true Monte Carlo trajectory/particle.
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.
AnaFgdTimeBinB ** FGDMichelElectrons[2]
----------— Michel Electron candidates -------------------------------—
Representation of a global track.
Float_t ComputeTPCPull(const AnaTPCParticleB &track, const std::string &particle)
Function to recompute the pull for a TPC track segment.
bool Apply(AnaEventC &event, ToyBoxB &box) const
Representation of a TPC segment of a global track.
bool IsRelevantTrueObjectForSystematic(const AnaEventC &event, AnaTrueObjectC *trueObj, SystId_h systId, Int_t branch) const
Is this true track relevant for a given systematic (prior to selection, call when initializing the ev...
AnaTrackB * MainTrack
For storing tracks information in the bunch.
bool IsRelevantRecObjectForSystematic(const AnaEventC &event, AnaRecObjectC *recObj, SystId_h systId, Int_t branch) const
Is this track relevant for a given systematic (prior to selection, call when initializing the event...
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
AnaEventSummaryC * Summary
A summary of the event with high level quantities.
Representation of a FGD segment of a global track.
int nFGDSegments
How many FGD tracks are associated with this track.
Int_t Containment
Containment flag required for proper PID analysis.
Int_t MostUpStreamLayerHit
Innermost layer hit of the ecal object (used in ecal pi0 veto)
AnaParticleB * GetSegmentWithMostNodesInClosestTpc(const AnaTrackB &track)
Combined function to address NuMu selection needs as efficiently as possible - gets the TPC segment w...
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
bool InFiducialVolume(SubDetId::SubDetEnum det, const Float_t *pos, const Float_t *FVdefmin, const Float_t *FVdefmax)
bool TrackUsesOnlyDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
AnaFGDParticleB * FGDSegments[NMAXFGDS]
The FGD segments that contributed to this global track.
A cut on event quality. Requires good beam and ND280 data quality flags.
Float_t PositionEnd[4]
The reconstructed end position of the particle.
bool IsRelevantRecObjectForSystematicInToy(const AnaEventC &, const ToyBoxB &, AnaRecObjectC *, SystId_h systId, Int_t branch=0) const
Is this track relevant for a given systematic (after selection, called for each toy) ...