ROOTPWA
integral.cc
Go to the documentation of this file.
1 #include <cstdlib>
2 
3 #include "sumAccumulators.hpp"
4 #include "integral.h"
5 
6 
7 using namespace std;
8 using namespace boost::accumulators;
9 
10 
12  : _nwaves (0),
13  _nevents (0),
14  _maxEvents(0)
15 {
16 }
17 
18 
19 integral::integral(char** fileList)
20  : _nwaves (0),
21  _nevents (0),
22  _maxEvents(0)
23 {
24  files(fileList);
26 }
27 
28 
30 {
31  _nwaves = ni._nwaves;
32  _nevents = ni._nevents;
34  _index = ni._index;
35  _sum = ni._sum;
36 }
37 
38 
40 {
41 }
42 
43 
44 integral&
46 {
47  _nwaves = ni._nwaves;
48  _nevents = ni._nevents;
50  _index = ni._index;
51  _sum = ni._sum;
53  return *this;
54 }
55 
56 
57 integral&
58 integral::files(char** fileList)
59 {
60  list<string> fList;
61  while (*fileList) {
62  // check if filesize is nonzero.
63  ifstream in;
64  in.open(*fileList);
65  bool isok = false;
66  if (in) {
67  in.seekg (0, ifstream::end);
68  int length = in.tellg();
69  if (length > 0)
70  isok = true;
71  else
72  cerr << "File "<< *fileList << " has zero length. Skipping." << endl;
73  } else
74  cerr << "File "<< *fileList << " not found." << endl;
75  if (isok)
76  fList.push_back(*fileList);
77  in.close();
78  ++fileList;
79  }
80  files(fList);
81  return *this;
82 }
83 
84 
85 integral&
86 integral::files(const list<string>& fileList)
87 {
88  list<string>::const_iterator file = fileList.begin();
89  while (file != fileList.end()) {
90  _index[*file] = _nwaves++;
91  file++;
92  }
94  return *this;
95 }
96 
97 
98 list<string>
100 {
101  list<string> fileList;
102  map<string, int>::const_iterator i = _index.begin();
103  while (i != _index.end() ) {
104  fileList.push_back(i->first);
105  ++i;
106  }
107  return fileList;
108 }
109 
110 
111 char** integral::files_c_str() const
112 {
113  char** fileList = (char**)malloc((_nwaves + 1) * sizeof(char*));
114  int index = 0;
115  map<string, int>::const_iterator i = _index.begin();
116  while (i != _index.end()) {
117  const string fileName = i->first;
118  fileList[index] = (char*)malloc((fileName.size() + 1) * sizeof(char));
119  strcpy(fileList[index], fileName.c_str());
120  ++i;
121  ++index;
122  }
123  fileList[index] = NULL;
124  return fileList;
125 }
126 
127 
128 integral&
130 {
131  if (_nwaves == 0)
132  throw "no waves";
133 
134  ifstream weightFile;
135  bool hasWeight = false;
136  if (_weightFileName.size() != 0) {
137  weightFile.open(_weightFileName.c_str());
138  if (!weightFile) {
139  cerr << "error: cannot open " << _weightFileName << endl;
140  throw "file not found";
141  }
142  hasWeight = true;
143  }
144 
145  ifstream* ampfile = new ifstream [_nwaves];
146  for (map<string, int>::const_iterator i = _index.begin(); i != _index.end(); ++i) {
147  const string fileName = i->first;
148  const int fileIndex = i->second;
149  ampfile[fileIndex].open((fileName).c_str());
150  if(!ampfile[fileIndex]) {
151  cerr << "error: cannot open " << fileName << endl;
152  throw "file not found";
153  }
154  }
155 
156  complex<double>* amps = new complex<double>[_nwaves];
157  int nRead = 0;
158  int eof = 0;
159  accumulator_set<double, stats<tag::sum(compensated)> > weightInt;
160  accumulator_set<complex<double>, stats<tag::sum(compensated)> > sums[_nwaves][_nwaves];
161  while (!eof && ((_maxEvents) ? nRead < _maxEvents : true)) {
162  double w = 1;
163  if (hasWeight)
164  weightFile >> w;
165  const double weight = 1. / w; // we have to de-weight the events!!!
166  weightInt(weight);
167 
168  for (map<string, int>::const_iterator i = _index.begin(); i != _index.end(); ++i) {
169  const int index = i->second;
170  ampfile[index].read((char*)&amps[index], sizeof(complex<double>));
171  if ((eof = ampfile[index].eof()))
172  break;
173  }
174  if (eof)
175  break;
176  ++_nevents;
177  ++nRead;
178 
179  if (!(nRead % 100))
180  cerr << nRead << "\r" << flush;
181 
182  for (map<string, int>::const_iterator i = _index.begin(); i != _index.end(); ++i) {
183  const int indexI = i->second;
184  for (map<string, int>::const_iterator j = _index.begin(); j != _index.end(); ++j) {
185  const int indexJ = j->second;
186  complex<double> val = amps[indexI] * conj(amps[indexJ]);
187  if (hasWeight)
188  val *= weight;
189  sums[indexI][indexJ](val);
190  }
191  }
192  }
193  for (int i = 0; i < _nwaves; ++i)
194  for (int j = 0; j < _nwaves; ++j)
195  _sum.el(i, j) = sum(sums[i][j]);
196 
197  if (hasWeight) {
198  // renormalize to importance sampling weight integral:
199  const double weightNorm = sum(weightInt) / (double)nRead;
200  cerr << "Weight integral= " << weightNorm << endl;
201  _sum *= 1. / weightNorm;
202  }
203 
204  delete [] ampfile;
205  delete [] amps;
206  return *this;
207 }
208 
209 
210 integral&
212 {
213  _sum = ((complex<double>) ((double) n / (double)_nevents)) * _sum;
214  _nevents = n;
215  return *this;
216 }
217 
218 
219 integral&
220 integral::max(const int m)
221 {
222  _maxEvents = m;
223  return *this;
224 }
225 
226 
228 {
229  _nevents = n;
230  return *this;
231 }
232 
233 
234 complex<double>
235 integral::val(const string& iName,
236  const string& jName)
237 {
238  if (_index.find(iName) == _index.end()) {
239  cerr << "error: " << iName << " not in integral" << endl;
240  throw "bad wave access";
241  }
242  if (_index.find(jName) == _index.end()) {
243  cerr << "error: " << jName << " not in integral" << endl;
244  throw "bad wave access";
245  }
246  return el(iName, jName) / ((double)_nevents);
247 }
248 
249 
250 integral
251 integral::get(char** fileList)
252 {
253  list<string> fList;
254  while (*fileList) {
255  fList.push_back(*fileList);
256  ++fileList;
257  }
258  return get(fList);
259 }
260 
261 
262 integral
263 integral::get(const list<string>& fileList)
264 {
265  // need to check that all requested files are in list
266  for (list<string>::const_iterator i = fileList.begin(); i != fileList.end(); ++i)
267  if( _index.find(*i) == _index.end() ) {
268  cerr << "error: " << *i << " not in integral" << endl;
269  throw "bad wave access";
270  }
271  integral ret;
272  ret.files(fileList);
273  ret.events(_nevents);
274  for (list<string>::const_iterator i = fileList.begin(); i != fileList.end(); ++i)
275  for (list<string>::const_iterator j = fileList.begin(); j != fileList.end(); ++j)
276  ret.el(*i, *j) = el(*i, *j);
277  return ret;
278 }
279 
280 
283 {
284  return ((complex<double>)(1.0 / ((double)_nevents))) * _sum;
285 }
286 
287 
288 const integral&
289 integral::print(ostream& os) const
290 {
291  os << _nwaves << endl
292  << _nevents << endl
293  << _sum
294  << _index.size() << endl;
295  map<string, int>::const_iterator i = _index.begin();
296  while (i != _index.end()) {
297  os << i->first << " " << i->second << endl;
298  ++i;
299  }
300  return *this;
301 }
302 
303 
304 const integral&
305 integral::print_events(ostream& os) const
306 {
307  os << _nevents << endl;
308  return *this;
309 }
310 
311 
312 integral&
313 integral::scan(istream& is)
314 {
315  int indexSize = 0, index = 0;
316  string name;
317  is >> _nwaves >> _nevents >> _sum >> indexSize;
318  while (indexSize--) {
319  is >> name >> index;
320  // get rid of an eventual path
321  int slashpos = name.rfind('/');
322  if (slashpos != (int) string::npos) {
323  name.erase(0, slashpos + 1);
324  }
325  _index[name] = index;
326  }
327  return *this;
328 }