HighLAND
numuCCAnalysis.cxx
1 #include "numuCCAnalysis.hxx"
2 #include "FiducialVolumeDefinition.hxx"
3 #include "Parameters.hxx"
4 #include "UseGlobalAltMomCorrection.hxx"
5 #include "numuCCSelection.hxx"
6 #include "numuCCFGD2Selection.hxx"
7 #include "CategoriesUtils.hxx"
8 #include "BasicUtils.hxx"
9 
10 #include "NuDirUtils.hxx"
11 #include "TreeConverterUtils.hxx"
12 #include "ConfigTreeTools.hxx"
13 
14 //********************************************************************
15 numuCCAnalysis::numuCCAnalysis(AnalysisAlgorithm* ana) : baseTrackerAnalysis(ana) {
16 //********************************************************************
17 
18  // Add the package version
19  ND::versioning().AddPackage("numuCCAnalysis", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("NUMUCCANALYSISROOT")));
20 }
21 
22 //********************************************************************
24 //********************************************************************
25 
26  // Initialize the baseTrackerAnalysis
27  if(!baseTrackerAnalysis::Initialize()) return false;
28 
29  // Minimum accum level to save event into the output tree
30  SetMinAccumCutLevelToSave(ND::params().GetParameterI("numuCCAnalysis.MinAccumLevelToSave"));
31 
32  // which analysis: FGD1, FGD2 or FGDs
33  _whichFGD = ND::params().GetParameterI("numuCCAnalysis.Selections.whichFGD");
34  if (_whichFGD == 3) {
35  std::cout << "----------------------------------------------------" << std::endl;
36  std::cout << "WARNING: only for events with accum_level > 5 the vars in the output microtree will surely refer to the muon candidate in that FGD" << std::endl;
37  std::cout << "----------------------------------------------------" << std::endl;
38  }
39 
40  // Use alternative FV
41  if (ND::params().GetParameterI("numuCCAnalysis.Selections.UseAlternativeFV")) SetFV();
42 
43  // store mass weights in a single entry tree
44  _saveMassWeights = ND::params().GetParameterI("numuCCAnalysis.MicroTrees.SaveMassWeights");
45 
46  // Define categories
47  // for FGD2 same categories with prefix "fgd2", i,e, "fgd2reaction" etc.)
50 
51  return true;
52 }
53 
54 //********************************************************************
55 void numuCCAnalysis::DefineSelections(){
56 //********************************************************************
57 
58  // ----- Inclusive CC -----------
59  if (_whichFGD==1) // FGD1
60  sel().AddSelection("kTrackerNumuCC", "inclusive numuCC selection", new numuCCSelection(false)); // true/false for forcing break
61  else if (_whichFGD==2) // FGD2
62  sel().AddSelection("kTrackerNumuCCFGD2", "inclusive numuCCFGD2 selection", new numuCCFGD2Selection(false)); // true/false for forcing break
63  else if (_whichFGD==3) { // both FGDs, in 2 selections
64  sel().AddSelection("kTrackerNumuCC", "inclusive numuCC selection", new numuCCSelection(false)); // true/false for forcing break
65  sel().AddSelection("kTrackerNumuCCFGD2", "inclusive numuCCFGD2 selection", new numuCCFGD2Selection(false)); // true/false for forcing break
66  }
67 }
68 
69 //********************************************************************
70 void numuCCAnalysis::DefineCorrections(){
71 //********************************************************************
72 
73  // Some corrections are defined in baseTrackerAnalysis
74  baseTrackerAnalysis::DefineCorrections();
75 
76  //------------ Corrections -----------
77 
78  // Change the main fit momentum by the muon alternate momentum, but only for P5
79 #if !VERSION_HAS_EQUIVALENT_MAIN_AND_ALT_FITS
80  if (ND::params().GetParameterI("numuCCAnalysis.Corrections.EnableUseMuonAltMom") == 1) {
81  corr().AddCorrection("altmom_corr", new UseGlobalAltMomCorrection(UseGlobalAltMomCorrection::kMuon));
82  }
83 #endif
84 
85 }
86 
87 //********************************************************************
89 //********************************************************************
90 
91  // Fill the single entry in the massWeightTree once all events have been processed
92  if (_saveMassWeights)
93  output().GetTree(massWeightTree)->Fill();
94 }
95 
96 //********************************************************************
97 void numuCCAnalysis::DefineMicroTrees(bool addBase){
98 //********************************************************************
99 
100  // -------- Add variables to the analysis tree ----------------------
101 
102  // Variables from baseTrackerAnalysis (run, event, ...)
103  if (addBase) baseTrackerAnalysis::DefineMicroTrees(addBase);
104 
105  // --- muon candidate truth variables ---
106  AddVarF( output(), selmu_truemom, "muon candidate true momentum");
107  AddVar4VF(output(), selmu_truepos, "muon candidate true position");
108  AddVar4VF(output(), selmu_trueendpos, "muon candidate true end position");
109  AddVar3VF(output(), selmu_truedir, "muon candidate true direction");
110 
111  // --- true lepton truth variables ---
112  AddVarI(output(), truelepton_pdg, "true lepton PDG");
113  AddVarF(output(), truelepton_mom, "true lepton true momentum");
114  AddVarF(output(), truelepton_costheta, "true lepton true cos(theta) w.r.t. neutrino direction");
115  // AddVarI(output(), truelepton_det, "detector enum of the true lepton start position"); // equivalent to detector but in different detector convention
116 
117  // --- muon candidate recon variables ---
118  AddVar3VF(output(), selmu_dir, "muon candidate reconstructed direction");
119  AddVar3VF(output(), selmu_enddir, "muon candidate reconstructed end direction");
120  AddVar4VF(output(), selmu_pos, "muon candidate reconstructed position");
121  AddVar4VF(output(), selmu_endpos, "muon candidate reconstructed end position");
122 
123  AddVarI( output(), selmu_closest_tpc,"muon candidate closest TPC");
124  AddVarI( output(), selmu_detectors, "muon candidate detectors");
125  AddVarI( output(), selmu_det, "detector enum of the muon candidate start position");
126 
127  AddToyVarF(output(), selmu_mom, "muon candidate reconstructed momentum");
128  AddToyVarF(output(), selmu_costheta, "muon candidate reconstructed cos(theta). w.r.t. to neutrino direction");
129 
130  // --- reconstructed neutrino energy ----
131  // (true neutrino energy is already saved in basAnalysis as nu_trueE)
132  AddToyVarF(output(), selmu_nuErecQE, "neutrino reconstructed energy with muon candidate's reconstructed kinematics in ccqe formula");
133  AddVarF(output(), truelepton_nuErecQE, "neutrino reconstructed energy with true lepton kinematics in CCQE formula");
134 
135  if (ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")){
136  AddToyVarF(output(), selmu_amom, "muon candidate alternate reconstructed momentum ");
137  AddToyVarF(output(), selmu_likemu, "muon candidate muon TPC PID likelihood");
138  AddToyVarF(output(), selmu_likemip, "muon candidate MIP TPC PID likelihood");
139  AddToyVarF(output(), shmn_mom, "second highest momentum negative track reconstructed momentum ");
140  }
141  else{
142  AddVarF(output(), selmu_amom, "muon candidate alternate reconstructed momentum ");
143  AddVarF(output(), selmu_likemu, "muon candidate muon TPC PID likelihood");
144  AddVarF(output(), selmu_likemip, "muon candidate MIP TPC PID likelihood");
145  AddVarF(output(), shmn_mom, "second highest momentum negative track reconstructed momentum ");
146  }
147 
148  // --- info by tpc
149  AddVarVI(output(), selmu_tpc_det, "muon candidate TPC number", selmu_ntpcs);
150  AddVarVI(output(), selmu_tpc_nhits, "muon candidate #hits in each TPC", selmu_ntpcs);
151  AddVarVI(output(), selmu_tpc_nnodes, "muon candidate #nodes in each TPC", selmu_ntpcs);
152  AddVarVF(output(), selmu_tpc_charge, "muon candidate reconstructed charge in each TPC", selmu_ntpcs);
153  AddVarVF(output(), selmu_tpc_mom, "muon candidate reconstructed momentum in each TPC", selmu_ntpcs);
154  AddVarVF(output(), selmu_tpc_bfield_mom, "muon candidate reconstructed momentum with BField refit in each TPC", selmu_ntpcs);
155  AddVarVF(output(), selmu_tpc_efield_mom, "muon candidate reconstructed momentum with EFiled refit in each TPC", selmu_ntpcs);
156  AddVarVF(output(), selmu_tpc_emom, "muon candidate reconstructed momentum error in each TPC", selmu_ntpcs);
157  AddVarVF(output(), selmu_tpc_truemom, "muon candidate true momentum in each TPC", selmu_ntpcs);
158  AddVarVF(output(), selmu_tpc_dedx_raw, "muon candidate raw dEdx (CT) in each TPC", selmu_ntpcs);
159  AddVarVF(output(), selmu_tpc_dedx_expmu, "muon candidate expected dEdx for muons in each TPC", selmu_ntpcs);
160  AddVarVF(output(), selmu_tpc_dedx_exppi, "muon candidate expected dEdx for pions in each TPC", selmu_ntpcs);
161  AddVarVF(output(), selmu_tpc_dedx_expele, "muon candidate expected dEdx for electrons in each TPC", selmu_ntpcs);
162  AddVarVF(output(), selmu_tpc_dedx_expp, "muon candidate expected dEdx for protons in each TPC", selmu_ntpcs);
163 
164  if (ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")){
165  AddToyVarVF(output(), selmu_tpc_pullmu, "muon candidate muon pull in each TPC", NMAXTPCS);
166  AddToyVarVF(output(), selmu_tpc_pullpi, "muon candidate pion pull in each TPC", NMAXTPCS);
167  AddToyVarVF(output(), selmu_tpc_pullele, "muon candidate electron pull in each TPC", NMAXTPCS);
168  AddToyVarVF(output(), selmu_tpc_pullp, "muon candidate proton pull in each TPC", NMAXTPCS);
169  AddToyVarVF(output(), selmu_tpc_dedx, "muon candidate dEdx (CT) in each TPC", NMAXTPCS);
170  }
171  else{
172  AddVarVF(output(), selmu_tpc_pullmu, "muon candidate muon pull in each TPC", selmu_ntpcs);
173  AddVarVF(output(), selmu_tpc_pullpi, "muon candidate pion pull in each TPC", selmu_ntpcs);
174  AddVarVF(output(), selmu_tpc_pullele, "muon candidate electron pull in each TPC", selmu_ntpcs);
175  AddVarVF(output(), selmu_tpc_pullp, "muon candidate proton pull in each TPC", selmu_ntpcs);
176  AddVarVF(output(), selmu_tpc_dedx, "muon candidate dEdx (CT) in each TPC", selmu_ntpcs);
177  }
178 
179  // --- info by FGD
180  AddVarVI(output(), selmu_fgd_det, "fgd index of muon candidate's fgd segments", selmu_nfgds);
181  AddVarVF(output(), selmu_fgd_x, "muon candidate track length in each FGD", selmu_nfgds);
182  AddVarVF(output(), selmu_fgd_V11, "muon candidate V11 vertex activity in each FGD", selmu_nfgds);
183  AddVarVF(output(), selmu_fgd_V33, "muon candidate V33 vertex activity in each FGD", selmu_nfgds);
184  AddVarVF(output(), selmu_fgd_V55, "muon candidate V55 vertex activity in each FGD", selmu_nfgds);
185  AddVarVF(output(), selmu_fgd_V77, "muon candidate V77 vertex activity in each FGD", selmu_nfgds);
186  AddVarVF(output(), selmu_fgd_VLayer,"muon candidate VLayer vertex activity in each FGD", selmu_nfgds);
187 
188  if (ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")){
189  AddToyVarVF(output(), selmu_fgd_pullmu,"muon candidate muon pull in each FGD ", NMAXFGDS);
190  }
191  else{
192  AddVarVF(output(), selmu_fgd_pullmu,"muon candidate muon pull in each FGD ", selmu_nfgds);
193  }
194 
195  // --- info by ECAL
196  AddVarVI(output(), selmu_ecal_det, "ECal sub-module", selmu_necals);
197  AddVarVI(output(), selmu_ecal_nhits, "The number of hits in the selected track's ECal segment", selmu_necals);
198  AddVarVI(output(), selmu_ecal_nnodes, "", selmu_necals);
199  AddVarVF(output(), selmu_ecal_length, "", selmu_necals);
200  AddVarMF(output(), selmu_ecal_showerstartpos, "", selmu_necals,-30,4);
201  AddVarMF(output(), selmu_ecal_showerendpos, "", selmu_necals,-30,4);
202  AddVarMF(output(), selmu_ecal_showerstartdir, "", selmu_necals,-30,3);
203  AddVarMF(output(), selmu_ecal_showerenddir, "", selmu_necals,-30,3);
204 
205  AddVarVF(output(), selmu_ecal_EMenergy, "", selmu_necals);
206  AddVarVF(output(), selmu_ecal_edeposit, "", selmu_necals);
207  AddVarVI(output(), selmu_ecal_IsShower, "", selmu_necals);
208 
209  AddVarVF(output(), selmu_ecal_mipem, "MipEm value of the selected track's ECal segment. Negative means more MIP-like, positive means more EM shower-like", selmu_necals);
210  AddVarVF(output(), selmu_ecal_mippion, "MipPion value the selected track's ECal segment. Negative means more MIP-like, positive means more showering pion-like", selmu_necals);
211  AddVarVF(output(), selmu_ecal_emhip, "EmHip value of the selected track's ECal segment. Negative means more EM shower-like, positive means more HIP-like.", selmu_necals);
212  AddVarVF(output(), selmu_ecal_containment, "", selmu_necals);
213  AddVarVF(output(), selmu_ecal_trshval, "", selmu_necals);
214  AddVarVI(output(), selmu_ecal_mostupstreamlayerhit, "", selmu_necals);
215 
216  // --- info by SMRD
217  AddVarVI(output(), selmu_smrd_det, "", selmu_nsmrds);
218  AddVarVI(output(), selmu_smrd_nhits, "", selmu_nsmrds);
219  AddVarVI(output(), selmu_smrd_nnodes, "", selmu_nsmrds);
220  AddVarMF(output(), selmu_smrd_dir, "", selmu_nsmrds, -30, 3);
221  AddVarMF(output(), selmu_smrd_enddir, "", selmu_nsmrds, -30, 3);
222  AddVarVF(output(), selmu_smrd_edeposit, "", selmu_nsmrds);
223 
224  // Variables to handle the number of targets in xsTool
225  AddToyVarI(output(), truevtx_mass_component, "mass component enum related to the true vtx position (FGD1 / FGD2_scint / FGD2_water");
226 
227  //------- TEMPORARILY HERE. Add a single entry tree to store the mass weights for each mass component ---------------------
228 
229  if (_saveMassWeights){
230  // Add the tree
231  AddTree(output(),massWeightTree,NULL);
232 
233  // Add mass weight for each toy and each target
234  output().AddMatrixVar(massWeightTree,massWeight, "massWeight","F", "mass weight (FGD1, FGD1scint, FGD1water)",100,3);
235 
236  // initialize that tree
237  output().InitializeTree(massWeightTree, true);
238  }
239 }
240 
241 //********************************************************************
242 void numuCCAnalysis::DefineTruthTree(){
243 //********************************************************************
244 
245  // Variables from baseTrackerAnalysis (run, event, ...)
246  baseTrackerAnalysis::DefineTruthTree();
247 
248  // Variables to handle the number of targets in xsTool
249  AddVarI(output(), truevtx_mass_component, "mass component enum related to the true vtx position (FGD1 / FGD2_scint / FGD2_water");
250 
251  // --- reconstructed neutrino energy ----
252  AddVarF(output(), truelepton_nuErecQE, "neutrino reconstructed energy with true lepton kinematics in CCQE formula");
253 }
254 
255 //********************************************************************
256 void numuCCAnalysis::FillMicroTrees(bool addBase){
257 //********************************************************************
258 
259  // WARNING: IF YOU RUN FGD1 AND FGD2 AT ONCE ( "whichFGD" parameter = 3), only for events with accum_level > 5
260  // the vars in the output microtree will surely refer to the muon candidate in that FGD
261 
262  // Variables from baseTrackerAnalysis (run, event, ...)
263  if (addBase) baseTrackerAnalysis::FillMicroTrees(addBase);
264 
265  // Muon candidate variables
266  if (box().MainTrack){
267 
268  // Properties of the true muon
269  if (box().MainTrack->TrueObject) {
270  AnaTrueVertex *vtx = static_cast<AnaTrueVertex*>(box().MainTrack->GetTrueParticle()->TrueVertex);
271  if (vtx) {
272  output().FillVar(truelepton_pdg, vtx->LeptonPDG);
273  output().FillVar(truelepton_mom, vtx->LeptonMom);
274  double costheta_mu_nu = cos(anaUtils::ArrayToTVector3(vtx->LeptonDir).Angle(anaUtils::ArrayToTVector3(vtx->NuDir)));
275  output().FillVar(truelepton_costheta, (Float_t)costheta_mu_nu);
276  // output().FillVar(truelepton_det, anaUtils::GetDetector(vtx->Position)); // equivalent to detector but in different detector convention
277  Float_t Erec = anaUtils::ComputeRecNuEnergyCCQE(vtx->LeptonMom, units::mass_muon, costheta_mu_nu);
278  output().FillVar(truelepton_nuErecQE, Erec);
279  } // end if (vtx)
280  } // end if (MainTrack->TrueObject)
281 
282  output().FillVectorVarFromArray(selmu_pos, box().MainTrack->PositionStart, 4);
283  output().FillVectorVarFromArray(selmu_endpos, box().MainTrack->PositionEnd, 4);
284  output().FillVectorVarFromArray(selmu_dir, box().MainTrack->DirectionStart, 3);
285  output().FillVectorVarFromArray(selmu_enddir, box().MainTrack->DirectionEnd, 3);
286  output().FillVar(selmu_det, anaUtils::GetDetector(box().MainTrack->PositionStart));
287 
288 
289 
290  // Additional Toy Vars
291  if (!ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")){
292  output().FillVar(selmu_amom, (static_cast<AnaTrack*>(box().MainTrack))->MomentumMuon);
293  // PID likelihoods
294  output().FillVar(selmu_likemu, anaUtils::GetPIDLikelihood( *(box().MainTrack),0));
295  output().FillVar(selmu_likemip,anaUtils::GetPIDLikelihoodMIP( *(box().MainTrack)));
296  }
297 
298  // Properties of the true particle associated to the muon candidate
299  if( box().MainTrack->TrueObject ) {
300  output().FillVar(selmu_truemom, box().MainTrack->GetTrueParticle()->Momentum);
301  output().FillVectorVarFromArray(selmu_truepos, box().MainTrack->GetTrueParticle()->Position, 4);
302  output().FillVectorVarFromArray(selmu_trueendpos,box().MainTrack->GetTrueParticle()->PositionEnd, 4);
303  output().FillVectorVarFromArray(selmu_truedir, box().MainTrack->GetTrueParticle()->Direction, 3);
304  }
305 
306  // The closest TPC
307  SubDetId::SubDetEnum tpc = anaUtils::GetClosestTPC(*(box().MainTrack));
308  output().FillVar(selmu_closest_tpc, tpc+1);
309 
310  // Track composition
311  output().FillVar(selmu_detectors, static_cast<AnaTrack*>(box().MainTrack)->Detectors);
312 
313  // Info in all TPCs
314 
315  for (Int_t subdet = 0; subdet<3; subdet++) {
316  if (!SubDetId::GetDetectorUsed(box().MainTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet+2))) continue;
317  AnaTPCParticle* TPCSegment = static_cast<AnaTPCParticle*>(anaUtils::GetSegmentInDet( *box().MainTrack,static_cast<SubDetId::SubDetEnum >(subdet+2)));
318  if (!TPCSegment) continue;
319  output().FillVectorVar(selmu_tpc_det, subdet);
320  output().FillVectorVar(selmu_tpc_mom, TPCSegment->Momentum);
321 
322  output().FillVectorVar(selmu_tpc_bfield_mom, TPCSegment->RefitMomentum);
323  output().FillVectorVar(selmu_tpc_efield_mom, TPCSegment->EFieldRefitMomentum);
324  output().FillVectorVar(selmu_tpc_charge, TPCSegment->Charge);
325  output().FillVectorVar(selmu_tpc_nhits, TPCSegment->NHits);
326  output().FillVectorVar(selmu_tpc_nnodes, TPCSegment->NNodes);
327  output().FillVectorVar(selmu_tpc_emom, TPCSegment->MomentumError);
328 
329  if (TPCSegment->TrueObject)
330  output().FillVectorVar(selmu_tpc_truemom, TPCSegment->GetTrueParticle()->Momentum);
331 
332  if (TPCSegment->Original->Original)
333  output().FillVectorVar(selmu_tpc_dedx_raw, (static_cast< const AnaTPCParticle* >(TPCSegment->Original->Original))->dEdxMeas);
334 
335  output().FillVectorVar(selmu_tpc_dedx_expmu, TPCSegment->dEdxexpMuon);
336  output().FillVectorVar(selmu_tpc_dedx_exppi, TPCSegment->dEdxexpPion);
337  output().FillVectorVar(selmu_tpc_dedx_expele, TPCSegment->dEdxexpEle);
338  output().FillVectorVar(selmu_tpc_dedx_expp, TPCSegment->dEdxexpProton);
339 
340  if (!ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")){
341  output().FillVectorVar(selmu_tpc_dedx, TPCSegment->dEdxMeas);
342  output().FillVectorVar(selmu_tpc_pullmu, TPCSegment->Pullmu);
343  output().FillVectorVar(selmu_tpc_pullpi, TPCSegment->Pullpi);
344  output().FillVectorVar(selmu_tpc_pullele,TPCSegment->Pullele);
345  output().FillVectorVar(selmu_tpc_pullp, TPCSegment->Pullp);
346  }
347 
348  output().IncrementCounterForVar(selmu_tpc_det);
349  }
350 
351  // Info in all FGDs
352  for (Int_t subdet = 0; subdet<2; subdet++) {
353  if (!SubDetId::GetDetectorUsed(box().MainTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet))) continue;
354  AnaFGDParticle* FGDSegment = static_cast<AnaFGDParticle*>(anaUtils::GetSegmentInDet( *box().MainTrack,static_cast<SubDetId::SubDetEnum >(subdet)));
355  if (!FGDSegment) continue;
356 
357  // output().FillVectorVar("selmu_fgd_det", (Int_t)FGDSegment->Detector);
358  output().FillVectorVar(selmu_fgd_det, subdet);
359  output().FillVectorVar(selmu_fgd_x, FGDSegment->X);
360  output().FillVectorVar(selmu_fgd_V11, FGDSegment->Vertex1x1);
361  output().FillVectorVar(selmu_fgd_V33, FGDSegment->Vertex3x3);
362  output().FillVectorVar(selmu_fgd_V55, FGDSegment->Vertex5x5);
363  output().FillVectorVar(selmu_fgd_V77, FGDSegment->Vertex7x7);
364  output().FillVectorVar(selmu_fgd_VLayer, FGDSegment->VertexLayer);
365 
366  if (!ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars"))
367  output().FillVectorVar(selmu_fgd_pullmu, FGDSegment->Pullmu);
368 
369  output().IncrementCounterForVar(selmu_fgd_det);
370  }
371 
372  // Info in all ECALs
373  for (Int_t subdet = 0; subdet<9; subdet++) {
374  if (!SubDetId::GetDetectorUsed(box().MainTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet+6))) continue;
375 
376  AnaECALParticle* ECALSegment = static_cast<AnaECALParticle*>(anaUtils::GetSegmentInDet( *box().MainTrack,static_cast<SubDetId::SubDetEnum >(subdet+6)));
377 
378  if (!ECALSegment) continue;
379 
380  output().FillVectorVar(selmu_ecal_det, subdet);
381  output().FillVectorVar(selmu_ecal_nhits, ECALSegment->NHits);
382  output().FillVectorVar(selmu_ecal_nnodes, ECALSegment->NNodes);
383  output().FillVectorVar(selmu_ecal_length, ECALSegment->Length);
384  output().FillMatrixVarFromArray(selmu_ecal_showerstartpos, ECALSegment->PositionStart, 4 );
385  output().FillMatrixVarFromArray(selmu_ecal_showerendpos, ECALSegment->PositionEnd, 4 );
386  output().FillMatrixVarFromArray(selmu_ecal_showerstartdir, ECALSegment->DirectionStart, 3 );
387  output().FillMatrixVarFromArray(selmu_ecal_showerenddir, ECALSegment->DirectionEnd, 3 );
388 
389  output().FillVectorVar(selmu_ecal_EMenergy, ECALSegment->EMEnergy);
390  output().FillVectorVar(selmu_ecal_edeposit, ECALSegment->EDeposit);
391  output().FillVectorVar(selmu_ecal_IsShower, ECALSegment->IsShowerLike);
392 
393  output().FillVectorVar(selmu_ecal_trshval, ECALSegment->TrShVal);
394  output().FillVectorVar(selmu_ecal_emhip, ECALSegment->PIDEmHip);
395  output().FillVectorVar(selmu_ecal_mippion, ECALSegment->PIDMipPion);
396  output().FillVectorVar(selmu_ecal_mipem, ECALSegment->PIDMipEm);
397  output().FillVectorVar(selmu_ecal_containment, ECALSegment->Containment);
398  output().FillVectorVar(selmu_ecal_mostupstreamlayerhit, ECALSegment->MostUpStreamLayerHit);
399 
400  output().IncrementCounterForVar(selmu_ecal_det);
401 
402  }
403 
404  // Info in SMRDs
405  for (Int_t i = 0; i < box().MainTrack->nSMRDSegments; i++){
406  AnaSMRDParticle* smrdTrack = static_cast<AnaSMRDParticle*>(box().MainTrack->SMRDSegments[i]);
407  if (!smrdTrack) continue;
408 
409  output().FillVectorVar(selmu_smrd_det,
411  output().FillVectorVar(selmu_smrd_nhits, smrdTrack->NHits);
412  output().FillVectorVar(selmu_smrd_nnodes, smrdTrack->NNodes);
413  output().FillVectorVar(selmu_smrd_edeposit, smrdTrack->EDeposit);
414  output().FillMatrixVarFromArray(selmu_smrd_dir, smrdTrack->DirectionStart, 3 );
415  output().FillMatrixVarFromArray(selmu_smrd_enddir, smrdTrack->DirectionEnd, 3 );
416  output().IncrementCounterForVar(selmu_smrd_det);
417  }
418 
419  } // end if MainTrack
420 
421  if ( ! ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")) {
422  if (box().SHMNtrack) output().FillVar(shmn_mom, box().SHMNtrack->Momentum);
423  }
424 
425 }
426 
427 //********************************************************************
428 void numuCCAnalysis::FillToyVarsInMicroTrees(bool addBase){
429 //********************************************************************
430 
431  // Fill all tree variables that vary for each virtual analysis (toy experiment)
432 
433  // Fill the common variables
434  if (addBase) baseTrackerAnalysis::FillToyVarsInMicroTrees(addBase);
435 
436  // variables specific for this analysis
437  if (box().MainTrack){
438 
439  // Momentum
440  output().FillToyVar(selmu_mom, box().MainTrack->Momentum);
441 
442  // Costheta
443  // vertex defined as start of muon track, neutrino direction calculated from this
444  TVector3 nuDirVec = anaUtils::GetNuDirRec(box().MainTrack->PositionStart);
445  TVector3 muDirVec = anaUtils::ArrayToTVector3(box().MainTrack->DirectionStart);
446  // The cosine of the angle between the muon and the neutrino
447  double costheta_mu_nu = nuDirVec.Dot(muDirVec);
448  output().FillToyVar(selmu_costheta, (Float_t)costheta_mu_nu);
449 
450  // Erec
451  Float_t Erec = anaUtils::ComputeRecNuEnergyCCQE(box().MainTrack->Momentum, units::mass_muon, costheta_mu_nu);
452  output().FillToyVar(selmu_nuErecQE, Erec);
453 
454  if (ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")){
455  output().FillToyVar(selmu_amom, (static_cast<AnaTrack*>(box().MainTrack))->MomentumMuon);
456  // PID likelihoods
457  output().FillToyVar(selmu_likemu, anaUtils::GetPIDLikelihood( *(box().MainTrack),0));
458  output().FillToyVar(selmu_likemip,anaUtils::GetPIDLikelihoodMIP( *(box().MainTrack)));
459 
460  // Info in all TPCs
461  for (Int_t subdet = 0; subdet<3; subdet++) {
462  if (!SubDetId::GetDetectorUsed(box().MainTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet+2))) continue;
463  AnaTPCParticle* TPCSegment = static_cast<AnaTPCParticle*>(anaUtils::GetSegmentInDet( *box().MainTrack, static_cast<SubDetId::SubDetEnum >(subdet+2)));
464  if (!TPCSegment) continue;
465  output().FillToyVectorVar(selmu_tpc_dedx, TPCSegment->dEdxMeas, subdet);
466  output().FillToyVectorVar(selmu_tpc_pullmu, TPCSegment->Pullmu, subdet);
467  output().FillToyVectorVar(selmu_tpc_pullpi, TPCSegment->Pullpi, subdet);
468  output().FillToyVectorVar(selmu_tpc_pullele,TPCSegment->Pullele, subdet);
469  output().FillToyVectorVar(selmu_tpc_pullp, TPCSegment->Pullp, subdet);
470  }
471 
472  // Info in all FGDs
473  for (Int_t subdet = 0; subdet<2; subdet++) {
474  if (!SubDetId::GetDetectorUsed(box().MainTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet))) continue;
475  AnaFGDParticle* FGDSegment = static_cast<AnaFGDParticle*>(anaUtils::GetSegmentInDet(*(box().MainTrack), static_cast<SubDetId::SubDetEnum >(subdet)));
476  if (!FGDSegment) continue;
477  output().FillToyVectorVar(selmu_fgd_pullmu, FGDSegment->Pullmu, subdet);
478  }
479  }
480 
481  // if there is a true vertex associated
482  if(box().MainTrack->TrueObject) {
483  AnaTrueVertex *vtx = static_cast<AnaTrueVertex*>(box().MainTrack->GetTrueParticle()->TrueVertex);
484  if (vtx) {
485  // Fill the mass component related to the mass weight
486  anaUtils::massComponentEnum massComponent = anaUtils::GetMassComponent(GetEvent().GetIsMC(), vtx->Position);
487  output().FillToyVar(truevtx_mass_component, massComponent);
488 
489  // Fill whether it is signal or bkg
490  if (anaUtils::GetReactionCC(*vtx, SubDetId::kFGD1) == 1)
491  output().FillToyVar(true_signal, 1);
492  else if (anaUtils::GetReactionCC(*vtx, SubDetId::kFGD2) == 1)
493  output().FillToyVar(true_signal, 2);
494  else
495  output().FillToyVar(true_signal, 0);
496 
497 
498  static Int_t mass_weight_index=-2;
499  if (_saveMassWeights && conf().GetCurrentConfigurationIndex() == all_syst && mass_weight_index!=-1){
500  // Get the index of the mass weight in the all_syst configuration, but only once
501  if (mass_weight_index==-2){
502  ConfigTreeTools config(syst(),conf());
503  mass_weight_index = config.GetWeightIndex(all_syst, SystId::kFgdMass);
504  }
505  if (mass_weight_index>=0){
506  Float_t massWeightValue = output().GetToyVectorVarValueF(AnalysisAlgorithm::weight_syst, mass_weight_index);
507 
508  // Get the current tree
509  Int_t index = output().GetCurrentTree();
510 
511  // Set as current tree the massWeightTree
512  output().SetCurrentTree(massWeightTree);
513 
514  Int_t massComponentIndex=-1;
515  if (massComponent == anaUtils::kFGD1) massComponentIndex=0;
516  else if (massComponent == anaUtils::kFGD2xymodules) massComponentIndex=1;
517  else if (massComponent == anaUtils::kFGD2watermodules) massComponentIndex=2;
518 
519  // if not yet filled fill it
520  if (massComponentIndex>= 0 && output().GetMatrixVarValueF(massWeight, output().GetToyIndex(),massComponentIndex) <=0)
521  output().FillMatrixVar( massWeight, massWeightValue, output().GetToyIndex(),massComponentIndex);
522 
523  // Go back to the standard current tree
524  output().SetCurrentTree(index);
525  }
526  }
527  }
528  }
529 
530  } // end if MainTrack
531 
532 
533  if (ND::params().GetParameterI("numuCCAnalysis.MicroTrees.AdditionalToyVars")){
534  if (box().SHMNtrack){
535  output().FillToyVar(shmn_mom, box().SHMNtrack->Momentum);
536  }
537  }
538 
539 }
540 
541 //********************************************************************
542 bool numuCCAnalysis::CheckFillTruthTree(const AnaTrueVertex& vtx){
543 //********************************************************************
544  SubDetId::SubDetEnum fgdID;
545  if (_whichFGD == 1) fgdID = SubDetId::kFGD1;
546  if (_whichFGD == 2) fgdID = SubDetId::kFGD2;
547  if (_whichFGD > 2) fgdID = SubDetId::kFGD;
548  // GetReactionCC already takes into account the outFV and also
549  // the NuWro reaction code for 2p2h in prod5 (that is 70)
550  bool numuCCinFV = (anaUtils::GetReactionCC(vtx, fgdID) == 1);
551  return (numuCCinFV);
552 }
553 
554 //********************************************************************
555 void numuCCAnalysis::FillTruthTree(const AnaTrueVertex& vtx){
556 //********************************************************************
557 
558  // workaround to use the same code for the antuNumu package
559  // calling numuCCAnalysis::FillTruthTreeBase(vtx,true)
560  bool IsAntinu = false;
561  return FillTruthTreeBase(vtx, IsAntinu);
562 }
563 
564 //********************************************************************
565 void numuCCAnalysis::FillTruthTreeBase(const AnaTrueVertex& vtx, bool IsAntinu){
566 //********************************************************************
567 
568  // this method is also called from the antiNumu package with IsAntinu = true
569 
570  // Fill the common variables
571  baseTrackerAnalysis::FillTruthTreeBase(vtx, SubDetId::kFGD1, IsAntinu);
572 
573  // Muon true-rec association.
574  // if (box().MainTrack)
575  // if (box().MainTrack->TrueObject)
576  // output().FillVar("mu_true_rec", (box().MainTrack->GetTrueParticle()->PDG==13)); // Is the recon muon a true muon ?
577 
578  // Fill truth categories for FGD2, same categories with prefix "fgd2", i,e, "fgd2reaction" etc.
579  // We could directly set which FGD in the usual categories, but this is not possible for the true vertices
580  anaUtils::FillCategories(&vtx, "fgd2", SubDetId::kFGD2, IsAntinu,GetSpill().GetIsSandMC());
581 
582  // Fill whether it is signal or bkg
583  if (anaUtils::GetReactionCC(vtx, SubDetId::kFGD1, IsAntinu) == 1)
584  output().FillVar(true_signal, 1);
585  else if (anaUtils::GetReactionCC(vtx, SubDetId::kFGD2, IsAntinu) == 1)
586  output().FillVar(true_signal, 2);
587  else
588  output().FillVar(true_signal, 0);
589 
590  // Fill the mass component related to the mass weight
591  anaUtils::massComponentEnum massComponent = anaUtils::GetMassComponent(GetSpill().GetIsMC(), vtx.Position);
592  output().FillVar(truevtx_mass_component, massComponent);
593 
594  // Fill the reconstructed energy with true lepton kinematics in CCQE formula
595  double costheta_mu_nu = cos(anaUtils::ArrayToTVector3(vtx.LeptonDir).Angle(anaUtils::ArrayToTVector3(vtx.NuDir)));
596  Float_t Erec = anaUtils::ComputeRecNuEnergyCCQE(vtx.LeptonMom, units::mass_muon, costheta_mu_nu);
597  output().FillVar(truelepton_nuErecQE, Erec);
598 }
599 
600 //********************************************************************
601 void numuCCAnalysis::FillCategories(){
602 //********************************************************************
603 
604  // Fill the track categories for color drawing
605 
606  // For the muon candidate
607  anaUtils::FillCategories(&GetEvent(), static_cast<AnaTrack*>(box().MainTrack),"", SubDetId::kFGD1);
608 
609  // For FGD2, same categories with prefix "fgd2", i,e, "fgd2reaction" etc.
610  // We could directly set which FGD in the usual categories, but this cannot be done for the true vertices
611  anaUtils::FillCategories(&GetEvent(), static_cast<AnaTrack*>(box().MainTrack), "fgd2", SubDetId::kFGD2);
612 }
613 
614 //********************************************************************
615 void numuCCAnalysis::FillConfigTree(){
616 //********************************************************************
617 
618  // Add and fill number of nucleons in each of the targets
619  AddVarD(output(), nNucleonsFGD1, "number of targets in FGD1");
620  AddVarD(output(), nNucleonsFGD2scint, "number of targets in FGD2 scintillator");
621  AddVarD(output(), nNucleonsFGD2water, "number of targets in FGD2 water");
622 
623  output().FillVar(nNucleonsFGD1, anaUtils::GetNTargets(anaUtils::kFGD1));
624  output().FillVar(nNucleonsFGD2scint, anaUtils::GetNTargets(anaUtils::kFGD2xymodules));
625  output().FillVar(nNucleonsFGD2water, anaUtils::GetNTargets(anaUtils::kFGD2watermodules));
626 
627 }
628 
629 //********************************************************************
630 void numuCCAnalysis::SetFV(){
631 //********************************************************************
632 
633  // Use reduced FV (needed before numuCCAnalysis->Initialize which calls GetNTargets)
634  if (ND::params().GetParameterI("numuCCAnalysis.Selections.UseAlternativeFV")) {
635 
636  // make FGD1 and FGD2 FV identical
637 
638  // use smaller FV in X and Y
639  double FVXmin = TMath::Max(FVDef::FVdefminFGD1[0], FVDef::FVdefminFGD2[0]);
640  double FVXmax = TMath::Max(FVDef::FVdefmaxFGD1[0], FVDef::FVdefmaxFGD2[0]);
641  double FVYmin = TMath::Max(FVDef::FVdefminFGD1[1], FVDef::FVdefminFGD2[1]);
642  double FVYmax = TMath::Max(FVDef::FVdefmaxFGD1[1], FVDef::FVdefmaxFGD2[1]);
643  FVDef::FVdefminFGD1[0] = FVDef::FVdefminFGD2[0] = FVXmin;
644  FVDef::FVdefmaxFGD1[0] = FVDef::FVdefmaxFGD2[0] = FVXmax;
645  FVDef::FVdefminFGD1[1] = FVDef::FVdefminFGD2[1] = FVYmin;
646  FVDef::FVdefmaxFGD1[1] = FVDef::FVdefmaxFGD2[1] = FVYmax;
647 
648  // discard first and last layer of both FGDs
649  // (official FV only discards first layer of FGD2 and first two layers of FGD1)
650  double halfmodule = DetDef::fgdXYModuleWidth/2.;
651  FVDef::FVdefminFGD1[2] = FVDef::FVdefminFGD2[2] = halfmodule;
652  FVDef::FVdefmaxFGD1[2] = FVDef::FVdefmaxFGD2[2] = halfmodule;
653 
654  // cout new values
655  std::cout << "Using an alternative Fiducial Volume: " << std::endl;
656  std::cout << " DetDef::fgd1min = " << DetDef::fgd1min[0] << " "
657  << DetDef::fgd1min[1] << " "
658  << DetDef::fgd1min[2]
659  << std::endl;
660  std::cout << " DetDef::fgd1max = " << DetDef::fgd1max[0] << " "
661  << DetDef::fgd1max[1] << " "
662  << DetDef::fgd1max[2]
663  << std::endl;
664  std::cout << " DetDef::fgd2min = " << DetDef::fgd2min[0] << " "
665  << DetDef::fgd2min[1] << " "
666  << DetDef::fgd2min[2]
667  << std::endl;
668  std::cout << " DetDef::fgd2max = " << DetDef::fgd2max[0] << " "
669  << DetDef::fgd2max[1] << " "
670  << DetDef::fgd2max[2]
671  << std::endl;
672  std::cout << " FVDef::FVdefminFGD1 = " << FVDef::FVdefminFGD1[0] << " "
673  << FVDef::FVdefminFGD1[1] << " "
674  << FVDef::FVdefminFGD1[2]
675  << std::endl;
676  std::cout << " FVDef::FVdefmaxFGD1 = " << FVDef::FVdefmaxFGD1[0] << " "
677  << FVDef::FVdefmaxFGD1[1] << " "
678  << FVDef::FVdefmaxFGD1[2]
679  << std::endl;
680  std::cout << " FVDef::FVdefminFGD2 = " << FVDef::FVdefminFGD2[0] << " "
681  << FVDef::FVdefminFGD2[1] << " "
682  << FVDef::FVdefminFGD2[2]
683  << std::endl;
684  std::cout << " FVDef::FVdefmaxFGD2 = " << FVDef::FVdefmaxFGD2[0] << " "
685  << FVDef::FVdefmaxFGD2[1] << " "
686  << FVDef::FVdefmaxFGD2[2]
687  << std::endl;
688  }
689 }
Float_t dEdxexpMuon
Expected dE/dx for a muon, based on the reconstructed momentum.
Float_t Pullmu
Muon pull of the segment: (dEdxMeas-dEdxexpMuon)/dEdxSigmaMuon.
Float_t PositionStart[4]
The reconstructed start position of the particle.
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 dEdxexpProton
Expected dE/dx for a proton, based on the reconstructed momentum.
void Finalize()
[AnalysisAlgorithm_optional]
Float_t LeptonDir[3]
The direction of the primary outgoing electron/muon.
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 Pullpi
Pion pull of the segment: (dEdxMeas-dEdxexpPion)/dEdxSigmaPion.
Int_t NNodes
The number of nodes in the reconstructed object.
SubDetId::SubDetEnum GetClosestTPC(const AnaTrackB &track)
For tracks that start in the FGD, get the closest TPC in the direction of the track.
Float_t Vertex1x1
Vertex activity variables.
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.
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
bool Initialize()
[AnalysisAlgorithm_mandatory]
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.
SubDetId::SubDetEnum GetDetector(const Float_t *pos)
Return the detector in which the position is.
AnaParticleB * GetSegmentInDet(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.
std::string GetSoftwareVersionFromPath(const std::string &path)
Get The software version from the path of the package.
Float_t MomentumError
Error of the momentum at the start of the segment.
Float_t GetPIDLikelihood(const AnaTrackB &track, Int_t hypo, bool prod5Cut=0)
Definition: PIDUtils.cxx:180
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
const AnaParticleB * Original
Float_t Position[4]
The position the true interaction happened at.
SubDetEnum
Enumeration of all detector systems and subdetectors.
Definition: SubDetId.hxx:25
Float_t EFieldRefitMomentum
Reconstructed momentum with the E-field distortion corrections.
Int_t NHits
The number of hits in the particle.
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.
static SubDetId::SubDetEnum GetSubdetectorEnum(unsigned long BitField)
Get the single subdetector that this track is from.
Definition: SubDetId.cxx:165
virtual bool Initialize()
[AnalysisAlgorithm_mandatory]
Int_t GetWeightIndex(const std::string &conf, const std::string &name) const
int GetLocalDetEnum(SubDetId::SubDetEnum det, SubDetId::SubDetEnum idet)
Get old local detector enumeration to find array index of Flat tree.
Float_t Pullp
Proton pull of the segment: (dEdxMeas-dEdxexpProton)/dEdxSigmaProton.
Float_t Length
The length of the ECal segment.
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
Float_t Pullele
Electron pull of the segment: (dEdxMeas-dEdxexpEle)/dEdxSigmaEle.
void AddStandardCategories(const std::string &prefix="")
Add the standard categories only, given a prefix for their name.
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 NuDir[3]
The true (unit) direction of the incoming neutrino.
Definition: DataClasses.hxx:82
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
Float_t GetPIDLikelihoodMIP(const AnaTrackB &track)
Get the likelihood for MIP: (like_mu+like_pi)/(1-like_p)
Definition: PIDUtils.cxx:191
Float_t PositionEnd[4]
The reconstructed end position of the particle.
Float_t RefitMomentum
Reconstructed momentum with the empirical distortion corrections.