HighLAND
tutorialAnalysis.cxx
1 #include "tutorialAnalysis.hxx"
2 #include "FiducialVolumeDefinition.hxx"
3 #include "Parameters.hxx"
4 #include "tutorialSelection.hxx"
5 #include "tutorialBranchesSelection.hxx"
6 #include "tutorialCorrection.hxx"
7 #include "tutorialWeightSystematics.hxx"
8 #include "tutorialVariationSystematics.hxx"
9 #include "CategoriesUtils.hxx"
10 #include "BasicUtils.hxx"
11 #include "baseToyMaker.hxx"
12 #include "NuDirUtils.hxx"
13 #include "KinematicsUtils.hxx"
14 
15 
16 /* CHANGES IN NEW VERSION
17 
18  Updated documentation
19 */
20 
21 
22 
23 /*
24  A highland2 Analysis inherits in ultimate instance from AnalysisAlgorithm.
25  In this particular case an intermediate class baseTrackerAnalysis is used,
26  which does all the work that is common for tracker analysis
27  Then tutorialAnalysis inherits from baseTrackerAnalysis, which inherits from baseAnalysis, which inherits from AnalysisAlgorithm.
28 
29  The class that does the loops (over events, over toys, etc) is AnalysisLoop (under highlandCore).
30  There you can see the analysis flow, which is as follows
31 
32  LOOP over Spills{
33  InitializeSpill
34  LOOP over Bunches in the Spill{
35  InitializeBunch
36  LOOP over Configurations{
37  InitializeConfiguration
38  LOOP over Toy experiments for each configuration{
39  InitializeToy
40  LOOP over Enabled Selections{
41  InitializeSelection
42  Apply The Selection
43  FinalizeSelection
44  }
45  FinalizeToy
46  FillMicroTrees (Fill toy-dependent variables in micro-trees)
47  }
48  FillToyVarsInMicroTrees (Fill toy-independent variables)
49  FillCategories (Fill categories for color code drawing)
50  FinalizeConfiguration
51  }
52  FinalizeBunch
53  }
54  FillTruthTree (Fill the truth tree)
55  FinalizeSpill
56  }
57 
58  The Initialize.. and Finalize... methods can be implemented by the user to do more complicated analyses, but are not mandatory
59 
60 
61  These is the list of mandatory methods to configure the analysis (call at initialization level):
62 
63  - Initialize: This is all initializations that cannot be done in the constructor should be put
64  (the ones that require access to a parameter in the parameters file)
65  - DefineSelections: Add to the SelectionManager the selections we have defined in other files
66  - DefineSystematics: Add to the SystematicManager the systematics to be run (defined in other files)
67  - DefineCorrections: Add to the CorrectionManager the corrections to be run (defined in other files)
68  - DefineConfigurations: Add to the ConfigurationManager the configurations to be considered
69  - DefineMicroTrees: Define the micro-tree variables
70  - DefineTruthTree: Define the variables of the truth tree
71 
72  These are the mandatory methods that are run for each Toy Experiment
73 
74  - FillToyVarsInMicroTrees: Fill the micro-trees toy-dependent variables (run for each toy experiment)
75 
76  These are the methods that are run for Event (Bunch)
77 
78  - FillMicroTrees: Fill the micro-trees toy-independent variables. (MANDATORY)
79  - FillCategories: Fill the micro-tree variables used for color code drawing (OPTIONAL)
80 
81  These are the mandatory methods that are run for each Spill
82 
83  - FillTruthTree: Fill the truth tree variables
84  - CheckFillTruthTree: Check whether to include or not a given true vertex in the truth tree
85 
86  These are the methods that are run at initialization level
87 
88  - FillConfigTree: Fill the user defined variables in the single-entry config tree
89 
90 */
91 
92 
93 //********************************************************************
94 tutorialAnalysis::tutorialAnalysis(AnalysisAlgorithm* ana) : baseTrackerAnalysis(ana) {
95 //********************************************************************
96  // Add the package version (to be stored in the "config" tree)
97  ND::versioning().AddPackage("tutorialAnalysis", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("TUTORIALANALYSISROOT")));
98 }
99 
100 //********************************************************************
102 //********************************************************************
103 
104  /* In this method we Initialize everything that requires access to parameters in the parameters file.
105  This is because in order to the overwride parameters file
106  option (-p param.dat) to work, parameters cannot be accessed in the constructors.
107  */
108 
109  // Initialize the base class
110  if (!baseTrackerAnalysis::Initialize()) return false;
111 
112  // Define categories
114 
115  // We could add a second set of categories with a given prefix ("fgd2" in this case)
116  // anaUtils::AddStandardCategories("fgd2");
117 
118  // Minimum accum level to save event into the output Micro-trees
119  SetMinAccumCutLevelToSave(ND::params().GetParameterI("tutorialAnalysis.MinAccumLevelToSave"));
120 
121  return true;
122 }
123 
124 //! [tutorialAnalysis_DefineSelections]
125 //********************************************************************
127 //********************************************************************
128 
129  /* In this method the user will add to the SelectionManager (accessed by sel() ) the selections to be run,
130  defined in other files. In general an analysis has a single selection, which could have multiple branches.
131  Each of the branches is in fact a different selection (different cuts and actions), but defining them as branches
132  we ussualy gain in speed and simplicity since the steps that are common are applied only once.
133  Sometimes the user does not want to expend time merging two selections in a single one (as branches), but preffers to run
134  both independently. This is in general done for quick checks (are the selections mutually exclusive ?, etc).
135  This is possible in highland2. An example on how to do that is shown below.
136 
137  In this case we add two selections to the SelectionManager provided:
138  - Name of the selection (kTrackerTutorial, kTrackerTutorialBranches)
139  - Title, the one dumped by the DrawingTools::DumpSelections() method. It is an explaination of the selection
140  - Pointer to the selection. The argument in the constructor (false) indicates that the
141  step sequence is not broken when a cut is not passed. In this way we can save intermediate information for events
142  not passing the entire selection
143  */
144 
145 
146  // Add a simple selection with no branches
147  sel().AddSelection("kTrackerTutorial", "tutorial selection", new tutorialSelection(false));
148 
149  // Add a more complicated selection with branches
150  sel().AddSelection("kTrackerTutorialBranches", "tutorial selection with branches", new tutorialBranchesSelection(false));
151 
152  // Disable the ones not enabled in parameters file
153  if (!ND::params().GetParameterI("tutorialAnalysis.Selections.RunSelectionWithoutBranches"))
154  sel().DisableSelection("kTrackerTutorial");
155 
156  if (!ND::params().GetParameterI("tutorialAnalysis.Selections.RunSelectionWithBranches"))
157  sel().DisableSelection("kTrackerTutorialBranches");
158 
159 }
160 //! [tutorialAnalysis_DefineSelections]
161 
162 //! [tutorialAnalysis_DefineCorrections]
163 //********************************************************************
165 //********************************************************************
166 
167  /* Corrections change the input data to rectify a problem in the MC or in the real data. Imagine for example that the energy deposited by a particle
168  in a given sub-detector is overestimated in the MC by about 5%, and that this effect depends on the particle type (6% for muons and 4% for electrons).
169  We could introduce a correction for the MC, which would scale the deposited energy by 0.94 for true muons and by 0.96 for true electrons. In this way
170  we make sure that any cut using the deposited energy will have the same effect in data and MC, avoiding the corresponding systematic.
171 
172  The entire analysis will proceed on the modified data
173  Corrections are only applied once per spill.
174  */
175 
176  // Some corrections are defined in baseTrackerAnalysis (have a look at baseTrackerAnalysis/vXrY/src/baseTrackerAnalysis.cxx)
177  baseTrackerAnalysis::DefineCorrections();
178 
179  // ----- We can add here extra corrections ----------
180 
181  // A dummy correction which moves forward the position of all global tracks by some mm, as specified in
182  // an external data file (data/tutorialCorrection.dat)
183  corr().AddCorrection("tutorialCorrection", new tutorialCorrection());
184 }
185 //! [tutorialAnalysis_DefineCorrections]
186 
187 //! [tutorialAnalysis_DefineSystematics]
188 //********************************************************************
190 //********************************************************************
191 
192  /* Systematics will modify the effective number of events passing the selection and the distribution of the observables.
193 
194  After corrections have been applied it is possible to
195  "manipulate" again the information using Systematics. In this case the purpose is different: we want to test several values of
196  a given detector property and check the impact on the number of selected events. This allows propagating systematic errors numerically.
197 
198  There are two kind of systematics:
199  - Variations: modify the input data (momentum, PID variables, etc). The selection is run on the modified data such that
200  the result of the selection can be different
201  - Weights: do not modify the input data. The selection is not affected. Simply a weight is added to the event.
202  Since events with different values of a given observable (i.e. momentum ) can have different weights,
203  distributions of that observable may change.
204 
205  In the above example about the deposited energy (in DefineCorrections(), the correction introduced cannot be perfectly known.
206  The 4% and 6% mentioned have an error (i.e. 0.5%).
207  This error should be propagated as a systematic. A given number of toy experiments will be run with different values of the scaling parameter
208  for the deposited energy (i.e. for muons 0.93, 0.935, 0.95, ..., following
209  a gaussian distribution with mean 0.94 and sigma 0.005). If a cut on the deposited energy (or a variable using it)
210  is applied the number of selected events could differ depending on the scaling applied.
211  The RMS of the number of selected events for all toy experiments represents the systematic error induced by the deposited energy scaling.
212  */
213 
214 
215  // Some systematics are defined in baseTrackerAnalysis (have a look at baseTrackerAnalysis/vXrY/src/baseTrackerAnalysis.cxx)
217 
218  // ----- We can add here extra systematics ----------
219 
220  // An example of variation systematic, which is added to the EventVariationManager
221  evar().AddEventVariation(kTutorialVariation, "TutorialVarSyst", new tutorialVariationSystematics());
222 
223  // A example of weight systematic, which is added to the EventWeightManager
224  eweight().AddEventWeight( kTutorialWeight, "TutorialWeightSyst", new tutorialWeightSystematics());
225 }
226 //! [tutorialAnalysis_DefineSystematics]
227 
228 //! [tutorialAnalysis_DefineConfigurations]
229 //********************************************************************
231 //********************************************************************
232 
233  /*
234  The user can run several analyses in parallel minimising the acces to disk.
235  Those parallel analyses are call configurations. Although this might be extended in the future, currenly
236  configurations only allow you to specify which systematics errors will be propagated, the number of toy experiments
237  and the random seed.
238 
239  A tree for each configuration is produced in the output file, with the same name as the configuration.
240  By default a single configuration (called "default") is run, producing
241  a single tree (with name default). This tree does not have any systematics enabled and hence it represents the nominal selection.
242  */
243 
244  // Some configurations are defined in baseTrackerAnalysis (have a look at baseTrackerAnalysis/vXrY/src/baseTrackerAnalysis.cxx)
246 
247  Int_t ntoys = ND::params().GetParameterI("baseAnalysis.Systematics.NumberOfToys");
248  Int_t randomSeed = ND::params().GetParameterI("baseAnalysis.Systematics.RandomSeed");
249 
250  // Add a new configuration called "tutorial_syst" with the following properties:
251  // - the number of toys defined in the baseAnalysis parameters file
252  // - the random seed for toy experiments defined in the baseAnalysis parameters file
253  // - The ToyMaker used to CreateTheToyExperiments (random throws for each systematic parameter).
254  // Have a look at baseToyMaker in baseAnalysis/vXrY/src
255  // - This configuration has two systematics kTutorialWeight and kTutorialVariation, defined above
256 
257  AddConfiguration(conf(), tutorial_syst, ntoys, randomSeed, new baseToyMaker(randomSeed));
258  conf().EnableSystematic(kTutorialWeight, tutorial_syst); // Enable the kTutorialWeight in the tutorial_syst configuration
259  conf().EnableSystematic(kTutorialVariation, tutorial_syst); // Enable the kTutorialVariation in the tutorial_syst configuration
260 
261  // Disable the configuration when requested
262  if (!ND::params().GetParameterI("tutorialAnalysis.Systematics.EnableTutorialSystematics"))
263  conf().DisableConfiguration(tutorial_syst);
264 }
265 //! [tutorialAnalysis_DefineConfigurations]
266 
267 //! [tutorialAnalysis_DefineMicroTrees]
268 //********************************************************************
270 //********************************************************************
271 
272  /* We call Micro-trees to the standard analysis trees appearing in the output file.
273  There is always a Micro-Tree call "default" which should contain the basic info to understand our selection.
274  The user can add extra Micro-Trees by adding configurations to the analysis (see DefineConfigurations method above).
275 
276  Here we give an example of different variables that can be added. Have a look at OutputManager.hxx under highlandCore
277  to see all available methods.
278  */
279 
280  // -------- Add variables to the analysis tree ----------------------
281 
282  // Variables from baseTrackerAnalysis (run, event, ..., tracker related stuff, ...)
283  if (addBase) baseTrackerAnalysis::DefineMicroTrees(addBase);
284 
285  // --- Single variables -------
286  AddVarD( output(), selmu_costheta, "muon candidate reconstructed cos(theta) w.r.t. to neutrino direction"); // Double
287  AddVarF( output(), selmu_truemom, "muon candidate true momentum"); // Float
288  AddVarI( output(), selmu_detectors, "muon candidate detectors"); // Integer
289  AddVarC( output(), selmu_sense, "muon candidate sense"); // Char
290 
291  AddVarF( output(), selmu_deltaPhi, "angle between muon candidate and the proton candidate (HMP track)"); // Float
292  AddVarF( output(), selmu_pT, "muon candidate reconstructed transverse momentum w.r.t to neutrino direction"); // Float
293 
294  AddVarI( output(), nLongTPCTracks, "number of long TPC tracks"); // Integer
295 
296  // --- Vector variables -------
297  // selmu_ntpcs is the counter, which is added automatically as integer variable
298  AddVarVI(output(), selmu_tpc_det, "muon candidate TPC number", selmu_ntpcs);
299  AddVarVI(output(), selmu_tpc_nnodes, "muon candidate #nodes in each TPC", selmu_ntpcs); // Vector of integers
300  AddVarVF(output(), selmu_tpc_mom, "muon candidate reconstructed momentum in each TPC", selmu_ntpcs); // Vector of floats
301  AddVarVD(output(), selmu_tpc_truemom, "muon candidate true momentum in each TPC", selmu_ntpcs); // Vector of doubles
302 
303  // --- 3D and 4D vector variables (i.e. directions and positions) -------
304  AddVar4VF(output(), selmu_pos, "muon candidate reconstructed position"); // 4-Vector of floats
305  AddVar3VF(output(), selmu_dir, "muon candidate reconstructed direction"); // 3-Vector of floats
306 
307  // --- Matrix variables -------
308  // AddVarMF(output(), selmu_tpc, "",selmu_necals,-30,4);
309 
310  // --- 3D and 4D matrix variables (i.e. directions and positions for constituents) -------
311  AddVar4MF(output(), selmu_tpc_pos, "muon candidate true position in each tpc", selmu_ntpcs);
312  AddVar3MF(output(), selmu_tpc_dir, "muon candidate true direction in each tpc", selmu_ntpcs);
313 
314 
315  // Now we had toy-dependent variables
316  // There could be many variables that are toy-dependent. We don't need to save all of them as toy variables,
317  // but only the ones we are interested in plotting for different toys.
318  // TOY VARIABLES ARE VERY SPACE CONSUMING SO WE SHOULD MINIMISE ITS NUMBER !!!!
319 
320  // --- single toy variables -------
321  AddToyVarF(output(), selmu_mom, "muon candidate reconstructed momentum");
322 
323  // --- vector toy variables -------
324  AddToyVarVF(output(), selmu_tpc_dedx, "muon candidate dEdx (CT) in each TPC", NMAXTPCS);
325 }
326 //! [tutorialAnalysis_DefineMicroTrees]
327 
328 
329 
330 
331 
332 //! [tutorialAnalysis_DefineTruthTree]
333 //********************************************************************
335 //********************************************************************
336 
337 
338 //! \if INTERNAL
339 
340 hello
341 //! \endif
342 
343 //! [tutorialAnalysis_DefineTruthTree_info]
344  The main trees in the output file are the "default" and "truth" trees. The "default" tree contains all selected events (the ones that passed a given cut, ussualy
345  specified in the parameters file). This is the tree used to optimise the selection cuts, to make selection plots and to compute or plot the purity of the selection.
346  The main reason for having a separate tree, call "truth", is to allow the efficiency computation. The "default" tree does not contain all true signal events,
347  because it will be too big. The preselection for that tree is only based in reconstructed quantities (selection cuts). Instead, to compute true signal efficiencies
348  we need all true signal events to be present in the output tree. The "truth" tree fullfils this condition. Since, in general, this tree will contain many events, only a
349  reduced set of variables (the ones needed to compute the efficiency) is stored in that tree.
350 
351  SUMMARY: The "truth" tree also appears in the output file. It contains all interactions in which we are interested in regardless on whether
352  the selection was passed or not. This is the tree that should be used to compute signal efficiencies
353 //! [tutorialAnalysis_DefineTruthTree_info]
354 
355 
356 
357  // Variables from baseTrackerAnalysis (run, event, ...)
358  baseTrackerAnalysis::DefineTruthTree();
359 
360  //--- muon variables -------
361  AddVarI( output(), truelepton_pdg, "true lepton PDG");
362  AddVar4VF(output(), truelepton_pos, "true lepton position");
363  // Moved to baseAnalysis !!!!!!!
364  // AddVarF( output(), truelepton_mom, "true lepton momentum");
365  // AddVarF( output(), truelepton_costheta, "true lepton cos(theta) w.r.t. neutrino direction");
366  // AddVar3VF(output(), truelepton_dir, "true lepton direction");
367 }
368 //! [tutorialAnalysis_DefineTruthTree]
369 
370 //! [tutorialAnalysis_FillMicroTrees]
371 //********************************************************************
373 //********************************************************************
374 
375  /* In this method we fill all toy-independent variables (all except the ones added with AddToy...) defined in the method DefineMicroTrees.
376  This method is called once all toys has been run, what means that the value of all variables for the last toy will be saved. This is not a problem
377  for variables that are not expected to change from a toy to another.
378  */
379 
380  // Variables from baseTrackerAnalysis (run, event, ...)
381  if (addBase) baseTrackerAnalysis::FillMicroTreesBase(addBase);
382 
383  // Add a variable that is only in the derived box AnaBoxTutorial. We need to cast the base box to have access
384  output().FillVar(nLongTPCTracks, static_cast<const ToyBoxTutorial*>(&box())->nLongTPCTracks);
385 
386  // Muon candidate variables. The MainTrack (The muon candidate) should exist in the box
387  if (box().MainTrack){
388 
389  // Since Detectors is not in BaseDataClasses (in psycheEventModel) but in DataClasses in (highlandEventModel) we need to cast
390  // the AnaTrackB pointer in box().MainTrack to the derived class AnaTrack.
391  output().FillVar(selmu_detectors, static_cast<AnaTrack*>(box().MainTrack)->Detectors);
392 
393  // Compute the cosine of the angle between the muon and the neutrino
394  // vertex defined as start of muon track, neutrino direction calculated from this
395  TVector3 nuDirVec = anaUtils::GetNuDirRec(box().MainTrack->PositionStart); // Method in NuDirUtils (in psycheND280Utils)
396  TVector3 muDirVec = anaUtils::ArrayToTVector3(box().MainTrack->DirectionStart);
397  double costheta_mu_nu = nuDirVec.Dot(muDirVec);
398 
399  // Cast it to a double because we have defined this variable as double in DefineMicroTrees
400  // (no need to be a double, it is just to have an example of double variable)
401  output().FillVar(selmu_costheta, costheta_mu_nu);
402 
403  // Transverse component of muon momentum calculated relative to reconstructed neutrino direction
404  Float_t nuDirArr[3];
405  nuDirVec.GetXYZ(nuDirArr);
406  Float_t pT = anaUtils::GetTransverseMom(nuDirArr,box().MainTrack->DirectionStart,box().MainTrack->Momentum); // Method in NuDirUtils (in psycheND280Utils)
407  output().FillVar(selmu_pT, pT);
408 
409  // Coplanarity angle requires a proton... for now just assume use highest momentum +ve track
410  Float_t deltaPhi=0;
411  if(box().HMPtrack)
412  deltaPhi = anaUtils::GetDPhi(nuDirArr,box().MainTrack->DirectionStart,box().HMPtrack->DirectionStart); // Method in NuDirUtils (in psycheND280Utils)
413  output().FillVar(selmu_deltaPhi, deltaPhi);
414 
415  // This is unnecessary here (we could use 1 and -1 which are smaller types), but serves as an example
416  if (box().MainTrack->DirectionStart[2]>0)
417  output().FillVar(selmu_sense, "forward");
418  else
419  output().FillVar(selmu_sense, "backward");
420 
421  // This is the way we fill 3 and 4-vectors. Must specify the array size when using FillVectorVarFromArray
422  output().FillVectorVarFromArray(selmu_pos, box().MainTrack->PositionStart, 4);
423  output().FillVectorVarFromArray(selmu_dir, box().MainTrack->DirectionStart, 3);
424 
425  // Properties of the true particle associated to the muon candidate.
426  // We can also acces the truth with box().MainTrack->TrueObject, but this is of the more basic type AnaTrueObjectC, which does not have Momentum. The GetTrueParticle() method
427  // just do the casting
428  if( box().MainTrack->GetTrueParticle() ) {
429  output().FillVar(selmu_truemom, box().MainTrack->GetTrueParticle()->Momentum);
430  }
431 
432  // Info in all TPCs
433  for (Int_t subdet = 0; subdet<3; subdet++) {
434  if (!SubDetId::GetDetectorUsed(box().MainTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet+2))) continue;
435  AnaTPCParticle* TPCSegment = static_cast<AnaTPCParticle*>(anaUtils::GetSegmentInDet( *box().MainTrack,static_cast<SubDetId::SubDetEnum >(subdet+2)));
436  if (!TPCSegment) continue;
437  output().FillVectorVar(selmu_tpc_det, subdet);
438  output().FillVectorVar(selmu_tpc_mom, TPCSegment->Momentum);
439  output().FillVectorVar(selmu_tpc_nnodes, TPCSegment->NNodes);
440 
441  // Must specify the array size when using FillMatrixVarFromArray
442  output().FillMatrixVarFromArray(selmu_tpc_pos, TPCSegment->PositionStart, 4);
443  output().FillMatrixVarFromArray(selmu_tpc_dir, TPCSegment->DirectionStart, 3);
444 
445  if (TPCSegment->GetTrueParticle()){
446  // Cast it to a double because we have defined this variable as double in DefineMicroTrees
447  // (no need to be a double, it is just to have an example of double variable)
448  output().FillVectorVar(selmu_tpc_truemom, (Double_t)TPCSegment->GetTrueParticle()->Momentum);
449  }
450 
451  // increment the value of the counter for all TPC variables (selmu_ntpcs)
452  // The same effect will have output().IncrementCounter(selmu_ntpcs);
453  output().IncrementCounterForVar(selmu_tpc_det);
454  }
455  }
456 
457 }
458 //! [tutorialAnalysis_FillMicroTrees]
459 
460 //! [tutorialAnalysis_FillToyVarsInMicroTrees]
461 //********************************************************************
463 //********************************************************************
464 
465  /* In this method we fill all toy-dependent variables (the ones added with AddToy...) defined in the method DefineMicroTrees.
466  This method is called at the end of each toy.
467 
468  There could be many variables that are toy-dependent. We don't need to save all of them as toy variables, but only the ones we are interested in plotting
469  for different toys.
470 
471  TOY VARIABLES ARE VERY SPACE CONSUMING SO WE SHOULD MINIMISE ITS NUMBER !!!!
472  */
473 
474  // Fill the common variables
475  if (addBase) baseTrackerAnalysis::FillToyVarsInMicroTreesBase(addBase);
476 
477  //---- variables specific for this analysis -----
478  if (box().MainTrack){
479  // Since we are applying a systematic that varies the momentum we need to save the momentum for each toy
480  output().FillToyVar(selmu_mom, box().MainTrack->Momentum);
481 
482  // Info in all TPCs
483  for (Int_t subdet = 0; subdet<3; subdet++) {
484  if (!SubDetId::GetDetectorUsed(box().MainTrack->Detector, static_cast<SubDetId::SubDetEnum >(subdet+2))) continue;
485  AnaTPCParticle* TPCSegment = static_cast<AnaTPCParticle*>(anaUtils::GetSegmentInDet( *box().MainTrack, static_cast<SubDetId::SubDetEnum >(subdet+2)));
486  if (!TPCSegment) continue;
487  // In principle we need this variable here when PID systematics are run
488  output().FillToyVectorVar(selmu_tpc_dedx, TPCSegment->dEdxMeas, subdet);
489  }
490  }
491 }
492 //! [tutorialAnalysis_FillToyVarsInMicroTrees]
493 
494 //********************************************************************
496 //********************************************************************
497 
498  /* To avoid unecessary events in the "truth" tree in this method we define the condition to include or not a given
499  true vertex in the tree. In principle we whould only save the true vertices that match our signal definition
500  */
501 
502  // In this case we only save numu (NuPDG=14) charged current (0<ReacCode<30) interactions in the FGD1 FV
503  bool numuCC=vtx.ReacCode>0 && vtx.ReacCode<30 && vtx.NuPDG==14;// && vtx.LeptonPDG==13;
504  return (anaUtils::InFiducialVolume(SubDetId::kFGD1, vtx.Position, FVDef::FVdefminFGD1,FVDef::FVdefmaxFGD1) && numuCC);
505 }
506 
507 //********************************************************************
508 void tutorialAnalysis::FillTruthTree(const AnaTrueVertex& vtx){
509 //********************************************************************
510 
511  // Fill the common variables defined in baseTrackerAnalysis/vXrY/src/baseTrackerAnalysis.cxx
512  baseTrackerAnalysis::FillTruthTreeBase(vtx);
513 
514  // ---- Fill the extra variables ------
515  output().FillVar(truelepton_pdg,vtx.LeptonPDG);
516  output().FillVectorVarFromArray(truelepton_pos, vtx.Position, 4);
517  // Moved to baseAnalysis !!!!!!!
518  // output().FillVar(truelepton_costheta,(Float_t)cos(anaUtils::ArrayToTVector3(vtx.LeptonDir).Angle(anaUtils::ArrayToTVector3(vtx.NuDir))));
519  // output().FillVar(truelepton_mom,vtx.LeptonMom);
520  // output().FillVectorVarFromArray(truelepton_dir, vtx.LeptonDir,3);
521 }
522 
523 //********************************************************************
524 void tutorialAnalysis::FillCategories(){
525 //********************************************************************
526 
527  /* This method fills the micro-tree variables related with event and particle categories for color drawing.
528  Those variables are added automatically (no need to explicitely add them in DefineMicroTrees) to the
529  micro-trees, but must be filled by the analyser, provided the event and the relevant track (the lepton candidate,
530  that is the HMN track, in this case).
531 
532  This method is not in baseTrackerAnalysis anymore, meaning that if it is not implemented in your analysis, the cattegories will not be filled
533  */
534 
535  // For the muon candidate
536  anaUtils::FillCategories(&GetEvent(), static_cast<AnaTrack*>(box().MainTrack),"", SubDetId::kFGD1);
537 
538  // We could add a second set of categories with a given prefix ("fgd2" in this case). See tutorialAnalysis::Initialize() above
539  // anaUtils::FillCategories(&GetEvent(), static_cast<AnaTrack*>(box().MainTrack),"fgd2", SubDetId::kFGD2);
540 
541 }
542 
543 //********************************************************************
544 void tutorialAnalysis::FillConfigTree(){
545 //********************************************************************
546 
547  /*
548  In this method we fill variables in the config tree. This is a single entry tree (event independent) where information about the
549  analysis being run is stored (enabled systematics, corrections and selections, description of the selection, info about the input file, etc).
550  All this is done automatically. However the user can add its own variables. Since this is a single entry tree, the same method can be used
551  to add and fill the variables
552  */
553 
554 
555  // Add and fill number of nucleons in each of the targets
556  AddVarD(output(), nNucleonsFGD1, "number of targets in FGD1");
557  AddVarD(output(), nNucleonsFGD2scint, "number of targets in FGD2 scintillator");
558  AddVarD(output(), nNucleonsFGD2water, "number of targets in FGD2 water");
559 
560  output().FillVar(nNucleonsFGD1, anaUtils::GetNTargets(anaUtils::kFGD1));
561  output().FillVar(nNucleonsFGD2scint, anaUtils::GetNTargets(anaUtils::kFGD2xymodules));
562  output().FillVar(nNucleonsFGD2water, anaUtils::GetNTargets(anaUtils::kFGD2watermodules));
563 }
564 
void FillMicroTrees(bool addBase=true)
[tutorialAnalysis_DefineTruthTree]
Float_t PositionStart[4]
The reconstructed start position of the particle.
Int_t NuPDG
The PDG code of the incoming neutrino.
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
void AddPackage(const std::string &name, const std::string &version)
Add a package.
Int_t NNodes
The number of nodes in the 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]
Float_t Momentum
The initial momentum of the true particle.
AnaParticleB * GetSegmentInDet(const AnaTrackB &track, SubDetId::SubDetEnum det)
virtual void DefineSystematics()
std::string GetSoftwareVersionFromPath(const std::string &path)
Get The software version from the path of the package.
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
Representation of a true Monte Carlo vertex.
Definition: DataClasses.hxx:50
Float_t Position[4]
The position the true interaction happened at.
void DefineMicroTrees(bool addBase=true)
[tutorialAnalysis_DefineConfigurations]
void FillToyVarsInMicroTrees(bool addBase=true)
[tutorialAnalysis_FillMicroTrees]
Float_t GetTransverseMom(const Float_t *nudir, const Float_t *thisdir, Float_t thismom)
Get the transverse momentum.
void DefineTruthTree()
[tutorialAnalysis_DefineMicroTrees]
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.
virtual bool Initialize()
[AnalysisAlgorithm_mandatory]
void DefineConfigurations()
[tutorialAnalysis_DefineSystematics]
Creates ToyExperiments.
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
void DefineCorrections()
[tutorialAnalysis_DefineSelections]
void DefineSelections()
Add to the selection manager the selections for this analysis.
void AddStandardCategories(const std::string &prefix="")
Add the standard categories only, given a prefix for their name.
Representation of a TPC segment of a global track.
This is a normalization systematic. It takes into account the uncertainty on the FGD mass introduced ...
AnaTrueParticleB * GetTrueParticle() const
Return a casted version of the AnaTrueObject associated.
bool InFiducialVolume(SubDetId::SubDetEnum det, const Float_t *pos, const Float_t *FVdefmin, const Float_t *FVdefmax)
bool CheckFillTruthTree(const AnaTrueVertex &vtx)
[tutorialAnalysis_FillToyVarsInMicroTrees]
Float_t GetDPhi(const Float_t *nudir, const Float_t *mudir, const Float_t *pdir)
Returns pi-(the angle between muon and proton). Should be delta-fn in ideal back2back.
void DefineSystematics()
[tutorialAnalysis_DefineCorrections]
virtual void DefineConfigurations()