laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauResultsExtractor.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2005 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 "LauResultsExtractor.hh"
30 
31 #include "TChain.h"
32 #include "TFile.h"
33 #include "TH1.h"
34 #include "TLeaf.h"
35 #include "TObjArray.h"
36 #include "TSystem.h"
37 
38 #include <cstdlib>
39 #include <fstream>
40 #include <iostream>
41 #include <map>
42 #include <vector>
43 
44 LauResultsExtractor::LauResultsExtractor( const TString& inputFileName,
45  const TString& outputFileName,
46  const TString& treeName ) :
47  inputFileName_( inputFileName ),
48  outputFileName_( outputFileName ),
49  treeName_( treeName ),
50  inputTree_( 0 ),
51  outputFile_( 0 ),
52  outputTree_( 0 ),
53  nEntries_( 0 )
54 {
55 }
56 
58 {
59  this->clearMaps();
60  delete inputTree_;
61  inputTree_ = 0;
62  if ( outputFile_ && outputFile_->IsOpen() ) {
63  delete outputTree_;
64  outputTree_ = 0;
65  }
66  delete outputFile_;
67  outputFile_ = 0;
68 }
69 
71 {
72  TObjArray* leaves = inputTree_->GetListOfLeaves();
73  Int_t nLeaves = leaves->GetEntries();
74 
75  std::cout << "Setting branches for input tree \"" << inputTree_->GetName() << "\" with "
76  << nEntries_ << " entries..." << std::endl;
77  inputTree_->SetBranchAddress( "iExpt", &iExpt_ );
78  inputTree_->SetBranchAddress( "fitStatus", &fitStatus_ );
79  inputTree_->SetBranchAddress( "NLL", &NLL_ );
80  inputTree_->SetBranchAddress( "EDM", &EDM_ );
81 
82  for ( Int_t iLeaf( 3 ); iLeaf < nLeaves; ++iLeaf ) {
83 
84  TLeaf* leaf = dynamic_cast<TLeaf*>( ( *leaves )[iLeaf] );
85  TString type = leaf->GetTypeName();
86  TString name = leaf->GetName();
87  Int_t size = leaf->GetNdata();
88 
89  if ( ( type != "Double_t" ) || ( size != 1 ) ) {
90  continue;
91  }
92 
93  std::pair<std::map<TString, Double_t>::iterator, bool> result = otherVars_.insert(
94  std::make_pair( name, 0.0 ) );
95  std::map<TString, Double_t>::iterator iter = result.first;
96  bool ok = result.second;
97  if ( ok ) {
98  inputTree_->SetBranchAddress( name, &( iter->second ) );
99  }
100  }
101 
102  std::cout << "Set branch addresses for " << otherVars_.size() + 3 << " branches.\n"
103  << std::endl;
104 }
105 
107 {
108  std::cout << "Creating branches for output tree \"" << tree->GetName() << "\"..." << std::endl;
109 
110  tree->Branch( "iExpt", &iExpt_, "iExpt/I" );
111  tree->Branch( "fitStatus", &fitStatus_, "fitStatus/I" );
112  tree->Branch( "NLL", &NLL_, "NLL/D" );
113  tree->Branch( "EDM", &EDM_, "EDM/D" );
114 
115  for ( std::map<TString, Double_t>::iterator iter = otherVars_.begin(); iter != otherVars_.end();
116  ++iter ) {
117  TString name = iter->first;
118  Double_t* address = &( iter->second );
119  TString thirdBit = name;
120  thirdBit += "/D";
121 
122  tree->Branch( name, address, thirdBit );
123  }
124  std::cout << "Created " << otherVars_.size() << " branches.\n" << std::endl;
125 }
126 
128 {
129  inputTree_->SetBranchStatus( "iExpt", kTRUE );
130  inputTree_->SetBranchStatus( "fitStatus", kTRUE );
131  inputTree_->SetBranchStatus( "NLL", kTRUE );
132  inputTree_->SetBranchStatus( "EDM", kTRUE );
133 
134  for ( std::map<TString, Double_t>::iterator iter = otherVars_.begin(); iter != otherVars_.end();
135  ++iter ) {
136  TString name = iter->first;
137  inputTree_->SetBranchStatus( name, status );
138  }
139 }
140 
142 {
143  for ( std::map<Int_t, TH1*>::iterator iter = nllHistos_.begin(); iter != nllHistos_.end();
144  ++iter ) {
145  delete ( iter->second );
146  }
147  bestNLL_.clear();
148  worstNLL_.clear();
149  allNLLs_.clear();
150  nllHistos_.clear();
151 }
152 
153 void LauResultsExtractor::process( Int_t numExpts )
154 {
155  // open the text file
156  std::cout << "\n"
157  << "Chaining...\n"
158  << std::endl;
159  std::ifstream textFile( inputFileName_, std::ios::in );
160  if ( ! textFile.good() ) {
161  std::cerr << "Problem opening file: \"" << inputFileName_ << "\", exiting..." << std::endl;
162  gSystem->Exit( EXIT_FAILURE );
163  }
164 
165  if ( inputTree_ ) {
166  delete inputTree_;
167  inputTree_ = 0;
168  }
169  inputTree_ = new TChain( treeName_ );
170 
171  // Read the text file and add each valid entry to the chain
172  TString inputFileName = "";
173  while ( inputFileName.ReadLine( textFile ) && ( ! inputFileName.IsNull() ) ) {
174  if ( inputFileName.EndsWith( ".root" ) && ! inputFileName.BeginsWith( "#" ) ) {
175  std::cout << inputFileName << std::endl;
176  inputTree_->Add( inputFileName );
177  } else {
178  std::cout << inputFileName << "\t *** Skipped ***" << std::endl;
179  }
180  }
181 
182  textFile.close();
183  std::cout << "\n"
184  << "... finished.\n"
185  << std::endl;
186 
187  nEntries_ = inputTree_->GetEntries();
188  this->setupInputTree();
189 
190  outputTree_ = new TTree( treeName_, "" );
191  this->setupOutputTree( outputTree_ );
192 
193  // setup the map:
194  // for each experiment there is a pair object holding
195  // the best NLL and the tree entry for that NLL value
196  // each expt starts out with NLL = 0.0 and entry = -1
197  std::cout << "Setting up the map..." << std::flush;
198  this->clearMaps();
199  for ( Int_t i( 0 ); i < numExpts; ++i ) {
200  bestNLL_.insert( std::make_pair( i, std::make_pair( 0.0, -1 ) ) );
201  worstNLL_.insert( std::make_pair( i, std::make_pair( 0.0, -1 ) ) );
202  allNLLs_.insert( std::make_pair( i, std::vector<Double_t>() ) );
203  allNLLs_[i].reserve( nEntries_ );
204  }
205  std::cout << " done.\n" << std::endl;
206 
207  // only read the 3 info branches
208  //this->setInputTreeBranchStatus(kFALSE);
209 
210  // loop over the tree and store the best entries for each expt
211  std::cout << "Starting to store best entry info..." << std::endl;
212  for ( Int_t j( 0 ); j < nEntries_; ++j ) {
213 
214  if ( ( nEntries_ < 100 ) || ( j % ( nEntries_ / 100 ) == 0 ) ) {
215  std::cout << "Examining entry " << j << std::endl;
216  }
217 
218  inputTree_->GetEntry( j );
219 
220  if ( ( fitStatus_ == 3 ) && ( NLL_ > -DBL_MAX / 10.0 ) ) {
221  allNLLs_[iExpt_].push_back( NLL_ );
222 
223  Double_t curBestNLL = bestNLL_[iExpt_].first;
224  Int_t curBestEntry = bestNLL_[iExpt_].second;
225  if ( ( NLL_ < curBestNLL ) || ( curBestEntry == -1 ) ) {
226  bestNLL_[iExpt_] = std::make_pair( NLL_, j );
227  }
228 
229  Double_t curWorstNLL = worstNLL_[iExpt_].first;
230  Int_t curWorstEntry = worstNLL_[iExpt_].second;
231  if ( ( NLL_ > curWorstNLL ) || ( curWorstEntry == -1 ) ) {
232  worstNLL_[iExpt_] = std::make_pair( NLL_, j );
233  }
234  }
235  }
236  std::cout << "Finished storing best entry info.\n" << std::endl;
237 
238  std::cout << "Creating NLL histograms..." << std::flush;
239  TH1* histo( 0 );
240  for ( Int_t i( 0 ); i < numExpts; ++i ) {
241  Double_t min = bestNLL_[i].first;
242  Double_t max = worstNLL_[i].first;
243  Double_t range = max - min;
244  if ( range < 1e-3 ) {
245  min -= 0.005;
246  max += 0.005;
247  } else {
248  min -= range * 0.2;
249  max += range * 0.2;
250  }
251  TString name( "expt" );
252  name += i;
253  name += "NLL";
254  histo = new TH1F( name, "", 100, min, max );
255  for ( std::vector<Double_t>::const_iterator iter = allNLLs_[i].begin();
256  iter != allNLLs_[i].end();
257  ++iter ) {
258  histo->Fill( *iter );
259  }
260  nllHistos_.insert( std::make_pair( i, histo ) );
261  }
262  std::cout << " done.\n" << std::endl;
263 
264  // now need to read all branches
265  //this->setInputTreeBranchStatus(kTRUE);
266 
267  std::ofstream fout( "best-fit.txt" );
268 
269  // loop over the experiments, grab the best entry and store it
270  std::cout << "Starting to retrieve best entries and fill output tree." << std::endl;
271  for ( Int_t i( 0 ); i < numExpts; ++i ) {
272  Int_t bestEntry = bestNLL_[i].second;
273  if ( bestEntry != -1 ) {
274  inputTree_->GetEntry( bestEntry );
275  outputTree_->Fill();
276  }
277  if ( ( numExpts < 100 ) || ( i % ( numExpts / 100 ) == 0 ) ) {
278  std::cout << "Writing out experiment " << i << std::endl;
279  }
280  TString bestFit( inputTree_->GetCurrentFile()->GetName() );
281  bestFit.Remove( 0, 3 );
282  Int_t index = bestFit.Index( "_" );
283  if ( index < 1 ) {
284  index = bestFit.Index( "." );
285  }
286  bestFit.Remove( index );
287  fout << "Experiment " << i << " BestFit " << bestFit << std::endl;
288  }
289  std::cout << "Finished filling best entries in output tree.\n" << std::endl;
290  fout.close();
291 
292  std::cout << "Writing output file." << std::endl;
293 
294  this->writeFile();
295 }
296 
298 {
299  if ( ! outputFile_ ) {
300  outputFile_ = new TFile( outputFileName_, "recreate" );
301  }
302  for ( std::map<Int_t, TH1*>::iterator iter = nllHistos_.begin(); iter != nllHistos_.end();
303  ++iter ) {
304  ( iter->second )->SetDirectory( outputFile_ );
305  }
306  outputTree_->SetDirectory( outputFile_ );
307  outputFile_->Write();
308  outputFile_->Close();
309  delete outputFile_;
310  outputFile_ = 0;
311  nllHistos_.clear();
312 }
TString outputFileName_
Name of output ROOT file.
std::map< Int_t, std::vector< Double_t > > allNLLs_
All NLL values for each experiment.
Int_t iExpt_
Storage for experiment ID variable.
void setupInputTree()
Create storage for leaves and call SetBranchAddress for each.
TString inputFileName_
Name of text file containing list of input files.
std::map< TString, Double_t > otherVars_
Storage for other input variables.
std::map< Int_t, std::pair< Double_t, Int_t > > bestNLL_
Best NLL and corresponding tree entries for each experiment.
TTree * outputTree_
Output tree.
Int_t nEntries_
Number of entries in the input chain.
File containing declaration of LauResultsExtractor class.
LauResultsExtractor(const TString &inputFileName, const TString &outputFileName, const TString &treeName)
Constructor.
Double_t NLL_
Storage for NLL variable.
Double_t EDM_
Storage for EDM variable.
void setupOutputTree(TTree *tree)
Create branches in the output tree.
TFile * outputFile_
Output file.
std::map< Int_t, std::pair< Double_t, Int_t > > worstNLL_
Worst NLL and corresponding tree entries for each experiment.
virtual ~LauResultsExtractor()
Destructor.
void writeFile()
Write the output file.
TChain * inputTree_
Chain of inputs.
const TString & name() const
The parameter name.
Double_t range() const
The range allowed for the parameter.
std::map< Int_t, TH1 * > nllHistos_
Histograms of the NLL values for each experiment.
TString treeName_
Name of tree in input ROOT files.
void process(const Int_t numExpts)
Run the calculations.
void setInputTreeBranchStatus(const Bool_t status)
Toggle branch status of input tree branches (except iExpt, fitStatus and NLL)
Int_t fitStatus_
Storage for fit status variable.
void clearMaps()
Clear all information.