HighLAND
nueCCSelection.cxx
1 #include "nueCCSelection.hxx"
2 
3 #include "baseSelection.hxx"
4 #include "CutUtils.hxx"
5 #include "EventBoxUtils.hxx"
6 #include "VersioningUtils.hxx"
7 #include "SystematicUtils.hxx"
8 #include "trackerSelectionUtils.hxx"
9 
10 #include "nueCCUtils.hxx"
11 #include "nueCutUtils.hxx"
12 #include "SystematicTuning.hxx"
13 
14 //********************************************************************
15 nueCCSelection::nueCCSelection(bool forceBreak): SelectionBase(forceBreak, EventBoxId::kEventBoxTracker) {
16 //********************************************************************
17 
18  //_pullel_accept_min = (Float_t)ND::params().GetParameterD("psycheSelections.nueCCAnalysis.Cuts.PID.PullElecMin");
19  //_pullel_accept_max = (Float_t)ND::params().GetParameterD("psycheSelections.nueCCAnalysis.Cuts.PID.PullElecMax");
20  //_pullel_accept_tight_min = (Float_t)ND::params().GetParameterD("psycheSelections.nueCCAnalysis.Cuts.PID.PullElecTightMin");
21  //_pullel_accept_tight_max = (Float_t)ND::params().GetParameterD("psycheSelections.nueCCAnalysis.Cuts.PID.PullElecTightMax");
22  _Ethreshold = (Float_t)ND::params().GetParameterD("psycheSelections.nueCCAnalysis.Cuts.PID.EThreshold");
23  //_minMom_ecal = (Float_t)ND::params().GetParameterD("psycheSelections.nueCCAnalysis.Cuts.EcalThreshold");
24  //_protonregion_low = (Float_t)ND::params().GetParameterD("psycheSelections.nueCCAnalysis.Analysis.ProtonMomentumRegion.Low");
25 
26  // Initialize systematic tuning parameters
27  systTuning::Initialize();
28 
29 }
30 
31 //********************************************************************
33 //********************************************************************
34 
35  // The detector in which the selection is applied
36  SetDetectorFV(SubDetId::kFGD1);
37 }
38 
39 //********************************************************************
41 //********************************************************************
42 
43  // last "true" means the step sequence is broken if cut is not passed (default is "false")
44 
45  AddStep(StepBase::kCut, "event quality", new EventQualityCut(), true); // 0
46  AddStep(StepBase::kCut, "> 0 tracks ", new MultiplicityCut(), true); // 1
47  AddStep(StepBase::kAction, "find leading tracks", new FillLeadingTracksAction());
48  AddStep(StepBase::kAction, "Fill vertex info", new FillVertex());
49  AddStep(StepBase::kAction, "fill summary", new FillSummaryAction_nueCC());
50 
51  AddStep(StepBase::kCut, "TPC Quality", new TrackQualityCut(), true); // 2
52  AddStep(StepBase::kCut, "Momentum", new HighestMomentumCut()); // 3
53 
54  // e- PID cuts.
55  AddStep(StepBase::kCut, "TPC Electron Pull", new TPCElectronPullCut()); // 4
56  AddStep(StepBase::kCut, "TPC Muon Pull", new TPCMuonPullCut()); // 5
57  AddStep(StepBase::kCut, "TPC Pion Pull", new TPCPionPullCut()); // 6
58  AddStep(StepBase::kCut, "Ecal EMEnergy", new EcalEMEnergyCut()); // 7
59  AddStep(StepBase::kCut, "Ecal MIPEM PID", new EcalMIPEMPIDCut()); // 8
60  AddStep(StepBase::kCut, "TPC2 PID", new SecondTPCPIDCut()); // 9
61 
62  // Upstream vetos. Reduce OOFV background.
63  AddStep(StepBase::kAction, "find TPC Veto track", new FillTPCVetoTrackAction());
64  AddStep(StepBase::kCut, "TPC Veto", new TPCVetoCut()); // 10
65  AddStep(StepBase::kCut, "Gamma Iso Veto", new GammaIsoVetoCut()); // 11
66  AddStep(StepBase::kCut, "External FGD1", new ExternalFGD1layersCut()); // 12
67 
68  AddStep(StepBase::kAction, "find best e+e- pair", new FindPairsAction());
69  AddStep(StepBase::kCut, "Pair Veto", new PairCut()); // 13
70 
71  AddStep(StepBase::kAction, "find P0D veto track", new FindP0DVetoTrackAction());
72  AddStep(StepBase::kCut, "P0D Veto", new P0DVetoCut()); // 14
73 
74  AddStep(StepBase::kAction, "find ecal veto track", new FindECalVetoTrackAction());
75  AddStep(StepBase::kCut, "ECal Veto", new ECalVetoCut()); // 15
76 
77  // ToF
78  AddStep(StepBase::kCut, "ToF", new ToFCut()); // 16
79 
80  // Momentum quality cut
81  AddStep(StepBase::kCut, "Momentum quality", new MomentumQualityCut()); // 17
82 
83  SetBranchAlias(0,"trunk");
84 
85  // By default the preselection correspond to cuts 0-3
86  // It means that if any of the four first cuts (0,1,2,3) is not passed
87  // the loop over toys will be broken ===> A single toy will be run
88  SetPreSelectionAccumLevel(3);
89 
90  _FindLeadingTracksStepIndex = GetStepNumber("find leading tracks");
91  _TotalMultiplicityCutIndex = GetCutNumber("> 0 tracks ");
92 
93  _ElecPIDCutIndex = GetCutNumber("TPC Electron Pull");
94  _ElecPIDStepIndex = GetStepNumber("TPC Electron Pull");
95 }
96 
97 //********************************************************************
98 bool nueCCSelection::FillEventSummary(AnaEventC& event, Int_t allCutsPassed[]){
99 //********************************************************************
100 
101  if(allCutsPassed[0])
102  static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1NuECC;
103 
104  return (static_cast<AnaEventSummaryB*>(event.Summary)->EventSample != SampleId::kUnassigned);
105 }
106 
107 //********************************************************************
109 //********************************************************************
110 
111  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
112 
113  if(!nuebox.MainTrack) return false;
114 
115  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD1NuECC] = nuebox.MainTrack;
116  for(int i = 0; i < 4; ++i)
117  static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD1NuECC][i] = nuebox.MainTrack->PositionStart[i];
118 
119  if(nuebox.MainTrack->GetTrueParticle())
120  static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD1NuECC] = nuebox.MainTrack->GetTrueParticle()->TrueVertex;
121 
122  return true;
123 }
124 
125 //*********************************************************************
126 bool nueCCSelection::IsRelevantRecObjectForSystematic(const AnaEventC& event, AnaRecObjectC* recObj, SystId_h systId, Int_t branch) const{
127 //*********************************************************************
128 
129  (void)event;
130  (void)branch;
131 
132  AnaTrackB* track = static_cast<AnaTrackB*>(recObj);
133 
134  // True track should always exist
135  if(!track->TrueObject) return false;
136 
137  if(systId == SystId::kTpcClusterEff){
138  if(track->nTPCSegments == 0) return false;
139  // AnaTPCParticleB* tpcTrack = static_cast<AnaTPCParticleB*>(track->TPCSegments[0]);
141  if(!tpcTrack) return false;
142 
143  // Different number of TPC nodes if the main track goes in the ECal
144  if(nueCCUtils::UseEcal(track) && (tpcTrack->NNodes == 17 || tpcTrack->NNodes == 18) ) return true;
145  if(!nueCCUtils::UseEcal(track) && (tpcTrack->NNodes == 35 || tpcTrack->NNodes == 36) ) return true;
146 
147  return false;
148  }
149 
150  return true;
151 }
152 
153 //*********************************************************************
154 bool nueCCSelection::IsRelevantTrueObjectForSystematic(const AnaEventC& event, AnaTrueObjectC* trueObj, SystId_h systId, Int_t branch) const{
155 //*********************************************************************
156 
157  (void)event;
158  (void)branch;
159 
160  AnaTrueParticleB* truePart=static_cast<AnaTrueParticleB*>(trueObj);
161 
162  // TPC track eff
163  if(systId == SystId::kTpcTrackEff){
164  if(!anaUtils::InFiducialVolume(static_cast<SubDetId::SubDetEnum>(GetDetectorFV()), truePart->Position)) return false;
165  }
166 
167  return true;
168 }
169 
170 //**************************************************
171 bool nueCCSelection::IsRelevantRecObjectForSystematicInToy(const AnaEventC& event, const ToyBoxB& boxB, AnaRecObjectC* recObj, SystId_h systId, Int_t branch) const{
172 //**************************************************
173 
174  (void)event;
175  (void)branch;
176 
177  AnaTrackB* track = static_cast<AnaTrackB*>(recObj);
178 
179  // cast the box to the appropriate type
180  const ToyBoxNueCC& box = *static_cast<const ToyBoxNueCC*>(&boxB);
181 
182  // All are relevant if no main track concept applied
183  //if (!systTuning::APPLY_SYST_FINE_TUNING) return true;
184 
185  if (!box.MainTrack) return false;
186 
187  if(systId == SystId::kChargeIDEff){
188  if(!systTuning::APPLY_SYST_FINE_TUNING) return true;
189  // Inclusive selection only depends on the charge ID of the electron candidate
190  if (track == box.MainTrack) return true;
191 
192  return false;
193  }
194  // This is now applied to all tracks
195  //else if(systId == SystId::kTpcFgdMatchEff){
196  //if(!systTuning::APPLY_SYST_FINE_TUNING) return true;
197  //if (track != box.MainTrack) return false;
198  //}
199  else if(systId == SystId::kTpcClusterEff){
200  if(!systTuning::APPLY_SYST_FINE_TUNING) return true;
201  // Applied to the main track
202  if (track == box.MainTrack) return true;
203 
204  if (track->Charge == box.MainTrack->Charge &&
205  cutUtils::FiducialCut(track->PositionStart, static_cast<SubDetId::SubDetEnum>(GetDetectorFV())) &&
206  track->Momentum > box.MainTrack->Momentum)
207  return true;
208 
209  return false;
210  }
211  else if(systId == SystId::kECalPID){
212  // Only applied to main track
213  if (track != box.MainTrack) return false;
214 
215  if(!nueCCUtils::UseEcal(track)) return false;
216 
217  // Only applied to tracks with p < 1000 MeV/c or to tracks not contained in the Ecal
218  if(track->ECALSegments[0] && !nueCCUtils::IsEcalContained(track->ECALSegments[0])) return true;
219 
220  AnaTPCParticleB* tpcTrackBack = static_cast<AnaTPCParticleB*> (anaUtils::GetTPCBackSegment(track));
221  if(!tpcTrackBack) return false;
222  if(tpcTrackBack->Momentum > _Ethreshold) return false;
223  }
224 
225  return true;
226 }
227 
228 //**************************************************
229 bool nueCCSelection::IsRelevantTrueObjectForSystematicInToy(const AnaEventC& event, const ToyBoxB& boxB, AnaTrueObjectC* trueObj, SystId_h systId, Int_t branch) const{
230 //**************************************************
231 
232  (void)event;
233  (void)branch;
234 
235  // cast the box to the appropriate type
236  const ToyBoxNueCC& box = *static_cast<const ToyBoxNueCC*>(&boxB);
237 
238  AnaTrueParticleB* truePart=static_cast<AnaTrueParticleB*>(trueObj);
239 
240  if (!box.MainTrack) return false;
241 
242  if(systId == SystId::kTpcTrackEff){
243  if(!systTuning::APPLY_SYST_FINE_TUNING) return true;
244  // Main track
245  if(box.MainTrack->GetTrueParticle()){
246  // At first order the inclusive selection only depends on the tracking efficiency of the electron candidate.
247  if(truePart->ID == box.MainTrack->GetTrueParticle()->ID) return true;
248  // Consider also the case in which the electron candidate is not a true electron but this track it is
249  if(abs(truePart->PDG) == 11 && abs(box.MainTrack->GetTrueParticle()->PDG) != 11) return true;
250  }
251  // Apply for all tracks starting in the same FGD as the main track
252  else{
253  if(anaUtils::InDetVolume(static_cast<SubDetId::SubDetEnum>(GetDetectorFV()), truePart->Position)) return true;
254  //if (abs(truePart->PDG) == 11) return true;
255  }
256 
257  return false;
258  }
259  else if(systId == SystId::kSIPion){
260  if(!systTuning::APPLY_SYST_FINE_TUNING) return true;
261  // If this truePart is associated to the MainTrack
262  if(box.MainTrack->GetTrueParticle() && truePart->ID == box.MainTrack->GetTrueParticle()->ID){
263  if(abs(box.MainTrack->GetTrueParticle()->PDG) == 211) return true;
264  if(abs(box.MainTrack->GetTrueParticle()->ParentPDG) == 211) return true;
265  if(abs(box.MainTrack->GetTrueParticle()->GParentPDG) == 211) return true;
266  return false;
267  }
268  // If this truePart is NOT associated to the MainTrack, consider the posibility of this truePart to become the MainTrack and be identified as electron
269  // For the moment assume a negative pion may become the MainTrack if its momentum its above 90% of the current MainTrack momentum.
270  // Ideally we should check that this true pion is not associated to any reconstructed track, but this is not possible now without looping.
271  // Multiply by the charge of the MainTrack such that it can be use for antiNumu selection
272  if (truePart->PDG == 211*((Int_t)box.MainTrack->Charge) && truePart->Momentum > 0.9*box.MainTrack->Momentum) return true;
273  return false;
274  }
275  else if(systId == SystId::kSIProton){
276  if(!systTuning::APPLY_SYST_FINE_TUNING) return true;
277  // If this truePart is associated to the MainTrack
278  if(box.MainTrack->GetTrueParticle() && truePart->ID == box.MainTrack->GetTrueParticle()->ID){
279  if(box.MainTrack->GetTrueParticle()->PDG == 2212) return true;
280  if(box.MainTrack->GetTrueParticle()->ParentPDG == 2212) return true;
281  if(box.MainTrack->GetTrueParticle()->GParentPDG == 2212) return true;
282  return false;
283  }
284  // If this truePart is NOT associated to the MainTrack, consider the posibility of this truePart to become the MainTrack
285 
286  // May be relevant for anti-neutrino case but much less here
287  //if(truePart->PDG == 2212 && truePart->Momentum > 0.9*box.MainTrack->Momentum) return true;
288  return false;
289  }
290  else if(systId == SystId::kTpcECalMatchEff){
291  //if(!nueCCUtils::UseEcal(box.MainTrack)) return false;
292  if(box.MainTrack->GetTrueParticle() && truePart->ID == box.MainTrack->GetTrueParticle()->ID) return true;
293 
294  return false;
295  }
296 
297  return true;
298 }
299 
300 //*********************************************************************
301 bool nueCCSelection::IsRelevantSystematic(const AnaEventC& event, const ToyBoxB& box, SystId_h systId, Int_t branch) const{
302 //*********************************************************************
303 
304  //(void)event;
305  (void)branch;
306  (void)box;
307 
308  if (systId == SystId::kFgdTrackEff) // No FGD track eff
309  return false;
310  else if(systId == SystId::kFgdHybridTrackEff) // No FGD hybrid track eff
311  return false;
312  else if(systId == SystId::kFgdPid) // No FGD PID
313  return false;
314  else if(systId == SystId::kMichelEleEff) // No Michel elec
315  return false;
316  else if(systId == SystId::kSIPion){
317  // check whether should be applied what the main track is a true pion or its product
318  if (!systTuning::APPLY_SYST_FINE_TUNING) return false;
319  }
320  else if(systId == SystId::kSIProton){
321  //check whether should be still applied when the main track is a true proton or its product: TESTING PURPOSES
322  if(!systTuning::APPLY_SYST_FINE_TUNING) return false;
323  }
324  else if(systId == SystId::kECalEmHipPID) // No Ecal emhip
325  return false;
326  else if(systId == SystId::kFGD2Shower) // No FGD2 shower
327  return false;
328  else if(systId == SystId::kPileUp) // Different pile-up syst for nue
329  return false;
330  else if(systId == SystId::kOOFV) // Different oofv syst for nue
331  return false;
332  else if(systId == SystId::kECalTrackEff) // Ecal Track efficiency is calsulated with the TPC-Ecal matching efficiency
333  return false;
334  // The next two can also be controlled from here
335  else if (systId == SystId::kFluxWeightNu){ // only applied to fhc
336  const AnaEventB& eventB = *static_cast<const AnaEventB*>(&event);
337  Int_t run = anaUtils::GetRunPeriod(eventB.EventInfo.Run, eventB.EventInfo.SubRun);
338  if(run >= 8 && run < 13) return false;
339  }
340  else if (systId == SystId::kFluxWeightAntiNu){ // only applied to rhc
341  const AnaEventB& eventB = *static_cast<const AnaEventB*>(&event);
342  Int_t run = anaUtils::GetRunPeriod(eventB.EventInfo.Run, eventB.EventInfo.SubRun);
343  if(run < 8 || run == 13) return false;
344  }
345  // Decouple the following systematic in case they are accidentally turned-on
346  else if(systId == SystId::kTpcP0dMatchEff) return false;
347  else if(systId == SystId::kFgdECalMatchEff) return false;
348  else if(systId == SystId::kFgdECalSmrdMatchEff) return false;
349  else if(systId == SystId::kMomRangeResol) return false;
350 
351  return true;
352 }
353 
354 //*********************************************************************
355 bool nueCCSelection::CheckRedoSelection(const AnaEventC& eventC, const ToyBoxB& PreviousToyBoxB, Int_t& redoFromStep){
356 //*********************************************************************
357 
358  const AnaEventB& event = *static_cast<const AnaEventB*>(&eventC);
359 
360  // cast the box to the appropriate type
361  const ToyBoxNueCC& PreviousToyBox = *static_cast<const ToyBoxNueCC*>(&PreviousToyBoxB);
362 
363  /// Nothing to do if there is no HMN track
364  if(!PreviousToyBox.HMNtrack) return false;
365 
366  // TODO: The code below implies calling cutUtils::FindLeadingTracks(event, box) twice. Can we avoid that ?
367  if(PreviousToyBox.MaxAccumLevel > _TotalMultiplicityCutIndex){
368  ToyBoxNueCC box;
369  trackerSelUtils::FindLeadingTracks(event, box);
370 
371  // Redo the selection if any of the leading tracks changes identity
372  if(PreviousToyBox.SHMNtrack!=box.SHMNtrack ||
373  PreviousToyBox.SHMPtrack!=box.SHMPtrack ||
374  PreviousToyBox.HMNtrack !=box.HMNtrack ||
375  PreviousToyBox.HMPtrack !=box.HMPtrack ||
376  PreviousToyBox.SHMtrack !=box.SHMtrack ||
377  PreviousToyBox.HMtrack !=box.HMtrack){
378 
379  redoFromStep = _FindLeadingTracksStepIndex;
380  return true;
381  }
382  }
383 
384  // When the HMN track does not change identity, Redo the selection if the effect of the PID cut is different.
385  // We have previously saved in the EventBox the AccumLevel of the previous toy for each branch.
386  // PreviousToyBox->AccumLevel[0]>_ElecPIDCutIndex means that the PID cut was passed, so we check whether the cut
387  // was passed in the previous toy and not in the current one, or the opposit, it was not passed before
388  // and it is passed now.
389 
390  if(PreviousToyBox.MaxAccumLevel >= _ElecPIDCutIndex){
391  //bool pidCut = nueCutUtils::TPCElectronPull(PreviousToyBox.HMNtrack, _pullel_accept_min, _pullel_accept_max, _pullel_accept_tight_min, _pullel_accept_tight_max, _minMom_ecal);
392  //if(( pidCut && (PreviousToyBox.AccumLevel[0] == _ElecPIDCutIndex)) ||
393  // (!pidCut && (PreviousToyBox.AccumLevel[0] > _ElecPIDCutIndex))){
394  // We should redo the selection starting from the PIDCut step
395  redoFromStep = _ElecPIDStepIndex;
396  return true;
397  //}
398  }
399 
400  return false;
401 }
402 
403 //*********************************************************************
405 //*********************************************************************
406 
407  AnaEventB& event = *static_cast<AnaEventB*>(&eventC);
408 
409  // Create the appropriate EventBox if it does not exist yet
410  if(!event.EventBoxes[EventBoxId::kEventBoxTracker])
411  event.EventBoxes[EventBoxId::kEventBoxTracker] = new EventBoxTracker();
412 
413  boxUtils::FillTracksWithTPC(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
414  boxUtils::FillTracksWithFGD(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
415  boxUtils::FillTracksWithECal(event);
416  boxUtils::FillTrajsChargedInTPC(event);
417  boxUtils::FillTrajsChargedInFGDAndNoTPC(event, static_cast<SubDetId::SubDetEnum>(GetDetectorFV()));
418  boxUtils::FillTrajsInECal(event);
419 }
420 
421 //**************************************************
422 bool MultiplicityCut::Apply(AnaEventC& event, ToyBoxB& boxB) const{
423 //**************************************************
424 
425  (void)boxB;
426  // Check we have at least one reconstructed track in the TPC
427  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
428  return (EventBox->nRecObjectsInGroup[EventBoxTracker::kTracksWithTPC]>0);
429 }
430 
431 //*********************************************************************
433 //*********************************************************************
434 
435  (void)event;
436 
437  // cast the box to the appropriate type
438  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
439 
440  //trackerSelUtils::FindLeadingTracksOld(event, box, false, det_FGD, true);
441  trackerSelUtils::FindLeadingTracks(event,boxB);
442 
443  if(nuebox.HMNtrack) nuebox.MainTrack = nuebox.HMNtrack;
444  if(!nuebox.MainTrack) return false;
445 
446  return true;
447 }
448 
449 //**************************************************
450 bool FillVertex::Apply(AnaEventC& event, ToyBoxB& boxB) const{
451 //**************************************************
452 
453  (void)event;
454 
455  // cast the box to the appropriate type
456  ToyBoxNueCC& box = *static_cast<ToyBoxNueCC*>(&boxB);
457 
458  // reset the vertex
459  if(box.Vertex) delete box.Vertex;
460  box.Vertex = NULL;
461 
462  if(!box.MainTrack) return false;
463 
464  box.Vertex = new AnaVertexB();
465  anaUtils::CreateArray(box.Vertex->Particles, 1);
466 
467  box.Vertex->nParticles = 0;
468  box.Vertex->Particles[box.Vertex->nParticles++] = box.MainTrack;
469 
470  for(Int_t i = 0; i < 4; ++i){
471  box.Vertex->Position[i] = box.MainTrack->PositionStart[i];
472  }
473 
474  if(box.MainTrack->GetTrueParticle())
476 
477  return true;
478 }
479 
480 //*********************************************************************
482 //*********************************************************************
483 
484  AnaEventB& event = *static_cast<AnaEventB*>(&eventC);
485 
486  // cast the box to the appropriate type
487  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
488 
489  int nTrack[3];
490  nueCCUtils::FindP0DVetoTracks(event, *nuebox.MainTrack, nTrack);
491 
492  nuebox.P0DVetoP0DTracks = nTrack[0];
493  nuebox.P0DVetoP0DEcalTracks = nTrack[1];
494  nuebox.P0DVetoFGD1Tracks = nTrack[2];
495 
496  return true;
497 }
498 
499 //**************************************************
500 bool HighestMomentumCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
501 //**************************************************
502 
503  (void) event;
504 
505  // cast the box to the appropriate type
506  ToyBoxNueCC& box = *static_cast<ToyBoxNueCC*>(&boxB);
507 
508  AnaTrackB* track = box.MainTrack;
509  if(!track) return false;
510 
511  return (track->Momentum > _min_mom);
512 }
513 
514 //**************************************************
515 bool TrackQualityCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
516 //**************************************************
517 
518  (void) event;
519 
520  // cast the box to the appropriate type
521  ToyBoxNueCC& box = *static_cast<ToyBoxNueCC*>(&boxB);
522 
523  // No vertex - reject
524  if(!box.Vertex) return false;
525 
526  AnaTrackB* track = box.MainTrack;
527  if(!track) return false;
528 
529  return nueCutUtils::TrackQuality(track, _num_tpc_nodes, _num_tpc_nodes_ecal);
530 }
531 
532 //**************************************************
533 bool TPCElectronPullCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
534 //**************************************************
535 
536  (void) event;
537 
538  // cast the box to the appropriate type
539  ToyBoxNueCC& box = *static_cast<ToyBoxNueCC*>(&boxB);
540 
541  AnaTrackB* track = box.MainTrack;
542  if(!track || track->nTPCSegments == 0) return false;
543 
544  return nueCutUtils::TPCElectronPull(track, _pullel_accept_min, _pullel_accept_max, _pullel_accept_tight_min, _pullel_accept_tight_max, _minMom_ecal);
545 }
546 
547 //**************************************************
548 bool TPCMuonPullCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
549 //**************************************************
550 
551  (void) event;
552 
553  // cast the box to the appropriate type
554  ToyBoxNueCC& box = *static_cast<ToyBoxNueCC*>(&boxB);
555 
556  AnaTrackB* track = box.MainTrack;
557  if(!track) return false;
558 
559  return nueCutUtils::TPCMuonPull(track, _pullmu_reject_min, _pullmu_reject_max, _minMom_ecal);
560 }
561 
562 //**************************************************
563 bool TPCPionPullCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
564 //**************************************************
565 
566  (void) event;
567 
568  // cast the box to the appropriate type
569  ToyBoxNueCC& box = *static_cast<ToyBoxNueCC*>(&boxB);
570 
571  AnaTrackB* track = box.MainTrack;
572  if(!track) return false;
573 
574  return nueCutUtils::TPCPionPull(track, _pullpi_reject_min, _pullpi_reject_max, _num_tpc_nodes, _minMom_ecal);
575 }
576 
577 //**************************************************
578 bool EcalEMEnergyCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
579 //**************************************************
580 
581  (void) event;
582 
583  // cast the box to the appropriate type
584  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
585 
586  AnaTrackB* track = nuebox.MainTrack;
587  if(!track) return false;
588 
589  return nueCutUtils::EcalEMEnergy(track, _Ethreshold, _Emin_ecal, _EoverP, false);
590 }
591 
592 //**************************************************
593 bool EcalMIPEMPIDCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
594 //**************************************************
595 
596  (void) event;
597 
598  // cast the box to the appropriate type
599  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
600 
601  AnaTrackB* track = nuebox.MainTrack;
602  if(!track) return false;
603 
604  return nueCutUtils::EcalMIPEMPID(track, _Ethreshold, _ecal_mipem_min);
605 }
606 
607 //**************************************************
608 bool SecondTPCPIDCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
609 //**************************************************
610 
611  (void) event;
612 
613  // cast the box to the appropriate type
614  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
615 
616  AnaTrackB* track = nuebox.MainTrack;
617  if(!track) return false;
618 
619  return nueCutUtils::SecondTPCPID(track, _pullmu_reject_min, _pullmu_reject_max);
620 }
621 
622 //*********************************************************************
624 //*********************************************************************
625 
626  AnaEventB& event = *static_cast<AnaEventB*>(&eventC);
627 
628  // cast the box to the appropriate type
629  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
630 
631  AnaTrackB* track = nuebox.MainTrack;
632  if(!track) return false;
633 
634  nuebox.VetoTrack = nueCCUtils::FindTPCVetoTrack(event, *track);
635  nuebox.SecondMostEnergeticFGDTPCTrack = nueCCUtils::FindFGDTPCVetoTrack(event, *track, static_cast<SubDetId::SubDetEnum>(nuebox.DetectorFV) );
636 
637  /// Gamma isolation veto
638  Int_t nTracks[3];
639  nueCCUtils::FindGammaIsoTracks(event, *track, _vertex_activity, nTracks);
640  // Find activity near and far from the vertex
641  nuebox.TPCVetoNearTracks = nTracks[1];
642  nuebox.TPCVetoFarTracks = nTracks[0];
643  // Tracks at vertex going in the P0D
644  nuebox.TPCVetoP0DNearTracks = nTracks[2];
645 
646  // Tracks starting in the first two layers for FGD1 or in the first layer for FGD2
647  nuebox.NOOFVTracks = nueCCUtils::FindOOFVFGDTPCTracks(event, *track, static_cast<SubDetId::SubDetEnum>(nuebox.DetectorFV) );
648 
649  // FGD OOFV track
650  nuebox.OOFVtrack = cutUtils::FindFGDOOFVtrack(event, *track, static_cast<SubDetId::SubDetEnum>(nuebox.DetectorFV));
651 
652  // FGD2 Shower Tracks
653  Int_t nSTracks[2];
654  nueCCUtils::FindFGD2ShowerTracks(event, *track, nSTracks);
655 
656  nuebox.FGD2ShowerNFGD1TPC2Tracks = nSTracks[0];
657  nuebox.FGD2ShowerNFGD2TPC3Tracks = nSTracks[1];
658 
659  return true;
660 }
661 
662 //**************************************************
663 bool TPCVetoCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
664 //**************************************************
665 
666  (void) event;
667 
668  // cast the box to the appropriate type
669  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
670 
671  AnaTrackB* track = nuebox.MainTrack;
672  if(!track) return false;
673 
674  AnaTrackB* vetoTrack = nuebox.VetoTrack;
675  if(!vetoTrack) return true;
676 
677  return (nueCutUtils::TPCVeto(*track, vetoTrack, _delta_z_min));
678 }
679 
680 //**************************************************
681 bool GammaIsoVetoCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
682 //**************************************************
683 
684  (void) event;
685 
686  // cast the box to the appropriate type
687  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
688 
689  if(nuebox.TPCVetoNearTracks < 1 && nuebox.TPCVetoFarTracks > 1)
690  return false;
691 
692  return true;
693 }
694 
695 //**************************************************
696 bool FindPairsAction::Apply(AnaEventC& eventC, ToyBoxB& boxB) const {
697 //**************************************************
698 
699  AnaEventB& event = *static_cast<AnaEventB*>(&eventC);
700 
701  // Cast the ToyBox to the appropriate type
702  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
703 
704  AnaTrackB* track = nuebox.MainTrack;
705  if(!track) return false;
706 
707  //if(track)
708  //nuebox.PairTrack = nueCCUtils::FindPairTrack(event, track, _delta_pos_max, _pullel_min, _pullel_max);
709  //else
710  //nuebox.PairTrack = NULL;
711 
712  nuebox.PairTrack = nueCCUtils::FindPairTrack(event, *track, _delta_pos_max, _pullel_min, _pullel_max);
713 
714  return true;
715 }
716 
717 //**************************************************
718 bool PairCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
719 //**************************************************
720 
721  (void) event;
722 
723  // Cast the ToyBox to the appropriate type
724  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
725 
726  AnaTrackB* track = nuebox.MainTrack;
727  if(!track) return false;
728 
729  AnaTrackB* pair = nuebox.PairTrack;
730  if(!pair) return true;
731 
732  return (nueCutUtils::PairCut(*track, pair, _inv_mass_min));
733 }
734 
735 //**************************************************
736 bool P0DVetoCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
737 //**************************************************
738 
739  (void) event;
740 
741  // Cast the ToyBox to the appropriate type
742  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
743 
744  if(nuebox.P0DVetoP0DTracks > 0 || nuebox.P0DVetoP0DEcalTracks > 0) return false;
745 
746  return true;
747 }
748 
749 //*********************************************************************
751 //*********************************************************************
752 
753  AnaEventB& event = *static_cast<AnaEventB*>(&eventC);
754 
755  // Cast the ToyBox to the appropriate type
756  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
757 
758  nuebox.ECalVetoTrack = nueCCUtils::FindEcalVetoTrack(event, *(nuebox.MainTrack));
759  nuebox.ECalNCVetoTrack = nueCCUtils::FindEcalVetoTrack(event, *(nuebox.MainTrack), true);
760  return true;
761 }
762 
763 //**************************************************
764 bool ECalVetoCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
765 //**************************************************
766 
767  (void) event;
768 
769  // Cast the ToyBox to the appropriate type
770  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
771 
772  AnaTrackB* track = nuebox.MainTrack;
773  if(!track) return false;
774 
775  AnaTrackB* veto = nuebox.ECalVetoTrack;
776  if(!veto) return true;
777 
778  return (nueCutUtils::EcalVeto(*track, veto, _delta_z_min));
779 
780 }
781 
782 //**************************************************
783 bool ToFCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
784 //**************************************************
785 
786  AnaEventB& eventB = *static_cast<AnaEventB*>(&event);
787 
788  // Cast the ToyBox to the appropriate type
789  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
790 
791  AnaTrackB* track = nuebox.MainTrack;
792  if(!track) return false;
793 
794  Int_t realrun = eventB.EventInfo.Run;
795  Int_t realsubrun = eventB.EventInfo.SubRun;
796 
797  Int_t run = anaUtils::GetRunPeriod(realrun,realsubrun);
798 
799  return(nueCutUtils::ToF(*track, _fgdecaltof, run));
800 }
801 
802 //********************************************************************
804 //********************************************************************
805 
806  (void)event;
807  // Cast the ToyBox to the appropriate type
808  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
809 
810  if(!nuebox.MainTrack) return false;
811 
812  // Reject external background from the first 2 layers of FGD1
813  if(nuebox.NOOFVTracks > 0) return false;
814 
815  // Reject external background from the last 2 layers of FGD1
816  if(!nuebox.OOFVtrack) return true;
817 
818  if(nuebox.MainTrack->PositionStart[2] > 425.) return false;
819 
820  return true;
821 }
822 
823 //**************************************************
824 bool MomentumQualityCut::Apply(AnaEventC& event, ToyBoxB& boxB) const {
825 //**************************************************
826 
827  (void) event;
828 
829  // cast the box to the appropriate type
830  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
831 
832  AnaTrackB* track = nuebox.MainTrack;
833  if(!track) return false;
834 
835  // Only applied to specific momentum range
836  if(track->Momentum < 200.0) return true;
837 
839  if(!longCloseTPC) return false;
840 
841  Float_t pullmuon = (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpMuon)/longCloseTPC->dEdxSigmaMuon;
842  Float_t pullpion = (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpPion)/longCloseTPC->dEdxSigmaPion;
843 
844  if(pullmuon < 0.0 || pullpion < 0.0) return false;
845 
846  return true;
847 }
Float_t dEdxexpMuon
Expected dE/dx for a muon, based on the reconstructed momentum.
AnaTrackB * SHMtrack
For storing the second highest momentum track.
AnaTrueVertexB * TrueVertex
Pointer to the AnaTrueVertexB of the interaction that created this AnaTrueParticleB.
Float_t PositionStart[4]
The reconstructed start position of the particle.
bool IsRelevantRecObjectForSystematic(const AnaEventC &event, AnaRecObjectC *track, SystId_h systId, Int_t branch) const
Is this track relevant for a given systematic (prior to selection, call when initializing the event...
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
AnaTrueVertexB * TrueVertex
void DefineDetectorFV()
Define the detector Fiducial Volume in which this selection is applied.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
Int_t MaxAccumLevel
Definition: ToyBoxB.hxx:39
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
AnaECALParticleB * ECALSegments[NMAXECALS]
The ECAL segments that contributed to this global track.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
Float_t Position[4]
The identified position of the global vertex.
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.
AnaTrackB * MainTrack
For storing the Main Track (The lepton candidate in geranal: HMN or HMP track)
Int_t FGD2ShowerNFGD2TPC3Tracks
FGD2 shower.
Int_t P0DVetoP0DEcalTracks
Number of P0DEcal tracks. Used in the P0D veto cut.
AnaTrackB * ECalVetoTrack
The most-upstream track containing ECal information.
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.
AnaTrueVertexB * TrueVertex
For storing the true vertex, for analyses with no reconstructed primary vertex.
Definition: ToyBoxND280.hxx:22
Int_t TPCVetoNearTracks
Updated TPC veto.
AnaTrackB * HMPtrack
For storing the highest momentum positive track.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
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) ...
bool IsRelevantSystematic(const AnaEventC &event, const ToyBoxB &box, SystId_h systId, Int_t branch) const
Is this systematic relevant for this selection.
AnaEventInfoB EventInfo
Run, sunrun, event, time stamp, etc.
Float_t dEdxexpPion
Expected dE/dx for a pion, based on the reconstructed momentum.
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...
Int_t SubRun
The subrun number.
Int_t P0DVetoFGD1Tracks
The number of tracks that start in FGD1. Used in the P0D veto cut.
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.
AnaVertexB * Vertex
For storing the reconstructed vertex.
int nTPCSegments
How many TPC tracks are associated with this track.
Representation of a true Monte Carlo trajectory/particle.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
void InitializeEvent(AnaEventC &event)
Fill the EventBox with the objects needed by this selection.
int GetRunPeriod(int run, int subrun=-1)
Returns the run period (sequentially: 0,1,2,3,4,5 ...)
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) ...
AnaTrackB * VetoTrack
The TPC veto track.
Int_t PDG
The PDG code of this particle.
AnaTrackB * HMNtrack
For storing the highest momentum negative track.
Int_t ParentPDG
The PDG code of this particle&#39;s immediate parent, or 0 if there is no parent.
Float_t dEdxMeas
dE/dx as measured by the TPC.
AnaTrackB * SHMPtrack
For storing the second highest momentum positive track.
Representation of a global track.
AnaTrackB * HMtrack
For storing the highest momentum track.
Int_t NOOFVTracks
OOFV tracks.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
AnaTrackB * SecondMostEnergeticFGDTPCTrack
The second most energetic TPC track in the same FGD as the main track.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
Representation of a TPC segment of a global track.
AnaParticleB ** Particles
bool IsRelevantTrueObjectForSystematic(const AnaEventC &event, AnaTrueObjectC *trueTrack, SystId_h systId, Int_t branch) const
Is this true track relevant for a given systematic (prior to selection, call when initializing the ev...
Representation of a global vertex.
bool APPLY_SYST_FINE_TUNING
General tuning, the concept of apply the systematic for only the "relevant" objects.
bool InDetVolume(SubDetId::SubDetEnum det, const Float_t *pos)
bool Apply(AnaEventC &event, ToyBoxB &box) const
AnaEventSummaryC * Summary
A summary of the event with high level quantities.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool CheckRedoSelection(const AnaEventC &eventC, const ToyBoxB &PreviousToyBox, Int_t &redoFromStep)
AnaTrackB * SHMNtrack
For storing the second highest momentum negative track.
AnaTrackB * PairTrack
The particle that isn&#39;t HMTrackSelected that forms the e+e- pair with the lowest invariant mass...
Float_t dEdxSigmaMuon
Expected error on the dE/dx measurement, for the muon hypothesis.
AnaTPCParticleB * GetTPCBackSegment(const AnaTrackB *track)
Get the most dowstream TPC segment of the track.
Float_t Position[4]
The initial position of the true particle.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
void DefineSteps()
Define all steps in the selection.
AnaParticleB * GetSegmentWithMostNodesInClosestTpc(const AnaTrackB &track)
Combined function to address NuMu selection needs as efficiently as possible - gets the TPC segment w...
Float_t dEdxSigmaPion
Expected error on the dE/dx measurement, for the pion hypothesis.
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 Apply(AnaEventC &event, ToyBoxB &boxB) const
Int_t P0DVetoP0DTracks
The number of tracks that start in the P0D. Used in the P0D veto cut.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
A cut on event quality. Requires good beam and ND280 data quality flags.
AnaTrackB * OOFVtrack
For storing the oofv fgd tracks.
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
Int_t Run
The ND280 run number.