HighLAND
nueCCAnalysis.cxx
1 #include "nueCCAnalysis.hxx"
2 #include "nueCCSelection.hxx"
3 #include "nueCCFGD2Selection.hxx"
4 
5 #include "CutUtils.hxx"
6 #include "nueCCUtils.hxx"
7 #include "CategToolsNueCC.hxx"
8 
9 #include "FiducialVolumeDefinition.hxx"
10 #include "Parameters.hxx"
11 #include "UseGlobalAltMomCorrection.hxx"
12 #include "CategoriesUtils.hxx"
13 #include "BasicUtils.hxx"
14 #include "baseToyMaker.hxx"
15 
16 #include "NuDirUtils.hxx"
17 
18 //********************************************************************
19 nueCCAnalysis::nueCCAnalysis(AnalysisAlgorithm* ana) : baseTrackerAnalysis(ana) {
20 //********************************************************************
21 
22  // Add the package version
23  ND::versioning().AddPackage("nueCCAnalysis", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("NUECCANALYSISROOT")));
24 }
25 
26 //********************************************************************
28 //********************************************************************
29 
30  // Initialize the baseTrackerAnalysis
31  if(!baseTrackerAnalysis::Initialize()) return false;
32 
33  // Minimum accum level to save event Int_to the output tree
34  SetMinAccumCutLevelToSave(ND::params().GetParameterI("nueCCAnalysis.MinAccumLevelToSave"));
35 
36  // which analysis: FGD1, FGD2 or FGDs
37  _whichFGD = ND::params().GetParameterI("nueCCAnalysis.Analysis.Sample.whichFGD");
38 
39  // Save all the secondary tarcks in the microtree
40  _savesecondaries = ND::params().GetParameterI("nueCCAnalysis.Analysis.SaveSecondaries");
41 
42  // Michel defined differently for P5 and P6. P5 only had FGD1 systematics
43  _p5 = ND::params().GetParameterI("nueCCAnalysis.Corrections.p5michel");
44 
45  // Extrend the list of toy variables
46  _addmoretoyvariables = ND::params().GetParameterI("nueCCAnalysis.MicroTrees.AdditionalToyVars");
47 
48  // Add new categories specific for nue analysis
49  nue_categs::AddCategories("", false);
50  nue_categs::AddCategories("fgd2", false);
51 
54 
55  return true;
56 }
57 
58 //********************************************************************
59 void nueCCAnalysis::DefineSelections(){
60 //********************************************************************
61 
62  // ----- Inclusive CC -----------
63  if (_whichFGD==1) // FGD1
64  sel().AddSelection("kTrackerNueCC", "inclusive nueCC selection", new nueCCSelection(false)); // true/false for forcing break
65  else if (_whichFGD==2) // FGD2
66  sel().AddSelection("kTrackerNueCCFGD2", "inclusive nueCCFGD2 selection", new nueCCFGD2Selection(false)); // true/false for forcing break
67  else if (_whichFGD==3) { // both FGDs, in 2 selections
68  sel().AddSelection("kTrackerNueCC", "inclusive nueCC selection", new nueCCSelection(false)); // true/false for forcing break
69  sel().AddSelection("kTrackerNueCCFGD2", "inclusive nueCCFGD2 selection", new nueCCFGD2Selection(false)); // true/false for forcing break
70  }
71 }
72 
73 //********************************************************************
74 void nueCCAnalysis::DefineCorrections(){
75 //********************************************************************
76 
77  // Some corrections are defined in baseTrackerAnalysis
78  baseTrackerAnalysis::DefineCorrections();
79 
80  //------------ Corrections -----------
81 
82  // Change the main fit momentum by the muon alternate momentum, but only for P5
83 #if !VERSION_HAS_EQUIVALENT_MAIN_AND_ALT_FITS
84  if (ND::params().GetParameterI("nueCCAnalysis.Corrections.UseGlobalEleMom.Enable") == 1) {
85  corr().AddCorrection("altmom_corr", new UseGlobalAltMomCorrection(UseGlobalAltMomCorrection::kElectron));
86  }
87 #endif
88 
89 }
90 
91 //********************************************************************
92 void nueCCAnalysis::DefineTruthTree(){
93 //********************************************************************
94 
95  // Variables from baseTrackerAnalysis
96  baseTrackerAnalysis::DefineTruthTree();
97 
98  AddVarF(output(), truelepton_costheta_z, "True Cos(Theta) of the true electron w.r.t z-axis");
99  AddVarF(output(), truelepton_costheta_offaxis, "True Cos(Theta) of the true electron w.r.t off-axis direction");
100  AddVarF(output(), truelepton_costheta_nuDir, "True Cos(Theta) of the true electron w.r.t. nu direction");
101  AddVar4VF(output(), truelepton_pos, "True position of the true electron");
102  AddVarI(output(), truelepton_det, "FGD where the true electron start position is");
103 
104  // Variables to handle the number of targets in xsTool
105  AddVarI(output(), truevtx_mass_component, "mass component enum related to the true vtx position (FGD1 / FGD2_scint / FGD2_water");
106  AddVarF(output(), Q2_true, "true Q2");
107  AddVarI(output(), InitiatorPDG, "Gamma comes from what particle");
108  AddVarI(output(), InitiatorParentPDG, "Initiator parentpdg");
109  AddVarF(output(), InitiatorMom, "initiator momentum");
110  AddVar3VF(output(), InitiatorDir, "initiator direction");
111 
112 }
113 
114 //********************************************************************
115 void nueCCAnalysis::DefineMicroTrees(bool addBase){
116 //********************************************************************
117 
118  // -------- Add variables to the analysis tree ----------------------
119  // Variables from baseTrackerAnalysis
120  if (addBase) baseTrackerAnalysis::DefineMicroTrees(addBase);
121 
122  // Toy variables
123  // Variables to handle the number of targets in xsTool
124  AddToyVarI(output(), truevtx_mass_component, "mass component enum related to the true vtx position (FGD1 / FGD2_scint / FGD2_water");
125 
126  // Recon variables
127  AddToyVarF(output(),selelec_mom, "Recon momentum of the selected track");
128  AddToyVarF(output(),selelec_costheta, "Electron candidate reconstructed polar angle wrt neutrino direction");
129  AddToyVarF(output(),selelec_ENuRec, "The reconstructed neutrino energy, assuming CCQE kinematics");
130  AddToyVarF(output(),selelec_Q2Rec, "The reconstructed Momentum Transfer, assuming CCQE kinematics");
131 
132  if(_addmoretoyvariables){
133  // 1st TPC variables
134  AddToyVarF(output(), selelec_tpcdedx, "First TPC dEdx");
135  AddToyVarF(output(), selelec_pullmuon, "Muon pull in the most upstream TPC");
136  AddToyVarF(output(), selelec_pullelec, "Electron pull in the most upstream TPC");
137  AddToyVarF(output(), selelec_pullpion, "Pion pull in the most upstream TPC");
138  AddToyVarF(output(), selelec_pullprot, "Proton pull in the most upstream TPC");
139 
140  // 2nd TPC variables
141  AddToyVarF(output(), selelec_pullmuon2nd, "Muon pull of the second TPC segment, if the track uses more than 1 TPC");
142  AddToyVarF(output(), selelec_pullelec2nd, "Electron pull of the second TPC segment, if the track uses more than 1 TPC");
143 
144  // Ecal
145  AddToyVarF(output(), selelec_ecalemene, "Reconstructed EM energy deposit (in MeV) of the selected track's ECal segment");
146  }
147  else{
148  // 1st TPC variables
149  AddVarF(output(), selelec_tpcdedx, "First TPC dEdx");
150  AddVarF(output(), selelec_pullmuon, "Muon pull in the most upstream TPC");
151  AddVarF(output(), selelec_pullelec, "Electron pull in the most upstream TPC");
152  AddVarF(output(), selelec_pullpion, "Pion pull in the most upstream TPC");
153  AddVarF(output(), selelec_pullprot, "Proton pull in the most upstream TPC");
154 
155  // 2nd TPC variables
156  AddVarF(output(), selelec_pullmuon2nd, "Muon pull of the second TPC segment, if the track uses more than 1 TPC");
157  AddVarF(output(), selelec_pullelec2nd, "Electron pull of the second TPC segment, if the track uses more than 1 TPC");
158 
159  // Ecal
160  AddVarF(output(), selelec_ecalemene, "Reconstructed EM energy deposit (in MeV) of the selected track's ECal segment");
161  }
162 
163  // Add the standard tree variables
164  AddVarF(output(), selelec_costheta_z, "Recon Cos(Theta) of the selected track w.r.t z-axis");
165  AddVarF(output(), selelec_costheta_offaxis, "Recon Cos(Theta) of the selected track w.r.t. off-axis direction");
166  AddVarF(output(), selelec_phi, "Recon Phi of the selected track");
167  AddVarF(output(), selelec_pt, "Pt of the selected track");
168  AddVar4VF(output(), selelec_startpos, "Recon position of the selected track");
169  AddVar4VF(output(), selelec_startdir, "Recon direction of the selected track");
170  AddVarF(output(), selelec_momErr, "Uncertainty on the reconstructed momentum of the selected track");
171  AddVarF(output(), selelec_momEleFit, "Reconstructed momentum of selected track, assuming the electron hypothesis");
172  AddVarF(output(), selelec_momMuonFit, "Reconstructed momentum of selected track, assuming the muon hypothesis");
173  AddVarF(output(), selelec_ElemomECalEntrance, "Reconstructed momentum of selected track, at the entrance to the ECal");
174  AddVarI(output(), selelec_tpcNNodes, "The number of nodes in the most upstream TPC segment of the selected track");
175  AddVarI(output(), selelec_FGD, "The FGD in which the selected track starts (either 0 or 1)");
176  AddVarF(output(), selelec_ElemomTPCBack, "The momentum of the selected track at the back of the most downstream TPC segment");
177  AddVar4VF(output(), selelec_tpcBackPos, "The position of the selected track at the back of the most downstream TPC segment");
178  AddVar3VF(output(), selelec_tpcBackDir, "The direction of the selected track at the back of the most downstream TPC segment");
179  AddVarI(output(), selelec_inp0d, "Is the main track goes in the P0D");
180 
181  // FGD variables
182  AddVarVI(output(), selelec_fgd_det, "Electron candidate FGD number", selelec_nfgds);
183  AddVarVF(output(), selelec_fgd_x, "Electron candidate track length in each FGD", selelec_nfgds);
184  AddVarVF(output(), selelec_fgd_E, "Electron candidate energy deposit in each FGD", selelec_nfgds);
185  AddVarVF(output(), selelec_fgd_V11, "Electron candidate V11 vertex activity in each FGD", selelec_nfgds);
186  AddVarVF(output(), selelec_fgd_V33, "Electron candidate V33 vertex activity in each FGD", selelec_nfgds);
187  AddVarVF(output(), selelec_fgd_V55, "Electron candidate V55 vertex activity in each FGD", selelec_nfgds);
188  AddVarVF(output(), selelec_fgd_V77, "Electron candidate V77 vertex activity in each FGD", selelec_nfgds);
189  AddVarVF(output(), selelec_fgd_VLayer, "Electron candidate VLayer vertex activity in each FGD", selelec_nfgds);
190  AddVarVF(output(), selelec_fgd_pullmu, "Electron candidate muon pull in each FGD", selelec_nfgds);
191  AddVarVF(output(), selelec_fgd_pullpi, "Electron candidate pion pull in each FGD", selelec_nfgds);
192  AddVarVF(output(), selelec_fgd_pullprot, "Electron candidate protn pull in each FGD", selelec_nfgds);
193  AddVarVI(output(), selelec_fgd_containment, "Electron candidate containment in each FGD", selelec_nfgds);
194 
195  // ECal variables
196  AddVarI(output(), selelec_nECALs, "Number of Ecal clusters found");
197  AddVarI(output(), selelec_ecaldetector, "The detector in which the selected track's ECal segment was found, DsECal is 6. Barrel ECal: 7- top, 8-bottom, 9-left, 10-right ");
198  AddVarI(output(), selelec_ecalnhits, "The number of hits in the selected track's ECal segment");
199  AddVarI(output(), selelec_ecalMostUpStreamLayerHit,"The first layer hit in the selected track's ECal segment");
200  AddVarF(output(), selelec_ecalmipem, "MipEm value of the selected track's ECal segment, if it uses the DSECal. Negative means more MIP-like, positive means more EM shower-like.");
201  AddVarF(output(), selelec_ecalmippion, "MipPion value of the selected track's ECal segment");
202  AddVarF(output(), selelec_ecalemhip, "EmHip value of the selected track's ECal segment");
203  AddVarI(output(), selelec_ecalcontained, "Whether the selected track's ECal segment is 'contained' or not, according to the definition used in the analysis");
204  AddVar3VF(output(), selelec_ecalshowerpos, "The reconstructed position of the selected track's ECal segment (according to the shower-based reconstruction)");
205  AddVarF(output(), selelec_ecallength, "Length of the ECal segment");
206 
207  // ToF
208  AddVarF(output(), selelec_ToF_P0D_FGD1, "ToF between P0D and FGD1");
209  AddVarF(output(), selelec_ToF_ECal_FGD1, "ToF between BrEcal and FGD1");
210  AddVarF(output(), selelec_ToF_ECal_FGD2, "ToF between BrEcal and FGD2");
211  AddVarF(output(), selelec_ToF_FGD1_FGD2, "ToF between FGD1 and FGD2");
212  AddVarF(output(), selelec_ToF_DsECal_FGD1, "ToF between DsEcal and FGD1");
213  AddVarF(output(), selelec_ToF_DsECal_FGD2, "ToF between DsEcal and FGD2");
214 
215  // Truth variables of the selected track (taken from true track)
216  AddVarI(output(), selelec_true_pdg, "PDG code of true particle");
217  AddVarF(output(), selelec_true_mom, "True momentum of the selected track");
218  AddVar4VF(output(), selelec_true_pos, "True position of the selected track");
219  AddVar4VF(output(), selelec_true_endpos, "True endposition of the selected track");
220  AddVar3VF(output(), selelec_true_dir, "True directionof the selected track");
221  AddVarF(output(), selelec_true_costheta_z, "True Cos(Theta) of the selected track w.r.t z-axis");
222  AddVarF(output(), selelec_true_costheta_offaxis, "True Cos(Theta) of the selected track w.r.t off-axis direction");
223  AddVarF(output(), selelec_true_costheta_nuDir, "True Cos(Theta) of the selected track w.r.t nu direction");
224 
225  // truth variables of true electron (taken from true vertex)
226  AddVarI(output(), truelepton_pdg, "Pdg of the true lepton");
227  AddVarI(output(), truelepton_det, "Detector where the true lepton start position is");
228  AddVarF(output(), truelepton_mom, "True momentum of the true lepton");
229  AddVarF(output(), truelepton_costheta_z, "True Cos(Theta) of the true lepton w.r.t. z-axis");
230  AddVarF(output(), truelepton_costheta_nuDir, "True Cos(Theta) of the true lepton w.r.t. nu direction");
231  AddVarF(output(), truelepton_costheta_offaxis, "True Cos(Theta) of the true lepton w.r.t off-axis direction");
232  AddVar4VF(output(), truelepton_pos, "True position of the true lepton");
233  AddVar3VF(output(), truelepton_dir, "True direction of the true lepton");
234  AddVarF(output(), truelepton_nuErecQE, "Neutrino reconstructed energy with true lepton kinematics in ccqe formula");
235  AddVarI(output(), InitiatorPDG, "Gamma comes from what particle");
236  AddVarI(output(), InitiatorParentPDG, "Initiator parentpdg");
237  AddVarF(output(), InitiatorMom, "initiator momentum");
238  AddVar3VF(output(), InitiatorDir, "initiator direction");
239 
240  // TPC veto variables
241  AddVarF(output(), TPCVetoDeltaz, "Z difference between the selected track and the track used in the TPC1 veto");
242  AddVarF(output(), TPCVetoMomentum, "Momentum of the track used in the TPC1 veto");
243  AddVarI(output(), TPCVetoCharge, "Charge (+1/-1) of the track used in the TPC1 veto.");
244  AddVarI(output(), TPCVetoNNearP0DTracks, "Number of FGD-TPC tracks near the vertex entering the P0D");
245  AddVarI(output(), TPCVetoNNearTracks, "Number of FGD-TPC tracks near the vertex");
246  AddVarI(output(), TPCVetoNFarTracks, "Number of FGD-TPC tracks far from vertex");
247  AddVarF(output(), SecMomFGDDeltaZ, "DZ between the selected track and the second most energetic track in the same FGD");
248 
249  // P0D veto variables
250  AddVarI(output(), NP0DVetoP0DTracks, "Number of reconstructed objects in the P0D FV");
251  AddVarI(output(), NP0DVetoFGD1Tracks, "Number of reconstructed objects in the FGD1 FV");
252  AddVarI(output(), NP0DVetoP0DEcalTracks, "Number of P0DEcal objects");
253  AddVarI(output(), FGD2ShowerNFGD1TPC2Tracks, "Number of FGD1-TPC2 tracks used in the FGD2 shower cut");
254  AddVarI(output(), FGD2ShowerNFGD2TPC3Tracks, "Number of FGD2-TPC3 tracks used in the FGD2 shower cut");
255  AddVarI(output(), FGDOOFVActivity, "Check for OOFV FGD Iso");
256  AddVarI(output(), NFGDOOFVTracksReqTPC, "Number of OOFV FGD-TPC tracks");
257 
258  // ECal veto variables
259  AddVarF(output(), ECALMinZ, "Z distance between the selected track and the most upstream ECal segment");
260  AddVarF(output(), ECALNCMinZ, "Z distance between the selected track and the most upstream ECal neutral cluster segment");
261  AddVarF(output(), TPCECALdist, "Distance between the end of the most downstream TPC segment of the selected track and the nearest ECal track");
262  AddVar3VF(output(), ECALPosECALSegment, "Position of the ECal segment of the closest ECal track to the selected track");
263  AddVar3VF(output(), ECALPosGlobalTrack, "Start position of the closest ECal track to the selected track");
264  AddVar3VF(output(), ECALTrueVertexPos, "True vertex position of the closest ECal track to the selected track");
265 
266  // Pair-finder variables
267  AddVarF(output(), PairTrack_mom, "Momentum of the matched e-/e+ pair");
268  AddVarF(output(), PairTrack_costheta, "Angle of the matched e-/e+ pair");
269  AddVarI(output(), PairTrack_pdg, "Pdg of the matched e-/e+ pair");
270  AddVarF(output(), PairTrack_InvMass, "Invariant mass of the matched e-/e+ pair");
271  AddVar4VF(output(), PairTrack_startdir, "Recon direction of the matched e-/e+ paired track");
272  AddVar4VF(output(), PairTrack_startpos, "Recon position of the matched e-/e+ paired track");
273  AddVar4VF(output(), PairTrack_true_startdir, "True direction of the matched e-/e+ paired track");
274  AddVar4VF(output(), PairTrack_true_startpos, "True position of the matched e-/e+ paired track");
275  AddVarI(output(), PairTrack_tpcNNodes, "Number of TPC hits of the matched e-/e+ pair");
276 
277  AddVarF(output(), TruePairTrack_true_mom, "Momentum of the true paired track from gamma background");
278  AddVarI(output(), TruePairTrack_pdg, "PDG of the true paired track from gamma background");
279  AddVarF(output(), selelec_parent_true_mom, "Momentum of the selected track's parent - only for background events");
280  AddVarI(output(), selelec_parent_pdg, "PDG of the selected track's parent - only for background events");
281  AddVarF(output(), selelec_gparent_true_mom, "Momentum of the selected tracks's grandparent - only for background events");
282  AddVarI(output(), selelec_gparent_pdg, "PDG of the selected tracks's grandparent - only for background events");
283 
284  // Truth variables
285  AddVarI(output(), NuParentPDGRaw, "True parent that decayed to create the neutrino");
286  AddVarI(output(), TargetPDG, "True target of the neutrino Int_teraction (oxygen, carbon etc.)");
287  AddVar4VF(output(), NuParentDecPoint, "True position at which the neutrino was created");
288  AddVarI(output(), NTruePions, "Number of true pions ejected from the nucleus");
289  AddVarI(output(), NTruePi0, "Number of true pi0 ejected from the nucleus");
290  AddVarI(output(), NTrueKaonRhoEta, "Number of true kaons-rhos-etas ejected from the nucleus");
291  AddVarF(output(), Q2_true, "true Q2");
292 
293  // All secondary FGD-TPC tracks
294  if(_savesecondaries){
295  AddVarVI(output(), FGDTPCTrack_det, "FGD detector of the FGD-TPC track", Nfgdtpc);
296  AddVarVF(output(), FGDTPCTrack_mom, "Recon momentum FGD-TPC track", Nfgdtpc);
297  AddVarVF(output(), FGDTPCTrack_charge, "Charge FGD-TPC track", Nfgdtpc);
298  AddVarVF(output(), FGDTPCTrack_costheta, "Recon cos(theta) FGD-TPC track", Nfgdtpc);
299  AddVarMF(output(), FGDTPCTrack_startpos, "Recon position FGD-TPC track", Nfgdtpc, -40 ,4);
300  AddVarMF(output(), FGDTPCTrack_startdir, "Recon direction FGD-TPC track", Nfgdtpc, -40, 3);
301  AddVarVF(output(), FGDTPCTrack_pullmuon, "Muon pull FGD-TPC track", Nfgdtpc);
302  AddVarVF(output(), FGDTPCTrack_pullelec, "Electron pullFGD-TPC track", Nfgdtpc);
303  AddVarVF(output(), FGDTPCTrack_pullpion, "Pion pull FGD-TPC track", Nfgdtpc);
304  AddVarVF(output(), FGDTPCTrack_pullprot, "Proton pull FGD-TPC track", Nfgdtpc);
305  AddVarVI(output(), FGDTPCTrack_tpcNNodes, "TPC nodes FGD-TPC track", Nfgdtpc);
306  AddVarVI(output(), FGDTPCTrack_pdg, "PDG FGD-TPC track", Nfgdtpc);
307 
308  AddVarVF(output(), FGDTPCTrack_MomECalEntrance, "Momentum at the entrance of the Ecal", Nfgdtpc);
309  AddVarVF(output(), FGDTPCTrack_EMEnergy, "Ecal EM Energy", Nfgdtpc);
310  AddVarVF(output(), FGDTPCTrack_MipEm, "Ecal MipEm", Nfgdtpc);
311  AddVarVF(output(), FGDTPCTrack_MipPion, "Ecal MipPion", Nfgdtpc);
312  AddVarVF(output(), FGDTPCTrack_EmHip, "Ecal EmHip", Nfgdtpc);
313  AddVarMF(output(), FGDTPCTrack_ShowerPosition, "Ecal Shower Position", Nfgdtpc, -40 ,4);
314  AddVarVI(output(), FGDTPCTrack_ECALdet, "Ecal detector", Nfgdtpc);
315  AddVarVI(output(), FGDTPCTrack_NHits, "Ecal number of shower hits", Nfgdtpc);
316  AddVarVI(output(), FGDTPCTrack_MostUpStreamLayerHit, "Ecal first layer", Nfgdtpc);
317  AddVarVI(output(), FGDTPCTrack_IsEcalContained, "Ecal containtment", Nfgdtpc);
318 
319  AddVarVI(output(), fgdiso_det, "In which FGD is the FGD-iso selected", NisoFgds);
320  AddVarVF(output(), fgdiso_x, "Length of the FGD-iso tracks", NisoFgds);
321  AddVarVF(output(), fgdiso_E, "Energy deposit of the FGD-iso tracks", NisoFgds);
322  AddVarVF(output(), fgdiso_pullmu, "Muon pull of the FGD-iso tracks", NisoFgds);
323  AddVarVF(output(), fgdiso_pullpi, "Pion pull of the FGD-iso tracks", NisoFgds);
324  AddVarVF(output(), fgdiso_pullprot, "Proton pull of the FGD-iso tracks", NisoFgds);
325  AddVarMF(output(), fgdiso_position, "Recon position of the the FGD-iso tracks",NisoFgds,-40,4);
326  AddVarVI(output(), fgdiso_containment, "Containment of the FGD-iso tracks", NisoFgds);
327  AddVarVF(output(), fgdiso_costheta, "Cos(theta) of the FGD-iso tracks", NisoFgds);
328  AddVarVI(output(), fgdiso_pdg, "PDG of the FGD-iso tracks", NisoFgds);
329 
330  // Michel variables
331  AddVarI(output(), NME, "Number of Michel electrons in the event FGD. (For P5 this only applies to FGD1 events)");
332 
333  AddVarI(output(), NFGDTracksReqTPC, "Number of FGD-TPC tracks in the same FGD as the selected track");
334  AddVarI(output(), NFGD1TracksReqTPC1, "Number of FGD1-TPC1 tracks");
335  AddVarI(output(), NFGD1TracksReqTPC2, "Number of FGD1-TPC2 tracks");
336  AddVarI(output(), NFGD2TracksReqTPC2, "Number of FGD2-TPC2 tracks");
337  AddVarI(output(), NFGD2TracksReqTPC3, "Number of FGD2-TPC3 tracks");
338  AddVarI(output(), NFGD1TracksReqEcal, "Number of FGD1-Ecal tracks");
339  AddVarI(output(), NFGD2TracksReqEcal, "Number of FGD2-Ecal tracks");
340  AddVarF(output(), FGDDistanceReqTpc, "Distance between the selected track and the nearest FGD-TPC track");
341  AddVarF(output(), FGDMaxDistanceReqTpc, "Distance between the selected track and the most far away FGD-TPC track");
342  AddVarF(output(), FGDDistanceNoReqTpc, "Distance between the selected track and the nearest FGD-TPC or FGD-only track");
343  AddVarF(output(), FGDMaxDistanceNoReqTpc, "Distance between the selected track and the most far away FGD-TPC or FGD-only track");
344  AddVarF(output(), FGD2XYMaxTrackDist, "Maximum XY distance of any tracks in FGD2");
345 
346  // Neutral clusters and brem
347  AddVarI(output(), NECalTracks, "Number of ECal tracks that aren't attached to the selected track");
348  AddVarI(output(), NDsEcalNeutralClusters, "Number of DsEcal neutral cluster");
349  AddVarI(output(), NBrEcalNeutralClusters, "Number of BrEcal neutral cluster");
350  AddVarF(output(), MostEnergeticEcalNeutralCluster, "Most energetic ecal neutral cluster");
351  AddVarF(output(), EcalNeutralClusterEnergySum, "The energy sum of the all the ecal neutral clusters");
352  AddVarI(output(), EcalClusterMostEnergeticThanHMT, "Number of Tracker-ECal tracks that aren't the HM track and have EMEnergy larger than the momentum of the HM track");
353  AddVarI(output(), BremNeutralClusters, "Number of ECal neutral cluster selected as Brem candidates associated with the HM track");
354  AddVarF(output(), BremNeutralClustersEnergy, "Energy of the ECal neutral cluster selected as Brem candidates associated with the HM track");
355  AddVarF(output(), BremNeutralClustersMinTheta, "Minimum theta of the ECal neutral cluster selected as Brem candidates associated with the HM track");
356  AddVarF(output(), BremNeutralClustersMinPhi, "Minimum phi of the ECal neutral cluster selected as Brem candidates associated with the HM track");
357  AddVarI(output(), FragmentsNeutralClusters, "Number of ECal neutral cluster classified as shower fragments from the main shower");
358  AddVarF(output(), FragmentsDistanceToShower, "Distance of the fragment ecal shower to electron shower");
359  AddVarI(output(), NTPCTracksReqEcal, "Number of TPC-Ecal tracks");
360  }
361 
362 }
363 
364 //********************************************************************
365 void nueCCAnalysis::FillMicroTrees(bool addBase){
366 //********************************************************************
367 
368  // Variables from baseTrackerAnalysis
369  if (addBase) baseTrackerAnalysis::FillMicroTreesBase(addBase);
370 
371  if (!box().MainTrack) return;
372 
373  // Save the basic variables
374  FillTrackVars();
375  FillTPCVetoVars();
376  FillP0DVetoVars();
377  FillECalVetoVars();
378  FillPairFinderVars();
379  FillTruthVars();
380  FillToFVars();
381 
382  if(_savesecondaries){
383  FillMichelVars();
384  FillEcalNeutralClusterVars();
385  FillAllTracksVars();
386  }
387 }
388 
389 //********************************************************************
390 void nueCCAnalysis::FillTruthVars() {
391 //********************************************************************
392 
393  AnaTrack* track = static_cast<AnaTrack*> ( box().MainTrack );
394  if (!track) return;
395 
396  if(!track->GetTrueParticle()) return;
397 
398  // True Track
399  AnaTrueParticle* truth = static_cast<AnaTrueParticle*> (box().MainTrack->TrueObject);
400  if(!truth) return;
401 
402  output().FillVar(selelec_true_pdg, truth->PDG);
403  output().FillVar(selelec_true_mom, truth->Momentum);
404  output().FillVectorVarFromArray(selelec_true_pos, truth->Position, 4);
405  output().FillVectorVarFromArray(selelec_true_endpos, truth->PositionEnd, 4);
406  output().FillVectorVarFromArray(selelec_true_dir, truth->Direction, 3);
407 
408  Float_t selelec_true_cosT_z = truth->Direction[2];
409  output().FillVar(selelec_true_costheta_z, selelec_true_cosT_z);
410 
411  // ND280 position to get off-axis angle
412  Float_t _nd280_pos[3] = {-3.221999, -8.14599, 280.10};
413 
414  Float_t selelec_true_cosT_offaxis = (Float_t)cos(anaUtils::ArrayToTVector3(truth->Direction).Angle(_nd280_pos));
415  output().FillVar(selelec_true_costheta_offaxis, selelec_true_cosT_offaxis);
416 
417  // True Vertex
418  AnaTrueVertex* vtx = static_cast<AnaTrueVertex*> (box().MainTrack->GetTrueParticle()->TrueVertex);
419  if(!vtx) return;
420 
421  Float_t selelec_true_cosT_nuDir = (Float_t)cos(anaUtils::ArrayToTVector3(truth->Direction).Angle(anaUtils::ArrayToTVector3(vtx->NuDir)));
422  output().FillVar(selelec_true_costheta_nuDir, selelec_true_cosT_nuDir);
423 
424  output().FillVar(NuParentPDGRaw, vtx->NuParentPDG);
425  output().FillVar(TargetPDG, vtx->TargetPDG);
426  output().FillVectorVarFromArray(NuParentDecPoint, vtx->NuParentDecPoint, 4);
427 
428  // Truth variables to match the truth tree for xsTool/consistency
429  // True electron true variables
430  output().FillVar(truelepton_pdg, vtx->LeptonPDG);
431  output().FillVar(truelepton_mom, vtx->LeptonMom);
432  output().FillVar(truelepton_det, anaUtils::GetDetector(vtx->Position));
433  Float_t trueelec_true_cosT_z = anaUtils::ArrayToTLorentzVector(vtx->LeptonDir).CosTheta();
434  output().FillVar(truelepton_costheta_z, trueelec_true_cosT_z);
435 
436  Float_t trueelec_true_cosT_offaxis = (Float_t)cos( anaUtils::ArrayToTVector3(vtx->LeptonDir).Angle(_nd280_pos) ) ;
437  output().FillVar(truelepton_costheta_offaxis, trueelec_true_cosT_offaxis);
438 
439  Float_t trueelec_true_cosT_nuDir = (Float_t)cos( anaUtils::ArrayToTVector3(vtx->LeptonDir).Angle(anaUtils::ArrayToTVector3(vtx->NuDir) ) );
440  output().FillVar(truelepton_costheta_nuDir, trueelec_true_cosT_nuDir);
441 
442  Float_t Erec = anaUtils::ComputeRecNuEnergyCCQE(vtx->LeptonMom, units::mass_electron, trueelec_true_cosT_nuDir);
443  output().FillVar(truelepton_nuErecQE, Erec);
444 
445  output().FillVar(Q2_true, anaUtils::ComputeQ2(vtx->LeptonMom, units::mass_electron, trueelec_true_cosT_nuDir, vtx->NuEnergy));
446 
447  output().FillVectorVarFromArray(truelepton_dir, vtx->LeptonDir,3);
448  output().FillVectorVarFromArray(truelepton_pos, vtx->Position, 4);
449 
450  // True particles exiting nucleus
451  output().FillVar(NTruePions, nue_categs::NpiC(*vtx));
452  output().FillVar(NTruePi0, nue_categs::Npi0(*vtx));
453  output().FillVar(NTrueKaonRhoEta, nue_categs::NKaonRhoEta(*vtx));
454 
455  const AnaTrueVertex *vtx1 = static_cast<const AnaTrueVertex*>(vtx);
456  AnaTrueParticleB* Init=NULL;
457 
458  if(vtx1)
459  Init = GoBackToPrimaryParticle(box().MainTrack->GetTrueParticle(), vtx1);
460 
461  if(Init){
462  output().FillVar(InitiatorPDG, (Int_t) Init->PDG);
463  output().FillVar(InitiatorParentPDG, (Int_t) Init->ParentPDG);
464  output().FillVar(InitiatorMom, (Float_t)Init->Momentum);
465  output().FillVectorVarFromArray(InitiatorDir, Init->Direction, 3);
466  }
467 
468  // Get (grad)parent momentum
469  AnaTrueParticle* parent = static_cast<AnaTrueParticle*> ( anaUtils::GetTrueParticleByID(static_cast<const AnaEventB&> (GetEvent()), truth->ParentID) );
470  if(!parent) return;
471 
472  output().FillVar(selelec_parent_true_mom, parent->Momentum);
473  output().FillVar(selelec_parent_pdg, parent->PDG);
474 
475  AnaTrueParticle* gparent = static_cast<AnaTrueParticle*> ( anaUtils::GetTrueParticleByID(static_cast<const AnaEventB&> (GetEvent()), parent->ParentID) );
476  if(gparent){
477  output().FillVar(selelec_gparent_true_mom, gparent->Momentum);
478  output().FillVar(selelec_gparent_pdg, gparent->PDG);
479  }
480 
481  // Find pair track for the gamma background
482  for(int i = 0; i < vtx->nTrueParticles; i++){
483  AnaTrueParticle* ttruth = static_cast<AnaTrueParticle*> (vtx->TrueParticles[i]);
484  if(ttruth == truth) continue;
485  if(ttruth->ParentID == parent->ID){
486  output().FillVar(TruePairTrack_true_mom, ttruth->Momentum);
487  output().FillVar(TruePairTrack_pdg, ttruth->PDG);
488  break;
489  }
490  }
491 
492 }
493 
494 
495 //********************************************************************
496 void nueCCAnalysis::FillTrackVars() {
497 //********************************************************************
498 
499  AnaTrack* track = static_cast<AnaTrack*> (box().MainTrack);
500  if (!track) return;
501 
502  Float_t selelec_cosT_z = track->DirectionStart[2];
503  output().FillVar(selelec_costheta_z, selelec_cosT_z);
504 
505  // ND280 position to get off-axis angle
506  Float_t _nd280_pos[3] = {-3.221999, -8.14599, 280.10};
507 
508  Float_t selelec_cosT_offaxis = (Float_t)cos(anaUtils::ArrayToTVector3(track->DirectionStart).Angle(_nd280_pos));
509  output().FillVar(selelec_costheta_offaxis, selelec_cosT_offaxis);
510 
511  Float_t cosT = selelec_cosT_z;
512  Float_t phia = anaUtils::ArrayToTLorentzVector(track->DirectionStart).Phi();
513  //Float_t invpt = anaUtils::ComputeInversePT(*box().MainTrack);
514  Float_t invpt = (track->Momentum)*sqrt((1-cosT*cosT));
515 
516  output().FillVar(selelec_phi, phia);
517  output().FillVar(selelec_pt, invpt);
518  output().FillVectorVarFromArray(selelec_startpos, track->PositionStart, 4);
519  output().FillVectorVarFromArray(selelec_startdir, track->DirectionStart, 4);
520 
521  output().FillVar(selelec_momErr, track->MomentumError);
522  output().FillVar(selelec_momEleFit, track->MomentumEle);
523  output().FillVar(selelec_momMuonFit, track->MomentumMuon);
524 
525  output().FillVar(selelec_FGD, anaUtils::GetDetector(track->PositionStart));
526 
527  AnaTPCParticle* backTpc = static_cast<AnaTPCParticle*> (anaUtils::GetTPCBackSegment(track));
528 
529  if(backTpc){
530  output().FillVar(selelec_ElemomTPCBack, backTpc->MomentumEnd);
531  output().FillVectorVarFromArray(selelec_tpcBackPos, backTpc->PositionEnd, 4);
532  output().FillVectorVarFromArray(selelec_tpcBackDir, track->DirectionEnd, 3);
533  }
534 
536  if(TpcSegment)
537  output().FillVar(selelec_tpcNNodes, TpcSegment->NNodes);
538 
539  FillFirstTPCVars();
540  FillSecondTPCVars();
541  FillECalVars();
542  FillFGDVars();
543 }
544 
545 //********************************************************************
546 void nueCCAnalysis::FillFirstTPCVars() {
547 //********************************************************************
548 
549  if(!_addmoretoyvariables){
550  AnaTrackB* track = box().MainTrack;
551  if (!track) return;
552 
554  if(!longCloseTPC ) return;
555 
556  output().FillVar(selelec_tpcdedx, longCloseTPC->dEdxMeas);
557  output().FillVar(selelec_pullmuon, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpMuon)/longCloseTPC->dEdxSigmaMuon);
558  output().FillVar(selelec_pullelec, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpEle)/longCloseTPC->dEdxSigmaEle);
559  output().FillVar(selelec_pullpion, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpPion)/longCloseTPC->dEdxSigmaPion);
560  output().FillVar(selelec_pullprot, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpProton)/longCloseTPC->dEdxSigmaProton);
561  }
562 }
563 
564 //********************************************************************
565 void nueCCAnalysis::FillSecondTPCVars() {
566 //********************************************************************
567 
568  if(!_addmoretoyvariables){
569  AnaTrackB* track = box().MainTrack;
570  if (!track) return;
571 
572  if(anaUtils::InDetVolume(SubDetId::kFGD1, track->PositionStart)){
573  AnaTPCParticleB* longestTPC3 = static_cast<AnaTPCParticleB*>(anaUtils::GetSegmentWithMostNodesInDet(*track,SubDetId::kTPC3));
574 
575  if(!longestTPC3) return;
576  // Pass track quality cut
577  if(!cutUtils::TPCTrackQualityCut(*longestTPC3)) return;
578 
579  output().FillVar(selelec_pullmuon2nd, (longestTPC3->dEdxMeas-longestTPC3->dEdxexpMuon)/longestTPC3->dEdxSigmaMuon);
580  output().FillVar(selelec_pullelec2nd, (longestTPC3->dEdxMeas-longestTPC3->dEdxexpEle)/longestTPC3->dEdxSigmaEle);
581  }
582  }
583 }
584 //********************************************************************
585 void nueCCAnalysis::FillECalVars() {
586 //********************************************************************
587 
588  AnaTrackB* track = box().MainTrack;
589  if (!track) return;
590 
591  AnaECALParticleB* ecaltracks[100];
592  Int_t nECAL = anaUtils::GetTrackerDsEcals(box().MainTrack, ecaltracks);
593 
594  if(nECAL >=1 && nueCCUtils::UseEcal(box().MainTrack) ){
595 
596  AnaECALParticle* EcalSegment = static_cast<AnaECALParticle*> (ecaltracks[nECAL - 1]);
597  //AnaECALParticleB* EcalSegmentB = ecaltracks[nECAL - 1];
598  if(!EcalSegment) return;
599 
601  Int_t detector = ECALdet;
602 
603  AnaTPCParticle* backTPC = static_cast<AnaTPCParticle*> (anaUtils::GetTPCBackSegment(box().MainTrack));
604  output().FillVar(selelec_ElemomECalEntrance, backTPC->Momentum);
605 
606  if(!_addmoretoyvariables)
607  output().FillVar(selelec_ecalemene, EcalSegment->EMEnergy);
608 
609  output().FillVar(selelec_ecalmipem, EcalSegment->PIDMipEm);
610  output().FillVar(selelec_ecalmippion, EcalSegment->PIDMipPion);
611  output().FillVar(selelec_ecalemhip, EcalSegment->PIDEmHip);
612  output().FillVectorVarFromArray(selelec_ecalshowerpos, EcalSegment->ShowerPosition, 3 );
613  output().FillVar(selelec_ecallength,EcalSegment->Length);
614  output().FillVar(selelec_ecalnhits, EcalSegment->NHits);
615  output().FillVar(selelec_ecalMostUpStreamLayerHit, EcalSegment->MostUpStreamLayerHit);
616  output().FillVar(selelec_ecalcontained, nueCCUtils::IsEcalContained(EcalSegment));
617  output().FillVar(selelec_ecaldetector, detector);
618  }
619 
620  output().FillVar(selelec_nECALs, nECAL);
621 }
622 
623 //********************************************************************
624 void nueCCAnalysis::FillTPCVetoVars() {
625 //********************************************************************
626 
627  if(!box().MainTrack) return;
628 
629  output().FillVar(TPCVetoNNearTracks, nuebox().TPCVetoNearTracks);
630  output().FillVar(TPCVetoNFarTracks, nuebox().TPCVetoFarTracks);
631  output().FillVar(TPCVetoNNearP0DTracks, nuebox().TPCVetoP0DNearTracks);
632 
633  //
634  AnaTrackB* SecFGCTPCTrack = nuebox().SecondMostEnergeticFGDTPCTrack;
635  Float_t DZ = -999.0;
636  if(SecFGCTPCTrack){
637  DZ = box().MainTrack->PositionStart[2]-SecFGCTPCTrack->PositionStart[2];
638  }
639 
640  output().FillVar(SecMomFGDDeltaZ, DZ);
641 
642  //
643  Int_t fgdoofv = -1;
644  if(nuebox().OOFVtrack)
645  fgdoofv = 1;
646 
647  output().FillVar(FGDOOFVActivity, fgdoofv);
648  output().FillVar(NFGDOOFVTracksReqTPC, nuebox().NOOFVTracks);
649  //
650 
651  AnaTrackB* VetoTrack = nuebox().VetoTrack;
652  if(!VetoTrack) return;
653 
654  Float_t hmnZstart = box().MainTrack->PositionStart[2];
655  Float_t vetoZ = VetoTrack->Original->Original->PositionStart[2];
656  Float_t deltaZ = vetoZ - hmnZstart;
657 
658  Float_t mom = VetoTrack->Momentum;
659  Int_t charge = VetoTrack->Charge;
660 
661  output().FillVar(TPCVetoDeltaz, deltaZ);
662  output().FillVar(TPCVetoMomentum, mom);
663  output().FillVar(TPCVetoCharge, charge);
664 }
665 
666 //********************************************************************
667 void nueCCAnalysis::FillPairFinderVars() {
668 //********************************************************************
669 
670  AnaTrackB* track = nuebox().MainTrack;
671  if (!track ) return;
672 
673  // pair track
674  AnaTrackB* pairtrack = nuebox().PairTrack;
675  if (!pairtrack ) return;
676  // pair track truth
677  AnaTrueParticle* pair_truth = static_cast<AnaTrueParticle*> (pairtrack->TrueObject);
678 
679  // Fill the output tree
680  output().FillVar(PairTrack_mom, pairtrack->Momentum);
681  output().FillVar(PairTrack_costheta, pairtrack->DirectionStart[2]);
682 
683  Float_t mass = 0.511;
684  TLorentzVector secondary_PE = nueCCUtils::GetMomLorentzVector(*pairtrack, mass);
685  TLorentzVector primary_PE = nueCCUtils::GetMomLorentzVector(*track, mass);
686  Float_t minv = 2. * mass * mass + 2. * (secondary_PE.Dot(primary_PE));
687 
688  if(minv > 0)
689  minv = sqrt(minv);
690 
691  output().FillVar(PairTrack_InvMass, minv);
692 
693  // recon pair track dir
694  output().FillVectorVarFromArray(PairTrack_startdir, pairtrack->DirectionStart, 4);
695  output().FillVectorVarFromArray(PairTrack_startpos, pairtrack->PositionStart, 4);
696 
698  if(TpcSegment)
699  output().FillVar(PairTrack_tpcNNodes, TpcSegment->NNodes);
700 
701  if(pair_truth){
702  output().FillVectorVarFromArray(PairTrack_true_startdir, pair_truth->Direction, 4);
703  output().FillVectorVarFromArray(PairTrack_true_startpos, pair_truth->Position, 4);
704  output().FillVar(PairTrack_pdg, pair_truth->PDG);
705  }
706 }
707 
708 //********************************************************************
709 void nueCCAnalysis::FillP0DVetoVars() {
710 //********************************************************************
711 
712  output().FillVar(NP0DVetoP0DTracks, nuebox().P0DVetoP0DTracks);
713  output().FillVar(NP0DVetoFGD1Tracks, nuebox().P0DVetoFGD1Tracks);
714  output().FillVar(NP0DVetoP0DEcalTracks, nuebox().P0DVetoP0DEcalTracks);
715 
716  // Temporary
717  output().FillVar(FGD2ShowerNFGD1TPC2Tracks, nuebox().FGD2ShowerNFGD1TPC2Tracks);
718  output().FillVar(FGD2ShowerNFGD2TPC3Tracks, nuebox().FGD2ShowerNFGD2TPC3Tracks);
719 
720  AnaTrackB* track = nuebox().MainTrack;
721  if(track)
722  output().FillVar(selelec_inp0d, anaUtils::TrackUsesDet(*track, SubDetId::kP0D));
723 }
724 
725 //********************************************************************
726 void nueCCAnalysis::FillECalVetoVars() {
727 //********************************************************************
728 
729  AnaTrackB* track = nuebox().MainTrack;
730  AnaTrackB* ecal = nuebox().ECalVetoTrack;
731 
732  if (!track || !ecal) return;
733 
734  Float_t start_z = track->PositionStart[2];
735  Float_t ecal_z = 0;
737 
738  if (ecaltrack){
739  ecal_z = ecaltrack->PositionStart[2];
740  if (ecaltrack->PositionEnd[2] < ecaltrack->PositionStart[2])
741  ecal_z = ecaltrack->PositionEnd[2];
742 
743  Float_t* ecal_pos = ecaltrack->PositionStart;
744  if (ecaltrack->PositionEnd[2] < ecaltrack->PositionStart[2])
745  ecal_pos = ecaltrack->PositionEnd;
746  output().FillVectorVarFromArray(ECALPosECALSegment, ecal_pos, 3);
747 
748  }
749 
750  output().FillVar(ECALMinZ, ecal_z - start_z);
751 
752 
753  Float_t ecaldist = (anaUtils::ArrayToTVector3(ecal->PositionStart) - anaUtils::ArrayToTVector3(track->PositionStart)).Mag();
754  output().FillVar(TPCECALdist, ecaldist);
755 
756  output().FillVectorVarFromArray(ECALPosGlobalTrack, ecal->PositionStart, 3);
757 
758  if(ecal->GetTrueParticle() && ecal->GetTrueParticle()->TrueVertex)
759  output().FillVectorVarFromArray(ECALTrueVertexPos, ecal->GetTrueParticle()->TrueVertex->Position, 3);
760 
761  // Look for ecal neutral clusters
762  AnaTrackB* ecalB = nuebox().ECalNCVetoTrack;
763  if(ecalB){
764  AnaECALParticleB* ecaltrackB = nueCCUtils::GetMostUpstreamECalNCSegment(ecalB);
765  ecal_z = 0;
766  if (ecaltrackB){
767  ecal_z = ecaltrackB->PositionStart[2];
768  if (ecaltrackB->PositionEnd[2] < ecaltrackB->PositionStart[2])
769  ecal_z = ecaltrackB->PositionEnd[2];
770 
771  output().FillVar(ECALNCMinZ, ecal_z - start_z);
772  }
773  }
774 
775 }
776 
777 //********************************************************************
778 void nueCCAnalysis::FillMichelVars() {
779 //********************************************************************
780 
781  if(!box().MainTrack) return;
782 
784  if(anaUtils::GetDetector(box().MainTrack->PositionStart) == 0) det = SubDetId::kFGD1;
785  else if(anaUtils::GetDetector(box().MainTrack->PositionStart) == 1) det = SubDetId::kFGD2;
786 
787  AnaFgdTimeBinB* michels[100];
788  int fgd_nMichels;
789 
790  if( _p5 ==1 ){ // P5
791  fgd_nMichels = anaUtils::GetFGDMichelElectrons(GetEvent(), SubDetId::kFGD1, michels, true);
792  if(det==SubDetId::kFGD2) fgd_nMichels =0;
793  }
794  else { // P6
795  fgd_nMichels = anaUtils::GetFGDMichelElectrons(GetEvent(), det, michels, false);
796  }
797 
798  output().FillVar(NME, fgd_nMichels);
799 }
800 
801 //********************************************************************
802 void nueCCAnalysis::FillFGDVars() {
803 //********************************************************************
804 
805  AnaTrackB* HMTrack = box().MainTrack;
806  if (!HMTrack) return;
807 
808  for (Int_t subdet = 0; subdet<2; subdet++) {
809  if (!SubDetId::GetDetectorUsed(HMTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet))) continue;
810  AnaFGDParticle* FGDSegment = static_cast<AnaFGDParticle*>(anaUtils::GetSegmentInDet(*HMTrack,static_cast<SubDetId::SubDetEnum >(subdet)));
811  if (!FGDSegment) continue;
812 
813  output().FillVectorVar(selelec_fgd_det, subdet);
814  output().FillVectorVar(selelec_fgd_x, FGDSegment->X);
815  output().FillVectorVar(selelec_fgd_E, FGDSegment->E);
816  output().FillVectorVar(selelec_fgd_V11, FGDSegment->Vertex1x1);
817  output().FillVectorVar(selelec_fgd_V33, FGDSegment->Vertex3x3);
818  output().FillVectorVar(selelec_fgd_V55, FGDSegment->Vertex5x5);
819  output().FillVectorVar(selelec_fgd_V77, FGDSegment->Vertex7x7);
820  output().FillVectorVar(selelec_fgd_VLayer, FGDSegment->VertexLayer);
821  output().FillVectorVar(selelec_fgd_pullmu, FGDSegment->Pullmu);
822  output().FillVectorVar(selelec_fgd_pullpi, FGDSegment->Pullpi);
823  output().FillVectorVar(selelec_fgd_pullprot, FGDSegment->Pullp);
824  output().FillVectorVar(selelec_fgd_containment, FGDSegment->Containment);
825 
826  output().IncrementCounterForVar(selelec_fgd_det);
827  }
828 }
829 
830 //********************************************************************
831 void nueCCAnalysis::FillEcalNeutralClusterVars() {
832 //********************************************************************
833 
834  if(!box().MainTrack) return;
835 
836  // Default values for the brem search
837  Float_t _thetacut = 15.0; // degrees
838  Float_t _phicut = 15.0; // degrees
839  Int_t _firstlayercut = 7;
840  Float_t _ecalfrag = 0.15;
841  Float_t _ecalfragdist = 400.0;
842 
843  AnaTrackB* ecaltracks[100];
844  Int_t ntracks = anaUtils::GetAllTracksUsingECAL(static_cast<const AnaEventB&> (GetEvent()), ecaltracks);
845  output().FillVar(NECalTracks, ntracks);
846 
847  // Get all the ecal neutral clusters
848  AnaTrackB* dsecaltracks[100];
849  AnaTrackB* brecaltracks[100];
850  Int_t nDSEcal = anaUtils::GetAllTracksUsingDet(static_cast<const AnaEventB&> (GetEvent()), SubDetId::kDSECAL, dsecaltracks);
851  Int_t nBREcal = anaUtils::GetAllTracksUsingDet(static_cast<const AnaEventB&> (GetEvent()), SubDetId::kTECAL, brecaltracks);
852 
853  Int_t nDSEcalNC = 0, nBREcalNC = 0, nBremEcalNC = 0, nFragmentEcalNC = 0;
854  Float_t mostenenc = 0.0, allenenc = 0.0, neutclustenergy = 0.0, fragmentdist = 0.0;
855  Float_t mintheta = 10000.0, minphi = 10000.0;
856  // Angular information about the HM track
857  Float_t track_theta = anaUtils::ArrayToTLorentzVector(box().MainTrack->DirectionStart).Theta()*180/3.14159;
858  Float_t track_phi = anaUtils::ArrayToTLorentzVector(box().MainTrack->DirectionStart).Phi()*180/3.14159;
859  // Ecal of the HM track
860  AnaECALParticleB* HMecaltrack[100];
861  Int_t nECAL = anaUtils::GetTrackerDsEcals(box().MainTrack, HMecaltrack);
862  Int_t ecaldetector = 0;
863  TVector3 showerposition;
864 
865  Float_t emenergy = 0.0;
866  if(nECAL > 0){
867  AnaECALParticle* EcalSegment = static_cast<AnaECALParticle*> (HMecaltrack[nECAL - 1]);
868  ecaldetector = SubDetId::GetSubdetectorEnum(EcalSegment->Detector);
869  showerposition = anaUtils::ArrayToTVector3(EcalSegment->ShowerPosition);
870  emenergy = EcalSegment->EMEnergy;
871  }
872 
873  for (Int_t i=0; i<nDSEcal; i++) {
874  if(SubDetId::GetDetectorUsed(dsecaltracks[i]->Detector, SubDetId::kTPC) || SubDetId::GetDetectorUsed(dsecaltracks[i]->Detector, SubDetId::kFGD) || SubDetId::GetDetectorUsed(dsecaltracks[i]->Detector, SubDetId::kP0D) || SubDetId::GetDetectorUsed(dsecaltracks[i]->Detector, SubDetId::kPECAL) ){continue;}
875  nDSEcalNC++;
876  Int_t nseg = dsecaltracks[i]->nECALSegments;
877  for(Int_t j=0; j<nseg; j++){
878  AnaECALParticle* ecaltrack = static_cast<AnaECALParticle*> (dsecaltracks[i]->ECALSegments[j]);
879  //AnaECALParticleB* ecaltrack = dsecaltracks[i]->ECALSegments[j];
880 
881  // Brem tag
882  Float_t theta = anaUtils::ArrayToTVector3(ecaltrack->DirectionStart).Theta()*180/3.14159;
883  Float_t phia = anaUtils::ArrayToTVector3(ecaltrack->DirectionStart).Phi()*180/3.14159;
884 
885  if(fabs(theta-track_theta) < mintheta)
886  mintheta = fabs(theta-track_theta);
887  if(fabs(phia-track_phi) < minphi)
888  minphi = fabs(phia-track_phi);
889 
890  if(fabs(theta-track_theta) < _thetacut && fabs(phia-track_phi) < _phicut && ecaltrack->MostUpStreamLayerHit < _firstlayercut){
891  nBremEcalNC++;
892  neutclustenergy += ecaltrack->EMEnergy;
893  }
894  else{
895  if(emenergy > 0 && ecaltrack->EMEnergy/emenergy < _ecalfrag && ecaldetector == SubDetId::GetSubdetectorEnum(ecaltrack->Detector)){
896  TVector3 fragmentposition = anaUtils::ArrayToTVector3(ecaltrack->ShowerPosition);
897  Float_t tempdist = (fragmentposition-showerposition).Mag();
898  if(tempdist > fragmentdist)
899  fragmentdist = tempdist;
900  // count only if it near the main shower
901  if(tempdist < _ecalfragdist)
902  nFragmentEcalNC++;
903  }
904  }
905 
906  allenenc += ecaltrack->EMEnergy;
907  if(ecaltrack->EMEnergy > mostenenc)
908  mostenenc = ecaltrack->EMEnergy;
909  }
910  }
911 
912  for (Int_t i=0; i<nBREcal; i++) {
913  if(SubDetId::GetDetectorUsed(brecaltracks[i]->Detector, SubDetId::kTPC) || SubDetId::GetDetectorUsed(brecaltracks[i]->Detector, SubDetId::kFGD) || SubDetId::GetDetectorUsed(brecaltracks[i]->Detector, SubDetId::kP0D) || SubDetId::GetDetectorUsed(brecaltracks[i]->Detector, SubDetId::kPECAL) ){continue;}
914  Int_t nseg = brecaltracks[i]->nECALSegments;
915  nBREcalNC++;
916  for(Int_t j=0; j<nseg; j++){
917  AnaECALParticle* ecaltrack = static_cast<AnaECALParticle*> (brecaltracks[i]->ECALSegments[j]);
918  //AnaECALParticleB* ecaltrack = brecaltracks[i]->ECALSegments[j];
919 
920  // Brem tag
921  Float_t theta = anaUtils::ArrayToTVector3(ecaltrack->DirectionStart).Theta()*180/3.14159;
922  Float_t phia = anaUtils::ArrayToTVector3(ecaltrack->DirectionStart).Phi()*180/3.14159;
923 
924  if(fabs(theta-track_theta) < mintheta)
925  mintheta = fabs(theta-track_theta);
926  if(fabs(phia-track_phi) < minphi)
927  minphi = fabs(phia-track_phi);
928 
929  if(fabs(theta-track_theta) < _thetacut && fabs(phia-track_phi) < _phicut && ecaltrack->MostUpStreamLayerHit < _firstlayercut){
930  nBremEcalNC++;
931  neutclustenergy += ecaltrack->EMEnergy;
932  }
933  else{
934  if(emenergy > 0 && ecaltrack->EMEnergy/emenergy < _ecalfrag && ecaldetector == SubDetId::GetSubdetectorEnum(ecaltrack->Detector)){
935  TVector3 fragmentposition = anaUtils::ArrayToTVector3(ecaltrack->ShowerPosition);
936  Float_t tempdist = (fragmentposition-showerposition).Mag();
937  if(tempdist > fragmentdist)
938  fragmentdist = tempdist;
939  // count only if it near the main shower
940  if(tempdist < _ecalfragdist)
941  nFragmentEcalNC++;
942  }
943  }
944 
945  allenenc += ecaltrack->EMEnergy;
946  if(ecaltrack->EMEnergy > mostenenc)
947  mostenenc = ecaltrack->EMEnergy;
948  }
949  }
950 
951  output().FillVar(NDsEcalNeutralClusters, nDSEcalNC);
952  output().FillVar(NBrEcalNeutralClusters, nBREcalNC);
953  output().FillVar(MostEnergeticEcalNeutralCluster, mostenenc);
954  output().FillVar(EcalNeutralClusterEnergySum, allenenc);
955  output().FillVar(BremNeutralClusters, nBremEcalNC);
956  output().FillVar(BremNeutralClustersEnergy, neutclustenergy);
957  output().FillVar(BremNeutralClustersMinTheta, mintheta);
958  output().FillVar(BremNeutralClustersMinPhi, minphi);
959  output().FillVar(FragmentsNeutralClusters, nFragmentEcalNC);
960  output().FillVar(FragmentsDistanceToShower, fragmentdist);
961 
962  // Find other ecal tracks that EMEnergy > p of the HMT
963  Int_t nfound = 0;
964  for(Int_t i=0; i<ntracks; i++) {
965  AnaTrackB* track = ecaltracks[i];
966  if(track){
967  if(track == box().MainTrack){continue;}
968  if(track->nTPCSegments == 0 && track->nFGDSegments == 0){continue;}
969  for(Int_t j=0; j<track->nECALSegments; j++) {
970  AnaECALParticleB* EcalSegment = track->ECALSegments[j];
971  if(EcalSegment->EMEnergy > box().MainTrack->Momentum)
972  nfound++;
973  }
974  }
975  }
976 
977  output().FillVar(EcalClusterMostEnergeticThanHMT, nfound);
978 
979 }
980 
981 //********************************************************************
982 void nueCCAnalysis::FillAllTracksVars() {
983 //********************************************************************
984 
985  AnaTrackB* track = box().MainTrack;
986  if(!track) return;
987 
988  // Get all the FGD-iso tracks
989  AnaTrackB* fgdonlytracks[100];
990  Int_t nFGDOnly = anaUtils::GetAllTracksUsingOnlyDet(static_cast<const AnaEventB&> (GetEvent()), SubDetId::kFGD, fgdonlytracks);
991  for(Int_t i=0; i<nFGDOnly; i++){
992  Int_t subdet = -1;
993  if (SubDetId::GetDetectorUsed(fgdonlytracks[i]->Detector, SubDetId::kFGD1))
994  subdet = 0;
995  else if(SubDetId::GetDetectorUsed(fgdonlytracks[i]->Detector, SubDetId::kFGD2))
996  subdet = 1;
997 
998  AnaFGDParticle* FGDSegment = static_cast<AnaFGDParticle*>(anaUtils::GetSegmentInDet(*fgdonlytracks[i],static_cast<SubDetId::SubDetEnum >(subdet)));
999  if (!FGDSegment) continue;
1000 
1001  output().FillVectorVar(fgdiso_det, subdet);
1002  output().FillVectorVar(fgdiso_x, FGDSegment->X);
1003  output().FillVectorVar(fgdiso_E, FGDSegment->E);
1004  output().FillVectorVar(fgdiso_pullmu, FGDSegment->Pullmu);
1005  output().FillVectorVar(fgdiso_pullpi, FGDSegment->Pullpi);
1006  output().FillVectorVar(fgdiso_pullprot, FGDSegment->Pullp);
1007  output().FillVectorVar(fgdiso_containment, FGDSegment->Containment);
1008  output().FillMatrixVarFromArray(fgdiso_position, static_cast<AnaTrack*> (fgdonlytracks[i])->PositionStart, 4);
1009  Float_t cosT = anaUtils::ArrayToTLorentzVector(static_cast<AnaTrack*> (fgdonlytracks[i])->DirectionStart).CosTheta();
1010  output().FillVectorVar(fgdiso_costheta, cosT);
1011  if(static_cast<AnaTrueParticle*> (fgdonlytracks[i]->TrueObject))
1012  output().FillVectorVar(fgdiso_pdg, fgdonlytracks[i]->GetTrueParticle()->PDG);
1013 
1014  output().IncrementCounterForVar(fgdiso_det);
1015 
1016  }
1017 
1018  // Get all the FGD1-TPC tracks
1019  AnaTrackB* fgdtpctracks[100];
1020  Int_t nFGDs = anaUtils::GetAllTracksUsingDet(static_cast<const AnaEventB&> (GetEvent()), SubDetId::kFGD, fgdtpctracks);
1021  Int_t nFGD1TPC1 = 0, nFGD1TPC2 = 0, nFGD1Ecal = 0;
1022  Int_t nFGD2TPC2 = 0, nFGD2TPC3 = 0, nFGD2Ecal = 0;
1023  Float_t xymaxdist = -10.0, xinit = -999.0, yinit = -999.0;
1024  for(Int_t i=0; i<nFGDs; i++) {
1025  if(fgdtpctracks[i] == track){continue;}
1026 
1027  if(SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kFGD1)){ // FGD1
1028  if ( !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC2) && SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC1))
1029  nFGD1TPC1++;
1030 
1031  if ( SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC2) && !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC1))
1032  nFGD1TPC2++;
1033 
1034  if ( SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kECAL) && !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC))
1035  nFGD1Ecal++;
1036  }
1037  else if(SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kFGD2)){ // FGD2
1038  if ( SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC3) && !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC2) && !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kFGD1)){
1039  nFGD2TPC3++;
1040  if(xinit == -999.0 && yinit == -999.0){
1041  xinit = fgdtpctracks[i]->PositionStart[0];
1042  yinit = fgdtpctracks[i]->PositionStart[1];
1043  }
1044  else{
1045  Float_t temp = sqrt( (fgdtpctracks[i]->PositionStart[0] - xinit)*(fgdtpctracks[i]->PositionStart[0] - xinit) + (fgdtpctracks[i]->PositionStart[1] - yinit)*(fgdtpctracks[i]->PositionStart[1] - yinit));
1046  if(temp > xymaxdist)
1047  xymaxdist = temp;
1048  }
1049  }
1050 
1051  if ( !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC3) && SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC2) && !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kFGD1))
1052  nFGD2TPC2++;
1053 
1054  if ( SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kECAL) && !SubDetId::GetDetectorUsed(fgdtpctracks[i]->Detector, SubDetId::kTPC))
1055  nFGD2Ecal++;
1056  }
1057  }
1058 
1059  output().FillVar(NFGD1TracksReqTPC1, nFGD1TPC1);
1060  output().FillVar(NFGD1TracksReqTPC2, nFGD1TPC2);
1061  output().FillVar(NFGD1TracksReqEcal, nFGD1Ecal);
1062  output().FillVar(NFGD2TracksReqTPC2, nFGD2TPC2);
1063  output().FillVar(NFGD2TracksReqTPC3, nFGD2TPC3);
1064  output().FillVar(NFGD2TracksReqEcal, nFGD2Ecal);
1065  output().FillVar(FGD2XYMaxTrackDist, xymaxdist);
1066 
1067  // Get all the TPC-Ecal tracks and save all the secondary FGD-TPC tracks
1068  AnaTrackB* tpctracks[100];
1069  Int_t ntpctracks = anaUtils::GetAllTracksUsingDet(static_cast<const AnaEventB&> (GetEvent()), SubDetId::kTPC, tpctracks);
1070  Int_t nTPCECAL = 0;
1071  for (Int_t i=0; i<ntpctracks; i++) {
1072  if(tpctracks[i] == track) {continue;}
1073  // First find the TPC-Ecal tracks
1074  if ( SubDetId::GetDetectorUsed(tpctracks[i]->Detector, SubDetId::kECAL) && !SubDetId::GetDetectorUsed(tpctracks[i]->Detector, SubDetId::kFGD))
1075  nTPCECAL++;
1076 
1077  // Only take track if it's in the FGD
1078  if(!SubDetId::GetDetectorUsed(tpctracks[i]->Detector, SubDetId::kFGD)) {continue;}
1079 
1080  // Check in which TPC the track goes
1081  Int_t tpcdet = -1;
1082 
1083  Float_t cosT = anaUtils::ArrayToTLorentzVector(tpctracks[i]->DirectionStart).CosTheta();
1084 
1085  if(SubDetId::GetDetectorUsed(tpctracks[i]->Detector, SubDetId::kFGD1) && SubDetId::GetDetectorUsed(tpctracks[i]->Detector, SubDetId::kFGD2) && cosT < 0)
1086  tpcdet = 1;
1087  else if(SubDetId::GetDetectorUsed(tpctracks[i]->Detector, SubDetId::kFGD1))
1088  tpcdet = 0;
1089  else if(SubDetId::GetDetectorUsed(tpctracks[i]->Detector, SubDetId::kFGD2))
1090  tpcdet = 1;
1091 
1092  AnaTPCParticleB* longCloseTPC = static_cast<AnaTPCParticleB*>(anaUtils::GetSegmentWithMostNodesInClosestTpc(*tpctracks[i]));
1093  if(!longCloseTPC) {continue;}
1094 
1095  output().FillVectorVar(FGDTPCTrack_det, tpcdet );
1096  output().FillVectorVar(FGDTPCTrack_pullmuon, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpMuon)/longCloseTPC->dEdxSigmaMuon);
1097  output().FillVectorVar(FGDTPCTrack_pullelec, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpEle)/longCloseTPC->dEdxSigmaEle);
1098  output().FillVectorVar(FGDTPCTrack_pullpion, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpPion)/longCloseTPC->dEdxSigmaPion);
1099  output().FillVectorVar(FGDTPCTrack_pullprot, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpProton)/longCloseTPC->dEdxSigmaProton);
1100  output().FillVectorVar(FGDTPCTrack_tpcNNodes,longCloseTPC->NNodes);
1101 
1102  output().FillVectorVar(FGDTPCTrack_mom, tpctracks[i]->Momentum);
1103 
1104  output().FillVectorVar(FGDTPCTrack_costheta, cosT);
1105  output().FillVectorVar(FGDTPCTrack_charge, tpctracks[i]->Charge);
1106  output().FillMatrixVarFromArray(FGDTPCTrack_startpos, tpctracks[i]->PositionStart, 4);
1107  output().FillMatrixVarFromArray(FGDTPCTrack_startdir, tpctracks[i]->DirectionStart, 3);
1108 
1109  AnaTrueParticle* truth = static_cast<AnaTrueParticle*> (tpctracks[i]->TrueObject);
1110  if(truth)
1111  output().FillVectorVar(FGDTPCTrack_pdg, truth->PDG);
1112 
1113  // Check if the track goes in the Ecal
1114  AnaECALParticleB* ecaltracks[100];
1115  Int_t nECAL = anaUtils::GetTrackerDsEcals(tpctracks[i], ecaltracks);
1116 
1117  if(nECAL >=1 ){
1118  AnaECALParticle* EcalSegment = static_cast<AnaECALParticle*> (ecaltracks[nECAL - 1]);
1119  //AnaECALParticleB* EcalSegmentB = ecaltracks[nECAL - 1];
1121  AnaTPCParticle* backTPC = static_cast<AnaTPCParticle*> (anaUtils::GetTPCBackSegment(tpctracks[i]));
1122  if(backTPC)
1123  output().FillVectorVar(FGDTPCTrack_MomECalEntrance, backTPC->MomentumEnd);
1124 
1125  output().FillVectorVar(FGDTPCTrack_EMEnergy, EcalSegment->EMEnergy);
1126  output().FillVectorVar(FGDTPCTrack_MipEm, EcalSegment->PIDMipEm);
1127  output().FillVectorVar(FGDTPCTrack_MipPion, EcalSegment->PIDMipPion);
1128  output().FillVectorVar(FGDTPCTrack_EmHip, EcalSegment->PIDEmHip);
1129  output().FillMatrixVarFromArray(FGDTPCTrack_ShowerPosition, EcalSegment->ShowerPosition, 3 );
1130  output().FillVectorVar(FGDTPCTrack_ECALdet, ECALdet);
1131  output().FillVectorVar(FGDTPCTrack_NHits, EcalSegment->NHits);
1132  output().FillVectorVar(FGDTPCTrack_MostUpStreamLayerHit, EcalSegment->MostUpStreamLayerHit);
1133  output().FillVectorVar(FGDTPCTrack_IsEcalContained, nueCCUtils::IsEcalContained(EcalSegment));
1134  }
1135 
1136  output().IncrementCounterForVar(FGDTPCTrack_det);
1137  }
1138 
1139  output().FillVar(NTPCTracksReqEcal, nTPCECAL);
1140 
1141  // -------------------------------------------------------
1142  SubDetId::SubDetEnum det = SubDetId::kInvalid;
1143  if(anaUtils::InDetVolume(SubDetId::kFGD1, track->PositionStart)) det = SubDetId::kFGD1;
1144  else if(anaUtils::InDetVolume(SubDetId::kFGD2, track->PositionStart)) det = SubDetId::kFGD2;
1145 
1146  AnaTrackB* fgdtracks[100];
1147  Int_t nFGD = anaUtils::GetAllTracksUsingDet(static_cast<const AnaEventB&> (GetEvent()), det, fgdtracks);
1148 
1149  Int_t nFGDTPC = 0;
1150  Float_t min_reqtpc = 1e6, max_reqtpc = -1e6;
1151  Float_t min = 1e6, max = -1e6;
1152 
1153  for (Int_t i=0; i<nFGD; i++) {
1154  if(fgdtracks[i] == track) {continue;}
1155 
1156  Float_t diff = (anaUtils::ArrayToTVector3(track->PositionStart) - anaUtils::ArrayToTVector3(fgdtracks[i]->PositionStart)).Mag();
1157  min = std::min(min, diff);
1158  max = std::max(max, diff);
1159 
1160  if(SubDetId::GetDetectorUsed(fgdtracks[i]->Detector, SubDetId::kTPC)){
1161  nFGDTPC++;
1162  min_reqtpc = std::min(min_reqtpc, diff);
1163  max_reqtpc = std::max(max_reqtpc, diff);
1164  }
1165  }
1166 
1167  output().FillVar(NFGDTracksReqTPC, nFGDTPC);
1168  output().FillVar(FGDDistanceReqTpc, min_reqtpc);
1169  output().FillVar(FGDDistanceNoReqTpc, min);
1170  output().FillVar(FGDMaxDistanceReqTpc, max_reqtpc);
1171  output().FillVar(FGDMaxDistanceNoReqTpc, max);
1172 }
1173 
1174 //********************************************************************
1175 void nueCCAnalysis::FillToFVars() {
1176 //********************************************************************
1177 
1178  AnaTrackB* track = box().MainTrack;
1179  if (!track ) return;
1180 
1181  if(anaUtils::InDetVolume(SubDetId::kFGD1, track->PositionStart)){
1182  if( track->ToF.Flag_P0D_FGD1 )
1183  output().FillVar(selelec_ToF_P0D_FGD1, track->ToF.P0D_FGD1);
1184  else if(track->ToF.Flag_ECal_FGD1)
1185  output().FillVar(selelec_ToF_ECal_FGD1, track->ToF.ECal_FGD1);
1186  else if( track->ToF.Flag_FGD1_FGD2 )
1187  output().FillVar(selelec_ToF_FGD1_FGD2, track->ToF.FGD1_FGD2);
1188  }
1189  else{
1190  if(track->ToF.Flag_ECal_FGD2)
1191  output().FillVar(selelec_ToF_ECal_FGD2, track->ToF.ECal_FGD2);
1192  else if( track->ToF.Flag_FGD1_FGD2 )
1193  output().FillVar(selelec_ToF_FGD1_FGD2, track->ToF.FGD1_FGD2);
1194  }
1195 
1196 #if VERSION_HAS_TIME_FITS
1197  // Check for DsEcal
1198  const AnaTrack* atrack = static_cast<AnaTrack*> (box().MainTrack);
1199  if (!atrack ) return;
1200  bool fgd1 = false, fgd2 = false, ecal = false;
1201  Float_t tfgd1 = 0, tfgd2 = 0, tdsecal = 0;
1202  std::vector<AnaTimeNode*> timenodes = atrack->TimeNodes;
1203  for (unsigned int i=0;i<timenodes.size();i++){
1204  AnaTimeNode* node = timenodes.at(i);
1205  float t = (node->TimeStart + node->TimeEnd)/2.0;
1206 
1207 
1208  if(node->Detector == 4){
1209  if(!fgd1) tfgd1 = t;
1210  fgd1 = true;
1211  }
1212  else if(node->Detector == 5){
1213  if(!fgd2) tfgd2 = t;
1214  fgd2 = true;
1215  }
1216  else if(node->Detector == 7){
1217  if(!ecal) tdsecal = t;
1218  ecal = true;
1219  }
1220  }
1221 
1222  if(fgd1 && ecal)
1223  output().FillVar(selelec_ToF_DsECal_FGD1, tdsecal-tfgd1);
1224  else if(fgd2 && ecal)
1225  output().FillVar(selelec_ToF_DsECal_FGD2, tdsecal-tfgd2);
1226 #endif
1227 
1228 }
1229 
1230 //********************************************************************
1231 void nueCCAnalysis::FillToyVarsInMicroTrees(bool addBase){
1232 //********************************************************************
1233 
1234  if(addBase) baseTrackerAnalysis::FillToyVarsInMicroTreesBase(addBase);
1235 
1236  if(box().MainTrack){
1237  output().FillToyVar(selelec_mom, box().MainTrack->Momentum);
1238 
1239  // Costheta
1240  // vertex defined as start of electron track, neutrino direction calculated from this
1241  TVector3 nuDirVec = anaUtils::GetNuDirRec(box().MainTrack->PositionStart);
1242  TVector3 elDirVec = anaUtils::ArrayToTVector3(box().MainTrack->DirectionStart);
1243  // The cosine of the angle between the electron and the neutrino
1244  double costheta_el_nu = nuDirVec.Dot(elDirVec);
1245  output().FillToyVar(selelec_costheta, (Float_t)costheta_el_nu);
1246 
1247  // Erec
1248  Float_t Erec = anaUtils::ComputeRecNuEnergyCCQE(box().MainTrack->Momentum, units::mass_electron, costheta_el_nu);
1249  output().FillToyVar(selelec_ENuRec, Erec);
1250  Float_t Q2 = anaUtils::ComputeQ2(box().MainTrack->Momentum, units::mass_electron, costheta_el_nu, Erec);
1251  output().FillToyVar(selelec_Q2Rec, Q2);
1252 
1253  if(_addmoretoyvariables){
1254  // First TPC
1255  AnaTPCParticleB* longCloseTPC = static_cast<AnaTPCParticleB*>(anaUtils::GetSegmentWithMostNodesInClosestTpc(*box().MainTrack));
1256  if(longCloseTPC){
1257  output().FillToyVar(selelec_tpcdedx, longCloseTPC->dEdxMeas);
1258  output().FillToyVar(selelec_pullmuon, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpMuon)/longCloseTPC->dEdxSigmaMuon);
1259  output().FillToyVar(selelec_pullelec, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpEle)/longCloseTPC->dEdxSigmaEle);
1260  output().FillToyVar(selelec_pullpion, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpPion)/longCloseTPC->dEdxSigmaPion);
1261  output().FillToyVar(selelec_pullprot, (longCloseTPC->dEdxMeas-longCloseTPC->dEdxexpProton)/longCloseTPC->dEdxSigmaProton);
1262  }
1263 
1264  // Second TPC
1265  if(anaUtils::InDetVolume(SubDetId::kFGD1, box().MainTrack->PositionStart)){
1266  AnaTPCParticleB* longestTPC3 = static_cast<AnaTPCParticleB*>(anaUtils::GetSegmentWithMostNodesInDet(*box().MainTrack,SubDetId::kTPC3));
1267 
1268  if(longestTPC3 && cutUtils::TPCTrackQualityCut(*longestTPC3)){
1269  output().FillToyVar(selelec_pullmuon2nd, (longestTPC3->dEdxMeas-longestTPC3->dEdxexpMuon)/longestTPC3->dEdxSigmaMuon);
1270  output().FillToyVar(selelec_pullelec2nd, (longestTPC3->dEdxMeas-longestTPC3->dEdxexpEle)/longestTPC3->dEdxSigmaEle);
1271  }
1272  }
1273 
1274  // Ecal
1275  AnaECALParticleB* ecaltracks[100];
1276  Int_t nECAL = anaUtils::GetTrackerDsEcals(box().MainTrack, ecaltracks);
1277 
1278  if(nECAL >=1 && nueCCUtils::UseEcal(box().MainTrack) ){
1279 
1280  AnaECALParticle* EcalSegment = static_cast<AnaECALParticle*> (ecaltracks[nECAL - 1]);
1281  if(EcalSegment)
1282  output().FillToyVar(selelec_ecalemene, EcalSegment->EMEnergy);
1283  }
1284  }
1285 
1286  // if there is a true vertex associated
1287  if(box().MainTrack->TrueObject) {
1288  AnaTrueVertex *vtx = static_cast<AnaTrueVertex*>(box().MainTrack->GetTrueParticle()->TrueVertex);
1289  if (vtx) {
1290  // Fill the mass component related to the mass weight
1291  anaUtils::massComponentEnum massComponent = anaUtils::GetMassComponent(GetEvent().GetIsMC(), vtx->Position);
1292  output().FillToyVar(truevtx_mass_component, massComponent);
1293 
1294  bool AntiNu = false;
1295  // Fill whether it is signal or bkg
1296  if (nue_categs::IsNuESignal(*vtx, SubDetId::kFGD1, AntiNu))
1297  output().FillToyVar(true_signal, 1);
1298  else if (nue_categs::IsNuESignal(*vtx, SubDetId::kFGD2, AntiNu))
1299  output().FillToyVar(true_signal, 2);
1300  else
1301  output().FillToyVar(true_signal, 0);
1302 
1303  }
1304  }
1305 
1306  } // end if MainTrack
1307 
1308 }
1309 
1310 //********************************************************************
1311 bool nueCCAnalysis::CheckFillTruthTree(const AnaTrueVertex& vtx){
1312 //********************************************************************
1313 
1314  SubDetId::SubDetEnum fgdID;
1315  if (_whichFGD == 1) fgdID = SubDetId::kFGD1;
1316  if (_whichFGD == 2) fgdID = SubDetId::kFGD2;
1317  if (_whichFGD > 2) fgdID = SubDetId::kFGD;
1318 
1319  bool AntiNu = false;
1320  return (nue_categs::IsNuESignal(vtx, fgdID, AntiNu) ||
1321  nue_categs::ThereWasGammaInFGD(static_cast<const AnaTrueVertexB&> (vtx)));
1322 }
1323 
1324 //********************************************************************
1325 void nueCCAnalysis::FillTruthTree(const AnaTrueVertex& vtx){
1326 //********************************************************************
1327 
1328  bool AntiNu = false;
1329  return FillTruthTreeBase(vtx, AntiNu);
1330 }
1331 
1332 //********************************************************************
1333 void nueCCAnalysis::FillTruthTreeBase(const AnaTrueVertex& vtx, bool IsAntinu){
1334 //********************************************************************
1335 
1336  // Fill the common variables
1337  //baseTrackerAnalysis::FillTruthTreeBase(vtx);
1338  baseTrackerAnalysis::FillTruthTreeBase(vtx, SubDetId::kFGD1, IsAntinu);
1339 
1340  // Electron true variables
1341  output().FillVectorVarFromArray(truelepton_pos, vtx.Position, 4);
1342  output().FillVar(truelepton_det, anaUtils::GetDetector(vtx.Position));
1343 
1344  Float_t trueelec_true_cosT_z = anaUtils::ArrayToTLorentzVector(vtx.LeptonDir).CosTheta();
1345  output().FillVar(truelepton_costheta_z, trueelec_true_cosT_z);
1346 
1347  // ND280 position to get off-axis angle
1348  Float_t _nd280_pos[3] = {-3.221999, -8.14599, 280.10};
1349 
1350  Float_t trueelec_true_cosT_offaxis = (Float_t)cos( anaUtils::ArrayToTVector3(vtx.LeptonDir).Angle(_nd280_pos) ) ;
1351  output().FillVar(truelepton_costheta_offaxis, trueelec_true_cosT_offaxis);
1352 
1353  Float_t trueelec_true_cosT_nuDir = (Float_t)cos( anaUtils::ArrayToTVector3(vtx.LeptonDir).Angle(anaUtils::ArrayToTVector3(vtx.NuDir) ) );
1354  output().FillVar(truelepton_costheta_nuDir, trueelec_true_cosT_nuDir);
1355 
1356  // Fill whether it is signal or bkg
1357  if (nue_categs::IsNuESignal(vtx, SubDetId::kFGD1, IsAntinu))
1358  output().FillVar(true_signal, 1);
1359  else if (nue_categs::IsNuESignal(vtx, SubDetId::kFGD2, IsAntinu))
1360  output().FillVar(true_signal, 2);
1361  else
1362  output().FillVar(true_signal, 0);
1363 
1364  // Fill the mass component related to the mass weight
1365  anaUtils::massComponentEnum massComponent = anaUtils::GetMassComponent(GetSpill().GetIsMC(), vtx.Position);
1366  output().FillVar(truevtx_mass_component, massComponent);
1367  anaUtils::FillCategories(&vtx, "fgd2", SubDetId::kFGD2, IsAntinu, GetSpill().GetIsSandMC());
1368 
1369  const AnaTrueVertex *vtx1 = static_cast<const AnaTrueVertex*>(&vtx);
1370  AnaTrueParticleB* Init=NULL;
1371  AnaTrueParticleB* Main=NULL;
1372 
1373  double mom = 0;
1374  for(int i = 0; i < vtx.nTrueParticles; i++){
1375  AnaTrueParticleB* truth = vtx.TrueParticles[i];
1376  if(abs(truth->PDG) == 11 && truth->Momentum > mom && truth->ParentPDG == 22){
1377  Main = truth;
1378  }
1379  }
1380 
1381  if (Main){
1382  Float_t selelec_true_cosT_nuDir = (Float_t)cos(anaUtils::ArrayToTVector3(Main->Direction).Angle(anaUtils::ArrayToTVector3(vtx.NuDir)));
1383  output().FillVar(Q2_true, anaUtils::ComputeQ2(vtx.LeptonMom, units::mass_electron, selelec_true_cosT_nuDir, vtx.NuEnergy));
1384  }
1385 
1386  if(vtx1)
1387  Init = GoBackToPrimaryParticle(Main, vtx1);
1388 
1389  if(Init){
1390  output().FillVar(InitiatorPDG, (Int_t) Init->PDG);
1391  output().FillVar(InitiatorParentPDG, (Int_t) Init->ParentPDG);
1392  output().FillVar(InitiatorMom, (Float_t)Init->Momentum);
1393  output().FillVectorVarFromArray(InitiatorDir, Init->Direction, 3);
1394  }
1395 
1396 }
1397 
1398 //********************************************************************
1399 void nueCCAnalysis::FillCategories(){
1400 //********************************************************************
1401 
1402  bool IsAntinu = false;
1403 
1404  anaUtils::FillCategories(&GetEvent(), static_cast<AnaTrack*>(box().MainTrack), "", SubDetId::kFGD1);
1405  anaUtils::FillCategories(&GetEvent(), static_cast<AnaTrack*>(box().MainTrack), "fgd2", SubDetId::kFGD2);
1406 
1407  nue_categs::FillCategories(&GetEvent(), box().MainTrack, "", SubDetId::kFGD1, IsAntinu);
1408  nue_categs::FillCategories(&GetEvent(), box().MainTrack, "fgd2", SubDetId::kFGD2, IsAntinu);
1409 }
1410 
1411 //********************************************************************
1412 void nueCCAnalysis::FillConfigTree(){
1413 //********************************************************************
1414 
1415 
1416  // Add and fill number of nucleons in each of the targets
1417  AddVarD(output(), nNucleonsFGD1, "number of targets in FGD1");
1418  AddVarD(output(), nNucleonsFGD2scint, "number of targets in FGD2 scintillator");
1419  AddVarD(output(), nNucleonsFGD2water, "number of targets in FGD2 water");
1420 
1421  output().FillVar(nNucleonsFGD1, anaUtils::GetNTargets(anaUtils::kFGD1));
1422  output().FillVar(nNucleonsFGD2scint, anaUtils::GetNTargets(anaUtils::kFGD2xymodules));
1423  output().FillVar(nNucleonsFGD2water, anaUtils::GetNTargets(anaUtils::kFGD2watermodules));
1424 
1425 }
1426 
1427 
1428 
1429 
1430 //*********************************************************************
1431 AnaTrueParticleB* nueCCAnalysis::GoBackToPrimaryParticle(const AnaTrueParticleB* Gamma, const AnaTrueVertex *vtx){
1432 //*********************************************************************
1433 
1434  if(!Gamma)
1435  return NULL;
1436 
1437  if(!vtx)
1438  vtx = static_cast<const AnaTrueVertex*>(Gamma->TrueVertex);
1439 
1440  if(!vtx)
1441  return NULL;
1442 
1443  std::vector<AnaTrueParticleB*> EMParticle;
1444  std::vector<AnaTrueParticleB*> Pi0;
1445  std::vector<AnaTrueParticleB*> PiPM;
1446 
1447  EMParticle.clear();
1448  Pi0.clear();
1449  PiPM.clear();
1450 
1451  EMParticle.reserve(200);
1452  Pi0.reserve(200);
1453  PiPM.reserve(200);
1454 
1455  int imax = vtx->nTrueParticles;
1456  for(int i = 0; i < imax; i++){
1457 
1458  AnaTrueParticleB* trueTrack = vtx->TrueParticles[i];
1459 
1460  if(!trueTrack) continue;
1461 
1462  if(trueTrack->PDG == 111) Pi0.push_back(trueTrack);
1463  if(abs(trueTrack->PDG) == 211) PiPM.push_back(trueTrack);
1464 
1465  if(trueTrack->PDG == 22 || abs(trueTrack->PDG) == 11){ // Store all the gammas and electron positron
1466  EMParticle.push_back(trueTrack);
1467 
1468  }
1469  }
1470 
1471  int gammaID = -99;
1472  int ParentID = Gamma->ParentID;
1473  int ParentPDG = Gamma->ParentPDG;
1474 
1475  int itry = 0;
1476 
1477  while(abs(ParentPDG) == 11 || ParentPDG == 22){ // go back to the gamma from the pi0
1478  itry++; // for infinite loop
1479  int i = 0;
1480  while(i < vtx->nTrueParticles){
1481  AnaTrueParticleB* trueTrack = vtx->TrueParticles[i];
1482  //std::cout << "trueTrack[" << i << "]" << std::endl;
1483  //std::cout << "trueTrack->ID " << trueTrack->ID << std::endl;
1484  //std::cout << "trueTrack->ParentID " << trueTrack->ParentID << std::endl;
1485  //std::cout << "trueTrack->ParentPDG " << trueTrack->ParentPDG << std::endl;
1486 
1487  if(ParentID == trueTrack->ID){
1488  gammaID = trueTrack->ID;
1489  ParentID = trueTrack->ParentID;
1490  ParentPDG = trueTrack->ParentPDG;
1491  //std::cout << "gammaID " << gammaID << std::endl;
1492  //std::cout << "ParentID " << ParentID << std::endl;
1493  //std::cout << "ParentPDG " << ParentPDG << std::endl;
1494  break;
1495  }
1496  i++;
1497  }
1498 
1499  if(gammaID == -99)
1500  itry = 1500;
1501  if(itry > 1000)
1502  break;
1503  }
1504 
1505  for(int i = 0; i < vtx->nTrueParticles; i++){
1506  AnaTrueParticleB* trueTrack = vtx->TrueParticles[i];
1507 
1508  if(!trueTrack) continue;
1509  if(trueTrack->ID == ParentID) return trueTrack;
1510  }
1511 
1512  EMParticle.clear();
1513  Pi0.clear();
1514  PiPM.clear();
1515  return NULL;
1516 }
Float_t dEdxexpMuon
Expected dE/dx for a muon, based on the reconstructed momentum.
int GetAllTracksUsingECAL(const AnaEventB &event, AnaTrackB *selTracks[])
AnaTrueVertexB * TrueVertex
Pointer to the AnaTrueVertexB of the interaction that created this AnaTrueParticleB.
Float_t PositionStart[4]
The reconstructed start position of the particle.
int GetAllTracksUsingOnlyDet(const AnaBunchB &bunch, SubDetId::SubDetEnum det, AnaTrackB *selTracks[])
Representation of a global track.
unsigned long Detector
Int_t LeptonPDG
The PDG code of the primary outgoing electron/muon.
int GetParameterI(std::string)
Get parameter. Value is returned as integer.
Definition: Parameters.cxx:217
Float_t MomentumEle
Momentum from refitting the track assuming the electron hypothesis.
int nTrueParticles
How many true particles are associated with this vertex.
int GetFGDMichelElectrons(const AnaEventB &event, const SubDetId::SubDetEnum det, AnaFgdTimeBinB **arr, bool prod5Cut=0)
Get all delayed time bins as Michel Electron candidates.
Int_t Detector
Definition: DataClasses.hxx:40
Float_t dEdxexpProton
Expected dE/dx for a proton, based on the reconstructed momentum.
Int_t NuParentPDG
Neutrino parent PDG code.
Definition: DataClasses.hxx:88
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 LeptonDir[3]
The direction of the primary outgoing electron/muon.
Float_t ComputeQ2(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton, Float_t energy_neutrino)
Float_t Pullp
Proton pull, according to FGD information.
void AddCorrection(Int_t index, const std::string &name, CorrectionBase *corr)
Float_t NuParentDecPoint[4]
Decay point of the neutrino parent.
Definition: DataClasses.hxx:91
Float_t DirectionEnd[3]
The reconstructed end direction of the particle.
void AddPackage(const std::string &name, const std::string &version)
Add a package.
Float_t E
Input to the pull calculations. Needs to be documented properly in oaAnalysis.
Int_t NNodes
The number of nodes in the reconstructed object.
Representation of an ECAL segment of a global track.
Float_t Pullpi
Pion pull, according to FGD information.
Float_t Vertex1x1
Vertex activity variables.
Float_t dEdxSigmaProton
Expected error on the dE/dx measurement, for the proton hypothesis.
Float_t ComputeRecNuEnergyCCQE(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton, Float_t bindingEnergy=25.)
AnaTrueObjectC * TrueObject
The link to the true oject that most likely generated this reconstructed object.
AnaToF ToF
Times of flight between pairs of detectors.
static bool GetDetectorUsed(unsigned long BitField, SubDetId::SubDetEnum det)
Method to see if a certain subdetector or subdetector system is used.
Definition: SubDetId.cxx:40
massComponentEnum GetMassComponent(bool IsMC, const Float_t *pos)
Get the detector component in which the position is.
Float_t Momentum
The initial momentum of the true particle.
AnaTrueParticleB ** TrueParticles
The true particles associated with this vertex.
SubDetId::SubDetEnum GetDetector(const Float_t *pos)
Return the detector in which the position is.
AnaParticleB * GetSegmentInDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
Int_t TargetPDG
The PDG code of the target nucleus.
Definition: DataClasses.hxx:85
bool TrackUsesDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
Float_t dEdxexpPion
Expected dE/dx for a pion, based on the reconstructed momentum.
Float_t dEdxexpEle
Expected dE/dx for an electron, based on the reconstructed momentum.
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...
AnaECALParticleB * GetMostUpstreamECalSegment(AnaTrackB *track)
std::string GetSoftwareVersionFromPath(const std::string &path)
Get The software version from the path of the package.
Representation of detector time info.
Definition: DataClasses.hxx:11
Float_t ShowerPosition[3]
The position of the shower-fit to this object by ecalRecon.
Float_t LeptonMom
The momentum of the primary outgoing electron/muon.
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
Representation of a true Monte Carlo vertex.
Definition: DataClasses.hxx:50
int nTPCSegments
How many TPC tracks are associated with this track.
Representation of a true Monte Carlo trajectory/particle.
Float_t NuEnergy
The true energy of the incoming neutrino.
const AnaParticleB * Original
bool Initialize()
[AnalysisAlgorithm_mandatory]
Float_t Position[4]
The position the true interaction happened at.
Float_t dEdxSigmaEle
Expected error on the dE/dx measurement, for the electron hypothesis.
SubDetEnum
Enumeration of all detector systems and subdetectors.
Definition: SubDetId.hxx:25
Int_t PDG
The PDG code of this particle.
Int_t NHits
The number of hits in the particle.
Int_t ParentPDG
The PDG code of this particle&#39;s immediate parent, or 0 if there is no parent.
void FillCategories(AnaEventB *event, AnaTrack *track, const std::string &prefix, const SubDetId::SubDetEnum det=SubDetId::kFGD1, bool IsAntinu=false, bool useCATSAND=true)
Fill the track categories for color drawing.
Float_t dEdxMeas
dE/dx as measured by the TPC.
Float_t TimeEnd
End time.
Definition: DataClasses.hxx:46
Representation of a global track.
CorrectionManager & corr()
[DrawingToolsBaseDrawCutLineMethods]
static SubDetId::SubDetEnum GetSubdetectorEnum(unsigned long BitField)
Get the single subdetector that this track is from.
Definition: SubDetId.cxx:165
Float_t MomentumEnd
The reconstructed momentum of the particle, at the end position.
virtual bool Initialize()
[AnalysisAlgorithm_mandatory]
Representation of a TPC segment of a global track.
bool InDetVolume(SubDetId::SubDetEnum det, const Float_t *pos)
Float_t Length
The length of the ECal segment.
Float_t MomentumError
The error on the reconstructed momentum.
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
void AddSelection(const std::string &name, const std::string &title, SelectionBase *sel, Int_t presel=-1)
Add a user selection to the selection manager.
AnaTrueParticleB * GetTrueParticleByID(const AnaEventB &event, int ID)
Get the AnaTrueParticleB in the current spill with the given ID. Return NULL if it can&#39;t be found...
int nFGDSegments
How many FGD tracks are associated with this track.
Float_t dEdxSigmaMuon
Expected error on the dE/dx measurement, for the muon hypothesis.
Int_t ParentID
The ID of this particle&#39;s immediate parent, or 0 if there is no parent.
Float_t PositionEnd[4]
The end position of the true particle.
AnaTPCParticleB * GetTPCBackSegment(const AnaTrackB *track)
Get the most dowstream TPC segment of the track.
void AddStandardCategories(const std::string &prefix="")
Add the standard categories only, given a prefix for their name.
Float_t Position[4]
The initial position of the true particle.
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)
Representation of a TPC segment of a global track.
Float_t TimeStart
Start time.
Definition: DataClasses.hxx:43
AnaParticleB * GetSegmentWithMostNodesInClosestTpc(const AnaTrackB &track)
Combined function to address NuMu selection needs as efficiently as possible - gets the TPC segment w...
Float_t NuDir[3]
The true (unit) direction of the incoming neutrino.
Definition: DataClasses.hxx:82
Float_t dEdxSigmaPion
Expected error on the dE/dx measurement, for the pion hypothesis.
int GetAllTracksUsingDet(const AnaBunchB &bunch, SubDetId::SubDetEnum det, AnaTrackB *selTracks[])
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
AnaParticleB * GetSegmentWithMostNodesInDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
Method to get the subtrack with most nodes in a given detector.
Representation of a reconstructed particle (track or shower).
Float_t Direction[3]
The initial direction of the true particle.
Representation of a true Monte Carlo trajectory/particle.
Float_t MomentumMuon
Momentum from refitting the track assuming the muon hypothesis.
int GetTrackerDsEcals(AnaTrackB *track, AnaECALParticleB *selTracks[])
Float_t PositionEnd[4]
The reconstructed end position of the particle.