HighLAND
antiNueCCFGD2Selection.cxx
1 #include "antiNueCCSelection.hxx"
2 #include "nueCCFGD2Selection.hxx"
3 #include "antiNueCCFGD2Selection.hxx"
4 
5 #include "baseSelection.hxx"
6 #include "CutUtils.hxx"
7 #include "EventBoxUtils.hxx"
8 #include "VersioningUtils.hxx"
9 #include "SystematicUtils.hxx"
10 #include "trackerSelectionUtils.hxx"
11 
12 #include "nueCCUtils.hxx"
13 #include "nueCutUtils.hxx"
14 #include "SystematicTuning.hxx"
15 
16 //********************************************************************
17 antiNueCCFGD2Selection::antiNueCCFGD2Selection(bool forceBreak): SelectionBase(forceBreak, EventBoxId::kEventBoxTracker) {
18 //********************************************************************
19 
20  // Initialize selections being used
21  _nueCCSelection.Initialize();
22 
23  // Variables needed from datacard
24  _protonregion_low = (Float_t)ND::params().GetParameterD("psycheSelections.antiNueCCAnalysis.Analysis.ProtonMomentumRegion.Low");
25 
26  // Initialize systematic tuning parameters
27  systTuning::Initialize();
28 }
29 
30 //********************************************************************
32 //********************************************************************
33 
34  // The detector in which the selection is applied
35  SetDetectorFV(SubDetId::kFGD2);
36  // Set the detector field into the selection being used
37  _nueCCSelection.SetDetectorFV(SubDetId::kFGD2);
38 }
39 
40 //********************************************************************
42 //********************************************************************
43 
44  // last "true" means the step sequence is broken if cut is not passed (default is "false")
45 
46  AddStep(StepBase::kCut, "event quality", new EventQualityCut(), true); // 0
47  AddStep(StepBase::kCut, "> 0 tracks ", new MultiplicityCut(), true); // 1
48  AddStep(StepBase::kAction, "find leading tracks", new FillLeadingTracksAction_antiNueCC());
49 
50  AddStep(StepBase::kAction, "Fill vertex info", new FillVertex());
51  AddStep(StepBase::kAction, "fill summary", new FillSummaryAction_antiNueCCFGD2Selection());
52 
53  AddStep(StepBase::kCut, "TPC Quality", new TrackQualityCut(), true); // 2
54  AddStep(StepBase::kCut, "Momentum", new HighestMomentumCut()); // 3
55 
56  // Here the most energetic track must be positive and it has to be the most energetic compared to all TPC tracks
57  AddStep(StepBase::kAction, "find second most energetic track", new FindSecondMostEnergeticTPCTrack_antiNueCC());
58  AddStep(StepBase::kCut, "Most energetic positive track", new MostEnergeticTrackCut_antiNueCC()); // 4
59 
60  // e- PID cuts.
61  AddStep(StepBase::kCut, "TPC Electron Pull", new TPCElectronPullCut()); // 5
62  AddStep(StepBase::kCut, "TPC Muon Pull", new TPCMuonPullCut()); // 6
63  AddStep(StepBase::kCut, "TPC Pion Pull", new TPCPionPullCut()); // 7
64  AddStep(StepBase::kCut, "Ecal EMEnergy", new EcalEMEnergyCut_antiNueCC()); // 8
65  AddStep(StepBase::kCut, "Ecal MIPEM PID", new EcalMIPEMPIDCut()); // 9
66  AddStep(StepBase::kCut, "EoP", new EOverPCutFGD2_antiNueCC()); // 10
67 
68  // Upstream vetos. Reduce OOFV background.
69  AddStep(StepBase::kAction, "find TPC Veto tracks", new FillTPCVetoTrackAction());
70  AddStep(StepBase::kCut, "TPC Veto", new TPCVetoCut_FGD2()); // 11
71  AddStep(StepBase::kCut, "Gamma Iso Veto", new GammaIsoVetoCut()); // 12
72  AddStep(StepBase::kCut, "External FGD2", new ExternalFGD2layersCut()); // 13
73 
74  AddStep(StepBase::kAction, "find best e+e- pair", new FindPairsAction());
75  AddStep(StepBase::kCut, "Pair Veto", new PairCut()); // 14
76 
77  AddStep(StepBase::kAction, "find P0D-FGD1 veto track", new FindP0DVetoTrackAction());
78  AddStep(StepBase::kCut, "P0D-FGD1 Veto", new P0DFGD1VetoCut()); // 15
79 
80  AddStep(StepBase::kAction, "find ecal veto track", new FindECalVetoTrackAction());
81  AddStep(StepBase::kCut, "Ecal Veto", new ECalVetoCut()); // 16
82 
83  // Proton rejection in nuebar selection
84  AddStep(StepBase::kCut, "E over P", new EoverPCut_antiNueCC()); // 17
85  AddStep(StepBase::kCut, "Ecal EMHIP PID", new EcalEMHIPPIDCut_antiNueCC()); // 18
86  AddStep(StepBase::kCut, "FGD Shower", new FGDShowerCut_antiNueCC()); // 19
87 
88  // ToF for antinue selection - applied only to fhc selection
89  AddStep(StepBase::kCut, "ToF", new ToFCut_antiNueCC()); // 20
90 
91  // Momentum quality cut
92  AddStep(StepBase::kCut, "Momentum quality", new MomentumQualityCut()); // 21
93 
94  SetBranchAlias(0,"trunk");
95 
96  // By default the preselection correspond to cuts 0-3
97  // It means that if any of the four first cuts (0,1,2,3) is not passed
98  // the loop over toys will be broken ===> A single toy will be run
99  SetPreSelectionAccumLevel(3);
100 
101  _FindLeadingTracksStepIndex = GetStepNumber("find leading tracks");
102  _TotalMultiplicityCutIndex = GetCutNumber("> 0 tracks ");
103 
104  _ElecPIDCutIndex = GetCutNumber("TPC Electron Pull");
105  _ElecPIDStepIndex = GetStepNumber("TPC Electron Pull");
106 }
107 
108 //********************************************************************
109 bool antiNueCCFGD2Selection::FillEventSummary(AnaEventC& event, Int_t allCutsPassed[]){
110 //********************************************************************
111 
112  if(allCutsPassed[0])
113  static_cast<AnaEventSummaryB*>(event.Summary)->EventSample = SampleId::kFGD2AntiNuECC;
114 
115  return (static_cast<AnaEventSummaryB*>(event.Summary)->EventSample != SampleId::kUnassigned);
116 }
117 
118 //********************************************************************
120 //********************************************************************
121 
122  //ToyBoxTracker& nuebox = *static_cast<ToyBoxTracker*>(&box);
123  ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&box);
124 
125  if(!nuebox.MainTrack) return false;
126 
127  static_cast<AnaEventSummaryB*>(event.Summary)->LeptonCandidate[SampleId::kFGD2AntiNuECC] = nuebox.MainTrack;
128  for(Int_t i = 0; i < 4; ++i)
129  static_cast<AnaEventSummaryB*>(event.Summary)->VertexPosition[SampleId::kFGD2AntiNuECC][i] = nuebox.MainTrack->PositionStart[i];
130  if(nuebox.MainTrack->GetTrueParticle())
131  static_cast<AnaEventSummaryB*>(event.Summary)->TrueVertex[SampleId::kFGD2AntiNuECC] = nuebox.MainTrack->GetTrueParticle()->TrueVertex;
132 
133  return true;
134 }
135 
136 //*********************************************************************
137 bool antiNueCCFGD2Selection::IsRelevantRecObjectForSystematic(const AnaEventC& eventC, AnaRecObjectC* recObj, SystId_h systId, Int_t branch) const{
138 //*********************************************************************
139 
140  return _nueCCSelection.IsRelevantRecObjectForSystematic(eventC, recObj, systId, branch);
141 }
142 
143 //*********************************************************************
144 bool antiNueCCFGD2Selection::IsRelevantTrueObjectForSystematic(const AnaEventC& eventC, AnaTrueObjectC* trueObj, SystId_h systId, Int_t branch) const{
145 //*********************************************************************
146 
147  return _nueCCSelection.IsRelevantTrueObjectForSystematic(eventC, trueObj, systId, branch);
148 }
149 
150 //**************************************************
151 bool antiNueCCFGD2Selection::IsRelevantRecObjectForSystematicInToy(const AnaEventC& eventC, const ToyBoxB& boxB, AnaRecObjectC* recObj, SystId_h systId, Int_t branch) const{
152 //**************************************************
153 
154  AnaTrackB* track = static_cast<AnaTrackB*>(recObj);
155 
156  // cast the box to the appropriate type
157  const ToyBoxNueCC& box = *static_cast<const ToyBoxNueCC*>(&boxB);
158 
159  // Special nuebar systematics
160  if(systId == SystId::kECalEmHipPID){
161  // Only applied to main track
162  if (track != box.MainTrack) return false;
163 
164  if(!nueCCUtils::UseEcal(track)) return false;
165  // Only applied for tracks with p > 600 MeV/c
166  if(track->Momentum < _protonregion_low) return false;
167 
168  return true;
169  }
170 
171  return _nueCCSelection.IsRelevantRecObjectForSystematicInToy(eventC, boxB, recObj, systId, branch);
172 }
173 
174 //**************************************************
175 bool antiNueCCFGD2Selection::IsRelevantTrueObjectForSystematicInToy(const AnaEventC& eventC, const ToyBoxB& boxB, AnaTrueObjectC* trueObj, SystId_h systId, Int_t branch) const{
176 //**************************************************
177 
178  if(systId == SystId::kSIProton){
179  const ToyBoxTracker& box = *static_cast<const ToyBoxTracker*>(&boxB);
180 
181  AnaTrueParticleB* trueTrack = static_cast<AnaTrueParticleB*>(trueObj);
182 
183  // If this trueTrack is NOT associated to the MainTrack, consider the posibility of this trueTrack to become the MainTrack
184  // This is to be tuned: e.g. may consider explicitely those not reconstructed in TPC
185  // also the ones that have the momentum ~closer to the Bethe-Bloch crossing point,
186  // i.e. when proton background starts to become non-negligible
187  if (trueTrack->PDG == 2212 && trueTrack->Momentum > box.MainTrack->Momentum
188  && trueTrack->Momentum > _protonregion_low) return true;
189  }
190 
191  return _nueCCSelection.IsRelevantTrueObjectForSystematicInToy(eventC, boxB, trueObj, systId, branch);
192 }
193 
194 //*********************************************************************
195 bool antiNueCCFGD2Selection::IsRelevantSystematic(const AnaEventC& eventC, const ToyBoxB& boxB, SystId_h systId, Int_t branch) const{
196 //*********************************************************************
197 
198  // Anti-nue FGD2 related
199  if(systId == SystId::kECalEmHipPID) return true;
200 
201  // Rest are the same as in the nue analysis
202  return _nueCCSelection.IsRelevantSystematic(eventC, boxB, systId, branch);
203 }
204 
205 //*********************************************************************
206 bool antiNueCCFGD2Selection::CheckRedoSelection(const AnaEventC& eventC, const ToyBoxB& PreviousToyBoxB, Int_t& redoFromStep){
207 //*********************************************************************
208 
209  const AnaEventB& event = *static_cast<const AnaEventB*>(&eventC);
210 
211  // cast the box to the appropriate type
212  const ToyBoxNueCC& PreviousToyBox = *static_cast<const ToyBoxNueCC*>(&PreviousToyBoxB);
213 
214  /// Nothing to do if there is no HM or HMP track
215  if(!PreviousToyBox.HMtrack || !PreviousToyBox.HMPtrack) return false;
216 
217  // TODO: The code below implies calling cutUtils::FindLeadingTracks(event, box) twice. Can we avoid that ?
218  if(PreviousToyBox.MaxAccumLevel > _TotalMultiplicityCutIndex){
219  ToyBoxNueCC box;
220  trackerSelUtils::FindLeadingTracks(event, box);
221 
222  // Redo the selection if any of the leading tracks changes identity
223  if(PreviousToyBox.SHMNtrack!=box.SHMNtrack ||
224  PreviousToyBox.SHMPtrack!=box.SHMPtrack ||
225  PreviousToyBox.HMNtrack !=box.HMNtrack ||
226  PreviousToyBox.HMPtrack !=box.HMPtrack ||
227  PreviousToyBox.SHMtrack !=box.SHMtrack ||
228  PreviousToyBox.HMtrack !=box.HMtrack){
229 
230  redoFromStep = _FindLeadingTracksStepIndex;
231  return true;
232  }
233  }
234 
235  // When the HMP track does not change identity, Redo the selection if the effect of the PID cut is different.
236  // We have previously saved in the EventBox the AccumLevel of the previous toy for each branch.
237  // PreviousToyBox->AccumLevel[0]>_ElecPIDCutIndex means that the PID cut was passed, so we check whether the cut
238  // was passed in the previous toy and not in the current one, or the opposit, it was not passed before
239  // and it is passed now.
240 
241  if(PreviousToyBox.MaxAccumLevel >= _ElecPIDCutIndex){
242  //bool pidCut = nueCutUtils::TPCElectronPull(PreviousToyBox.HMPtrack, _pullel_accept_min, _pullel_accept_max, _pullel_accept_tight_min, _pullel_accept_tight_max, _minMom_ecal);
243  //if(( pidCut && (PreviousToyBox.AccumLevel[0] == _ElecPIDCutIndex)) ||
244  // (!pidCut && (PreviousToyBox.AccumLevel[0] > _ElecPIDCutIndex))){
245  // We should redo the selection starting from the PIDCut step
246  redoFromStep = _ElecPIDStepIndex;
247  return true;
248  //}
249  }
250 
251  return false;
252 }
253 
254 //*********************************************************************
256 //*********************************************************************
257 
258  _nueCCSelection.InitializeEvent(eventC);
259 }
260 
261 //**************************************************
263 //**************************************************
264 
265  (void) event;
266  (void) boxB;
267 
268  // Disabled for now
269  return true;
270 
271  // cast the box to the appropriate type
272  //ToyBoxNueCC& nuebox = *static_cast<ToyBoxNueCC*>(&boxB);
273 
274  //AnaTrackB* track = nuebox.MainTrack;
275  //if(!track) return false;
276 
277  //return nueCutUtils::EOverPNuE(track, _eoverp_threshold, _eoverp_minmom);
278 
279 }
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 CheckRedoSelection(const AnaEventC &eventC, const ToyBoxB &PreviousToyBox, Int_t &redoFromStep)
Int_t MaxAccumLevel
Definition: ToyBoxB.hxx:39
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 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...
AnaTrackB * MainTrack
For storing the Main Track (The lepton candidate in geranal: HMN or HMP track)
bool Apply(AnaEventC &event, ToyBoxB &boxB) const
Float_t Momentum
The initial momentum of the true particle.
AnaTrackB * HMPtrack
For storing the highest momentum positive track.
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...
void DefineSteps()
Define all steps in the selection.
void InitializeEvent(AnaEventC &event)
Fill the EventBox with the objects needed by this selection.
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
Representation of a true Monte Carlo trajectory/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) ...
Int_t PDG
The PDG code of this particle.
AnaTrackB * HMNtrack
For storing the highest momentum negative track.
AnaTrackB * SHMPtrack
For storing the second highest momentum positive track.
Representation of a global track.
AnaTrackB * HMtrack
For storing the highest momentum track.
AnaEventSummaryC * Summary
A summary of the event with high level quantities.
bool IsRelevantSystematic(const AnaEventC &event, const ToyBoxB &box, SystId_h systId, Int_t branch) const
Is this systematic relevant for this selection.
AnaTrackB * SHMNtrack
For storing the second highest momentum negative track.
void DefineDetectorFV()
Define the detector Fiducial Volume in which this selection is applied.
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
bool Apply(AnaEventC &event, ToyBoxB &box) const
A cut on event quality. Requires good beam and ND280 data quality flags.
void Initialize()
Initialize this selection: defines the steps and the detectorFV.