HighLAND
baseAnalysis.cxx
1 #include "baseAnalysis.hxx"
2 
3 #include "IgnoreRightECalRuns3and4Correction.hxx"
4 #include "CT4POTCorrection.hxx"
5 #include "DataQualityCorrection.hxx"
6 
7 #include "SIPionSystematics.hxx"
8 #include "SIProtonSystematics.hxx"
9 #include "FluxWeightSystematics.hxx"
10 
11 #include "FlatTreeConverter.hxx"
12 #include "HighlandMiniTreeConverter.hxx"
13 #include "oaAnalysisTreeConverter.hxx"
14 
15 #include "baseToyMaker.hxx"
16 
17 #include "ConfigTreeTools.hxx"
18 
19 //********************************************************************
21  //********************************************************************
22 
23  // Add the package version
24  // Add package versions
25  ND::versioning().AddPackage("psychePolicy", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHEPOLICYROOT")));
26  ND::versioning().AddPackage("psycheEventModel", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHEEVENTMODELROOT")));
27  ND::versioning().AddPackage("psycheCore", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHECOREROOT")));
28  ND::versioning().AddPackage("psycheUtils", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHEUTILSROOT")));
29  ND::versioning().AddPackage("psycheND280Utils", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHEND280UTILSROOT")));
30  ND::versioning().AddPackage("psycheIO", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHEIOROOT")));
31  ND::versioning().AddPackage("psycheSelections", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHESELECTIONSROOT")));
32  ND::versioning().AddPackage("psycheSystematics", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("PSYCHESYSTEMATICSROOT")));
33  ND::versioning().AddPackage("highlandEventModel", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDEVENTMODELROOT")));
34  ND::versioning().AddPackage("highlandTools", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDTOOLSROOT")));
35  ND::versioning().AddPackage("highlandCore", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDCOREROOT")));
36  ND::versioning().AddPackage("highlandCorrections", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDCORRECTIONSROOT")));
37  ND::versioning().AddPackage("highlandIO", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("HIGHLANDIOROOT")));
38 
39  ND::versioning().AddPackage("baseAnalysis", anaUtils::GetSoftwareVersionFromPath((std::string)getenv("BASEANALYSISROOT")));
40 
41  /// TODO
42  versionUtils::prod6_POT = false;
43 #if VERSION_HAS_OFFICIAL_POT
44  versionUtils::prod6_POT = true;
45 #endif
46 }
47 
48 //********************************************************************
49 void baseAnalysis::DefineProductions(){
50 //********************************************************************
51 
52  // Add the different productions
53  ND::versioning().AddProduction(ProdId::PROD5E, "PROD5E", "v10r11p17", "v10r11p18");
54  ND::versioning().AddProduction(ProdId::PROD5F, "PROD5F", "v10r11p19", "v10r11p24");
55  ND::versioning().AddProduction(ProdId::PROD5G, "PROD5G", "v10r11p27", "v10r11p28");
56  ND::versioning().AddProduction(ProdId::PROD6PRE, "PROD6PRE", "v11r17", "v11r28");
57  ND::versioning().AddProduction(ProdId::PROD6A, "PROD6A", "v11r29", "v11r30");
58  ND::versioning().AddProduction(ProdId::PROD6BC, "PROD6B/6C", "v11r31", "v11r32");
59  //May change when production evolves
60  ND::versioning().AddProduction(ProdId::PROD7DEVEL, "PROD7DEVEL", "v12", "v13");
61 
62 }
63 
64 //********************************************************************
65 void baseAnalysis::DefineInputConverters(){
66 //********************************************************************
67 
68  // Read or not the RooTrackerVtxTree
69  bool readRooTrackerVtxTree = (bool)ND::params().GetParameterI("baseAnalysis.ReadRooTrackerVtxTree");
70 
71  // add the different converters
72  input().AddConverter("FlatTree", new FlatTreeConverter(readRooTrackerVtxTree));
73  input().AddConverter("MiniTree", new HighlandMiniTreeConverter(readRooTrackerVtxTree));
74  input().AddConverter("oaAnalysisTree", new oaAnalysisTreeConverter());
75 
76  // Save or not the RooTrackerVtxTree
77  _saveRooTrackerVtxTree = (bool)ND::params().GetParameterI("baseAnalysis.SaveRooTrackerVtxTree");
78 
79  //------ TEMPORARY SOLUTION FOR ROOVTXENTRY IN ALGORITHMS USING OTHERS ------
80 
81  // Create a RooTrackerVtxManager
83 
84  for (std::vector<AnalysisAlgorithm*>::iterator it=_usedAnalyses.begin();it!=_usedAnalyses.end();it++){
85  // Set this parameter to all used algorithms
87  // Use the same manager for all used algorithms
88  static_cast<baseAnalysis*>( (*it))->SetRooVtxManager(_rooVtxManager);
89  }
90 
91  //----------------------------------------------------------------------------
92 
93 }
94 
95 //********************************************************************
97  //********************************************************************
98 
99  // Flux weight pointer
100  _flux = NULL;
101 
102  // Initialize trees or not at the beginnng of each configuration
103  SetInitializeTrees(ND::params().GetParameterI("baseAnalysis.InitializeTrees"));
104 
105  if (_versionCheck){
106  if(!ND::versioning().CheckVersionCompatibility(input().GetSoftwareVersion(),anaUtils::GetProductionIdFromND280AnalysisTools())) return false;
107  }
108 
109  // Select the production based on the software version of the input file. This will be used to select the appropriate corrections,
110  // bunching, systematics, etc. Assume production 5 when no software version exists
111  versionUtils::prod6_bunching = false;
112  versionUtils::prod6_corrections = false;
113  versionUtils::prod6_systematics = false;
114 
115  if (_versionCheck){
116  if (ND::versioning().GetProduction(input().GetSoftwareVersion()) >= ProdId::PROD6PRE){
117  versionUtils::prod6_bunching = true;
118  versionUtils::prod6_corrections = true;
119  versionUtils::prod6_systematics = true;
120  }
121  }
122 
123  // Select the production from the parameters file. This will be used for bunching, ...
124  if (ND::params().GetParameterI("baseAnalysis.Bunching.Production")==6){
125  versionUtils::prod6_bunching = true;
126  std::cout << "WARNING: production has been overwritten by parameter baseAnalysis.Bunching.Production == 6" << std::endl;
127  }
128  else if (ND::params().GetParameterI("baseAnalysis.Bunching.Production")==5){
129  versionUtils::prod6_bunching = false;
130  std::cout << "WARNING: production has been overwritten by parameter baseAnalysis.Bunching.Production == 5" << std::endl;
131  }
132 
133  // Select the production from the parameters file. This will be used for corrections
134  if (ND::params().GetParameterI("baseAnalysis.Corrections.Production")==6){
135  versionUtils::prod6_corrections = true;
136  std::cout << "WARNING: production has been overwritten by parameter baseAnalysis.Corrections.Production == 6" << std::endl;
137  }
138  else if (ND::params().GetParameterI("baseAnalysis.Corrections.Production")==5){
139  versionUtils::prod6_corrections = false;
140  std::cout << "WARNING: production has been overwritten by parameter baseAnalysis.Corrections.Production == 5" << std::endl;
141  }
142 
143  // Select the production from the parameters file. This will be used for systematics
144  if (ND::params().GetParameterI("baseAnalysis.Systematics.Production")==6){
145  versionUtils::prod6_systematics = true;
146  std::cout << "WARNING: production has been overwritten by parameter baseAnalysis.Systematics.Production == 6" << std::endl;
147  }
148  else if (ND::params().GetParameterI("baseAnalysis.Systematics.Production")==5){
149  versionUtils::prod6_systematics = false;
150  std::cout << "WARNING: production has been overwritten by parameter baseAnalysis.Systematics.Production == 5" << std::endl;
151  }
152 
153  // Dump the production used for corrections, bunching, systematics, etc
154  versionUtils::DumpProductions();
155 
156 
157  // This will take care of data/MC differences in detector volumes definitions
158  // Should be applied after the version has been defined
159  // TODO. Moved temporarily from AnalysisLoop to avoid dependency of highlandCore on psycheND280Utils
160  ND::hgman().InitializeGeometry(input().GetIsMC());
161 
162  return true;
163 }
164 
165 //********************************************************************
166 void baseAnalysis::DefineSystematics(){
167 //********************************************************************
168 
169  // We add here EventWeights and EventVariations that are common to all analyses
170 
171  eweight().AddEventWeight(SystId::kSIPion, "SIPion", new SIPionSystematics());
172  eweight().AddEventWeight(SystId::kSIProton, "SIProton", new SIProtonSystematics());
173 
174  eweight().AddEventWeight(SystId::kFluxWeightNu, "FluxWeightNu", new FluxWeightSystematicsNeutrino());
175  eweight().AddEventWeight(SystId::kFluxWeightAntiNu, "FluxWeightAntiNu", new FluxWeightSystematicsAntiNeutrino());
176 }
177 
178 //********************************************************************
179 void baseAnalysis::DefineCorrections(){
180  //********************************************************************
181 
182  //----------- Define all corrections ----------------
183  if (ND::params().GetParameterI("baseAnalysis.Corrections.DisableAllCorrections")){
184  // Should not be needed, but just in case !!!
185  corr().DisableAllCorrections();
186  }
187  else{
188  // Add corrections only when they are enabled. In that way the CorrectionManager does not have to loop over unused corrections
189 
190  // Ignore right ECal for runs 3 and 4 as part of it is broken.
191  if (ND::params().GetParameterI("baseAnalysis.Corrections.EnableIgnoreRightECal")) corr().AddCorrection("ignorerightecal_corr", new IgnoreRightECalRuns3and4Correction());
192  // Correct the data quality in periods when a FGD FEB wasn't working.
193  if (ND::params().GetParameterI("baseAnalysis.Corrections.EnableDQ")) corr().AddCorrection("dq_corr", new DataQualityCorrection());
194 
195 
196 #if !VERSION_HAS_OFFICIAL_POT
197  // Use CT4 for MR44 POT accounting, as CT5 wasn't working properly. Only need this correction for P5 files.
198  if (ND::params().GetParameterI("baseAnalysis.Corrections.EnableCT4POT")) corr().AddCorrection("ct4pot_corr", new CT4POTCorrection());
199 #endif
200 
201  }
202 
203  // if (ND::params().GetParameterI("baseAnalysis.Extensions.EcalPID")) {
204  // // ECal EM energy correction only applies if we've calculated the
205  // // ECal EM energy variables and put them into the extended
206  // // AnaECALParticleEcalPID class.
207  // corr().AddCorrection("ecalemene_corr", new EcalEMEnergyCorrection());
208  //}
209 
210 
211  // The Flux Weight is a correction, but for the moment is not defined as such (TODO). Keep it here
212 
213  _flux= NULL;
214  if ((bool)ND::params().GetParameterI("baseAnalysis.FluxWeighting.Enable")){
215  _flux = new FluxWeighting(ND::params().GetParameterS("baseAnalysis.FluxWeighting.Folder"),
216  ND::params().GetParameterS("baseAnalysis.FluxWeighting.Version"),
217  ND::params().GetParameterS("baseAnalysis.FluxWeighting.Tuning"));
218  }
219 
220  // If set to true corrections applied in the input file are applied again
221  corr().SetForceApplyCorrections((bool)ND::params().GetParameterI("baseAnalysis.Corrections.ForceApplyCorrections"));
222 }
223 
224 //********************************************************************
225 void baseAnalysis::DefineConfigurations(){
226  //********************************************************************
227 
228  //------- Add and define individual configurations with one systematic only ------------------
229 
230  _enableSingleVariationSystConf = (bool)ND::params().GetParameterI("baseAnalysis.Configurations.EnableSingleVariationSystConfigurations");
231  _enableSingleWeightSystConf = (bool)ND::params().GetParameterI("baseAnalysis.Configurations.EnableSingleWeightSystConfigurations");
232  _enableAllSystConfig = (bool)ND::params().GetParameterI("baseAnalysis.Configurations.EnableAllSystematics");
233  _enableZeroVarConfig = (bool)ND::params().GetParameterI("baseAnalysis.Configurations.EnableZeroVarConfiguration");
234 
235  _ntoys = (Int_t)ND::params().GetParameterI("baseAnalysis.Systematics.NumberOfToys"); // The number of Toy Experiments
236  _randomSeed = (Int_t)ND::params().GetParameterI("baseAnalysis.Systematics.RandomSeed"); // The random seed to generate the ToyExperiments
237 
238  if (_enableSingleWeightSystConf){
239  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableSIPion")){
240  AddConfiguration(conf(), sipion_syst, _ntoys, _randomSeed, new baseToyMaker(_randomSeed));
241  conf().EnableEventWeight(SystId::kSIPion,sipion_syst);
242  }
243  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableSIProton")){
244  AddConfiguration(conf(), siproton_syst, _ntoys, _randomSeed, new baseToyMaker(_randomSeed));
245  conf().EnableEventWeight(SystId::kSIProton,siproton_syst);
246  }
247  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableFluxNeutrino")) {
248  AddConfiguration(conf(), nuflux_syst, _ntoys, _randomSeed, new baseToyMaker(_randomSeed));
249  conf().EnableEventWeight(SystId::kFluxWeightNu , nuflux_syst);
250  }
251  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableFluxAntiNeutrino")) {
252  AddConfiguration(conf(), antinuflux_syst, _ntoys, _randomSeed, new baseToyMaker(_randomSeed));
253  conf().EnableEventWeight(SystId::kFluxWeightAntiNu , antinuflux_syst);
254  }
255  }
256 
257  // A configuration with all systematics
258  if (_enableAllSystConfig){
259  AddConfiguration(conf(), all_syst, _ntoys, _randomSeed, new baseToyMaker(_randomSeed));
260  }
261 
262  // A configuration with all syst but zero variation applied
263  if (_enableZeroVarConfig) AddZeroVarConfiguration();
264 
265  // Enable all Event Weights in the default and all_syst configurations
266  for (std::vector<ConfigurationBase* >::iterator it= conf().GetConfigurations().begin();it!=conf().GetConfigurations().end();it++){
267  Int_t index = (*it)->GetIndex();
268  if (index != ConfigurationManager::default_conf && (index != all_syst || !_enableAllSystConfig)) continue;
269  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableSIPion")) conf().EnableEventWeight(SystId::kSIPion , index);
270  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableSIProton")) conf().EnableEventWeight(SystId::kSIProton , index);
271  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableFluxNeutrino")) conf().EnableEventWeight(SystId::kFluxWeightNu , index);
272  if (ND::params().GetParameterI("baseAnalysis.Weights.EnableFluxAntiNeutrino")) conf().EnableEventWeight(SystId::kFluxWeightAntiNu , index);
273  }
274 
275 }
276 
277 //********************************************************************
278 void baseAnalysis::AddZeroVarConfiguration(){
279  //********************************************************************
280 
281  // Add the configuration if not already available
282  if (GetConfigurationIndex(zero_var) < 0)
283  AddConfiguration(conf(), zero_var, 1, 1, new baseToyMaker(1, true)); // true - zero-variation mode
284 
285 
286  // A configuration with all systematics but zero variation applied, will copy the enabled systematcis from the all_syst
287  if (GetConfigurationIndex(all_syst) > -1){
288  conf().EnableSystematics(conf().GetEnabledSystematics(all_syst), zero_var);
289  return;
290  }
291 
292  // Dump a warning if failed to get all_syst config
293  std::cout << " \n---- WARNING ----- " << std::endl;
294  std::cout << " baseAnalysis::AddZeroVariationConfig: requested zero-variation config but " <<
295  "all_syst is not available --> needed to get the enabled systematics " << std::endl;
296  std::cout << " ------------------\n " << std::endl;
297 
298  return;
299 }
300 
301 //********************************************************************
302 void baseAnalysis::DefineMicroTrees(bool addBase){
303  //********************************************************************
304 
305  (void)addBase;
306 
307  // -------- Add variables to the analysis tree ----------------------
308 
309  //--- event variables -------
310  AddVarI(output(), run, "run number");
311  AddVarI(output(), subrun, "subrun number ");
312  AddVarI(output(), evt, "event number ");
313  AddVarI(output(), evt_time, "event time MCM"); // highlandEventModel
314  AddVarI(output(), bunch, "bunch number ");
315 
316  //--- add event weights ----------------------
317  AddVarVF(output(), weight, "global weights (flux, pileup, ...)", NWEIGHTS);
318 
319  //--- link with truth ----
320  AddToyVarI(output(), TruthVertexID,"The unique ID of the true vertex associated to the selected event");
321  AddToyVarI(output(), RooVtxIndex, "The index of the associated RooTrackerVtx vertex from its position in the TClonesArray");
322  AddToyVarI(output(), RooVtxEntry, "The entry of the event in the saved RooTrackerVtx tree");
323  AddVarI(output(), RooVtxEntry2, "The entry of the event in the saved RooTrackerVtx tree");
324  AddVarI(output(), RooVtxFile, "The File of the event in the saved RooTrackerVtx tree");
325 
326  // --- neutrino truth variables ----
327  AddVarI( output(), nu_pdg, "neutrino PDG code");
328  AddVarF( output(), nu_trueE, "true neutrino energy");
329  AddVarI( output(), nu_truereac, "true netrino reaction code");
330  AddVar3VF(output(), nu_truedir, "true neutrino direction");
331 
332  // --- Vertex info
333  AddVarI( output(), selvtx_det, "detector in which the reconstructed vertex is");
334  AddVar4VF(output(), selvtx_pos, "reconstructed vertex position");
335  AddVar4VF(output(), selvtx_truepos, "position of the true vertex associated to the reconstructed vertex");
336 
337  // --- true signal definition ---
338  AddToyVarI(output(), true_signal, "true signal appraisal (filled differently in each analysis package)");
339 
340  // --- Total systematic without flux systematic in all_syst configuration------
341  if (conf().GetConfiguration(all_syst))
342  output().AddToyVar(conf().GetConfiguration(all_syst)->GetTreeIndex(), weight_syst_total_noflux, "weight_syst_total_noflux", "F", "Total weight (corr+syst) with no flux systematic");
343 
344 }
345 
346 //********************************************************************
347 void baseAnalysis::DefineTruthTree(){
348  //********************************************************************
349 
350  // Add a tree to save the truth info as a clone of the NRooTrackerVtx or GRooTrackerVtx tree
352  if (input().GetChain("NRooTrackerVtx"))
353  output().AddTreeWithName(OutputManager::RooTrackerVtx, "RooTrackerVtx", input().GetChain("NRooTrackerVtx"));
354  else if (input().GetChain("GRooTrackerVtx"))
355  output().AddTreeWithName(OutputManager::RooTrackerVtx, "RooTrackerVtx", input().GetChain("GRooTrackerVtx"));
356  }
357 
358  //--- event variables -------
359  AddVarI(output(), evt, "event number");
360  AddVarI(output(), run, "run number");
361  AddVarI(output(), subrun, "subrun number");
362 
363  // ---- link with ...
364  AddVarI(output(), TruthVertexID, "The unique ID of the true vertex associated to the selected event");
365  // AddVarI(output(), TruthVertexNB, "");
366  AddVarI(output(), RooVtxIndex, "The index of the associated RooTrackerVtx vertex from its position in the TClonesArray");
367  AddVarI(output(), RooVtxEntry, "The entry of the event in the saved RooTrackerVtx tree");
368  AddVarI(output(), RooVtxEntry2, "The entry of the event in the saved RooTrackerVtx tree");
369  AddVarI(output(), RooVtxFile, "The File of the event in the saved RooTrackerVtx tree");
370 
371  // ---- neutrino variables
372  AddVarI(output(), nu_pdg, "neutrino pdg code");
373  AddVarF(output(), nu_trueE, "true neutrino energy"); // true neutrino energy
374  AddVarI(output(), nu_truereac, "true neutrino reaction type"); // true neutrino reaction code
375  AddVar3VF(output(), nu_truedir, "true neutrino direction"); // true neutrino direction
376  AddVar4VF(output(), truevtx_pos, "true neutrino interaction position");
377  // AddVarI( output(), truevtx_det, "detector enum of the true neutrino interaction"); // is the same as the category detector
378 
379 
380  //--- main lepton variables -------
381  // AddVarF(output(), "truth","truemu_rec", "I"); // Is the recon muon a true muon
382  // AddVarI( output(), truelepton_pdg, "true lepton PDG"); // is the same as the category particle
383  AddVarF( output(), truelepton_mom, "true lepton momentum");
384  AddVarF( output(), truelepton_costheta, "true lepton cos(theta) w.r.t. neutrino direction");
385  AddVar3VF(output(), truelepton_dir, "true lepton direction");
386 
387 
388  //--- add event weights ----------------------
389  AddVarVF(output(), weight, "global weights (flux, pileup, ...)",NWEIGHTS);
390 
391  // --- true signal definition (one could fill this var wih a sub-sample of truth entries) ---
392  AddVarI(output(), true_signal, "true signal appraisal (filled differently in each analysis package)");
393 }
394 
395 //********************************************************************
396 bool baseAnalysis::InitializeSpill(){
397 //********************************************************************
398 
399  return _rooVtxManager->InitializeEntry();
400 }
401 
402 //********************************************************************
403 bool baseAnalysis::FinalizeConfiguration(){
404  //********************************************************************
405 
406  // This is called before FillMicroTrees()
407 
408  // Save the accum level for the true vertex associated to the recon one such that efficiencies can be computed from the truth tree
409  if (conf().GetCurrentConfigurationIndex() != ConfigurationManager::default_conf)
410  return true;
411 
412 
413  std::vector<AnaTrueVertex*> trueVertices;
414  trueVertices.reserve(NMAXTRUEVERTICES);
415  std::vector<AnaTrueVertex*>::const_iterator iter;
416 
417 
418  AnaTrueVertex* trueVertex = NULL;
419  if (GetVertex()) trueVertex = static_cast<AnaTrueVertex*>(GetVertex()->TrueVertex);
420  else trueVertex = static_cast<AnaTrueVertex*>(GetTrueVertex());
421 
422  if (trueVertex) trueVertices.push_back(trueVertex);
423 
424 
425  // If true vertex does not exist (e.g. can happen that reco vertex is not yet available at this step of the selection) then
426  // store the accum_level to all true vertices of the bunch -> i.e. this basically corresponds to the fact that event as a whole
427  // passed some cuts
428  if (trueVertices.size() == 0){
429  // Loop over all true vertices in the event and found those that belong to the bunch being processed
430  std::vector<AnaTrueVertexB*> vertices = GetSpill().TrueVertices;
431  for (std::vector<AnaTrueVertexB*>::iterator it = vertices.begin(); it!=vertices.end(); it++) {
432  if (!(*it)) continue;
433  AnaTrueVertex* vtx = static_cast<AnaTrueVertex*>(*it);
434 
435  // Check the bunch
436  if (GetBunch().Bunch != vtx->Bunch) continue;
437 
438  trueVertices.push_back(vtx);
439  }
440  }
441 
442  // Loop over all true vertices of interest
443  for (iter = trueVertices.begin(); iter != trueVertices.end(); iter++){
444  AnaTrueVertex* vtx = *iter;
445  if (!vtx) continue;
446 
447  // When the AccumLevel has not been already saved for this vertex
448  if (vtx->AccumLevel.size() == 0)
449  vtx->AccumLevel.resize(sel().GetNEnabledSelections());
450  //else{
451  // Sometimes the same true vertex is asigned to the candidate in another bunch, most likely because of a delayed track. In this case
452  // save the higher accum level
453  // std::cout << "baseAnalysis::FinalizeConfiguration(). This true vertex was used in another bunch (likely a delayed track). Save higher accum_level" << std::endl;
454  //}
455  for (std::vector<SelectionBase*>::iterator it = sel().GetSelections().begin(); it != sel().GetSelections().end(); it++){
456 
457  if (!(*it)->IsEnabled()) continue;
458 
459  Int_t isel = (*it)->GetEnabledIndex();
460 
461  if (vtx->AccumLevel[isel].size() == 0)
462  vtx->AccumLevel[isel].resize((*it)->GetNBranches());
463 
464  for (UInt_t ibranch=0;ibranch<(*it)->GetNBranches();ibranch++)
465  vtx->AccumLevel[isel][ibranch]=(*it)->GetAccumCutLevel(ibranch);
466  }
467  }
468  return true;
469 }
470 
471 //********************************************************************
472 void baseAnalysis::FillMicroTreesBase(bool addBase){
473  //********************************************************************
474 
475  (void)addBase;
476 
477  // This is called after FinalizeConfiguration
478 
479  // Fill all tree variables that are common to all toys in a given configuration
480 
481  // The index of the input file in which the RooTracker vtx is
482  output().FillVar(RooVtxFile, GetSpill().InputFileIndex);
483  output().FillVar(RooVtxEntry2, GetSpill().RooVtxEntry);
484 
485  // Event variables
486  output().FillVar(run, GetSpill().EventInfo->Run);
487  output().FillVar(subrun, GetSpill().EventInfo->SubRun);
488  output().FillVar(evt, GetSpill().EventInfo->Event);
489 
490  output().FillVar(evt_time, static_cast<AnaEventInfo*>(GetSpill().EventInfo)->EventTime);
491 
492  output().FillVar(bunch, GetBunch().Bunch);
493 
494  // default flux_weight. TO BE REMOVED
495  Float_t flux_weight =1;
496 
497  // Vertex info
498  if (GetVertex()){
499  output().FillVar(selvtx_det,anaUtils::GetDetector(GetVertex()->Position));
500  output().FillVectorVarFromArray(selvtx_pos,GetVertex()->Position, 4);
501  if (GetVertex()->TrueVertex)
502  output().FillVectorVarFromArray(selvtx_truepos, GetVertex()->TrueVertex->Position, 4);
503  }
504 
505  // Neutrino truth variables
506  if (GetVertex()){
507  if (GetVertex()->TrueVertex){
508  AnaTrueVertex* trueVertex = static_cast<AnaTrueVertex*>(GetVertex()->TrueVertex);
509  output().FillVar(nu_pdg, trueVertex->NuPDG);
510  output().FillVar(nu_trueE, trueVertex->NuEnergy);
511  output().FillVar(nu_truereac, trueVertex->ReacCode);
512 
513  output().FillVectorVarFromArray(nu_truedir, trueVertex->NuDir, 3);
514 
515  // Get the beam weight. By construction this is 1 for the data (no need to disable it). TO BE REMOVED
516  if (_flux && !GetSpill().GetIsSandMC()){
517  flux_weight = _flux->GetWeight(trueVertex,anaUtils::GetRunPeriod(GetSpill().EventInfo->Run));
518  }
519  }
520  }
521 
522  // Fill the flux weight. TO BE REMOVED
523  if (_flux){
524  output().FillVectorVar(weight, flux_weight);
525  output().IncrementCounter(NWEIGHTS);
526  }
527 
528  // The pile up correction weight. TO BE REMOVED
529  output().FillVectorVar(weight, GetBunch().Weight);
530  output().IncrementCounter(NWEIGHTS);
531 }
532 
533 //********************************************************************
534 void baseAnalysis::FillToyVarsInMicroTreesBase(bool addBase){
535  //********************************************************************
536 
537  (void)addBase;
538 
539  if (!GetVertex()) return;
540  if (!GetVertex()->TrueVertex) return;
541 
542  AnaTrueVertex* trueVertex = static_cast<AnaTrueVertex*>(GetVertex()->TrueVertex);
543 
544  output().FillToyVar(TruthVertexID, trueVertex->ID);
545  output().FillToyVar(RooVtxIndex, trueVertex->RooVtxIndex);
546 
549  output().FillToyVar(RooVtxEntry, _rooVtxManager->GetRooVtxEntry());
550  }
551  else
552  output().FillToyVar(RooVtxEntry, trueVertex->RooVtxEntry);
553 
554  // weight_syst_total without flux weight systematic (with flux weight correction)
555  static Int_t flux_weight_index=-2;
556  if (conf().GetCurrentConfigurationIndex() == all_syst && flux_weight_index!=-1){
557  if (flux_weight_index==-2){
558  ConfigTreeTools config(syst(),conf());
559  flux_weight_index = config.GetWeightIndex(all_syst, SystId::kFluxWeightNu);
560  }
561  if (flux_weight_index!=-1){
562  Float_t flux_corr = output().GetToyVectorVarValueF(AnalysisAlgorithm::weight_corr,flux_weight_index);
563  Float_t flux_syst = output().GetToyVectorVarValueF(AnalysisAlgorithm::weight_syst,flux_weight_index);
564 
565  Float_t total_noflux = output().GetToyVarValueF(AnalysisAlgorithm::weight_syst_total);
566  if (flux_syst!=0) total_noflux = total_noflux*flux_corr/flux_syst;
567  output().FillToyVar(weight_syst_total_noflux, total_noflux);
568  }
569  }
570 }
571 
572 //********************************************************************
573 void baseAnalysis::FillTruthTreeBase(const AnaTrueVertex& vtx, const SubDetId::SubDetEnum det, bool IsAntinu){
574  //********************************************************************
575 
576  // Fill track categories for color drawing
577  anaUtils::FillCategories(&vtx, det, IsAntinu, GetSpill().GetIsSandMC());
578 
579  // Event variables
580  output().FillVar(run, GetSpill().EventInfo->Run);
581  output().FillVar(subrun, GetSpill().EventInfo->SubRun);
582  output().FillVar(evt, GetSpill().EventInfo->Event);
583 
584  // true variables
585  output().FillVar(nu_pdg, vtx.NuPDG);
586  output().FillVar(nu_trueE, vtx.NuEnergy);
587  output().FillVar(nu_truereac, vtx.ReacCode);
588  output().FillVar(TruthVertexID, vtx.ID);
589  output().FillVar(RooVtxIndex, vtx.RooVtxIndex);
590  output().FillVar(RooVtxEntry, vtx.RooVtxEntry);
591  output().FillVar(RooVtxEntry2, GetSpill().RooVtxEntry);
592  output().FillVar(RooVtxFile, GetSpill().InputFileIndex);
593 
594  output().FillVectorVarFromArray(nu_truedir, vtx.NuDir, 3);
595  output().FillVectorVarFromArray(truevtx_pos, vtx.Position, 4);
596  // output().FillVar( truevtx_det, anaUtils::GetDetector(vtx.Position)); // is the same as the category detector
597 
598  // True lepton variables
599  // output().FillVar( truelepton_pdg, vtx.LeptonPDG); // is the same as the category particle
600  output().FillVar( truelepton_costheta, (Float_t)cos(anaUtils::ArrayToTVector3(vtx.LeptonDir).Angle(anaUtils::ArrayToTVector3(vtx.NuDir))));
601  output().FillVar( truelepton_mom, vtx.LeptonMom);
602  output().FillVectorVarFromArray(truelepton_dir, vtx.LeptonDir,3);
603 
604 
605  // Fill event weights. Currently, only the weight from flux tuning is filled here.
606  if (_flux && !GetSpill().GetIsSandMC()) {
607  output().FillVectorVar(weight, _flux->GetWeight(vtx,anaUtils::GetRunPeriod(GetSpill().EventInfo->Run)));
608  output().IncrementCounterForVar(weight);
609  }
610 }
611 
612 //********************************************************************
613 void baseAnalysis::FillTruthTree(){
614 //********************************************************************
615 
616  // Fill the "truth" tree
617 
618  if (!output().HasTree(OutputManager::truth)) return;
619 
620  output().SetCurrentTree(OutputManager::truth);
621 
622  // Loop over all true vertices
623  std::vector<AnaTrueVertexB*> vertices = GetSpill().TrueVertices;
624  for (std::vector<AnaTrueVertexB*>::iterator it = vertices.begin(); it!=vertices.end(); it++) {
625  AnaTrueVertex& vtx = *static_cast<AnaTrueVertex*>(*it);
626 
627  // Check if this vertex needs to be saved in the truth tree
628  if (!CheckFillTruthTree(vtx)) continue;
629 
630  // Initialize the truth tree. We must do that for each saved vertex since several entries may correspond to the save spill
631  output().InitializeTree(OutputManager::truth);
632 
633  // Check whether to save the RooTracker info for this vertex.
634  // Should not be saved if already saved in baseAnalysis::FillMicroTreesBase
636  if (!_rooVtxManager->GetRooVtxEntrySaved()) {
637  // The current RooVtxEntry should be saved in the RooTrackerVtx tree
639  }
640 
641  // Associate the vertex with the current RooTrackerVtx entry
642  // We should do this here (even when the current RooTrackerVtx entry has been already saved).
643  // if the RooVtxEntry has been already save in baseAnalysis::FillMicroTreesBase, but there is more than one vertex to be saved for
644  // this entry the link has not been yet established
645  vtx.RooVtxEntry = _rooVtxManager->GetRooVtxEntry();
646  }
647 
648  // accumulated cut levels to compute efficiencies. This is taken directly from the AnaTrueVertex
649  Int_t accumLevel=1; // intialize to 1 because EventQuality is passed by definition in MC (TODO: what about analysis in which the first cut is not EventQuality)
650  for (std::vector<SelectionBase*>::iterator itf=sel().GetSelections().begin();itf!=sel().GetSelections().end();itf++){
651  if (!(*itf)->IsEnabled()) continue;
652 
653  Int_t isel = (*itf)->GetEnabledIndex();
654 
655  for (UInt_t ibranch=0;ibranch<(*itf)->GetNBranches();ibranch++){
656  if (vtx.AccumLevel.size()>0) accumLevel = vtx.AccumLevel[isel][ibranch];
657  if (sel().GetNEnabledSelections()>1){
658  if (sel().GetNMaxBranches()>1)
659  output().FillMatrixVar(accum_level, accumLevel, isel, ibranch);
660  else
661  output().FillVectorVar(accum_level, accumLevel, isel);
662  }
663  else{
664  if (sel().GetNMaxBranches()>1)
665  output().FillVectorVar(accum_level, accumLevel, ibranch);
666  else
667  output().FillVar(accum_level, accumLevel);
668  }
669  }
670  }
671 
672  // Reset the categories for the current track
673  cat().ResetCurrentCategories();
674 
675  // Call the derive classes functions, that also fills the categories
676  FillTruthTree(vtx);
677 
678  // Fill the truth tree provided the true codes for color drawing
679  std::map< std::string, TrackCategoryDefinition* >::iterator its;
680  Int_t categ_index = AnalysisAlgorithm::firstCategory;
681  for (its=cat().GetCategories().begin();its!=cat().GetCategories().end();its++, categ_index++ ){
682  std::string categ_name = its->first;
683  TrackCategoryDefinition& categ = *(its->second);
684  if (categ.IsMultiType()){
685  for (unsigned int i=0;i<categ.GetNTypes();i++)
686  output().FillVectorVar(categ_index, (int)cat().CheckCategoryType(categ_name,i),i);
687  }
688  else output().FillVar(categ_index, cat().GetCode(categ_name));
689  }
690 
691  // Fill the tree
692  output().GetTree(OutputManager::truth)->Fill();
693  }
694 
695 
696  if (output().HasTree(OutputManager::RooTrackerVtx)){
697  // Fill the entry in the RooTrackerVertex tree (only if it has been missed in the default tree, see baseAnalysis::FillMicroTreesBase)
698  if (_rooVtxManager->GetSaveRooVtxEntry()) {
699  output().FillTree(OutputManager::RooTrackerVtx);
700  _rooVtxManager->SetRooVtxEntrySaved(true); // Not really needed, but just in case we do something related later
702  }
703  }
704 }
void DisableAllCorrections()
Disable all corrections in a given configuration (if conf=="" for all confs)
AnaTrueVertexB * TrueVertex
FluxWeighting * _flux
Access to the flux weighting.
Int_t NuPDG
The PDG code of the incoming neutrino.
Float_t GetToyVarValueF(Int_t index)
Get the value of a var already filled (so to be used in another package)
bool IsMultiType()
Is this a multi-type category ? (Can several types coexist?)
int GetParameterI(std::string)
Get parameter. Value is returned as integer.
Definition: Parameters.cxx:217
TTree * GetTree(Int_t index)
Returns the a tree with a given index.
Definition: TreeManager.hxx:28
void InitializeGeometry(bool IsMC=true) const
void SetInitializeTrees(bool ini)
Initialize trees at the beginning of each configuration.
Float_t LeptonDir[3]
The direction of the primary outgoing electron/muon.
void AddCorrection(Int_t index, const std::string &name, CorrectionBase *corr)
void AddTreeWithName(Int_t tree_index, const std::string &tree_name, TTree *tree=NULL)
Add a tree provided its index and name.
void AddToyVar(Int_t index, const std::string &name, const std::string &type, const std::string &docstring)
Add a single analysis variable to all trees.
Int_t RooVtxIndex
The index of the associated RooTrackerVtx vertex from its position in the TClonesArray.
Definition: DataClasses.hxx:75
void AddPackage(const std::string &name, const std::string &version)
Add a package.
Float_t Position[4]
The identified position of the global vertex.
void FillVectorVar(Int_t index, Float_t var, Int_t indx=-1)
Fill a vector variable.
std::vector< std::vector< Int_t > > AccumLevel
Accumulated cut level for all selections and cut branches. Tell us if a true vertex has been selected...
Definition: DataClasses.hxx:94
std::vector< AnaTrueVertexB * > TrueVertices
The true MC vertices used in this spill.
UInt_t GetNEnabledSelections()
Returns the number of enabled selections.
Float_t GetToyVectorVarValueF(Int_t index, Int_t i1)
Get the value of a var already filled (so to be used in another package)
virtual bool Initialize()
[AnalysisAlgorithm_mandatory]
bool _enableZeroVarConfig
SubDetId::SubDetEnum GetDetector(const Float_t *pos)
Return the detector in which the position is.
AnaBunch & GetBunch()
Get a casted AnaBunchBB to AnaBunch from the InputManager (TODO the protection)
void EnableSystematics(const std::vector< Int_t > &systs, Int_t conf=-1)
Enable the systematics registered with the given indices.
std::vector< SelectionBase * > & GetSelections()
Return the map of selections.
Int_t ID
The ID of the trueObj, which corresponds to the ID of the TTruthParticle that created it...
std::string GetSoftwareVersionFromPath(const std::string &path)
Get The software version from the path of the package.
Float_t LeptonMom
The momentum of the primary outgoing electron/muon.
Representation of a true Monte Carlo vertex.
Definition: DataClasses.hxx:50
RooTrackerVtxManager * _rooVtxManager
the manager of the RooTrackerVtx
Float_t NuEnergy
The true energy of the incoming neutrino.
Float_t Position[4]
The position the true interaction happened at.
void SetCurrentTree(Int_t index)
Sets the current tree provided the index.
Definition: TreeManager.hxx:58
int GetRunPeriod(int run, int subrun=-1)
Returns the run period (sequentially: 0,1,2,3,4,5 ...)
std::map< std::string, TrackCategoryDefinition * > & GetCategories()
Get the map of track categories.
void SetRooVtxEntrySaved(bool saved)
Methods to check whether the current RooTrackerVtxEntry has been already saved.
SubDetEnum
Enumeration of all detector systems and subdetectors.
Definition: SubDetId.hxx:25
Creates the appropriate AnaSpillB type. The rest of the work is done by the base converter.
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.
void ResetCurrentCategories()
Reset the properties of the current track.
Float_t GetWeight(AnaTrueVertexB *vertex, int RunPeriod)
bool _saveRooTrackerVtxTree
Save RooTracker tree in output file.
void FillToyVar(Int_t index, Int_t var)
Fill a single analysis variable.
Int_t GetWeightIndex(const std::string &conf, const std::string &name) const
std::vector< ConfigurationBase * > & GetConfigurations()
return the vector of configurations
void IncrementRooVtxEntry()
Increment by one the current entry in the RooTrackerVtx tree.
Creates ToyExperiments.
void AddEventWeight(Int_t index, EventWeightBase *sys)
Add a new Event Weight provided its index in the manager and a pointer to it.
void EnableEventWeight(Int_t syst, Int_t conf=-1)
Enable the systematic registered with the given index.
void SetForceApplyCorrections(bool force)
If set to true corrections applied in the input file are applied again.
void FillVar(Int_t index, Float_t var)
Fill a single variable.
void SetSaveRooTracker(bool save)
Set whether to save the RooTrackerVtx tree or not.
Int_t Bunch
The index of this bunch (0-7).
unsigned int GetNTypes()
Number of types defined for this category.
AnaSpill & GetSpill()
Get a casted AnaSpillC to AnaSpill from the InputManager.
std::vector< AnalysisAlgorithm * > _usedAnalyses
The Vector of used analysis.
void AddConverter(const std::string &name, InputConverter *conv)
Add this converter to the vector of recognised converters.
Int_t RooVtxEntry
Entry in the RooTrackerVtx tree (not set directly)
Definition: DataClasses.hxx:72
baseAnalysis(AnalysisAlgorithm *ana=NULL)
ProdId_h GetProductionIdFromND280AnalysisTools()
Get Production Id from nd280AnalysisTools.
UInt_t GetNMaxBranches()
Returns the maximum number of branches in all selections.
void SetRooVtxManager(RooTrackerVtxManager *man)
Set the RooTrackerVtxManager.
void AddProduction(ProdId_h prodId, const std::string &prodName, const std::string &prodLowVersion, const std::string &prodHighVersion)
Add a production.
Float_t NuDir[3]
The true (unit) direction of the incoming neutrino.
Definition: DataClasses.hxx:82
void FillMatrixVar(Int_t index, Float_t var, Int_t indx1, Int_t indx2)
Fill a matrix variable.
void FillVectorVarFromArray(Int_t index, const Double_t var[], UInt_t size)
Fill a vector variable from array.
void SetSaveRooVtxEntry(bool save)
Methods to check whether the current RooTrackerVtxEntry has been already scheduled for saving...
void FillTree(Int_t tree_index)
Fill a specific tree.