HighLAND
MiniTreeConverter.cxx
1 #include "MiniTreeConverter.hxx"
2 #include "BasicUtils.hxx"
3 #include "VersioningUtils.hxx"
4 #include "Parameters.hxx"
5 #include "GeometryManager.hxx"
6 #include "ND280AnalysisUtils.hxx"
7 #include <typeinfo>
8 
9 AnaSpillC* RawSpillC=NULL;
10 
11 //********************************************************************
12 MiniTreeConverter::MiniTreeConverter(bool readRooTrackerVtx):InputConverter("MiniTree"){
13 //********************************************************************
14 
15  // Use corrected values or raw values
16  // _useCorrectedValues = ND::params().GetParameterI("highlandIO.ReadFlatTree.UseCorrectedValues");
17 
18  AddChain(_treeName);
19 
20  minitree = GetChain(_treeName);
21  NRooTrackerVTX = NULL;
22  GRooTrackerVTX = NULL;
23  _spill = NULL;
24  _entry_roo=0;
25 
26  fChain = minitree;
27 
28  _firstFile = true;
29  _currentfilename="";
30  _currentBunch = 0;
31 
32  // If true the RooTrackerVtx tree will be read
33  _readRooTrackerVtx = readRooTrackerVtx;
34 }
35 
36 //********************************************************************
38 //********************************************************************
39 
40  // Set branch addresses and branch pointers
41  if (!fChain) return false;
42 
43  // Check the existence of the "minitree" tree
44  if (!gDirectory->FindObjectAny(_treeName.c_str())) return false;
45 
46  fCurrent = -1;
47  fChain->SetMakeClass(1);
48 
49  return true;
50 }
51 
52 //********************************************************************
53 MiniTreeConverter::~MiniTreeConverter(){
54 //********************************************************************
55 
56  if (!fChain) return;
57 
58  if (minitree) delete minitree->GetCurrentFile();
59  if (GRooTrackerVTX) delete GRooTrackerVTX->GetCurrentFile();
60  if (NRooTrackerVTX) delete NRooTrackerVTX->GetCurrentFile();
61  if (minitree) delete minitree;
62  if (GRooTrackerVTX) delete GRooTrackerVTX;
63  if (NRooTrackerVTX) delete NRooTrackerVTX;
64 }
65 
66 //****************************************************************************
67 bool MiniTreeConverter::AddFileToTChain(const std::string& inputString){
68 //****************************************************************************
69 
70  std::cout << "MiniTreeConverter::AddFileToTChain(). Adding file: " << inputString << std::endl;
71 
72  // ------------- Check that the file has some entries. Otherwise ignore it -----------------
73  TChain dummy(_treeName.c_str());
74  dummy.AddFile(inputString.c_str());
75  // if (dummy.GetEntries("sEvt>=0") == 0){
76  if (dummy.GetEntries() == 0){
77  std::cout << " ----> This file does not contain any entries. IGNORED !!!!" << std::endl;
78  return true;
79  }
80 
81  // Open the file to do few checks
82  TFile *f = TFile::Open(inputString.c_str());
83  f->cd();
84 
85  // ------------- Check that the header tree exists (needed for POT counting). If it doesn't ignore the file -----------------
86 
87  bool isMC = false;
88  if (!gDirectory->FindObjectAny("header")){
89  std::cout << " ----> This file does not contain a header tree. IGNORED !!!!" << std::endl;
90  return true;
91  }
92  else{
93  TChain chain("header");
94  chain.AddFile(inputString.c_str());
95  Header *header=0;
96  chain.SetBranchAddress("POTInfo", &header);
97  chain.GetEntry(0);
98  isMC = header->GetIsMC();
99  }
100 
101  // ---------- Deal with RooTrackerVtx trees. Only for the first file
102 
103  if( _firstFile ) {
104  _firstFile = false;
105  fGenie=fNeut=false;
106 
107  if( gDirectory->FindObjectAny("NRooTrackerVtx")) {
108  fNeut = true;
109  AddChain("NRooTrackerVtx");
110  NRooTrackerVTX = GetChain("NRooTrackerVtx");
111  NRooTrackerVTX->SetBranchAddress("RunID", &RunID);
112  NRooTrackerVTX->SetBranchAddress("SubrunID", &SubrunID);
113  NRooTrackerVTX->SetBranchAddress("EventID", &EventID);
114  NVtx = new TClonesArray("ND::NRooTrackerVtx",100);
115  NRooTrackerVTX->SetBranchAddress("NVtx",&NNVtx);
116  NRooTrackerVTX->SetBranchAddress("Vtx",&NVtx);
117  std::cout << "MiniTreeConverter::AddFileToTChain(). NEUT RooTrackerVtx tree found !!" << std::endl;
118  }
119  else if(gDirectory->FindObjectAny("GRooTrackerVtx")) {
120  fGenie = true;
121  AddChain("GRooTrackerVtx");
122  GRooTrackerVTX = GetChain("GRooTrackerVtx");
123  GRooTrackerVTX->SetBranchAddress("RunID", &RunID);
124  GRooTrackerVTX->SetBranchAddress("SubrunID", &SubrunID);
125  GRooTrackerVTX->SetBranchAddress("EventID", &EventID);
126  GVtx = new TClonesArray("ND::GRooTrackerVtx",100);
127  GRooTrackerVTX->SetBranchAddress("NVtx",&NGVtx);
128  GRooTrackerVTX->SetBranchAddress("Vtx",&GVtx);
129  std::cout << "MiniTreeConverter::AddFileToTChain(). GENIE RooTrackerVtx tree found !!" << std::endl;
130  }
131  }
132 
133  // Close the file
134  f->Close();
135 
136  // ------------- Add the file to the RooTrackerVtx chain
137 
138  if( fGenie && GRooTrackerVTX) {
139  GRooTrackerVTX->AddFile(inputString.c_str());
140  }
141  else if( fNeut && NRooTrackerVTX) {
142  NRooTrackerVTX->AddFile(inputString.c_str());
143  }
144 
145  // ------------- Add the file to the Minitree chain
146  minitree->AddFile(inputString.c_str());
147  // Read the header tree for POT counting (when running over a file list POT is incremented), IsMC and SoftwareVersion
148  bool bySpillPOT = (versionUtils::prod6_POT || !isMC); // by Spill POT is not available for prod5 MC
149  return header().AddHeader(inputString,bySpillPOT);
150 }
151 
152 //*****************************************************************************
153 Int_t MiniTreeConverter::GetEvent(Long64_t& entry, AnaEventC*& event){
154 //*****************************************************************************
155 
156 // static AnaSpillB* RawSpill = 0;
157  Int_t entry_temp=1;
158 
159  AnaSpillB* RawSpill = static_cast<AnaSpillB*>(RawSpillC);
160 
161  if (RawSpill && _currentBunch < (Int_t)(RawSpill->Bunches.size()-1)){
162  _currentBunch++;
163  }
164  else{
165  if (RawSpill) delete RawSpill;
166  entry_temp = GetSpill(entry,RawSpillC);
167  if (entry_temp<=0 || !RawSpill || RawSpill->Bunches.size()==0) return 0;
168  _currentBunch=0;
169  }
170 
171  // Create a new event from the RawSpill and the current bunch
172  event = MakeEvent(*RawSpill,*static_cast<AnaBunchB*>((RawSpill->Bunches[_currentBunch])));
173 
174  return entry_temp;
175 }
176 
177 //*****************************************************************************
178 Int_t MiniTreeConverter::GetSpill(Long64_t& entry, AnaSpillC*& spill){
179 //*****************************************************************************
180 
181  // Read contents of entry.
182  if (!fChain) return 0;
183 
184  // Create the appropriate instance of Spill
185  spill = MakeSpill();
186 
187  // cast to AnaSpillB
188  _spill = static_cast<AnaSpillB*>(spill);
189 
190  // Set the branch address
191  fChain->SetBranchAddress("Spill", &spill);
192 
193  // Print the current file
194  std::string filename =minitree->GetFile()->GetName();
195  if( filename != _currentfilename ) {
196  std::cout << " Running on file: " << filename << std::endl;
197  _currentfilename = filename;
198  }
199 
200  // get a new entry from the flat tree. entry_temp >0 when succesfull
201  Int_t entry_temp = minitree->GetEntry(entry);
202 
203  // If this is not one of the events to skim just go to the next entry (and don't process that event --> return <=0)
204  if (!anaUtils::CheckSkimmedEvent(_spill->EventInfo->Run,_spill->EventInfo->SubRun,_spill->EventInfo->Event)){
205  entry++;
206  return 0;
207  }
208 
209  if (_spill->EventInfo){
210  if (_readRooTrackerVtx){
211  bool sIsMC = _spill->EventInfo->IsMC;
212  Int_t sEvt = _spill->EventInfo->Event;
213  Int_t sSubrun = _spill->EventInfo->SubRun;
214  Int_t sRun = _spill->EventInfo->Run;
215 
216  // sEvt should be positive since sEvt=-999 is used for the last flatree entry
217  if (entry_temp>0 && sIsMC && (fGenie || fNeut) && sEvt>=0) {
218  // Loop over RooTrackerVtx entries until we get the same run, subrun and event numbers
219  // In general we will get the right entry in the first iteration, but just in case
220  do{
221  if (NRooTrackerVTX) NRooTrackerVTX->GetEntry(_entry_roo);
222  else if (GRooTrackerVTX) GRooTrackerVTX->GetEntry(_entry_roo);
223  if ((RunID> sRun ) ||
224  (RunID==sRun && SubrunID> sSubrun ) ||
225  (RunID==sRun && SubrunID==sSubrun && EventID>sEvt ))
226  _entry_roo--;
227  else
228  _entry_roo++;
229  }while(EventID!=sEvt || RunID!=sRun || SubrunID!=sSubrun);
230  }
231  }
232 
233  // Copy vectors into arrays
234  _spill->CopyVectorsIntoArrays();
235  // Redo reco-reco and reco-truth links (many not pressent in MiniTree)
236  _spill->RedoLinks();
237  }
238  else
239  entry_temp=0;
240 
241 
242  // Increment entry number
243  entry++;
244 
245  // Load the geometry for this spill(999 is the default value in BaseDataClasses)
246  if (_spill->GeomID!=999)
247  ND::hgman().LoadGeometry(filename,(Int_t)_spill->GeomID,"geom");
248 
249  return entry_temp;
250 }
251 
252 //********************************************************************
254 //********************************************************************
255 
256  anaUtils::IncrementPOTBySpill(*_spill,header());
257  // header().IncrementPOTBySpill(*_spill);
258 }
259 
260 //*****************************************************************************
261 AnaEventB* MiniTreeConverter::MakeEvent(AnaSpillB& spill, AnaBunchB& bunch) {
262 //*****************************************************************************
263 
264 #ifndef MULTITHREAD
265  return new AnaEventB(spill, bunch);
266 #endif
267 
268  // For MULTITHREAD we must recreate the links
269 
270  AnaEventB* event = new AnaEventB();
271 
272  event->UniqueID = 0;
273  event->Particles = NULL;
274  event->Vertices = NULL;
275  event->TrueParticles = NULL;
276  event->TrueVertices = NULL;
277  event->FgdTimeBins = NULL;
278  event->nParticles = 0;
279  event->nVertices = 0;
280  event->nFgdTimeBins = 0;
281  event->nTrueParticles = 0;
282  event->nTrueVertices = 0;
283  event->Beam = NULL;
284  event->DataQuality = NULL;
285  event->isClone = false;
286 
287  event->nEventBoxes=0;
288  for (UInt_t i=0;i<NMAXEVENTBOXES;i++)
289  event->EventBoxes[i]=NULL;
290 
291  // The initial weight of the Event is 1;
292  event->Weight=1;
293 
294  // Must create a summary object when we create an event
295  // This is initialised to NULL and SampleId::kUnassigned, so you know it has not passed a selection
296  event->Summary = new AnaEventSummaryB();
297 
298  std::map<AnaRecObjectC*, AnaRecObjectC*> clonedRecObject;
299  std::map<AnaTrueObjectC*, AnaTrueObjectC*> clonedTrueObject;
300  std::map<AnaTrueVertexB*, AnaTrueVertexB*> clonedTrueVertex;
301 
302  //------ Copy from Spill and Bunch ----------------
303 
304  event->Weight = bunch.Weight;
305  event->Bunch = bunch.Bunch;
306  event->EventInfo = *spill.EventInfo;
307  event->Beam = spill.Beam->Clone();
308  event->DataQuality = spill.DataQuality->Clone();
309 
310  // Fill the recon tracks vector
311  event->nParticles = 0;
312  anaUtils::CreateArray(event->Particles, bunch.Particles.size());
313  for (UInt_t i=0;i<bunch.Particles.size();i++){
314  clonedRecObject[bunch.Particles[i]] = event->Particles[event->nParticles] = bunch.Particles[i]->Clone();
315 
316  if (bunch.Particles[i]->TrueObject){
317  if (bunch.Particles[i]->TrueObject->ID>=0){
318  clonedTrueObject[bunch.Particles[i]->TrueObject] = event->Particles[event->nParticles]->TrueObject = bunch.Particles[i]->TrueObject->Clone();
319  bunch.Particles[i]->TrueObject->ID *=-1;
320  }
321  else{
322  event->Particles[event->nParticles]->TrueObject = clonedTrueObject[bunch.Particles[i]->TrueObject];
323  }
324  if (bunch.Particles[i]->GetTrueParticle()->TrueVertex){
325  if(bunch.Particles[i]->GetTrueParticle()->TrueVertex->ID>=0){
326  clonedTrueVertex[bunch.Particles[i]->GetTrueParticle()->TrueVertex] = event->Particles[event->nParticles]->GetTrueParticle()->TrueVertex = bunch.Particles[i]->GetTrueParticle()->TrueVertex->Clone();
327  bunch.Particles[i]->GetTrueParticle()->TrueVertex->ID*=-1;
328  }
329  else
330  event->Particles[event->nParticles]->GetTrueParticle()->TrueVertex = clonedTrueVertex[bunch.Particles[i]->GetTrueParticle()->TrueVertex];
331  }
332  }
333  event->nParticles++;
334  }
335 
336  // Fill the true tracks vector
337  event->nTrueParticles = 0;
338  anaUtils::CreateArray(event->TrueParticles, spill.TrueParticles.size());
339  for (UInt_t i=0; i<spill.TrueParticles.size();i++){
340  // Recreate the links
341  if (spill.TrueParticles[i]->ID>=0){
342  clonedTrueObject[spill.TrueParticles[i]] = event->TrueParticles[event->nTrueParticles] = spill.TrueParticles[i]->Clone();
343  spill.TrueParticles[i]->ID*=-1;
344 
345  if (spill.TrueParticles[i]->TrueVertex){
346  if(spill.TrueParticles[i]->TrueVertex->ID>=0){
347  clonedTrueVertex[spill.TrueParticles[i]->TrueVertex] = event->TrueParticles[event->nTrueParticles]->TrueVertex = spill.TrueParticles[i]->TrueVertex->Clone();
348  spill.TrueParticles[i]->TrueVertex->ID*=-1;
349  }
350  else
351  event->TrueParticles[event->nTrueParticles]->TrueVertex = clonedTrueVertex[spill.TrueParticles[i]->TrueVertex];
352  }
353  }
354  else
355  event->TrueParticles[event->nTrueParticles] = static_cast<AnaTrueParticleB*>(clonedTrueObject[spill.TrueParticles[i]]);
356 
357  event->nTrueParticles++;
358  }
359 
360  // Fill the true vertices vector
361  event->nTrueVertices = 0;
362  anaUtils::CreateArray(event->TrueVertices, spill.TrueVertices.size());
363  for (UInt_t i=0;i<spill.TrueVertices.size();i++){
364  if (spill.TrueVertices[i]->ID>=0){
365  clonedTrueVertex[spill.TrueVertices[i]] = event->TrueVertices[event->nTrueVertices] = spill.TrueVertices[i]->Clone();
366  spill.TrueVertices[i]->ID*=-1;
367  }
368  else
369  event->TrueVertices[event->nTrueVertices] = clonedTrueVertex[spill.TrueVertices[i]];
370 
371  for (Int_t j=0; j<event->TrueVertices[event->nTrueVertices]->nTrueParticles;j++){
372  event->TrueVertices[event->nTrueVertices]->TrueParticles[j] = static_cast<AnaTrueParticleB*>(clonedTrueObject[spill.TrueVertices[i]->TrueParticles[j]]);
373  }
374  event->nTrueVertices++;
375  }
376 
377 
378  // Fill the recon vertices vector
379  event->nVertices = 0;
380  anaUtils::CreateArray(event->Vertices, bunch.Vertices.size());
381  for (UInt_t i=0;i<bunch.Vertices.size();i++){
382  // Recreate the links
383  if (bunch.Vertices[i]->TrueVertex)
384  event->Vertices[event->nVertices]->TrueVertex = clonedTrueVertex[bunch.Vertices[i]->TrueVertex];
385 
386  for (Int_t j=0;j<bunch.Vertices[i]->nParticles;j++){
387  event->Vertices[i]->Particles[j] = static_cast<AnaParticleB*>(clonedRecObject[ bunch.Vertices[i]->Particles[j] ]);
388  }
389  event->nVertices++;
390  }
391 
392 
393  // Fill the FGD time bins vector
394  event->nFgdTimeBins = 0;
395  anaUtils::CreateArray(event->FgdTimeBins, spill.FgdTimeBins.size());
396  for (UInt_t i=0;i<spill.FgdTimeBins.size();i++){
397  event->FgdTimeBins[event->nFgdTimeBins] = spill.FgdTimeBins[i]->Clone();
398  event->nFgdTimeBins++;
399  }
400 
401  for (UInt_t i=0; i<spill.TrueParticles.size();i++){
402  if (spill.TrueParticles[i]->ID<0){
403  spill.TrueParticles[i]->ID*=-1;
404  }
405  }
406 
407  for (UInt_t i=0;i<spill.TrueVertices.size();i++){
408  if (spill.TrueVertices[i]->ID<=0){
409  spill.TrueVertices[i]->ID*=-1;
410  }
411  }
412 
413 }
414 
415 //*****************************************************************************
416 Int_t MiniTreeConverter::GetNEvents(Int_t entries0){
417 //*****************************************************************************
418 
419  Int_t entries = entries0;
420  if (entries0==-1) entries=GetEntries();
421 
422  // TODO. Assume for the moment 20% more events that entries in the MiniTree.
423  return 1.2*entries;
424 }
425 
426 
427 
virtual bool Initialize()
Int_t GetEvent(Long64_t &entry, AnaEventC *&event)
std::vector< AnaTrueVertexB * > TrueVertices
The true MC vertices used in this spill.
std::vector< AnaBunchC * > Bunches
The reconstructed objects, split into timing bunches.
AnaEventInfoB * EventInfo
Run, sunrun, event, time stamp, etc.
This class handles POT info, SoftwareVersion and IsMC.
Definition: Header.hxx:10
std::vector< AnaVertexB * > Vertices
Representation of a true Monte Carlo trajectory/particle.
bool GetIsMC() const
returns the Data/MC mode
Definition: Header.hxx:97
AnaBeamB * Beam
The beam quality flags for this spill.
std::vector< AnaFgdTimeBinB * > FgdTimeBins
The FGD time bins.
Float_t Weight
The weight to apply to this bunch (nominally 1). An example is the beam flux weight.
std::vector< AnaTrueParticleB * > TrueParticles
The true MC particles used in this spill.
virtual AnaBeamB * Clone()
Clone this object.
Int_t Bunch
The index of this bunch (0-7).
std::vector< AnaParticleB * > Particles
Representation of a reconstructed particle (track or shower).
AnaDataQualityB * DataQuality
The ND280 data quality flags for this spill.
virtual AnaDataQualityB * Clone()
Clone this object.
Int_t GetNEvents(Int_t entries=-1)
Return the total number of events for a given number of entries in the tree.
Int_t GetSpill(Long64_t &entry, AnaSpillC *&spill)
bool AddFileToTChain(const std::string &inputString)
Add the file specified to fChain, and any friend chains that were set up.
bool LoadGeometry(const std::string &file="", Int_t geomID=-1, const std::string &geomDir="")
Load the TGeoManager from the input root file. Returns true when the new geometry was loaded...