laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauFitDataTree.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2004 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 <cmath>
30 #include <cstdlib>
31 #include <iostream>
32 
33 #include "TFile.h"
34 #include "TLeaf.h"
35 #include "TString.h"
36 #include "TSystem.h"
37 
38 #include "LauFitDataTree.hh"
39 
41 
42 
43 LauFitDataTree::LauFitDataTree(const TString& rootFileName, const TString& rootTreeName) :
44  rootFileName_(rootFileName),
45  rootTreeName_(rootTreeName),
46  rootFile_(0),
47  rootTree_(0),
48  eventList_(0)
49 {
50  if (rootFileName_ != "" && rootTreeName_ != "") {
51  this->openFileAndTree();
52  }
53 }
54 
56 {
57  if (rootFile_ && rootFile_->IsOpen()) {
58  delete rootTree_; rootTree_ = 0;
59  delete eventList_; eventList_ = 0;
60  }
61  delete rootFile_; rootFile_ = 0;
62 }
63 
65 {
66  // first check whether we've already opened up the file or not
67  if (!rootFile_) {
68  // if not, first check the filename and if all ok create the file
69  if (rootFileName_ == "") {
70  std::cerr << "ERROR in LauFitDataTree::openFileAndTree : Bad filename supplied, not creating file or tree." << std::endl;
71  return;
72  }
73  rootFile_ = TFile::Open(rootFileName_, "read");
74  if (!rootFile_ || rootFile_->IsZombie() || !rootFile_->IsOpen()) {
75  std::cerr << "ERROR in LauFitDataTree::openFileAndTree : Problem opening file \"" << rootFileName_ << "\" for reading." << std::endl;
76  return;
77  }
78  }
79  // check whether we've already created the tree
80  if (!rootTree_) {
81  // if not change to the file's directory and grab the tree
82  rootFile_->cd();
83  rootTree_ = dynamic_cast<TTree*>(rootFile_->Get(rootTreeName_));
84  if (!rootTree_) {
85  std::cerr << "ERROR in LauFitDataTree::openFileAndTree : Problem reading tree \"" << rootTreeName_ << "\" from file." << std::endl;
86  return;
87  }
88  rootTree_->SetDirectory(rootFile_);
89  }
90 }
91 
93 {
94  if (!rootTree_) {
95  std::cerr << "ERROR in LauFitDataTree::findBranches : Invalid pointer to data tree." << std::endl;
96  return kFALSE;
97  }
98 
99  // this method should only be called once
100  if ( ! leafNames_.empty() ) {
101  std::cerr << "ERROR in LauFitDataTree::findBranches : Branches already found, not running again." << std::endl;
102  return kFALSE;
103  }
104 
105  leafNames_.clear();
106  eventData_.clear();
107  eventDataOut_.clear();
108  leaves_.clear();
109  treeEvents_.clear();
110  fakeEvents_.clear();
111 
112  const UInt_t numBranches(this->nBranches());
113  eventData_.reserve( numBranches );
114 
115  TObjArray* pLeaves = rootTree_->GetListOfLeaves();
116  if (!pLeaves) {
117  std::cerr << "ERROR in LauFitDataTree::findBranches : Problem retrieving leaves from the tree." << std::endl;
118  return kFALSE;
119  }
120  TObjArray& leaves = *pLeaves;
121 
122  const UInt_t numLeaves = static_cast<UInt_t>( leaves.GetEntries() );
123  if ( numBranches != numLeaves ) {
124  std::cerr << "ERROR in LauFitDataTree::findBranches : List of leaves is not the same size as the number of branches - this is strange!" << std::endl;
125  std::cerr << " : There are " << numLeaves << " leaves and " << numBranches << " branches" << std::endl;
126  return kFALSE;
127  }
128 
129  for (UInt_t iLeaf = 0; iLeaf < numBranches; ++iLeaf) {
130 
131  TLeaf * leaf = dynamic_cast<TLeaf*>(leaves[iLeaf]);
132 
133  // we can't deal with arrays
134  Int_t size = leaf->GetNdata();
135  if (size != 1) {
136  std::cerr << "ERROR in LauFitDataTree::findBranches : Tree has array branches, can't deal with those." << std::endl;
137  return kFALSE;
138  }
139 
140  // find the name and type of the leaf
141  TString name = leaf->GetName();
142 
143  // initialise an entry in the maps to hold the value
144  leafNames_[ name ] = iLeaf;
145  leaves_.push_back( leaf );
146  eventData_.push_back( 0.0 );
147  eventDataOut_[ name ] = 0.0;
148  }
149 
150  const UInt_t numEvents(this->nTotalEvents());
151 
152  std::cout << "INFO in LauFitDataTree::findBranches : Finished finding data tree branches." << std::endl;
153  std::cout << " : Tree contains " << numBranches << " branches and a total of " << numEvents << " events." << std::endl;
154 
155  return kTRUE;
156 }
157 
159 {
160  // Check that we have a valid tree to read from
161  if (!rootTree_) {
162  std::cerr << "ERROR in LauFitDataTree::readExperimentData : Invalid pointer to data tree." << std::endl;
163  return;
164  }
165 
166  rootFile_->cd();
167 
168  // If the event list doesn't exist, create it
169  if (!eventList_) {
170  eventList_ = new TEventList("elist","elist");
171  eventList_->SetDirectory(rootFile_);
172  }
173 
174  // Reset the event list so it contains no entries
175  eventList_->Reset();
176 
177  // Check that the tree contains the iExpt branch
178  if (!this->haveBranch("iExpt")) {
179  // If it doesn't, check which experiment we've been asked to read
180  if ( iExpt == 0 ) {
181  // If it's experiment 0, assume that we should read all events in the tree (but print a warning since this is an assumption)
182  std::cerr << "WARNING in LauFitDataTree::readExperimentData : Tree does not contain \"iExpt\" branch, will read all data in the tree" << std::endl;
183  this->readAllData();
184  return;
185  } else {
186  // Otherwise we can't really do anything, so print an error and return
187  std::cerr << "ERROR in LauFitDataTree::readExperimentData : Tree does not contain \"iExpt\" branch and experiment requested is > 0, will not read anything" << std::endl;
188  return;
189  }
190  }
191 
192  // Fill the event list with the entries for the requested experiment
193  TString listName(eventList_->GetName());
194  listName.Prepend(">>");
195  TString selection("iExpt==");
196  selection += iExpt;
197 
198  std::cout << "INFO in LauFitDataTree::readExperimentData : Setting tree to experiment number " << iExpt << "." << std::endl;
199  rootTree_->Draw(listName,selection);
200  std::cout << " : Found " << this->nEvents() << " events." << std::endl;
201 
202  // Load the data
203  this->loadData();
204 }
205 
207 {
208  if ( rootTree_ ) {
209  return static_cast<UInt_t>(rootTree_->GetNbranches());
210  } else if ( ! fakeEvents_.empty() ) {
211  std::vector<LauEventData>::const_iterator fakeIter = fakeEvents_.begin();
212  return (*fakeIter).size();
213  } else {
214  return 0;
215  }
216 }
217 
218 void LauFitDataTree::appendFakePoints( const std::vector<Double_t>& xCoords, const std::vector<Double_t>& yCoords)
219 {
220  if ( xCoords.size() != yCoords.size() ) {
221  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : The co-ordinate vectors are not the same size!" << std::endl;
222  gSystem->Exit(EXIT_FAILURE);
223  }
224 
225  // clear the list of fake events and reserve enough space
226  fakeEvents_.clear();
227  fakeEvents_.reserve(xCoords.size());
228 
229  // loop over the event data zeroing everything
230  for (LauEventData::iterator iter = eventData_.begin(); iter != eventData_.end(); ++iter) {
231  *iter = 0.0;
232  }
233 
234  // find the vector indices for the DP co-ordinates
235  LauNameIndexMap::const_iterator iter = leafNames_.find( "m13Sq" );
236  if ( iter == leafNames_.end() ) {
237  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : Can't find entry \"m13Sq\" in event data map." << std::endl;
238  gSystem->Exit(EXIT_FAILURE);
239  }
240  UInt_t m13SqIdx = iter->second;
241 
242  iter = leafNames_.find( "m23Sq" );
243  if ( iter == leafNames_.end() ) {
244  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : Can't find entry \"m23Sq\" in event data map." << std::endl;
245  gSystem->Exit(EXIT_FAILURE);
246  }
247  UInt_t m23SqIdx = iter->second;
248 
249  // TODO - is this really needed? Comment out for now.
250  /*
251  // and a fake tagCat which we don't care about, but the program
252  // needs a number here for comptibility with conventional events.
253  iter = leafNames_.find( "tagCat" );
254  if ( iter == leafNames_.end() ) {
255  std::cerr << "ERROR in LauFitDataTree::appendFakePoints : Can't find entry \"tagCat\" in event data map." << std::endl;
256  gSystem->Exit(EXIT_FAILURE);
257  }
258  UInt_t tagCatIdx = iter->second;
259  */
260 
261  for (UInt_t iEvt = 0; iEvt < xCoords.size() ; ++iEvt) {
262 
263  // set the values
264  eventData_[ m13SqIdx ] = xCoords[iEvt];
265  eventData_[ m23SqIdx ] = yCoords[iEvt];
266  //eventData_[ tagCatIdx ] = 0.0;
267 
268  // append to the list of fake events
269  fakeEvents_.push_back(eventData_);
270  }
271 }
272 
273 Bool_t LauFitDataTree::haveBranch(const TString& name) const
274 {
275  LauNameIndexMap::const_iterator iter = leafNames_.find( name );
276  return (iter != leafNames_.end());
277 }
278 
280 {
281  rootTree_->SetBranchStatus("*", 0);
282 }
283 
285 {
286  rootTree_->SetBranchStatus("*", 1);
287 }
288 
289 void LauFitDataTree::enableBranch(const TString& name) const
290 {
291  if (this->haveBranch(name)) {rootTree_->SetBranchStatus(name, 1);}
292 }
293 
294 void LauFitDataTree::disableBranch(const TString& name) const
295 {
296  if (this->haveBranch(name)) {rootTree_->SetBranchStatus(name, 0);}
297 }
298 
300 {
301  // Clear any data from previous expts
302  treeEvents_.clear();
303 
304  // Reserve enough space in the vector
305  Long64_t nEvts = this->nEvents();
306  treeEvents_.reserve( nEvts );
307 
308  const UInt_t nLeaves = this->nBranches();
309 
310  // Loop through the tree and store the data
311  for ( Long64_t iEvt(0); iEvt < nEvts; ++iEvt ) {
312 
313  // Find which entry from the full tree contains the requested event
314  Long64_t iEntry = eventList_ ? eventList_->GetEntry(iEvt) : iEvt;
315  if (iEntry<0) { // this shouldn't happen, but just in case...
316  std::cerr << "ERROR in LauFitDataTree::loadData : Requested event not found." << std::endl;
317  gSystem->Exit(EXIT_FAILURE);
318  }
319 
320  // Then retrieve that entry from the tree
321  rootTree_->GetEntry(iEntry);
322 
323  // Copy the leaf values into eventData_
324  for ( UInt_t iLeaf(0); iLeaf < nLeaves; ++iLeaf ) {
325 
326  const TLeaf * leaf = leaves_[ iLeaf ];
327 
328  Double_t value = leaf->GetValue();
329  if ( std::isnan( value ) || std::isinf( value ) ) {
330  std::cerr << "ERROR in LauFitDataTree::loadData : Event " << iEvt << " has infinite or NaN entry for variable " << leaf->GetName() << std::endl;
331  gSystem->Exit(EXIT_FAILURE);
332  }
333 
334  eventData_[ iLeaf ] = value;
335  }
336 
337  // Store the event in the vector
338  treeEvents_.push_back( eventData_ );
339  }
340 }
341 
343 {
344  delete eventList_; eventList_ = 0;
345  this->loadData();
346 }
347 
348 const LauFitData& LauFitDataTree::getData(UInt_t iEvt) const
349 {
350  // For a given event, within the current experiment,
351  // retrieve the input fit variables
352 
353  const UInt_t numTreeEvents = this->nEvents();
354  const UInt_t numFakeEvents = this->nFakeEvents();
355 
356  // Does the requested event come from the tree or from the fake events list?
357  if ( iEvt < numTreeEvents ) {
358  if ( iEvt > treeEvents_.size() ) { // this shouldn't happen, but just in case...
359  std::cerr << "ERROR in LauFitDataTree::getData : Requested event, " << iEvt << ", not found." << std::endl;
360  gSystem->Exit(EXIT_FAILURE);
361  }
362  // Retrieve that event from the vector
363  eventData_ = treeEvents_[iEvt];
364  } else if ( iEvt < (numTreeEvents + numFakeEvents) ) {
365  // Find the entry from the fake events list contains the requested event
366  UInt_t iEntry = iEvt - numTreeEvents;
367  // Copy the entry into eventData_
368  eventData_ = fakeEvents_[iEntry];
369  } else {
370  std::cerr << "ERROR in LauFitDataTree::getData : Requested event " << iEvt << " not found for " << rootTreeName_ << std::endl;
371  gSystem->Exit(EXIT_FAILURE);
372  }
373 
374  for ( LauNameIndexMap::const_iterator iter = leafNames_.begin(); iter != leafNames_.end(); ++iter ) {
375  const TString& name = iter->first;
376  UInt_t index = iter->second;
377 
378  LauFitData::iterator outIter = eventDataOut_.find( name );
379  if ( outIter == eventDataOut_.end() ) {
380  std::cerr << "ERROR in LauFitDataTree::getData : Something very strange happening." << std::endl;
381  gSystem->Exit(EXIT_FAILURE);
382  }
383 
384  outIter->second = eventData_[ index ];
385  }
386  return eventDataOut_;
387 }
388 
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.
ClassImp(LauAbsCoeffSet)
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.