ROOTPWA
amplitudeTreeHelper.cc
Go to the documentation of this file.
1 
2 //
3 // Copyright 2010
4 //
5 // This file is part of rootpwa
6 //
7 // rootpwa is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // rootpwa is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with rootpwa. If not, see <http://www.gnu.org/licenses/>.
19 //
21 //-------------------------------------------------------------------------
22 // File and Version Information:
23 // $Rev:: $: revision of last commit
24 // $Author:: $: author of last commit
25 // $Date:: $: date of last commit
26 //
27 // Description:
28 // helper functions that convert between standard binary PWA2000
29 // .amp files and the new ROOT tree format
30 //
31 //
32 // Author List:
33 // Boris Grube TUM (original author)
34 //
35 //
36 //-------------------------------------------------------------------------
37 
38 
39 #include <fstream>
40 #include <cassert>
41 
42 #include <boost/progress.hpp>
43 
44 #include "TTree.h"
45 #include "TChain.h"
46 
47 #include "reportingUtils.hpp"
48 #include "fileUtils.hpp"
49 #include "amplitudeTreeLeaf.h"
50 #include "amplitudeTreeHelper.h"
51 
52 
53 using namespace std;
54 using namespace boost;
55 
56 
57 namespace rpwa {
58 
59 
60  bool
61  fillTreeFromAmp(const string& inFileName,
62  TTree& outTree,
63  const long int maxNmbEvents,
64  const string& ampLeafName,
65  const long int treeCacheSize,
66  const bool)
67  {
68  // open input file
69  printInfo << "opening input file '" << inFileName << "'" << endl;
70  ifstream inFile(inFileName.c_str());
71  if (not inFile or not inFile.good()) {
72  printErr << "cannot open amplitude file '" << inFileName << "'." << endl;
73  return false;
74  }
75 
76  // create leaf variable and connect it to tree branch
77  amplitudeTreeLeaf* ampTreeLeaf = new amplitudeTreeLeaf();
78  const string ampTreeName = fileNameFromPath(inFileName);
79  printInfo << "writing to tree '" << ampTreeName << "'" << endl;
80  outTree.SetName (ampTreeName.c_str());
81  outTree.SetTitle(ampTreeName.c_str());
82  const int splitLevel = 99;
83  const int bufSize = 256000;
84  outTree.Branch(ampLeafName.c_str(), &ampTreeLeaf, bufSize, splitLevel);
85 
86  // loop over events and fill tree
87  printInfo << "writing amplitudes..." << endl;
88  long int countEvents = 0;
89  streampos fileLength = fileSize(inFile);
90  streampos lastPos = inFile.tellg();
91  progress_display progressIndicator(fileLength, cout, "");
92  complex<double> amp;
93  while (inFile.read((char*)&amp, sizeof(complex<double>))) {
94  ampTreeLeaf->setAmp(amp);
95  outTree.Fill();
96  ++countEvents;
97  progressIndicator += inFile.tellg() - lastPos;
98  lastPos = inFile.tellg();
99  if ((maxNmbEvents > 0) and (countEvents >= maxNmbEvents))
100  break;
101  }
102 
103  printInfo << "optimizing tree" << endl;
104  //outTree.Print();
105  outTree.OptimizeBaskets(treeCacheSize, 1, "d");
106  //outTree.Print();
107 
108  printInfo << "wrote amplitudes for " << countEvents << " events to tree "
109  << "'" << outTree.GetName() << "'" << endl;
110  return true;
111  }
112 
113 
114  bool
115  writeAmpFromTree(TChain& inTree,
116  const std::string& outFileName,
117  const long int maxNmbEvents,
118  const std::string& ampLeafName,
119  const bool)
120  {
121  // create output file
122  printInfo << "creating output file '" << outFileName << "'" << endl;
123  ofstream outFile(outFileName.c_str());
124  if (not outFile) {
125  printWarn << "cannot create amplitude file '" << outFileName << "'." << endl;
126  return false;
127  }
128 
129  // connect leaf variable to tree branch
130  amplitudeTreeLeaf* ampTreeLeaf = 0;
131  inTree.SetBranchAddress(ampLeafName.c_str(), &ampTreeLeaf);
132 
133  // loop over events
134  printInfo << "writing amplitudes..." << endl;
135  bool success = true;
136  const long int nmbEventsTree = inTree.GetEntries();
137  const long int nmbEvents = ((maxNmbEvents > 0) ? min(maxNmbEvents, nmbEventsTree)
138  : nmbEventsTree);
139  progress_display progressIndicator(nmbEvents, cout, "");
140  for (long int eventIndex = 0; eventIndex < nmbEvents; ++eventIndex) {
142 
143  if (inTree.LoadTree(eventIndex) < 0)
144  break;
145  inTree.GetEntry(eventIndex);
146  assert(ampTreeLeaf);
147 
148  if (ampTreeLeaf->nmbIncohSubAmps() == 0) {
149  printWarn << "amplitude leaf for event " << eventIndex << " is empty. skipping." << endl;
150  success = false;
151  continue;
152  }
153  if (ampTreeLeaf->nmbIncohSubAmps() > 1)
154  printWarn << "amplitude leaf for event " << eventIndex
155  << " has a size of " << ampTreeLeaf->nmbIncohSubAmps()
156  << " writing only first amplitude."<< endl;
157 
158  complex<double> amp = ampTreeLeaf->amp();
159  outFile.write((char*)(&amp), sizeof(complex<double>));
160  }
161 
162  outFile.close();
163  printInfo << "wrote amplitudes for " << nmbEvents << " events to output file "
164  << "'" << outFileName << "'" << endl;
165  return success;
166  }
167 
168 
169 } // namespace rpwa