38 #include <boost/progress.hpp>
39 #include <boost/numeric/conversion/cast.hpp>
48 #include "reportingUtils.hpp"
49 #include "fileUtils.hpp"
50 #include "sumAccumulators.hpp"
56 using namespace boost;
57 using namespace boost::accumulators;
61 #ifdef USE_STD_COMPLEX_TREE_LEAFS
66 bool ampIntegralMatrix::_debug =
false;
69 ampIntegralMatrix::ampIntegralMatrix()
72 _waveNameToIndexMap (),
77 _intStorageNmbElements(0),
113 if (
this != &integral) {
122 _integrals.resize(extents[shape[0]][shape[1]]);
134 printErr <<
"cannot add " << *
this << endl
135 <<
"and " << integral << endl
136 <<
"because the two integral matrices have different wave sets. aborting." << endl;
141 for (
unsigned int j = 0; j <
_nmbWaves; ++j)
154 printErr <<
"cannot subtract " << integral << endl
155 <<
"from " << *
this << endl
156 <<
"because the two integral matrices have different wave sets. aborting." << endl;
161 for (
unsigned int j = 0; j <
_nmbWaves; ++j)
174 for (
unsigned int j = 0; j <
_nmbWaves; ++j)
185 for (
unsigned int j = 0; j <
_nmbWaves; ++j)
207 printErr <<
"cannot find wave '" << waveName <<
"' in integral matrix. aborting." << endl;
210 return entry->second;
220 printErr <<
"wave index " << waveIndex <<
" is out of range. aborting." << endl;
247 const unsigned int waveIndexJ)
const
250 printErr <<
"wave index for i = " << waveIndexI <<
" out of range. "
251 <<
"number of waves = " <<
_nmbWaves << endl;
255 printErr <<
"wave index for j = " << waveIndexJ <<
" out of range. "
256 <<
"number of waves = " <<
_nmbWaves << endl;
265 const vector<string>& rootAmpFileNames,
266 const unsigned long maxNmbEvents,
267 const string& weightFileName)
270 vector<ifstream*> binAmpFiles;
271 const unsigned long nmbBinEvents =
openBinAmpFiles(binAmpFiles, binAmpFileNames, 0);
272 const unsigned int nmbBinWaves = binAmpFiles.size();
273 vector<TTree*> ampTrees;
274 vector<amplitudeTreeLeaf*> ampTreeLeafs;
275 const unsigned long nmbRootEvents =
openRootAmpFiles(ampTrees, ampTreeLeafs,
276 rootAmpFileNames, binAmpFiles.size());
277 const unsigned int nmbRootWaves = ampTrees.size();
280 printInfo <<
"calculating integral for " <<
_nmbWaves <<
" amplitude(s)" << endl;
282 printWarn <<
"could not open any amplitude files. cannot calculate integral." << endl;
285 if ((nmbBinEvents > 0) and (nmbRootEvents > 0) and (nmbBinEvents != nmbRootEvents)) {
286 printWarn <<
".bin and .root amplitude files contain different number of amplitude values "
287 <<
"(" << nmbBinEvents <<
" vs. " << nmbRootEvents <<
"). "
288 <<
"cannot calculate integral." << endl;
291 if ((nmbBinEvents == 0) and (nmbRootEvents == 0)) {
292 printWarn <<
"amplitude files contain no amplitudes values. cannot calculate integral." << endl;
295 if (nmbBinEvents > 0)
312 bool useWeight =
false;
313 if (weightFileName !=
"") {
315 printDebug <<
"opening importance sampling weight file '" << weightFileName <<
"'" << endl;
316 weightFile.open(weightFileName.c_str());
317 if (not weightFile) {
318 printWarn <<
"cannot open importance sampling weight file '" << weightFileName <<
"' "
319 <<
"cannot calculate integral." << endl;
326 accumulator_set<double, stats<tag::sum(compensated)> > weightAcc;
327 accumulator_set<complex<double>, stats<tag::sum(compensated)> > ampProdAcc[
_nmbWaves][
_nmbWaves];
329 vector<complex<double> > amps[
_nmbWaves];
332 for (
unsigned long iEvent = 0; iEvent <
_nmbEvents; ++iEvent) {
338 if (not(weightFile >> w)) {
340 printWarn <<
"error reading weight file. stopping integration "
341 <<
"at event " << iEvent <<
" of total " << _nmbEvents <<
"." << endl;
344 const double weight = 1 / w;
348 bool ampBinEof =
false;
352 if ((ampBinEof = binAmpFiles[waveIndex]->eof())) {
354 printWarn <<
"unexpected EOF while reading binary amplitude '"
356 <<
"at event " << iEvent <<
" of total " << _nmbEvents <<
"." << endl;
365 const unsigned int index =
waveIndex - nmbBinWaves;
366 ampTrees[index]->GetEntry(iEvent);
367 const unsigned int nmbSubAmps = ampTreeLeafs[index]->nmbIncohSubAmps();
368 if (nmbSubAmps < 1) {
370 <<
"does not contain any amplitude values "
371 <<
"at event " << iEvent <<
" of total " << _nmbEvents <<
". aborting." << endl;
376 for (
unsigned int subAmpIndex = 0; subAmpIndex < nmbSubAmps; ++subAmpIndex)
377 amps[
waveIndex][subAmpIndex] = ampTreeLeafs[index]->incohSubAmp(subAmpIndex);
381 for (
unsigned int waveIndexI = 0; waveIndexI <
_nmbWaves; ++waveIndexI)
382 for (
unsigned int waveIndexJ = 0; waveIndexJ <
_nmbWaves; ++waveIndexJ) {
384 const unsigned int nmbSubAmps = amps[waveIndexI].size();
385 if (nmbSubAmps != amps[waveIndexJ].size()) {
386 printErr <<
"number of incoherent sub-amplitudes for wave '"
387 <<
_waveNames[waveIndexI] <<
"' = " << nmbSubAmps
388 <<
" differs from that of wave '" <<
_waveNames[waveIndexJ] <<
"' = "
389 << amps[waveIndexJ].size()
390 <<
" at event " << iEvent <<
" of total " << _nmbEvents <<
". aborting. "
391 <<
"be sure to use only .root amplitude files, "
392 <<
"if your channel has sub-amplitudes." << endl;
395 complex<double> val = 0;
396 for (
unsigned int subAmpIndex = 0; subAmpIndex < nmbSubAmps; ++subAmpIndex)
397 val += amps[waveIndexI][subAmpIndex] *
conj(amps[waveIndexJ][subAmpIndex]);
400 ampProdAcc[waveIndexI][waveIndexJ](val);
406 const double weightNorm = sum(weightAcc) / (double)_nmbEvents;
407 for (
unsigned int waveIndexI = 0; waveIndexI <
_nmbWaves; ++waveIndexI)
408 for (
unsigned int waveIndexJ = 0; waveIndexJ <
_nmbWaves; ++waveIndexJ) {
409 _integrals[waveIndexI][waveIndexJ] = sum(ampProdAcc[waveIndexI][waveIndexJ]);
411 _integrals[waveIndexI][waveIndexJ] *= 1 / weightNorm;
414 printSucc <<
"calculated integrals of " << _nmbWaves <<
" amplitude(s) "
415 <<
"for " << _nmbEvents <<
" events" << endl;
417 for (
unsigned int i = 0;
i < binAmpFiles.size(); ++
i)
419 delete binAmpFiles[
i];
429 printDebug <<
"renormalizing integrals from " <<
_nmbEvents <<
" "
430 <<
"to " << nmbEventsRenorm <<
" events." << endl;
431 *
this *= (double)nmbEventsRenorm /
_nmbEvents;
440 printWarn <<
"cannot write to output stream. cannot write integral." << endl;
447 for (
unsigned int waveIndexI = 0; waveIndexI <
_nmbWaves; ++waveIndexI) {
448 for (
unsigned int waveIndexJ = 0; waveIndexJ <
_nmbWaves; ++waveIndexJ)
449 out << maxPrecisionDouble(
_integrals[waveIndexI][waveIndexJ]) <<
"\t";
456 out <<
i->first <<
" " <<
i->second << endl;
465 printWarn <<
"could not read number of waves and events" << endl;
469 unsigned int nmbRows, nmbCols;
470 if (not (in >> nmbRows >> nmbCols)) {
471 printWarn <<
"could not read number of rows and columns" << endl;
477 for (
unsigned int i = 0;
i < nmbRows; ++
i)
478 for (
unsigned int j = 0; j < nmbCols; ++j) {
480 printErr <<
"could not read integral values. stream seems trunkated." << endl;
485 unsigned int mapSize;
487 while ((mapSize > 0) and in) {
490 if (not (in >> waveName >> waveIndex)) {
491 printErr <<
"could not read wave name -> index map. stream seems trunkated." << endl;
509 printDebug <<
"opening ASCII file '" << outFileName <<
"' for writing of integral matrix" << endl;
510 ofstream outFile(outFileName.c_str());
511 if (not outFile or not outFile.good()) {
512 printWarn <<
"cannot open file '" << outFileName <<
"' for writing of integral matrix" << endl;
517 printSucc <<
"wrote integral to ASCII file '" << outFileName <<
"'" << endl;
519 printWarn <<
"problems writing integral to ASCII file '" << outFileName <<
"'" << endl;
528 printDebug <<
"opening ASCII file '" << inFileName <<
"' for reading of integral matrix" << endl;
529 fstream inFile(inFileName.c_str());
530 if (not inFile or not inFile.good()) {
531 printWarn <<
"cannot open file '" << inFileName <<
"' for reading of integral matrix" << endl;
536 printSucc <<
"read integral from ASCII file '" << inFileName <<
"'" << endl;
538 printWarn <<
"problems reading integral from ASCII file '" << inFileName <<
"'" << endl;
545 const bool printIntegralValues)
const
547 out <<
"amplitude integral matrix:" << endl
548 <<
" number of waves .... " <<
_nmbWaves << endl
549 <<
" number of events ... " <<
_nmbEvents << endl
550 <<
" wave name -> index map:" << endl;
553 out <<
" " <<
i->first <<
" -> " <<
i->second <<
" -> " <<
_waveNames[
i->second] << endl;
554 if (printIntegralValues) {
555 out <<
" integral matrix values:" << endl;
556 for (
unsigned int waveIndexI = 0; waveIndexI <
_nmbWaves; ++waveIndexI)
557 for (
unsigned int waveIndexJ = 0; waveIndexJ <
_nmbWaves; ++waveIndexJ)
558 out <<
" [" << setw(4) << waveIndexI <<
", " << setw(4) << waveIndexJ <<
"] = "
559 << maxPrecisionDouble(
_integrals[waveIndexI][waveIndexJ]) << endl;
567 const vector<string>& ampFileNames,
568 const unsigned int waveIndexOffset)
571 streampos ampFileSize = 0;
572 unsigned int waveIndex = waveIndexOffset;
573 for (
unsigned int i = 0;
i < ampFileNames.size(); ++
i) {
576 const string& ampFilePath = ampFileNames[
i];
580 printDebug <<
"opening binary amplitude file '" << ampFilePath <<
"'" << endl;
581 ifstream* ampFile =
new ifstream();
582 ampFile->open(ampFilePath.c_str());
584 printWarn <<
"cannot open amplitude file '" << ampFilePath <<
"'. skipping file." << endl;
589 const streampos fileSize = rpwa::fileSize(*ampFile);
591 printWarn <<
"amplitude file '" << ampFilePath <<
"' has zero size. skipping file." << endl;
594 if (ampFileSize == 0)
595 ampFileSize = fileSize;
596 else if (fileSize != ampFileSize) {
597 printWarn <<
"amplitude file '" << ampFilePath <<
"' has different size "
598 <<
"than previous file. skipping file." << endl;
603 const string waveName = fileNameFromPath(ampFilePath);
609 ampFiles.push_back(ampFile);
611 printWarn <<
"wave '" << waveName <<
"' already exists in integral matrix. "
612 <<
"ignoring file '" << ampFilePath <<
"'. "
613 <<
"make sure that there are no duplicate .amp files." << endl;
615 const unsigned int nmbAmpValues = ampFileSize /
sizeof(complex<double>);
622 vector<amplitudeTreeLeaf*>& ampTreeLeafs,
623 const vector<string>& ampFileNames,
624 const unsigned int waveIndexOffset,
625 const string& ampLeafName)
628 ampTreeLeafs.clear();
629 unsigned long nmbAmps = 0;
630 #ifdef USE_STD_COMPLEX_TREE_LEAFS
633 gROOT->ProcessLine(
"#include <complex>");
634 unsigned int waveIndex = waveIndexOffset;
635 vector<TTree*> trees;
636 vector<waveDescription*> waveDescs;
637 vector<string> keyNames;
638 for (
unsigned int ampFileIndex = 0; ampFileIndex < ampFileNames.size(); ++ampFileIndex) {
641 const string& ampFilePath = ampFileNames[ampFileIndex ];
645 printDebug <<
"opening .root amplitude file '" << ampFilePath <<
"'" << endl;
646 TFile* ampFile = TFile::Open(ampFilePath.c_str(),
"READ");
647 if (not ampFile or ampFile->IsZombie()) {
648 printErr <<
"could open amplitude file '" << ampFilePath <<
"'. skipping file." << endl;
653 TIterator* keys = ampFile->GetListOfKeys()->MakeIterator();
654 bool foundAmpKey =
false;
655 while (TKey* k = static_cast<TKey*>(keys->Next())) {
657 printWarn <<
"NULL pointer to TKey in file '" << ampFilePath <<
"'. skipping TKey." << endl;
662 const string keyName = k->GetName();
663 if (extensionFromPath(keyName) ==
"amp") {
665 ampFile->GetObject(keyName.c_str(), tree);
667 ampFile->GetObject((changeFileExtension(keyName,
"key")).c_str(), waveDesc);
668 trees.push_back (tree );
669 waveDescs.push_back(waveDesc);
670 keyNames.push_back (keyName );
674 printWarn <<
"no TKey in file '" << ampFilePath <<
"' matches '*.amp'. skipping file." << endl;
678 assert((trees.size() == waveDescs.size()) and (trees.size() == keyNames.size()));
679 for (
unsigned int i = 0;
i < trees.size(); ++
i)
680 if (not trees[
i] or not waveDescs[
i]) {
681 printWarn <<
"could not read tree or wave description from TKeys '"
682 << fileNameNoExtFromPath(keyNames[i]) <<
".{amp,key}'. "
683 <<
"skipping TKeys." << endl;
684 trees.erase (trees.begin () +
i);
685 waveDescs.erase(waveDescs.begin() +
i);
686 keyNames.erase (keyNames.begin () +
i);
688 assert((trees.size() == waveDescs.size()) and (trees.size() == keyNames.size()));
689 const unsigned int nmbAmpTrees = trees.size();
692 _waveNames.resize(waveIndex + nmbAmpTrees + 1);
694 for (
unsigned int i = 0; i < nmbAmpTrees; ++
i) {
697 trees[
i]->SetBranchAddress(ampLeafName.c_str(), &treeLeaf);
700 const unsigned long nmbEntries = numeric_cast<
unsigned long>(trees[
i]->GetEntriesFast());
701 if (nmbEntries == 0) {
702 printWarn <<
"amplitude tree '" << trees[
i]->GetName() <<
"' has zero entries. "
703 <<
"skipping tree." << endl;
707 nmbAmps = nmbEntries;
708 else if (nmbEntries != nmbAmps) {
709 printWarn <<
"amplitude tree '" << trees[
i]->GetName() <<
"' has different number "
710 <<
"of entries than previous tree. skipping tree." << endl;
715 const string waveName = fileNameNoExtFromPath(trees[i]->GetName());
721 ampTrees.push_back (trees[i]);
722 ampTreeLeafs.push_back(treeLeaf);
724 printWarn <<
"wave '" << waveName <<
"' already exists in integral matrix. "
725 <<
"ignoring tree '" << trees[
i]->GetName() <<
"'." << endl;
727 #endif // USE_STD_COMPLEX_TREE_LEAFS
740 printWarn <<
"wave '" <<
_waveNames[
i] <<
"' already exists in integral matrix. "
741 <<
"ignoring wave." << endl;
755 for (
unsigned int i = 0;
i < integral.
nmbWaves(); ++
i)
780 complex<double>* integralData =
_integrals.data();
798 ampIntegralMatrix::Streamer(TBuffer& R__b)
800 if (R__b.IsReading()) {
801 R__b.ReadClassBuffer(rpwa::ampIntegralMatrix::Class(),
this);
806 R__b.WriteClassBuffer(rpwa::ampIntegralMatrix::Class(),
this);