laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
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 
29 #include "LauMergeDataFiles.hh"
30 
31 #include "TLeaf.h"
32 #include "TObjArray.h"
33 #include "TSystem.h"
34 
35 #include <iostream>
36 #include <map>
37 
38 LauMergeDataFiles::LauMergeDataFiles( const TString& fileName1,
39  const TString& fileName2,
40  const TString& treeName ) :
41  fileName1_( fileName1 ),
42  fileName2_( fileName2 ),
43  treeName_( treeName ),
44  inputFile1_( 0 ),
45  inputFile2_( 0 ),
46  inputTree1_( 0 ),
47  inputTree2_( 0 ),
48  outputFile_( 0 ),
49  outputTree_( 0 )
50 {
51 }
52 
54 {
55  if ( inputFile1_ && inputFile1_->IsOpen() ) {
56  inputFile1_->Close();
57  }
58  delete inputFile1_;
59 
60  if ( inputFile2_ && inputFile2_->IsOpen() ) {
61  inputFile2_->Close();
62  }
63  delete inputFile2_;
64 
65  if ( outputFile_ && outputFile_->IsOpen() ) {
66  outputFile_->Close();
67  }
68  delete outputFile_;
69 }
70 
72 {
73  // open the two input ROOT files
74  inputFile1_ = TFile::Open( fileName1_ );
75  if ( ! inputFile1_ || inputFile1_->IsZombie() ) {
76  std::cerr << "Problem opening file: \"" << fileName1_ << "\", exiting..." << std::endl;
77  gSystem->Exit( EXIT_FAILURE );
78  }
79  inputTree1_ = dynamic_cast<TTree*>( inputFile1_->Get( treeName_ ) );
80  if ( ! inputTree1_ ) {
81  std::cerr << "Problem getting tree called " << treeName_ << "from file: \"" << fileName1_
82  << "\", exiting..." << std::endl;
83  gSystem->Exit( EXIT_FAILURE );
84  }
85 
86  inputFile2_ = TFile::Open( fileName2_ );
87  if ( ! inputFile2_ || inputFile2_->IsZombie() ) {
88  std::cerr << "Problem opening file: \"" << fileName2_ << "\", exiting..." << std::endl;
89  gSystem->Exit( EXIT_FAILURE );
90  }
91  inputTree2_ = dynamic_cast<TTree*>( inputFile2_->Get( treeName_ ) );
92  if ( ! inputTree2_ ) {
93  std::cerr << "Problem getting tree called " << treeName_ << "from file: \"" << fileName2_
94  << "\", exiting..." << std::endl;
95  gSystem->Exit( EXIT_FAILURE );
96  }
97 }
98 
100 {
101  TObjArray* leaves1 = inputTree1_->GetListOfLeaves();
102  TObjArray* leaves2 = inputTree2_->GetListOfLeaves();
103  Int_t nLeaves1 = leaves1->GetEntries();
104  Int_t nLeaves2 = leaves2->GetEntries();
105  if ( nLeaves1 != nLeaves2 ) {
106  std::cerr << "Different number of leaves in the two input trees, not continuing."
107  << std::endl;
108  return;
109  }
110 
111  std::cout << "Setting branches for input trees \"" << treeName_ << "\"..." << std::endl;
112  inputTree1_->SetBranchAddress( "iExpt", &iExpt_ );
113  inputTree1_->SetBranchAddress( "iEvtWithinExpt", &iEvtWithinExpt_ );
114  inputTree2_->SetBranchAddress( "iExpt", &iExpt_ );
115  inputTree2_->SetBranchAddress( "iEvtWithinExpt", &iEvtWithinExpt_ );
116 
117  for ( Int_t iLeaf( 0 ); iLeaf < nLeaves1; ++iLeaf ) {
118 
119  TLeaf* leaf = dynamic_cast<TLeaf*>( ( *leaves1 )[iLeaf] );
120  TString type = leaf->GetTypeName();
121  TString name = leaf->GetName();
122  Int_t size = leaf->GetNdata();
123 
124  if ( ( name == "iExpt" ) || ( name == "iEvtWithinExpt" ) || ( size != 1 ) ) {
125  continue;
126  }
127 
128  if ( type == "Double_t" ) {
129  std::pair<LeafDoubleMap::iterator, bool> result = doubleVars_.insert(
130  std::make_pair( name, 0.0 ) );
131  LeafDoubleMap::iterator iter = result.first;
132  bool ok = result.second;
133  if ( ok ) {
134  inputTree1_->SetBranchAddress( name, &( iter->second ) );
135  inputTree2_->SetBranchAddress( name, &( iter->second ) );
136  }
137  } else if ( type == "Int_t" ) {
138  std::pair<LeafIntegerMap::iterator, bool> result = integerVars_.insert(
139  std::make_pair( name, 0 ) );
140  LeafIntegerMap::iterator iter = result.first;
141  bool ok = result.second;
142  if ( ok ) {
143  inputTree1_->SetBranchAddress( name, &( iter->second ) );
144  inputTree2_->SetBranchAddress( name, &( iter->second ) );
145  }
146  }
147  }
148  std::cout << "Set branch addresses for " << doubleVars_.size() << " Double_t branches.\n";
149  std::cout << "Set branch addresses for " << integerVars_.size() << " Int_t branches.\n"
150  << std::endl;
151 }
152 
154 {
155  std::cout << "Creating branches for output tree \"" << outputTree_->GetName() << "\"..."
156  << std::endl;
157 
158  outputTree_->Branch( "iExpt", &iExpt_, "iExpt/I" );
159  outputTree_->Branch( "iEvtWithinExpt", &iEvtWithinExpt_, "iEvtWithinExpt/I" );
160 
161  for ( LeafDoubleMap::iterator iter = doubleVars_.begin(); iter != doubleVars_.end(); ++iter ) {
162  TString name = iter->first;
163  Double_t* address = &( iter->second );
164  TString thirdBit = name;
165  thirdBit += "/D";
166 
167  outputTree_->Branch( name, address, thirdBit );
168  }
169  for ( LeafIntegerMap::iterator iter = integerVars_.begin(); iter != integerVars_.end(); ++iter ) {
170  TString name = iter->first;
171  Int_t* address = &( iter->second );
172  TString thirdBit = name;
173  thirdBit += "/I";
174 
175  outputTree_->Branch( name, address, thirdBit );
176  }
177  std::cout << "Created " << doubleVars_.size() + integerVars_.size() << " branches.\n"
178  << std::endl;
179 }
180 
181 void LauMergeDataFiles::process( const TString& fileName )
182 {
183  this->openInputFiles();
184 
185  this->setupInputTrees();
186 
187  outputFile_ = TFile::Open( fileName, "recreate" );
188  outputTree_ = new TTree( treeName_, "" );
189  this->setupOutputTree();
190 
191  // loop over the trees and combine the corresponding experiments
192  std::cout << "Starting to combine the trees..." << std::endl;
193 
194  // Find the first and last entries for each experiment in each tree
197 
198  // Check that the experiments in the two trees match
199  if ( ! this->checkExperimentMaps() ) {
200  return;
201  }
202 
203  // Loop through the experiments
204  for ( ExptsMap::const_iterator iter1 = tree1Expts_.begin(); iter1 != tree1Expts_.end(); ++iter1 ) {
205 
206  // get the map element for tree2
207  Int_t expt = iter1->first;
208  ExptsMap::const_iterator iter2 = tree2Expts_.find( expt );
209 
210  // determine the number of entries in tree1
211  Int_t nEntriesInTree1 = iter1->second.second - iter1->second.first + 1;
212 
213  // read the entries from the trees, filling the output tree
214  this->readExperiment( inputTree1_, iter1, 0 );
215  this->readExperiment( inputTree2_, iter2, nEntriesInTree1 );
216  }
217 
218  // Write the output file
219  this->writeFile();
220 }
221 
222 void LauMergeDataFiles::findExperiments( TTree* tree, ExptsMap& exptsMap )
223 {
224  const Int_t nEntries = tree->GetEntries();
225 
226  // loop through the tree
227  for ( Int_t iEntry( 0 ); iEntry < nEntries; ++iEntry ) {
228  // grab the entry
229  tree->GetEntry( iEntry );
230 
231  // see if we already have an element in the map for the
232  // current experiment
233  ExptsMap::iterator iter = exptsMap.find( iExpt_ );
234  if ( iter == exptsMap.end() ) {
235  // if not, we need to add an element that points to
236  // this entry in the tree as the start entry
237  exptsMap.insert( std::make_pair( iExpt_, std::make_pair( iEntry, -99 ) ) );
238 
239  // also we need to complete the map element for the
240  // previous experiment with the previous tree entry
241  // as the last entry
242  ExptsMap::iterator previter = exptsMap.find( iExpt_ - 1 );
243  if ( previter != exptsMap.end() ) {
244  previter->second.second = iEntry - 1;
245  }
246  }
247  }
248  // need to complete the map element for the final experiment
249  exptsMap[iExpt_].second = nEntries - 1;
250 }
251 
253 {
254  // first check that the two maps are the same size
255  UInt_t size1 = tree1Expts_.size();
256  UInt_t size2 = tree2Expts_.size();
257  if ( size1 != size2 ) {
258  std::cerr << "ERROR in LauMergeDataFiles::checkExperimentMaps : Experiment maps are not the same size.\n";
259  std::cerr << " : Tree from " << fileName1_
260  << " has " << size1 << " experiments.";
261  std::cerr << " : Tree from " << fileName2_
262  << " has " << size2 << " experiments.";
263  return kFALSE;
264  }
265 
266  for ( ExptsMap::const_iterator iter1 = tree1Expts_.begin(); iter1 != tree1Expts_.end(); ++iter1 ) {
267  Int_t expt = iter1->first;
268  ExptsMap::const_iterator iter2 = tree2Expts_.find( expt );
269  if ( iter2 == tree2Expts_.end() ) {
270  std::cerr << "ERROR in LauMergeDataFiles::checkExperimentMaps : Cannot find experiment "
271  << expt << " in tree from " << fileName2_ << std::endl;
272  return kFALSE;
273  }
274  }
275 
276  return kTRUE;
277 }
278 
279 void LauMergeDataFiles::readExperiment( TTree* tree, const ExptsMap::const_iterator& expt, Int_t offset )
280 {
281  // find the first and last entry for this experiment from the map element
282  const Int_t firstEntry = expt->second.first;
283  const Int_t lastEntry = expt->second.second;
284 
285  // loop through all the entries
286  for ( Int_t iEntry( firstEntry ); iEntry <= lastEntry; ++iEntry ) {
287  // get the entry from the tree
288  tree->GetEntry( iEntry );
289  // apply the offset to the "event within experiment" variable
290  iEvtWithinExpt_ += offset;
291  // fill the output tree
292  outputTree_->Fill();
293  }
294 }
295 
297 {
298  std::cout << "Building experiment:event index" << std::endl;
299  outputTree_->BuildIndex( "iExpt", "iEvtWithinExpt" );
300 
301  std::cout << "Writing data to outputfile " << outputFile_->GetName() << std::endl;
302  outputTree_->SetDirectory( outputFile_ );
303  outputFile_->Write();
304 
305  // clean-up
306  outputFile_->Close();
307  delete outputFile_;
308  outputFile_ = 0;
309  outputTree_ = 0;
310 
311  inputFile1_->Close();
312  delete inputFile1_;
313  inputFile1_ = 0;
314  inputTree1_ = 0;
315 
316  inputFile2_->Close();
317  delete inputFile2_;
318  inputFile2_ = 0;
319  inputTree2_ = 0;
320 
321  doubleVars_.clear();
322  integerVars_.clear();
323  tree1Expts_.clear();
324  tree2Expts_.clear();
325 }
void findExperiments(TTree *tree, ExptsMap &exptsMap)
Determine the experiments stored a given tree.
TTree * inputTree2_
Input tree 2.
void process(const TString &fileName)
Do the merge.
TString fileName1_
Name of file 1.
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.
Bool_t checkExperimentMaps() const
Check that the experiments in each tree match.
TFile * outputFile_
Output file.
void setupOutputTree()
Create the structure of the output tree.
Int_t iEvtWithinExpt_
Storage for the event-within-experiment index variable.
TTree * outputTree_
Output tree.
LeafDoubleMap doubleVars_
Storage for double-precision leaves.
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.
TTree * inputTree1_
Input tree 1.
ExptsMap tree2Expts_
Experiment -> first and last tree entry for tree 2.
void openInputFiles()
Open the specified input files and check that the trees can be read.
const TString & name() const
The parameter name.
LauMergeDataFiles(const TString &fileName1, const TString &fileName2, const TString &treeName)
Constructor.
virtual ~LauMergeDataFiles()
Destructor.
LeafIntegerMap integerVars_
Storage for integer leaves.
TString fileName2_
Name of file 2.
TFile * inputFile2_
Input file 2.
File containing declaration of LauMergeDataFiles class.
TFile * inputFile1_
Input file 1.
ExptsMap tree1Expts_
Experiment -> first and last tree entry for tree 1.
void writeFile()
Write the output file.
void setupInputTrees()
Read the structure of the input trees, create appropriate storage and set the branch addresses.
TString treeName_
Name of the tree.
Int_t iExpt_
Storage for the experiment index variable.