laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauMergeDataFiles.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2008 University of Warwick
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17 
18 /*
19 Laura++ package authors:
20 John Back
21 Paul Harrison
22 Thomas Latham
23 */
24 
25 #include "LauMergeDataFiles.hh"
26 
27 #include <iostream>
28 #include <map>
29 
30 #include "TLeaf.h"
31 #include "TObjArray.h"
32 #include "TSystem.h"
33 
35 
36 
37 LauMergeDataFiles::LauMergeDataFiles(const TString& fileName1, const TString& fileName2, const TString& treeName) :
38  fileName1_(fileName1),
39  fileName2_(fileName2),
40  treeName_(treeName),
41  inputFile1_(0),
42  inputFile2_(0),
43  inputTree1_(0),
44  inputTree2_(0),
45  outputFile_(0),
46  outputTree_(0)
47 {
48 }
49 
51 {
52  if (inputFile1_ && inputFile1_->IsOpen()) {
53  inputFile1_->Close();
54  }
55  delete inputFile1_;
56 
57  if (inputFile2_ && inputFile2_->IsOpen()) {
58  inputFile2_->Close();
59  }
60  delete inputFile2_;
61 
62  if (outputFile_ && outputFile_->IsOpen()) {
63  outputFile_->Close();
64  }
65  delete outputFile_;
66 }
67 
69 {
70  // open the two input ROOT files
71  inputFile1_ = TFile::Open(fileName1_);
72  if (!inputFile1_ || inputFile1_->IsZombie()) {
73  std::cerr<<"Problem opening file: \""<<fileName1_<<"\", exiting..."<<std::endl;
74  gSystem->Exit(EXIT_FAILURE);
75  }
76  inputTree1_ = dynamic_cast<TTree*>( inputFile1_->Get(treeName_) );
77  if (!inputTree1_) {
78  std::cerr<<"Problem getting tree called "<<treeName_<<"from file: \""<<fileName1_<<"\", exiting..."<<std::endl;
79  gSystem->Exit(EXIT_FAILURE);
80  }
81 
82  inputFile2_ = TFile::Open(fileName2_);
83  if (!inputFile2_ || inputFile2_->IsZombie()) {
84  std::cerr<<"Problem opening file: \""<<fileName2_<<"\", exiting..."<<std::endl;
85  gSystem->Exit(EXIT_FAILURE);
86  }
87  inputTree2_ = dynamic_cast<TTree*>( inputFile2_->Get(treeName_) );
88  if (!inputTree2_) {
89  std::cerr<<"Problem getting tree called "<<treeName_<<"from file: \""<<fileName2_<<"\", exiting..."<<std::endl;
90  gSystem->Exit(EXIT_FAILURE);
91  }
92 }
93 
95 {
96  TObjArray* leaves1 = inputTree1_->GetListOfLeaves();
97  TObjArray* leaves2 = inputTree2_->GetListOfLeaves();
98  Int_t nLeaves1 = leaves1->GetEntries();
99  Int_t nLeaves2 = leaves2->GetEntries();
100  if ( nLeaves1 != nLeaves2 ) {
101  std::cerr<<"Different number of leaves in the two input trees, not continuing."<<std::endl;
102  return;
103  }
104 
105  std::cout<<"Setting branches for input trees \""<<treeName_<<"\"..."<<std::endl;
106  inputTree1_->SetBranchAddress("iExpt",&iExpt_);
107  inputTree1_->SetBranchAddress("iEvtWithinExpt",&iEvtWithinExpt_);
108  inputTree2_->SetBranchAddress("iExpt",&iExpt_);
109  inputTree2_->SetBranchAddress("iEvtWithinExpt",&iEvtWithinExpt_);
110 
111  for (Int_t iLeaf(0); iLeaf<nLeaves1; ++iLeaf) {
112 
113  TLeaf * leaf = dynamic_cast<TLeaf*>((*leaves1)[iLeaf]);
114  TString type = leaf->GetTypeName();
115  TString name = leaf->GetName();
116  Int_t size = leaf->GetNdata();
117 
118  if ((name == "iExpt") || (name == "iEvtWithinExpt") || (size != 1)) {
119  continue;
120  }
121 
122  if ( type == "Double_t" ) {
123  std::pair<LeafDoubleMap::iterator,bool> result = doubleVars_.insert(std::make_pair(name,0.0));
124  LeafDoubleMap::iterator iter = result.first;
125  bool ok = result.second;
126  if (ok) {
127  inputTree1_->SetBranchAddress(name,&(iter->second));
128  inputTree2_->SetBranchAddress(name,&(iter->second));
129  }
130  } else if ( type == "Int_t" ) {
131  std::pair<LeafIntegerMap::iterator,bool> result = integerVars_.insert(std::make_pair(name,0));
132  LeafIntegerMap::iterator iter = result.first;
133  bool ok = result.second;
134  if (ok) {
135  inputTree1_->SetBranchAddress(name,&(iter->second));
136  inputTree2_->SetBranchAddress(name,&(iter->second));
137  }
138  }
139  }
140  std::cout<<"Set branch addresses for "<<doubleVars_.size()<<" Double_t branches.\n";
141  std::cout<<"Set branch addresses for "<<integerVars_.size()<<" Int_t branches.\n"<<std::endl;
142 }
143 
145 {
146  std::cout<<"Creating branches for output tree \""<<outputTree_->GetName()<<"\"..."<<std::endl;
147 
148  outputTree_->Branch("iExpt",&iExpt_,"iExpt/I");
149  outputTree_->Branch("iEvtWithinExpt",&iEvtWithinExpt_,"iEvtWithinExpt/I");
150 
151  for (LeafDoubleMap::iterator iter = doubleVars_.begin(); iter != doubleVars_.end(); ++iter) {
152  TString name = iter->first;
153  Double_t * address = &(iter->second);
154  TString thirdBit = name;
155  thirdBit += "/D";
156 
157  outputTree_->Branch(name,address,thirdBit);
158  }
159  for (LeafIntegerMap::iterator iter = integerVars_.begin(); iter != integerVars_.end(); ++iter) {
160  TString name = iter->first;
161  Int_t * address = &(iter->second);
162  TString thirdBit = name;
163  thirdBit += "/I";
164 
165  outputTree_->Branch(name,address,thirdBit);
166  }
167  std::cout<<"Created "<<doubleVars_.size()+integerVars_.size()<<" branches.\n"<<std::endl;
168 }
169 
170 void LauMergeDataFiles::process(const TString& fileName)
171 {
172  this->openInputFiles();
173 
174  this->setupInputTrees();
175 
176  outputFile_ = TFile::Open(fileName,"recreate");
177  outputTree_ = new TTree(treeName_,"");
178  this->setupOutputTree();
179 
180  // loop over the trees and combine the corresponding experiments
181  std::cout<<"Starting to combine the trees..."<<std::endl;
182 
183  // Find the first and last entries for each experiment in each tree
186 
187  // Check that the experiments in the two trees match
188  if ( !this->checkExperimentMaps() ) {
189  return;
190  }
191 
192  // Loop through the experiments
193  for ( ExptsMap::const_iterator iter1 = tree1Expts_.begin(); iter1 != tree1Expts_.end(); ++iter1 ) {
194 
195  // get the map element for tree2
196  Int_t expt = iter1->first;
197  ExptsMap::const_iterator iter2 = tree2Expts_.find( expt );
198 
199  // determine the number of entries in tree1
200  Int_t nEntriesInTree1 = iter1->second.second - iter1->second.first + 1;
201 
202  // read the entries from the trees, filling the output tree
203  this->readExperiment( inputTree1_, iter1, 0 );
204  this->readExperiment( inputTree2_, iter2, nEntriesInTree1 );
205  }
206 
207  // Write the output file
208  this->writeFile();
209 }
210 
211 void LauMergeDataFiles::findExperiments(TTree* tree, ExptsMap& exptsMap)
212 {
213  const Int_t nEntries = tree->GetEntries();
214 
215  // loop through the tree
216  for ( Int_t iEntry(0); iEntry<nEntries; ++iEntry ) {
217  // grab the entry
218  tree->GetEntry(iEntry);
219 
220  // see if we already have an element in the map for the
221  // current experiment
222  ExptsMap::iterator iter = exptsMap.find(iExpt_);
223  if ( iter == exptsMap.end() ) {
224  // if not, we need to add an element that points to
225  // this entry in the tree as the start entry
226  exptsMap.insert( std::make_pair( iExpt_, std::make_pair( iEntry, -99 ) ) );
227 
228  // also we need to complete the map element for the
229  // previous experiment with the previous tree entry
230  // as the last entry
231  ExptsMap::iterator previter = exptsMap.find(iExpt_-1);
232  if ( previter != exptsMap.end() ) {
233  previter->second.second = iEntry-1;
234  }
235  }
236  }
237  // need to complete the map element for the final experiment
238  exptsMap[iExpt_].second = nEntries-1;
239 }
240 
242 {
243  // first check that the two maps are the same size
244  UInt_t size1 = tree1Expts_.size();
245  UInt_t size2 = tree2Expts_.size();
246  if ( size1 != size2 ) {
247  std::cerr<<"ERROR in LauMergeDataFiles::checkExperimentMaps : Experiment maps are not the same size.\n";
248  std::cerr<<" : Tree from "<<fileName1_<<" has "<<size1<<" experiments.";
249  std::cerr<<" : Tree from "<<fileName2_<<" has "<<size2<<" experiments.";
250  return kFALSE;
251  }
252 
253  for ( ExptsMap::const_iterator iter1 = tree1Expts_.begin(); iter1 != tree1Expts_.end(); ++iter1 ) {
254  Int_t expt = iter1->first;
255  ExptsMap::const_iterator iter2 = tree2Expts_.find( expt );
256  if ( iter2 == tree2Expts_.end() ) {
257  std::cerr<<"ERROR in LauMergeDataFiles::checkExperimentMaps : Cannot find experiment "<<expt<<" in tree from "<<fileName2_<<std::endl;
258  return kFALSE;
259  }
260  }
261 
262  return kTRUE;
263 }
264 
265 void LauMergeDataFiles::readExperiment(TTree* tree, const ExptsMap::const_iterator& expt, Int_t offset)
266 {
267  // find the first and last entry for this experiment from the map element
268  const Int_t firstEntry = expt->second.first;
269  const Int_t lastEntry = expt->second.second;
270 
271  // loop through all the entries
272  for ( Int_t iEntry(firstEntry); iEntry<=lastEntry; ++iEntry ) {
273  // get the entry from the tree
274  tree->GetEntry( iEntry );
275  // apply the offset to the "event within experiment" variable
276  iEvtWithinExpt_ += offset;
277  // fill the output tree
278  outputTree_->Fill();
279  }
280 }
281 
283 {
284  std::cout<<"Building experiment:event index"<<std::endl;
285  outputTree_->BuildIndex("iExpt","iEvtWithinExpt");
286 
287  std::cout<<"Writing data to outputfile "<<outputFile_->GetName()<<std::endl;
288  outputTree_->SetDirectory(outputFile_);
289  outputFile_->Write();
290 
291  // clean-up
292  outputFile_->Close();
293  delete outputFile_; outputFile_ = 0; outputTree_ = 0;
294 
295  inputFile1_->Close();
296  delete inputFile1_; inputFile1_ = 0; inputTree1_ = 0;
297 
298  inputFile2_->Close();
299  delete inputFile2_; inputFile2_ = 0; inputTree2_ = 0;
300 
301  doubleVars_.clear();
302  integerVars_.clear();
303  tree1Expts_.clear();
304  tree2Expts_.clear();
305 }
306 
TFile * inputFile2_
Input file 2.
ClassImp(LauAbsCoeffSet)
Int_t iExpt_
Storage for the experiment index variable.
TString treeName_
Name of the tree.
Bool_t checkExperimentMaps() const
Check that the experiments in each tree match.
const TString & name() const
The parameter name.
ExptsMap tree1Expts_
Experiment -&gt; first and last tree entry for tree 1.
File containing declaration of LauMergeDataFiles class.
std::map< Int_t, std::pair< Int_t, Int_t > > ExptsMap
Type to hold for each experiment the first and last entry numbers in a tree.
TTree * outputTree_
Output tree.
Int_t iEvtWithinExpt_
Storage for the event-within-experiment index variable.
void readExperiment(TTree *tree, const ExptsMap::const_iterator &exptsMap, Int_t offset)
Read the entries for a given experiment from the given tree and store in the output tree...
void findExperiments(TTree *tree, ExptsMap &exptsMap)
Determine the experiments stored a given tree.
TString fileName2_
Name of file 2.
TString fileName1_
Name of file 1.
void setupOutputTree()
Create the structure of the output tree.
LeafDoubleMap doubleVars_
Storage for double-precision leaves.
TFile * outputFile_
Output file.
TTree * inputTree1_
Input tree 1.
ExptsMap tree2Expts_
Experiment -&gt; first and last tree entry for tree 2.
void openInputFiles()
Open the specified input files and check that the trees can be read.
void setupInputTrees()
Read the structure of the input trees, create appropriate storage and set the branch addresses...
void writeFile()
Write the output file.
TTree * inputTree2_
Input tree 2.
TFile * inputFile1_
Input file 1.
virtual ~LauMergeDataFiles()
Destructor.
LeafIntegerMap integerVars_
Storage for integer leaves.
void process(const TString &fileName)
Do the merge.