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