laura is hosted by Hepforge, IPPP Durham
Laura++  v1r1p1
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauFitDataTree.cc
Go to the documentation of this file.
1 
2 // Copyright University of Warwick 2004 - 2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // Authors:
7 // Thomas Latham
8 // John Back
9 // Paul Harrison
10 
15 #include <cmath>
16 #include <cstdlib>
17 #include <iostream>
18 
19 #include "TFile.h"
20 #include "TLeaf.h"
21 #include "TString.h"
22 #include "TSystem.h"
23 
24 #include "LauFitDataTree.hh"
25 
26 ClassImp(LauFitDataTree)
27 
28 
29 LauFitDataTree::LauFitDataTree(const TString& rootFileName, const TString& rootTreeName) :
30  rootFileName_(rootFileName),
31  rootTreeName_(rootTreeName),
32  rootFile_(0),
33  rootTree_(0),
34  eventList_(0)
35 {
36  if (rootFileName_ != "" && rootTreeName_ != "") {
37  this->openFileAndTree();
38  }
39 }
40 
42 {
43  if (rootFile_ && rootFile_->IsOpen()) {
44  delete rootTree_; rootTree_ = 0;
45  delete eventList_; eventList_ = 0;
46  }
47  delete rootFile_; rootFile_ = 0;
48 }
49 
51 {
52  // first check whether we've already opened up the file or not
53  if (!rootFile_) {
54  // if not, first check the filename and if all ok create the file
55  if (rootFileName_ == "") {
56  std::cerr << "ERROR in LauFitDataTree::openFileAndTree : Bad filename supplied, not creating file or tree." << std::endl;
57  return;
58  }
59  rootFile_ = TFile::Open(rootFileName_, "read");
60  if (!rootFile_ || rootFile_->IsZombie() || !rootFile_->IsOpen()) {
61  std::cerr << "ERROR in LauFitDataTree::openFileAndTree : Problem opening file \"" << rootFileName_ << "\" for reading." << std::endl;
62  return;
63  }
64  }
65  // check whether we've already created the tree
66  if (!rootTree_) {
67  // if not change to the file's directory and grab the tree
68  rootFile_->cd();
69  rootTree_ = dynamic_cast<TTree*>(rootFile_->Get(rootTreeName_));
70  if (!rootTree_) {
71  std::cerr << "ERROR in LauFitDataTree::openFileAndTree : Problem reading tree \"" << rootTreeName_ << "\" from file." << std::endl;
72  return;
73  }
74  rootTree_->SetDirectory(rootFile_);
75  }
76 }
77 
79 {
80  if (!rootTree_) {
81  std::cerr << "ERROR in LauFitDataTree::findBranches : Invalid pointer to data tree." << std::endl;
82  return kFALSE;
83  }
84 
85  // this method should only be called once
86  if ( ! leafNames_.empty() ) {
87  std::cerr << "ERROR in LauFitDataTree::findBranches : Branches already found, not running again." << std::endl;
88  return kFALSE;
89  }
90 
91  leafNames_.clear();
92  eventData_.clear();
93  eventDataOut_.clear();
94  leaves_.clear();
95  treeEvents_.clear();
96  fakeEvents_.clear();
97 
98  const UInt_t numBranches(this->nBranches());
99  eventData_.reserve( numBranches );
100 
101  TObjArray* pLeaves = rootTree_->GetListOfLeaves();
102  if (!pLeaves) {
103  std::cerr << "ERROR in LauFitDataTree::findBranches : Problem retrieving leaves from the tree." << std::endl;
104  return kFALSE;
105  }
106  TObjArray& leaves = *pLeaves;
107 
108  const UInt_t numLeaves = static_cast<UInt_t>( leaves.GetEntries() );
109  if ( numBranches != numLeaves ) {
110  std::cerr << "ERROR in LauFitDataTree::findBranches : List of leaves is not the same size as the number of branches - this is strange!" << std::endl;
111  std::cerr << " : There are " << numLeaves << " leaves and " << numBranches << " branches" << std::endl;
112  return kFALSE;
113  }
114 
115  for (UInt_t iLeaf = 0; iLeaf < numBranches; ++iLeaf) {
116 
117  TLeaf * leaf = dynamic_cast<TLeaf*>(leaves[iLeaf]);
118 
119  // we can't deal with arrays
120  Int_t size = leaf->GetNdata();
121  if (size != 1) {
122  std::cerr << "ERROR in LauFitDataTree::findBranches : Tree has array branches, can't deal with those." << std::endl;
123  return kFALSE;
124  }
125 
126  // find the name and type of the leaf
127  TString name = leaf->GetName();
128 
129  // initialise an entry in the maps to hold the value
130  leafNames_[ name ] = iLeaf;
131  leaves_.push_back( leaf );
132  eventData_.push_back( 0.0 );
133  eventDataOut_[ name ] = 0.0;
134  }
135 
136  const UInt_t numEvents(this->nTotalEvents());
137 
138  std::cout << "INFO in LauFitDataTree::findBranches : Finished finding data tree branches." << std::endl;
139  std::cout << " : Tree contains " << numBranches << " branches and a total of " << numEvents << " events." << std::endl;
140 
141  return kTRUE;
142 }
143 
145 {
146  if (!rootTree_) {
147  std::cerr << "ERROR in LauFitDataTree::readExperimentData : Invalid pointer to data tree." << std::endl;
148  return;
149  }
150 
151  rootFile_->cd();
152 
153  if (!eventList_) {
154  eventList_ = new TEventList("elist","elist");
155  eventList_->SetDirectory(rootFile_);
156  }
157 
158  TString listName(eventList_->GetName());
159  listName.Prepend(">>");
160  TString selection("iExpt==");
161  selection += iExpt;
162 
163  std::cout << "INFO in LauFitDataTree::readExperimentData : Setting tree to experiment number " << iExpt << "." << std::endl;
164  rootTree_->Draw(listName,selection);
165  std::cout << " : Found " << this->nEvents() << " events." << std::endl;
166 
167  this->loadData();
168 }
169 
171 {
172  if ( rootTree_ ) {
173  return static_cast<UInt_t>(rootTree_->GetNbranches());
174  } else if ( ! fakeEvents_.empty() ) {
175  std::vector<LauEventData>::const_iterator fakeIter = fakeEvents_.begin();
176  return (*fakeIter).size();
177  } else {
178  return 0;
179  }
180 }
181 
182 void LauFitDataTree::appendFakePoints( const std::vector<Double_t>& xCoords, const std::vector<Double_t>& yCoords)
183 {
184  if ( xCoords.size() != yCoords.size() ) {
185  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : The co-ordinate vectors are not the same size!" << std::endl;
186  gSystem->Exit(EXIT_FAILURE);
187  }
188 
189  // clear the list of fake events and reserve enough space
190  fakeEvents_.clear();
191  fakeEvents_.reserve(xCoords.size());
192 
193  // loop over the event data zeroing everything
194  for (LauEventData::iterator iter = eventData_.begin(); iter != eventData_.end(); ++iter) {
195  *iter = 0.0;
196  }
197 
198  // find the vector indices for the DP co-ordinates
199  LauNameIndexMap::const_iterator iter = leafNames_.find( "m13Sq" );
200  if ( iter == leafNames_.end() ) {
201  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : Can't find entry \"m13Sq\" in event data map." << std::endl;
202  gSystem->Exit(EXIT_FAILURE);
203  }
204  UInt_t m13SqIdx = iter->second;
205 
206  iter = leafNames_.find( "m23Sq" );
207  if ( iter == leafNames_.end() ) {
208  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : Can't find entry \"m23Sq\" in event data map." << std::endl;
209  gSystem->Exit(EXIT_FAILURE);
210  }
211  UInt_t m23SqIdx = iter->second;
212 
213  // TODO - is this really needed? Comment out for now.
214  /*
215  // and a fake tagCat which we don't care about, but the program
216  // needs a number here for comptibility with conventional events.
217  iter = leafNames_.find( "tagCat" );
218  if ( iter == leafNames_.end() ) {
219  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : Can't find entry \"tagCat\" in event data map." << std::endl;
220  gSystem->Exit(EXIT_FAILURE);
221  }
222  UInt_t m23SqIdx = iter->second;
223  */
224 
225  for (UInt_t iEvt = 0; iEvt < xCoords.size() ; ++iEvt) {
226 
227  // set the values
228  eventData_[ m13SqIdx ] = xCoords[iEvt];
229  eventData_[ m23SqIdx ] = yCoords[iEvt];
230  //eventData_[ tagCatIdx ] = 0.0;
231 
232  // append to the list of fake events
233  fakeEvents_.push_back(eventData_);
234  }
235 }
236 
237 Bool_t LauFitDataTree::haveBranch(const TString& name) const
238 {
239  LauNameIndexMap::const_iterator iter = leafNames_.find( name );
240  return (iter != leafNames_.end());
241 }
242 
244 {
245  rootTree_->SetBranchStatus("*", 0);
246 }
247 
249 {
250  rootTree_->SetBranchStatus("*", 1);
251 }
252 
253 void LauFitDataTree::enableBranch(const TString& name) const
254 {
255  if (this->haveBranch(name)) {rootTree_->SetBranchStatus(name, 1);}
256 }
257 
258 void LauFitDataTree::disableBranch(const TString& name) const
259 {
260  if (this->haveBranch(name)) {rootTree_->SetBranchStatus(name, 0);}
261 }
262 
264 {
265  // Clear any data from previous expts
266  treeEvents_.clear();
267 
268  // Reserve enough space in the vector
269  Long64_t nEvts = this->nEvents();
270  treeEvents_.reserve( nEvts );
271 
272  const UInt_t nLeaves = this->nBranches();
273 
274  // Loop through the tree and store the data
275  for ( Long64_t iEvt(0); iEvt < nEvts; ++iEvt ) {
276 
277  // Find which entry from the full tree contains the requested event
278  Long64_t iEntry = eventList_ ? eventList_->GetEntry(iEvt) : iEvt;
279  if (iEntry<0) { // this shouldn't happen, but just in case...
280  std::cerr << "ERROR in LauFitDataTree::loadData : Requested event not found." << std::endl;
281  gSystem->Exit(EXIT_FAILURE);
282  }
283 
284  // Then retrieve that entry from the tree
285  rootTree_->GetEntry(iEntry);
286 
287  // Copy the leaf values into eventData_
288  for ( UInt_t iLeaf(0); iLeaf < nLeaves; ++iLeaf ) {
289 
290  const TLeaf * leaf = leaves_[ iLeaf ];
291 
292  Double_t value = leaf->GetValue();
293  if ( std::isnan( value ) || std::isinf( value ) ) {
294  std::cerr << "ERROR in LauFitDataTree::loadData : Event " << iEvt << " has infinite or NaN entry for variable " << leaf->GetName() << std::endl;
295  gSystem->Exit(EXIT_FAILURE);
296  }
297 
298  eventData_[ iLeaf ] = value;
299  }
300 
301  // Store the event in the vector
302  treeEvents_.push_back( eventData_ );
303  }
304 }
305 
307 {
308  delete eventList_; eventList_ = 0;
309  this->loadData();
310 }
311 
312 const LauFitData& LauFitDataTree::getData(UInt_t iEvt) const
313 {
314  // For a given event, within the current experiment,
315  // retrieve the input fit variables
316 
317  const UInt_t numTreeEvents = this->nEvents();
318  const UInt_t numFakeEvents = this->nFakeEvents();
319 
320  // Does the requested event come from the tree or from the fake events list?
321  if ( iEvt < numTreeEvents ) {
322  if ( iEvt > treeEvents_.size() ) { // this shouldn't happen, but just in case...
323  std::cerr << "ERROR in LauFitDataTree::getData : Requested event, " << iEvt << ", not found." << std::endl;
324  gSystem->Exit(EXIT_FAILURE);
325  }
326  // Retrieve that event from the vector
327  eventData_ = treeEvents_[iEvt];
328  } else if ( iEvt < (numTreeEvents + numFakeEvents) ) {
329  // Find the entry from the fake events list contains the requested event
330  UInt_t iEntry = iEvt - numTreeEvents;
331  // Copy the entry into eventData_
332  eventData_ = fakeEvents_[iEntry];
333  } else {
334  std::cerr << "ERROR in LauFitDataTree::getData : Requested event " << iEvt << " not found for " << rootTreeName_ << std::endl;
335  gSystem->Exit(EXIT_FAILURE);
336  }
337 
338  for ( LauNameIndexMap::const_iterator iter = leafNames_.begin(); iter != leafNames_.end(); ++iter ) {
339  const TString& name = iter->first;
340  UInt_t index = iter->second;
341 
342  LauFitData::iterator outIter = eventDataOut_.find( name );
343  if ( outIter == eventDataOut_.end() ) {
344  std::cerr << "ERROR in LauFitDataTree::getData : Something very strange happening." << std::endl;
345  gSystem->Exit(EXIT_FAILURE);
346  }
347 
348  outIter->second = eventData_[ index ];
349  }
350  return eventDataOut_;
351 }
352 
Bool_t findBranches()
Find all of the branches in the tree.
File containing declaration of LauFitDataTree class.
void loadData()
Load events from the tree.
LauEventData eventData_
Stores the current event.
void openFileAndTree()
Open the file and tree.
std::vector< LauEventData > fakeEvents_
The fake events, which are not from the tree.
const TString & name() const
The parameter name.
void readAllData()
Read all events from the tree.
TFile * rootFile_
The file containing the data.
TString rootFileName_
The name of the file containing the data.
LauFitData eventDataOut_
Stores the current event (for external use)
void enableAllBranches() const
Enable all branches.
std::map< TString, Double_t > LauFitData
Type for holding event data.
std::vector< LauEventData > treeEvents_
The events read from the tree.
UInt_t nBranches() const
Obtain the number of branches in the tree.
TString rootTreeName_
The name of the tree ocntaining the data.
void readExperimentData(UInt_t iExpt)
Read events only for the given experiment.
LauNameIndexMap leafNames_
Stores the mapping from the leaf names to the vector indices.
UInt_t nTotalEvents() const
Retrieve the total number of events.
TEventList * eventList_
A list of the events in the current experiment.
void disableAllBranches() const
Disable all branches.
TTree * rootTree_
The tree containing the data.
virtual ~LauFitDataTree()
Destructor.
void appendFakePoints(const std::vector< Double_t > &xCoords, const std::vector< Double_t > &yCoords)
Add fake events to the data.
const LauFitData & getData(UInt_t iEvt) const
Retrieve the data for a given event.
UInt_t nFakeEvents() const
Retrieve the number of fake events.
Bool_t haveBranch(const TString &name) const
Check if the named branch is stored.
Double_t value() const
The value of the parameter.
UInt_t nEvents() const
Retrieve the number of events.
void enableBranch(const TString &name) const
Enable the named branch.
void disableBranch(const TString &name) const
Disable the named branch.
LauLeafList leaves_
The leaf objects.
Class to store the input fit variables.