HighLAND
antiNumuCCMultiPiSelection.cxx
1 #include "antiNumuCCMultiPiSelection.hxx"
2 #include "antiNumuCCSelection.hxx"
3 #include "baseSelection.hxx"
4 #include "CutUtils.hxx"
5 #include "EventBoxUtils.hxx"
6 #include "SubDetId.hxx"
7 #include "SystId.hxx"
8 #include "VersioningUtils.hxx"
9 #include "SystematicUtils.hxx"
10 #include "SystematicTuning.hxx"
11 
12 
13 //********************************************************************
14 antiNumuCCMultiPiSelection::antiNumuCCMultiPiSelection(bool forceBreak): SelectionBase(forceBreak,EventBoxId::kEventBoxTracker) {
15  //********************************************************************
16 
17 }
18 
19 //********************************************************************
21  //********************************************************************
22 
23  // Copy all steps from the antiNumuCCSelection
24  CopySteps(_antiNumuCCSelection);
25 
26  //Pawel - Pions sele
27  //Additional actions for the multi-pi selection.
28  AddStep(StepBase::kAction, "fill_summary antinu_pion", new FillSummaryAction_antinuCCMultiPi());
29  AddStep(StepBase::kAction, "find_pions", new FindPionsAction_antinuCCMultiPi());
30  AddStep(StepBase::kAction, "find ECal photons", new FindEcalPhotonsAction_antinuCCMultiPi());
31 
32  //Add a split to the trunk with 3 branches.
33  AddSplit(3);
34 
35  //First branch is for CC-0pi
36  AddStep(0, StepBase::kCut, "CC-0pi", new NoPionCut_antinuCCMultiPi());
37  //AddStep(0, StepBase::kCut, "ECal Pi0 veto", new EcalPi0VetoCut());
38 
39  //Second branch is for CC-1pi
40  AddStep(1, StepBase::kCut, "CC-1pi", new OnePionCut_antinuCCMultiPi());
41  //AddStep(1, StepBase::kCut, "ECal Pi0 veto", new EcalPi0VetoCut());
42 
43  //Third branch is for CC-Other
44  AddStep(2, StepBase::kCut, "CC-Other", new OthersCut_antinuCCMultiPi());
45 
46  // Set the branch aliases to the three branches
47  SetBranchAlias(0,"CC-0pi", 0);
48  SetBranchAlias(1,"CC-1pi", 1);
49  SetBranchAlias(2,"CC-Other",2);
50 
51  // By default the preselection correspond to cuts 0-2
52  SetPreSelectionAccumLevel(2);
53 
54  // Step and Cut numbers needed by CheckRedoSelection
55  _MuonPIDCutIndex = GetCutNumber("muon PID");
56  _FindPionsStepIndex = GetStepNumber("find_pions");
57 
58 }
59 
60 //********************************************************************
62  //********************************************************************
63 
64  // The detector in which the selection is applied
65  SetDetectorFV(SubDetId::kFGD1);
66 }
67 
68 //********************************************************************
69 bool antiNumuCCMultiPiSelection::FillEventSummary(AnaEventC& event, Int_t allCutsPassed[]){
70  //********************************************************************
71 
72  //taken from numuCCMultiPi
73  //CC0pi
74  if(allCutsPassed[0]){
75  static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1AntiNuMuCC0Pi;
76  }
77  //CC1pi
78  else if (allCutsPassed[1]){
79  static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1AntiNuMuCC1Pi;
80  }
81  //CCOther
82  else if (allCutsPassed[2]){
83  static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD1AntiNuMuCCOther;
84  }
85 
86  // otherwise kUnassigned is used from the EventSummary constructor
87  return (static_cast<AnaEventSummaryB*>(event.Summary)->EventSample != SampleId::kUnassigned);
88 }
89 
90 //*********************************************************************
92  //*********************************************************************
93 
94  // Cast the ToyBox to the appropriate type
95  ToyBoxTracker& box = *static_cast<ToyBoxTracker*>(&boxB);
96 
97 
98  if(!box.HMPtrack) return 1;
99  //from numuCCMultiPi
100  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD1AntiNuMuCC0Pi] = box.HMPtrack;
101  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD1AntiNuMuCC1Pi] = box.HMPtrack;
102  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD1AntiNuMuCCOther] = box.HMPtrack;
103 
104  for(int i = 0; i < 4; ++i){
105  static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD1AntiNuMuCC0Pi][i] = box.HMPtrack->PositionStart[i];
106  static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD1AntiNuMuCC1Pi][i] = box.HMPtrack->PositionStart[i];
107  static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD1AntiNuMuCCOther][i] = box.HMPtrack->PositionStart[i];
108  }
109  if(box.HMPtrack->GetTrueParticle()){
110  static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD1AntiNuMuCC0Pi] = box.HMPtrack->GetTrueParticle()->TrueVertex;
111  static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD1AntiNuMuCC1Pi] = box.HMPtrack->GetTrueParticle()->TrueVertex;
112  static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD1AntiNuMuCCOther] = box.HMPtrack->GetTrueParticle()->TrueVertex;
113  }
114  return 1;
115 }
116 
117 //*********************************************************************
119  //*********************************************************************
120 
121  SubDetId::SubDetEnum det = static_cast<SubDetId::SubDetEnum>(box.DetectorFV);
122 
123  ToyBoxAntiCCMultiPi * ccmultipibox = static_cast<ToyBoxAntiCCMultiPi*>(&box);
124  EventBoxTracker* EventBox = static_cast<EventBoxTracker*>(event.EventBoxes[EventBoxId::kEventBoxTracker]);
125 
126  if (useTPCPions) antinumuCCMultiPiUtils::FindTPCPions(event, box, det, useOldSecondaryPID);
127  if (useME) antinumuCCMultiPiUtils::FindMEPions(event,det, prod5Cut);
128  if (useFGDPions) antinumuCCMultiPiUtils::FindIsoFGDPions(event, box, det);
129 
130  int nnegpions = ccmultipibox->nNegativePionTPCtracks;
131  int npospions = ccmultipibox->nPositivePionTPCtracks;
132  int nisofgdpions = ccmultipibox->nIsoFGDPiontracks;
133  int nmichelelectrons = EventBox->nFGDMichelElectrons[det];
134  int npi0 = ccmultipibox->nPosPi0TPCtracks + ccmultipibox->nElPi0TPCtracks;
135 
136  int pionFGD = 0;//nmichelelectrons;
137  if (!nmichelelectrons && nisofgdpions>0) pionFGD = 1;
138 
139  /*
140  ccmultipibox->nPosPions = npospions+pionFGD;
141  ccmultipibox->nOtherPions = nnegpions+npi0;
142  */
143  ccmultipibox->nPosPions = npospions + nmichelelectrons;
144  ccmultipibox->nNegPions = nnegpions + pionFGD;
145  ccmultipibox->nOtherPions = ccmultipibox->nPosPions+npi0;
146 
147  return true;
148 }
149 
150 //*********************************************************************
152  //*********************************************************************
153  // Find whether there is a pi0 track in the ECal or not
154  // In order to apply a pi0 veto cut later
155  ToyBoxAntiCCMultiPi * ccmultipibox = static_cast<ToyBoxAntiCCMultiPi*>(&box);
156  SubDetId::SubDetEnum det = static_cast<SubDetId::SubDetEnum>(box.DetectorFV);
157 
158  // Get all Ecal objects
159  EventBoxTracker::RecObjectGroupEnum groupID;
160  groupID = EventBoxTracker::kTracksWithECal;
161  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
162 
163  AnaTrackB *highestObject = NULL;
164  double higherEnergyObject = 0;
165 
166  //loop over all ECal objects
167  for(int i = 0; i < EventBox->nRecObjectsInGroup[groupID]; i++ ) {
168  AnaTrackB *allECALObjects = static_cast<AnaTrackB*>(EventBox->RecObjectsInGroup[groupID][i]);
169  if(!(allECALObjects->nECALSegments)) continue;
170  // Check for isolated ecal object
171  if(!(anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kDSECAL) ||
172  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kTopTECAL) ||
173  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kBottomTECAL) ||
174  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kLeftTECAL) ||
175  anaUtils::TrackUsesOnlyDet(*allECALObjects,SubDetId::kRightTECAL))
176  ) continue;
177 
178  AnaECALParticleB* ecalBase = allECALObjects->ECALSegments[0];
179  AnaTrackB* object = allECALObjects;
180  ccmultipibox->ISOEcal.push_back(object);
181 
182  // Find the most energetic object in ECal
183  if(ecalBase->EMEnergy > higherEnergyObject){
184  higherEnergyObject = ecalBase->EMEnergy;
185  highestObject = object;
186  }
187  }// end of loop on allECALTracks
188 
189  // Save the highest energetic ecal object in the box and the pi0 track
190  if (highestObject){
191  ccmultipibox->HObject = highestObject;
192  // Check if the highest energetic ecal object is shower-like
193  if( antinumuCCMultiPiUtils::ECALPi0Selection(event, box, highestObject, MostUpstreamLayerHitCut, det) ) {
194  ccmultipibox->Pi0Ecaltrack = highestObject;
195  ccmultipibox->nPi0Ecaltracks = ccmultipibox->nPi0Ecaltracks+1;
196  }
197  }
198  return true;
199 }
200 
201 //*********************************************************************
203  //*********************************************************************
204 
205  (void)event;
206 
207  ToyBoxAntiCCMultiPi * ccmultipibox = static_cast<ToyBoxAntiCCMultiPi*>(&box);
208 
209  // no negative[PP] and no other pions
210  if( ccmultipibox->nNegPions + ccmultipibox->nOtherPions == 0 ) return true;
211  return false;
212 }
213 
214 
215 //*********************************************************************
217  //*********************************************************************
218 
219  (void)event;
220 
221  ToyBoxAntiCCMultiPi * ccmultipibox = static_cast<ToyBoxAntiCCMultiPi*>(&box);
222 
223  // one negative pion and no other pions
224  if( ccmultipibox->nOtherPions != 0 ) return false;
225  if( ccmultipibox->nNegPions == 1 ) return true; //PP
226  return false;
227 }
228 
229 
230 //*********************************************************************
232  //*********************************************************************
233 
234  (void)event;
235 
236  ToyBoxAntiCCMultiPi * ccmultipibox = static_cast<ToyBoxAntiCCMultiPi*>(&box);
237 
238  // More than one positive pion or more than zero other pions or event doesn't pass the pi0 veto
239  if( ccmultipibox->nOtherPions != 0 ) return true;
240  if( ccmultipibox->nNegPions > 1 ) return true;
241  if( ccmultipibox->nPi0Ecaltracks > 0) return true;
242 
243  return false;
244 }
245 
246 //*********************************************************************
247 void antinumuCCMultiPiUtils::FindTPCPions(AnaEventC& event, ToyBoxB& box, SubDetId::SubDetEnum det, bool useOldSecondaryPID){
248  //*********************************************************************
249 
250  ToyBoxAntiCCMultiPi * ccmultipibox = static_cast<ToyBoxAntiCCMultiPi*>(&box);
251 
252  ccmultipibox->nPositivePionTPCtracks = 0;
253  ccmultipibox->nPosPi0TPCtracks = 0;
254  ccmultipibox->nNegativePionTPCtracks = 0;
255  ccmultipibox->nElPi0TPCtracks = 0;
256 
257  EventBoxTracker::RecObjectGroupEnum groupID;
258  if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD1FV;
259  else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithGoodQualityTPCInFGD2FV;
260  else return;
261 
262  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
263 
264  // Look for pions in positive tracks
265  for(int i = 0; i < EventBox->nRecObjectsInGroup[groupID]; i++ ) {
266  AnaTrackB *ptrack = static_cast<AnaTrackB*>(EventBox->RecObjectsInGroup[groupID][i]);
267 
268  if (ptrack->Charge>0){
269  if( ccmultipibox->HMPtrack == ptrack ) continue; // Same as the leading track. PP - for antineutrinos - leading positive
270 
271  if(useOldSecondaryPID){
272  if ( antinumuCCMultiPiUtils::TPCpionSelection(ptrack) ) {
273  ccmultipibox->PositivePionTPCtracks[ccmultipibox->nPositivePionTPCtracks] = ptrack;
274  ccmultipibox->nPositivePionTPCtracks++;
275  }
276  else if ( antinumuCCMultiPiUtils::TPCElPi0Selection(ptrack) ) {
277  ccmultipibox->PosPi0TPCtracks[ccmultipibox->nPosPi0TPCtracks] = ptrack;
278  ccmultipibox->nPosPi0TPCtracks++;
279  }
280  }
281  else {
282  Float_t PIDLikelihood[4];
283  anaUtils::GetPIDLikelihood(*ptrack, PIDLikelihood);
284 
285  // For Positive tracks we distinguish pions, electrons and protons.
286  double ElLklh = PIDLikelihood[1];
287  double ProtonLklh = PIDLikelihood[2];
288  double PionLklh = PIDLikelihood[3];
289  double norm = ElLklh+ProtonLklh+PionLklh;
290  ProtonLklh /= norm;
291  ElLklh /= norm;
292  PionLklh /= norm;
293 
294  if( ProtonLklh > ElLklh && ProtonLklh > PionLklh ) continue; // If the highest probability is a proton continue.
295 
296  // Id associated to the largest of the two probabilities.
297  if( PionLklh > ElLklh ){
298  ccmultipibox->PositivePionTPCtracks[ccmultipibox->nPositivePionTPCtracks] = ptrack;
299  ccmultipibox->nPositivePionTPCtracks++;
300  }
301  else {
302  if( ptrack->Momentum > 900. ) continue; // This is mainly protons.
303  ccmultipibox->PosPi0TPCtracks[ccmultipibox->nPosPi0TPCtracks] = ptrack;
304  ccmultipibox->nPosPi0TPCtracks++;
305  }
306  }
307  }
308  else{
309  //if( ccmultipibox->HMNtrack == ptrack ) continue; // Same as the leading track. (pp deleted)
310 
311  if(useOldSecondaryPID) {
312  if ( antinumuCCMultiPiUtils::TPCpionSelection(ptrack) ) {
313  ccmultipibox->NegativePionTPCtracks[ccmultipibox->nNegativePionTPCtracks] = ptrack;
314  ccmultipibox->nNegativePionTPCtracks++;
315  }
316  else if ( antinumuCCMultiPiUtils::TPCElPi0Selection(ptrack) ) {
317  ccmultipibox->ElPi0TPCtracks[ccmultipibox->nElPi0TPCtracks] = ptrack;
318  ccmultipibox->nElPi0TPCtracks++;
319  }
320  }
321  else {
322  // For Negative tracks we distinguish pions, electrons and protons.
323  Float_t PIDLikelihood[4];
324  anaUtils::GetPIDLikelihood(*ptrack, PIDLikelihood);
325 
326  // For Positive tracks we distinguish pions, electrons and protons.
327  double ElLklh = PIDLikelihood[1];
328  double PionLklh = PIDLikelihood[3];
329  double norm = ElLklh+PionLklh;
330  ElLklh /= norm;
331  PionLklh /= norm;
332 
333  if( PionLklh > 0.8 ){ // Id associated to the largest of the two probabilities.
334  ccmultipibox->NegativePionTPCtracks[ccmultipibox->nNegativePionTPCtracks] = ptrack;
335  ccmultipibox->nNegativePionTPCtracks++;
336  }
337  else{
338  ccmultipibox->ElPi0TPCtracks[ccmultipibox->nElPi0TPCtracks] = ptrack;
339  ccmultipibox->nElPi0TPCtracks++;
340  }
341  }
342  }
343  }
344 }
345 
346 
347 //*********************************************************************
348 void antinumuCCMultiPiUtils::FindIsoFGDPions(AnaEventC& event, ToyBoxB& box, SubDetId::SubDetEnum det){
349  //*********************************************************************
350 
351  ToyBoxAntiCCMultiPi * ccmultipibox = static_cast<ToyBoxAntiCCMultiPi*>(&box);
352  ccmultipibox->nIsoFGDPiontracks = 0;
353  ccmultipibox->nIsoFGDElPi0tracks = 0;
354 
355  EventBoxTracker::RecObjectGroupEnum groupID;
356  if (det==SubDetId::kFGD1) groupID = EventBoxTracker::kTracksWithFGD1AndNoTPC;
357  else if (det==SubDetId::kFGD2) groupID = EventBoxTracker::kTracksWithFGD2AndNoTPC;
358  else return;
359 
360  EventBoxB* EventBox = event.EventBoxes[EventBoxId::kEventBoxTracker];
361 
362  //loop over tracks
363  for (int i=0;i<EventBox->nRecObjectsInGroup[groupID]; i++ ){
364  AnaTrackB* track = static_cast<AnaTrackB*>(EventBox->RecObjectsInGroup[groupID][i]);
365  // Apply the fiducial cut and PID
366  if( antinumuCCMultiPiUtils::FGDpionSelection(track,det) ){
367  ccmultipibox->IsoFGDPiontracks[ccmultipibox->nIsoFGDPiontracks] = track;
368  ccmultipibox->nIsoFGDPiontracks++;
369  }
370  else if( antinumuCCMultiPiUtils::FGDElPi0Selection(event,box,track,det) ){
371  ccmultipibox->IsoFGDElPi0tracks[ccmultipibox->nIsoFGDElPi0tracks] = track;
372  ccmultipibox->nIsoFGDElPi0tracks++;
373  }
374  }
375 }
376 
377 //*********************************************************************
378 void antinumuCCMultiPiUtils::FindMEPions(AnaEventC& eventBB, SubDetId::SubDetEnum det, bool prod5Cut){
379  //*********************************************************************
380 
381  AnaEventB& event = *static_cast<AnaEventB*>(&eventBB);
382 
383  EventBoxTracker* EventBox = static_cast<EventBoxTracker*>(event.EventBoxes[EventBoxId::kEventBoxTracker]);
384 
385  // Fill the box only the first time this is used
386  if (EventBox->FGDMichelElectrons[det]) return;
387 
388  anaUtils::CreateArray(EventBox->FGDMichelElectrons[det], NMAXFGDTIMEBINS);
389  EventBox->nFGDMichelElectrons[det] = anaUtils::GetFGDMichelElectrons(event, det, EventBox->FGDMichelElectrons[det], prod5Cut);
390  anaUtils::ResizeArray(EventBox->FGDMichelElectrons[det], EventBox->nFGDMichelElectrons[det]);
391 
392 }
393 
394 //*********************************************************************
395 bool antinumuCCMultiPiUtils::TPCpionSelection(AnaTrackB *track){
396  //*********************************************************************
397 
398  Float_t PIDLikelihood[4];
399  anaUtils::GetPIDLikelihood(*track, PIDLikelihood);
400 
401  if ( PIDLikelihood[3] < 0.3 ) return false;
402 
403  double cut1 = (PIDLikelihood[0]+PIDLikelihood[3])/(1.-PIDLikelihood[2]);
404 
405  if( track->Momentum < 500. && cut1 < 0.8 ) return false;
406 
407  return true;
408 
409 
410 }
411 //*********************************************************************
412 bool antinumuCCMultiPiUtils::TPCElPi0Selection(AnaTrackB *track){
413  //*********************************************************************
414 
415  if( track->nTPCSegments == 0 ) return false; // There is no TPC segment
416 
417  bool seltrack = false;
418 
419  // if (!cutUtils::TrackQualityCut(*track)) return seltrack;
420 
421  if( track->Momentum < 50. ) return seltrack;
422 
423  // if( track->Charge > 0. && track->Momentum > 800.) return seltrack;
424 
425  Float_t pulls[4];
426 
427  for(int i = 0; i < track->nTPCSegments ; i++ ){
428 
429  AnaTPCParticleB *tpcTrack = track->TPCSegments[i];
430 
431  if( !tpcTrack ) continue; // Extra protection.
432 
433  // Pulls are: Muon, Electron, Proton, Pion
434  anaUtils::ComputeTPCPull(*tpcTrack,pulls);
435 
436  if (TMath::Abs(pulls[0]) > 1.e+6 // muon pull
437  || TMath::Abs(pulls[1]) > 1.e+6 // electron pull
438  || TMath::Abs(pulls[2]) > 1.e+6 // proton pull
439  || TMath::Abs(pulls[3]) > 1.e+6) continue; // pion pull
440 
441  if( pulls[1] < -2.0 || pulls[1] > 2.0 ) break;
442 
443  if( track->Charge > 0. && ( pulls[2] > -4.0 && pulls[2] < 8.0 ) ) break;
444 
445  seltrack = true;
446 
447  }
448  return seltrack;
449 }
450 
451 //*********************************************************************
452 bool antinumuCCMultiPiUtils::FGDpionSelection(AnaTrackB *track, SubDetId::SubDetEnum det){
453  //*********************************************************************
454  if( track->nFGDSegments != 1 ) return false; // There is no FGD segment or it has more than one FGD
455 
456  AnaFGDParticleB *fgdTrack = track->FGDSegments[0];
457 
458  if( !fgdTrack ) return false; // Extra protection.
459 
460  if( TMath::Abs(fgdTrack->Pullp) > 1.e+6 || TMath::Abs(fgdTrack->Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->Pullpi) > 1.e+6 ) return false;
461 
462  // Check the pullnotset variable.
463  // This tells us if the pull was calculated by the algorithm.
464  // If it was not calculated this variable will be 1, so for calculated pulls fgdpulls!=1.
465  if( fgdTrack->Pullno == 1 ) return false;
466 
467  // This tell us something about the geometry.
468  // If the algorithm says the particle started and stopped in 1st/ 2nd fgd this is equal 1 or 2.
469  // If the particle stopped in 1st/2nd fgd, this is equal -1/-2. Other cases: 0.
470  if( fgdTrack->Containment == 0 ) return false;
471  if ( det == SubDetId::kFGD1 && fgdTrack->Containment != 1 ) return false;
472  else if( det == SubDetId::kFGD2 && fgdTrack->Containment != 2 ) return false;
473  else if( det == SubDetId::kFGD && fgdTrack->Containment != 1 && fgdTrack->Containment != 2) return false;
474 
475  double cosFGDpion = fgdTrack->DirectionStart[2];
476 
477  if(cosFGDpion > -0.3 && cosFGDpion < 0.3) return false;/// only for systematics issues. Must be remove in the future!!
478 
479  if( fgdTrack->Pullpi < 2.5 && fgdTrack->Pullpi > -2.0 ) return true;
480 
481  return false;
482 
483 
484 }
485 
486 //*********************************************************************
487 bool antinumuCCMultiPiUtils::FGDElPi0Selection(AnaEventC& event, ToyBoxB& box, AnaTrackB *track, SubDetId::SubDetEnum det){
488  //*********************************************************************
489 
490  (void)box;
491 
492  if( track->nFGDSegments != 1 ) return false; // There is no FGD segment or it has more than one FGD
493 
494  // ToyBoxCCMultiPi * ccmultipibox = static_cast<ToyBoxCCMultiPi*>(&box);
495 
496  AnaFGDParticleB *fgdTrack = track->FGDSegments[0];
497 
498  if( !fgdTrack ) return false; // Extra protection.
499 
500  if( TMath::Abs(fgdTrack->Pullp) > 1.e+6 || TMath::Abs(fgdTrack->Pullmu) > 1.e+6 || TMath::Abs(fgdTrack->Pullpi) > 1.e+6 ) return false;
501 
502  // Check the pullnotset variable.
503  // This tells us if the pull was calculated by the algorithm.
504  // If it was not calculated this variable will be 1, so for calculated pulls fgdpulls!=1.
505  if( fgdTrack->Pullno == 1 ) return false;
506 
507  // This tell us something about the geometry.
508  // If the algorithm says the particle started and stopped in 1st/ 2nd fgd this is equal 1 or 2.
509  // If the particle stopped in 1st/2nd fgd, this is equal -1/-2. Other cases: 0.
510  if( fgdTrack->Containment == 0 ) return false;
511  if ( det == SubDetId::kFGD1 && fgdTrack->Containment != 1 ) return false;
512  else if( det == SubDetId::kFGD2 && fgdTrack->Containment != 2 ) return false;
513  else if( det == SubDetId::kFGD && fgdTrack->Containment != 1 && fgdTrack->Containment != 2) return false;
514 
515  EventBoxTracker* EventBox = static_cast<EventBoxTracker*>(event.EventBoxes[EventBoxId::kEventBoxTracker]);
516 
517  if(EventBox->nFGDMichelElectrons[det] > 0 && fgdTrack->Pullpi < -3.0 ) return true;
518  if(EventBox->nFGDMichelElectrons[det] == 0 && fgdTrack->Pullpi < -1.5 ) return true;
519 
520 
521  return false;
522 }
523 
524 
525 //***********************************************************************
526 bool antinumuCCMultiPiUtils::ECALPi0Selection(AnaEventC& event, ToyBoxB& box, AnaTrackB *HO, int MostUpstreamLayerHitCut, SubDetId::SubDetEnum det){
527  //***********************************************************************
528 
529  (void)event;
530  (void)box;
531  (void)det;
532 
533  // Identify if the highest ECal object comes from a TPC positive track
534  // or the muon candidate.
535  // If not, then the ecal object might comes from a pi0 (if the object is shower like)
536 
537  bool Ecalpi0 = false;
538 
539  double EMENERGY = -9999.;
540  double MIPEM = -9999.;
541  double EM_UPSTREAM = -9999;
542  AnaECALParticleB* EcalSegment = HO->ECALSegments[0];
543  if( !EcalSegment ) return false;
544 
545  // Check that the Highest energetic ecal obj is actually shower-like (MIPEM>0)
546  // Cut on EMEnergy because of big spike around 26 MeV (feature of the reconstruction)
547  MIPEM = EcalSegment->PIDMipEm;
548  EMENERGY = EcalSegment->EMEnergy;
549  if (EMENERGY > 30. && MIPEM > 0.) Ecalpi0 = true;
550 
551  // This is the cut on MostUpstreamLayerHit variable.
552  // The cut threshold has to be set in the parameter file
553  // For more information on this variable, see slide 10: http://www.t2k.org/nd280/physics/convener/2015/November2/ECal_pi0_veto
554  EM_UPSTREAM = EcalSegment->MostUpStreamLayerHit;
555  if(EM_UPSTREAM > MostUpstreamLayerHitCut ) Ecalpi0 = false;
556 
557  return Ecalpi0;
558 }
559 
560 
561 
562 //**************************************************
563 bool antiNumuCCMultiPiSelection::IsRelevantRecObjectForSystematic(const AnaEventC& event, AnaRecObjectC* track, SystId_h systId, Int_t branch) const{
564  //**************************************************
565 
566  return _antiNumuCCSelection.IsRelevantRecObjectForSystematic(event,track,systId,branch);
567 }
568 
569 //**************************************************
570 bool antiNumuCCMultiPiSelection::IsRelevantTrueObjectForSystematic(const AnaEventC& event, AnaTrueObjectC* trueTrack, SystId_h systId, Int_t branch) const{
571  //**************************************************
572 
573  return _antiNumuCCSelection.IsRelevantTrueObjectForSystematic(event,trueTrack,systId,branch);
574 }
575 
576 //**************************************************
577 bool antiNumuCCMultiPiSelection::IsRelevantSystematic(const AnaEventC& event, const ToyBoxB& box, SystId_h systId, Int_t branch) const{
578  //**************************************************
579 
580  (void)event;
581  (void)branch;
582  (void)box;
583 
584  switch(systId){
585  case SystId::kFgdTrackEff: return false;
586  //kSIProton: check whether should be still applied when the main track is a true proton or its product: TESTING PURPOSES
587  case SystId::kSIProton: if (!systTuning::APPLY_SYST_FINE_TUNING) return false;//new highland does not have SIProton_APPLY...
588  default: return true; //the rest is included (including KFgdHybridTrackEff, kMichelEleEff)
589  }
590 }
591 
592 //**************************************************
594  //**************************************************
595 
596  _antiNumuCCSelection.InitializeEvent(event);
597 }
598 
599 //********************************************************************
600 bool antiNumuCCMultiPiSelection::CheckRedoSelection(const AnaEventC& event, const ToyBoxB& PreviousToyBox, Int_t& redoFromStep){
601  //********************************************************************
602 
603  // Must redo selection if antiNumuCCSelection decides so
604  if( _antiNumuCCSelection.CheckRedoSelection(event,PreviousToyBox,redoFromStep)) return true;
605 
606  // Otherwise selection should not be redone since the number of tracks with TPC and FGD will not be changed by systematics
607  return false;
608 }
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 IsRelevantSystematic(const AnaEventC &event, const ToyBoxB &box, SystId_h systId, Int_t branch) const
Is this systematic relevant for 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.
Float_t Pullno
Dummy pull. If the FGD pulls weren&#39;t set, this is set to 1.
SubDetId_h DetectorFV
Indicate the FV we are interested in.
Definition: ToyBoxB.hxx:52
void InitializeEvent(AnaEventC &event)
Fill the EventBox with the objects needed by this selection.
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
AnaTrackB * HMPtrack
For storing the highest momentum positive track.
void DefineSteps()
Define all steps in the selection.
Float_t Pullmu
Muon pull, according to FGD information.
Float_t Charge
The reconstructed charge of the particle.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool Apply(AnaEventC &event, ToyBoxB &box) const
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.
bool CheckRedoSelection(const AnaEventC &event, const ToyBoxB &PreviousToyBox, Int_t &redoFromStep)
SubDetEnum
Enumeration of all detector systems and subdetectors.
Definition: SubDetId.hxx:25
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.
Representation of a TPC segment of a global track.
bool APPLY_SYST_FINE_TUNING
General tuning, the concept of apply the systematic for only the "relevant" objects.
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.
void DefineDetectorFV()
Define the detector Fiducial Volume in which this selection is applied.
bool Apply(AnaEventC &event, ToyBoxB &box) const
int nFGDSegments
How many FGD tracks are associated with this 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...
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)
bool Apply(AnaEventC &event, ToyBoxB &box) const
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...
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
bool Apply(AnaEventC &event, ToyBoxB &box) const
bool TrackUsesOnlyDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
AnaFGDParticleB * FGDSegments[NMAXFGDS]
The FGD segments that contributed to this global track.