46 #include <boost/tokenizer.hpp>
47 #include <boost/progress.hpp>
48 #include <boost/bimap.hpp>
49 #include <boost/assign/list_inserter.hpp>
53 #include "TTreePerfStats.h"
55 #include "TClonesArray.h"
56 #include "TObjString.h"
59 #include "reportingUtilsRoot.hpp"
60 #include "conversionUtils.hpp"
68 using namespace boost;
69 using namespace boost::bimaps;
79 const int chargeToCheck)
81 if (name ==
"unknown") {
82 printWarn <<
"error reading data line " << lineNmb <<
": unknown particle" << endl;
87 particleProperties::chargeFromName(name, charge);
88 if (chargeToCheck != charge) {
89 printWarn <<
"error reading data line " << lineNmb <<
": "
90 <<
"GEANT particle ID of " <<
id <<
" corresponds to particle "
91 <<
"'" << name <<
"'. this inconsistent with the charge of "
92 <<
"'" << chargeToCheck <<
"' in data file.";
106 prop = pdt.
entry(name);
108 const string n = particleProperties::stripChargeFromName(name);
113 printWarn <<
"neither particle '" << name <<
"' "
114 <<
"nor '" << particleProperties::stripChargeFromName(name) <<
"' "
115 <<
"are in particle data table. using mass 0." << endl;
124 string& prodKinPartNamesObjName,
125 string& prodKinMomentaLeafName,
126 string& decayKinPartNamesObjName,
127 string& decayKinMomentaLeafName)
129 typedef tokenizer<char_separator<char> > tokenizer;
130 char_separator<char> separator(
";");
131 tokenizer nameTokens(cmdLineString, separator);
132 tokenizer::iterator nameToken = nameTokens.begin();
133 prodKinPartNamesObjName = *nameToken;
134 prodKinMomentaLeafName = *(++nameToken);
135 decayKinPartNamesObjName = *(++nameToken);
136 decayKinMomentaLeafName = *(++nameToken);
137 printInfo <<
"using the following object/leaf names:" << endl
138 <<
" production kinematics: "
139 <<
"particle names = '" << prodKinPartNamesObjName <<
"', "
140 <<
"momenta = '" << prodKinMomentaLeafName <<
"'" << endl
141 <<
" decay kinematics: "
142 <<
"particle names = '" << decayKinPartNamesObjName <<
"', "
143 <<
"momenta = '" << decayKinMomentaLeafName <<
"'" << endl;
149 TClonesArray*& prodKinPartNames,
150 TClonesArray*& decayKinPartNames,
151 const string& inTreeName,
152 const string& prodKinPartNamesObjName,
153 const string& decayKinPartNamesObjName)
156 inFile.GetObject(prodKinPartNamesObjName.c_str(), prodKinPartNames );
157 inFile.GetObject(decayKinPartNamesObjName.c_str(), decayKinPartNames);
158 if (prodKinPartNames and decayKinPartNames) {
159 TVector3::Class()->IgnoreTObjectStreamer(
true);
164 inFile.GetObject(inTreeName.c_str(), inTree);
165 if (not prodKinPartNames) {
166 TBranch* prodKinPartNamesBr = 0;
167 if (inTree->SetBranchAddress(prodKinPartNamesObjName.c_str(),
168 &prodKinPartNames, &prodKinPartNamesBr) >= 0)
169 if (inTree->GetEntries() > 0)
170 if (inTree->LoadTree(0) >= 0)
171 prodKinPartNamesBr->GetEntry(0);
173 if (not decayKinPartNames) {
174 TBranch* decayKinPartNamesBr = 0;
175 if (inTree->SetBranchAddress(decayKinPartNamesObjName.c_str(),
176 &decayKinPartNames, &decayKinPartNamesBr) >= 0)
177 if (inTree->GetEntries() > 0)
178 if (inTree->LoadTree(0) >= 0)
179 decayKinPartNamesBr->GetEntry(0);
181 if (prodKinPartNames and decayKinPartNames)
190 TClonesArray*& prodKinPartNames,
191 TClonesArray*& decayKinPartNames,
192 const vector<string>& rootFileNames,
193 const vector<string>& evtFileNames,
194 const string& inTreeName,
195 const string& prodKinPartNamesObjName,
196 const string& prodKinMomentaLeafName,
197 const string& decayKinPartNamesObjName,
198 const string& decayKinMomentaLeafName,
203 if (rootFileNames.size() > 0) {
204 inChain =
new TChain(inTreeName.c_str());
205 for (
unsigned int i = 0;
i < rootFileNames.size(); ++
i) {
206 printInfo <<
"opening ROOT input file '" << rootFileNames[
i] <<
"'" << endl;
207 if (inChain->Add(rootFileNames[
i].c_str()) < 1)
208 printWarn <<
"no events in ROOT input file '" << rootFileNames[
i] <<
"'" << endl;
211 TFile* inFile = inChain->GetFile();
213 printWarn <<
"could not open file '" << rootFileNames[0] <<
"'" << endl;
217 prodKinPartNamesObjName, decayKinPartNamesObjName)) {
218 printErr <<
"cannot find production and/or decay kinematics particle names "
219 <<
"in input file '" << inChain->GetFile()->GetName() <<
"'" << endl;
225 inTrees.push_back(inChain);
228 for (
unsigned int i = 0;
i < evtFileNames.size(); ++
i) {
229 printInfo <<
"opening .evt input file '" << evtFileNames[
i] <<
"'" << endl;
230 ifstream evtFile(evtFileNames[
i].c_str());
231 if (not evtFile or not evtFile.good()) {
232 printWarn <<
"cannot open .evt input file '" << evtFileNames[
i] <<
"'. skipping." << endl;
235 printInfo <<
"converting .evt input file '" << evtFileNames[
i] <<
"' "
236 <<
"into memory resident tree. this might reduce performance. "
237 <<
"ROOT input format is recommended." << endl;
239 TTree* tree =
new TTree(inTreeName.c_str(), inTreeName.c_str());
241 printErr <<
"problems creating tree '" << inTreeName <<
"'. skipping." << endl;
244 TClonesArray prodNames (
"TObjString");
245 TClonesArray decayNames(
"TObjString");
247 prodKinMomentaLeafName, decayKinMomentaLeafName, debug))
248 inTrees.push_back(tree);
250 printWarn <<
"problems creating tree from .evt input file '" << evtFileNames[
i] <<
"' "
251 <<
"skipping." << endl;
255 if (prodKinPartNames) {
258 if (prodNames.GetEntriesFast() != prodKinPartNames->GetEntriesFast())
259 goto prodKinPartNamesInconsistent;
260 for (j = 0; j < prodNames.GetEntriesFast(); ++j) {
261 if (not (((TObjString*)prodNames[j])->GetString()
262 == ((TObjString*)(*prodKinPartNames)[j])->GetString()))
263 goto prodKinPartNamesInconsistent;
264 prodKinPartNamesInconsistent:
266 printErr <<
"production kinematics particle names read from input files "
267 <<
"are inconsistent:" << endl
269 for (
int k = 0; k < prodKinPartNames->GetEntriesFast(); ++k)
270 cout <<
" " << ((TObjString*)(*prodKinPartNames)[k])->GetString().Data()
272 cout << endl <<
" read from '" << evtFileNames[
i] <<
"':";
273 for (
int k = 0; k < prodNames.GetEntriesFast(); ++k)
274 cout <<
" " << ((TObjString*)prodNames[k])->GetString().Data() <<
"[" << k <<
"]";
275 cout << endl <<
" check input files." << endl;
280 prodKinPartNames =
new TClonesArray(
"TObjString");
281 *prodKinPartNames = prodNames;
283 if (decayKinPartNames) {
286 if (decayNames.GetEntriesFast() != decayKinPartNames->GetEntriesFast())
287 goto decayKinPartNamesInconsistent;
288 for (j = 0; j < decayNames.GetEntriesFast(); ++j) {
289 if (not (((TObjString*)decayNames[j])->GetString()
290 == (((TObjString*)(*decayKinPartNames)[j])->GetString())))
291 goto decayKinPartNamesInconsistent;
292 decayKinPartNamesInconsistent:
294 printErr <<
"decay kinematics particle names read from input files "
295 <<
"are inconsistent:" << endl
297 for (
int k = 0; k < decayKinPartNames->GetEntriesFast(); ++k)
298 cout <<
" " << ((TObjString*)(*decayKinPartNames)[k])->GetString().Data()
300 cout << endl <<
" read from '" << evtFileNames[
i] <<
"':";
301 for (
int k = 0; k < decayNames.GetEntriesFast(); ++k)
302 cout <<
" " << ((TObjString*)decayNames[k])->GetString().Data() <<
"[" << k <<
"]";
303 cout << endl <<
" check input files." << endl;
308 decayKinPartNames =
new TClonesArray(
"TObjString");
309 *decayKinPartNames = decayNames;
315 if (not prodKinPartNames) {
316 printErr <<
"no production kinematics particle names were found in input files." << endl;
319 if (not decayKinPartNames) {
320 printWarn <<
"no decay kinematics particle names were found in input files." << endl;
331 TClonesArray& prodKinPartNames,
332 TClonesArray& decayKinPartNames,
333 const long int maxNmbEvents,
334 const string& prodKinMomentaLeafName,
335 const string& decayKinMomentaLeafName,
337 const long int treeCacheSize)
339 if (not inEvt or not inEvt.good()) {
340 printWarn <<
"cannot read from input stream" << endl;
345 TVector3::Class()->IgnoreTObjectStreamer(
true);
346 TClonesArray* prodKinMomenta =
new TClonesArray(
"TVector3");
347 TClonesArray* decayKinMomenta =
new TClonesArray(
"TVector3");
350 const int splitLevel = 99;
351 const int bufSize = 256000;
352 outTree.Branch(prodKinMomentaLeafName.c_str(),
"TClonesArray", &prodKinMomenta, bufSize, splitLevel);
353 outTree.Branch(decayKinMomentaLeafName.c_str(),
"TClonesArray", &decayKinMomenta, bufSize, splitLevel);
356 vector<string> prodNames;
357 vector<string> decayNames;
359 long int countEvents = 0;
360 long int countLines = 0;
361 inEvt.seekg(0, ios::end);
362 long int fileLength = inEvt.tellg();
363 inEvt.seekg(0, ios::beg);
365 streampos lastPos = inEvt.tellg();
366 while (inEvt.good()) {
370 int nmbParticles = 0;
371 if (getline(inEvt, line)) {
373 stringstream lineStream(line);
378 printWarn <<
"event " << countEvents + 1 <<
": error reading number of particles "
379 <<
"from line " << countLines <<
": " << line << endl;
384 assert(nmbParticles > 0);
386 printDebug <<
"# of particles = " << nmbParticles << endl;
390 prodKinMomenta->Clear();
391 if (getline(inEvt, line)) {
393 stringstream lineStream(line);
394 int id = 0, charge = 0;
395 double momX = 0, momY = 0, momZ = 0, E = 0;
396 if (lineStream >>
id >> charge >> momX >> momY >> momZ >> E) {
397 const string partName = particleDataTable::particleNameFromGeantId(
id);
398 prodNames.push_back(partName);
401 new((*prodKinMomenta)[0]) TVector3(momX, momY, momZ);
403 printWarn <<
"event " << countEvents + 1 <<
": error reading beam data "
404 <<
"from line " << countLines <<
": " << line << endl;
411 const int nmbProdKinPart = prodNames.size();
412 assert((nmbProdKinPart > 0) and (nmbProdKinPart == prodKinMomenta->GetEntriesFast()));
414 printDebug << nmbProdKinPart <<
" production kinematics particles:" << endl;
415 for (
int i = 0;
i < nmbProdKinPart; ++
i)
416 cout <<
" particle[" <<
i <<
"]: "
417 << prodNames[
i] <<
"; " << *((TVector3*)(*prodKinMomenta)[
i]) << endl;
422 decayNames.resize(nmbParticles - 1,
"");
423 decayKinMomenta->Clear();
424 for (
int i = 0;
i < nmbParticles - 1; ++
i) {
425 if (getline(inEvt, line)) {
427 stringstream lineStream(line);
429 double momX, momY, momZ, E;
430 if (lineStream >>
id >> charge >> momX >> momY >> momZ >> E) {
431 const string partName = particleDataTable::particleNameFromGeantId(
id);
432 decayNames[
i] = partName;
435 new((*decayKinMomenta)[
i]) TVector3(momX, momY, momZ);
437 printWarn <<
"event " << countEvents + 1 <<
": error reading decay kinematics "
438 <<
"particle[" <<
i <<
"] data from line " << countLines <<
": " << line << endl;
446 const int nmbDecayKinPart = decayNames.size();
447 assert((nmbDecayKinPart > 0) and (nmbDecayKinPart == decayKinMomenta->GetEntriesFast()));
449 printDebug << nmbDecayKinPart <<
" decay kinematics particles:" << endl;
450 for (
int i = 0;
i < nmbDecayKinPart; ++
i)
451 cout <<
" particle[" <<
i <<
"]: "
452 << decayNames[
i] <<
"; " << *((TVector3*) (*decayKinMomenta)[
i]) << endl;
456 if (countEvents == 0) {
457 for (
unsigned int i = 0;
i < prodNames.size(); ++
i)
458 new(prodKinPartNames[
i]) TObjString(prodNames[i].c_str());
459 for (
unsigned int i = 0; i < decayNames.size(); ++
i)
460 new(decayKinPartNames[i]) TObjString(decayNames[i].c_str());
463 const int nmbIsPart = prodNames.size();
464 const int nmbIsPartExpected = prodKinPartNames.GetEntriesFast();
465 const int nmbFsPart = decayNames.size();
466 const int nmbFsPartExpected = decayKinPartNames.GetEntriesFast ();
467 if ((nmbIsPart != nmbIsPartExpected) || (nmbFsPart != nmbFsPartExpected)) {
468 printErr <<
"number of particles changed in event " << countEvents <<
". "
469 <<
"producion kinematics: " << nmbIsPart <<
" particles "
470 <<
"(" << nmbIsPartExpected <<
" expected); "
471 <<
"decay kinematics: " << nmbFsPart <<
" particles "
472 <<
"(" << nmbFsPartExpected <<
" expected). "
473 <<
"check .evt file. aborting." << endl;
476 for (
int i = 0;
i < nmbIsPart; ++
i) {
477 const string name = prodNames[
i];
478 const string nameExpected = ((TObjString*)prodKinPartNames[
i])->GetString().Data();
479 if (name != nameExpected) {
480 printErr <<
"particle[" << i <<
"] name mismatch in production kinematics in event "
481 << countEvents <<
": '" << name <<
"', expected '" << nameExpected <<
"'. "
482 <<
"check .evt file. aborting." << endl;
486 for (
int i = 0;
i < nmbFsPart; ++
i) {
487 const string name = decayNames[
i];
488 const string nameExpected = ((TObjString*)decayKinPartNames[
i])->GetString().Data();
489 if (name != nameExpected) {
490 printErr <<
"particle[" << i <<
"] name mismatch in decay kinematics in event "
491 << countEvents <<
": '" << name <<
"', expected '" << nameExpected <<
"'. "
492 <<
"check .evt file. aborting." << endl;
499 if (progressIndicator)
500 (*progressIndicator) += inEvt.tellg() - lastPos;
501 lastPos = inEvt.tellg();
502 if ((maxNmbEvents > 0) and (countEvents >= maxNmbEvents))
506 printInfo <<
"optimizing tree" << endl;
508 outTree.OptimizeBaskets(treeCacheSize, 1,
"d");
511 printInfo <<
"read " << countLines <<
" lines from input stream and wrote "
512 << countEvents <<
" events to tree '" << outTree.GetName() <<
"' "
513 <<
"assuming fixed target" << endl;
521 const TClonesArray& prodKinPartNames,
522 const TClonesArray& decayKinPartNames,
523 const long int maxNmbEvents,
524 const string& inTreeName,
525 const string& prodKinMomentaLeafName,
526 const string& decayKinMomentaLeafName,
529 const long int nmbEventsTree = inTree.GetEntries();
531 printWarn <<
"cannot write to output stream" << endl;
534 string partClassName = prodKinPartNames.GetClass()->GetName();
535 if (partClassName !=
"TObjString") {
536 printWarn <<
"production kinematics particle names are of type '" << partClassName
537 <<
"' and not TObjString." << endl;
540 partClassName = decayKinPartNames.GetClass()->GetName();
541 if (partClassName !=
"TObjString") {
542 printWarn <<
"decay kinematics particle names are of type '" << partClassName
543 <<
"' and not TObjString." << endl;
548 TClonesArray* prodKinMomenta = 0;
549 TClonesArray* decayKinMomenta = 0;
552 inTree.SetBranchAddress(prodKinMomentaLeafName.c_str(), &prodKinMomenta );
553 inTree.SetBranchAddress(decayKinMomentaLeafName.c_str(), &decayKinMomenta);
556 const long int nmbEvents = ((maxNmbEvents > 0) ? min(maxNmbEvents, nmbEventsTree)
559 for (
long int eventIndex = 0; eventIndex < nmbEvents; ++eventIndex) {
560 if (progressIndicator)
561 ++(*progressIndicator);
563 if (inTree.LoadTree(eventIndex) < 0)
565 inTree.GetEntry(eventIndex);
567 assert(prodKinMomenta );
568 assert(decayKinMomenta);
569 const int nmbProdKinPart = prodKinPartNames.GetEntriesFast ();
570 const int nmbDecayKinPart = decayKinPartNames.GetEntriesFast();
571 assert(nmbProdKinPart == prodKinMomenta->GetEntriesFast ());
572 assert(nmbDecayKinPart == decayKinMomenta->GetEntriesFast());
573 if (nmbProdKinPart < 1) {
574 printWarn <<
"array of production kinematics particles does not have any entries. "
575 <<
"at least entry for beam (index 0) is required. skipping event." << endl;
578 if (nmbDecayKinPart < 1) {
579 printWarn <<
"array of decay kinematics particles does not have any entries. "
580 <<
"at least one final state particle is required. skipping event." << endl;
585 outEvt << 1 + nmbDecayKinPart << endl;
589 printDebug <<
"event[" << eventIndex <<
"]: " << nmbProdKinPart
590 <<
" production kinematics particles:" << endl;
592 assert(prodKinPartNames [0]);
593 assert((*prodKinMomenta)[0]);
594 const string name = ((TObjString*)prodKinPartNames[0])->GetString().Data();
595 const TVector3* mom =
dynamic_cast<TVector3*
>((*prodKinMomenta)[0]);
599 particleDataTable::geantIdAndChargeFromParticleName(name,
id, charge);
600 outEvt << setprecision(numeric_limits<double>::digits10 + 1)
601 <<
id <<
" " << charge <<
" " << mom->X() <<
" " << mom->Y() <<
" " << mom->Z() <<
" "
602 << sqrt(mass * mass + mom->Mag2()) << endl;
604 cout <<
" particle[" << 0 <<
"]: " << name <<
", id = " <<
id <<
", "
605 <<
"charge = " << charge <<
"; " << *mom << endl;
611 printDebug <<
"event[" << eventIndex <<
"]: " << nmbDecayKinPart
612 <<
" decay kinematics particles:" << endl;
613 for (
unsigned int i = 0;
i < (
unsigned int)nmbDecayKinPart; ++
i) {
614 assert(decayKinPartNames [
i]);
615 assert((*decayKinMomenta)[i]);
616 const string name = ((TObjString*)decayKinPartNames[i])->GetString().Data();
617 const TVector3* mom =
dynamic_cast<TVector3*
>((*decayKinMomenta)[
i]);
621 particleDataTable::geantIdAndChargeFromParticleName(name,
id, charge);
622 outEvt << setprecision(numeric_limits<double>::digits10 + 1)
623 <<
id <<
" " << charge <<
" " << mom->X() <<
" " << mom->Y() <<
" " << mom->Z() <<
" "
624 << sqrt(mass * mass + mom->Mag2()) << endl;
626 cout <<
" particle[" << i <<
"]: " << name <<
", id = " <<
id <<
", "
627 <<
"charge = " << charge <<
"; " << *mom << endl;
635 printInfo <<
"wrote " << nmbEvents <<
" events to output stream" << endl;
642 const TClonesArray& prodKinPartNames,
643 const TClonesArray& decayKinPartNames,
645 vector<complex<double> >& ampValues,
646 const long int maxNmbEvents,
647 const string& prodKinMomentaLeafName,
648 const string& decayKinMomentaLeafName,
649 const bool printProgress,
650 const string& treePerfStatOutFileName,
651 const long int treeCacheSize)
654 printWarn <<
"null pointer to isobar decay amplitude. cannot process tree." << endl;
662 TBranch* prodKinMomentaBr = 0;
663 TBranch* decayKinMomentaBr = 0;
664 TClonesArray* prodKinMomenta = 0;
665 TClonesArray* decayKinMomenta = 0;
668 tree.SetBranchAddress(prodKinMomentaLeafName.c_str(), &prodKinMomenta, &prodKinMomentaBr );
669 tree.SetBranchAddress(decayKinMomentaLeafName.c_str(), &decayKinMomenta, &decayKinMomentaBr);
670 tree.SetCacheSize(treeCacheSize);
671 tree.AddBranchToCache(prodKinMomentaLeafName.c_str(),
true);
672 tree.AddBranchToCache(decayKinMomentaLeafName.c_str(),
true);
673 tree.StopCacheLearningPhase();
674 TTreePerfStats* treePerfStats = 0;
675 if (treePerfStatOutFileName !=
"")
676 treePerfStats =
new TTreePerfStats(
"ioPerf", &tree);
679 if (not decayTopo->initKinematicsData(prodKinPartNames, decayKinPartNames)) {
680 printWarn <<
"problems initializing input data. cannot read input data." << endl;
683 const long int nmbEventsTree = tree.GetEntries();
684 const long int nmbEvents = ((maxNmbEvents > 0) ? min(maxNmbEvents, nmbEventsTree)
687 progress_display*
progressIndicator = (printProgress) ?
new progress_display(nmbEvents, cout,
"") : 0;
688 for (
long int eventIndex = 0; eventIndex < nmbEvents; ++eventIndex) {
689 if (progressIndicator)
690 ++(*progressIndicator);
692 if (tree.LoadTree(eventIndex) < 0)
695 prodKinMomentaBr->GetEntry (eventIndex);
696 decayKinMomentaBr->GetEntry(eventIndex);
698 if (not prodKinMomenta or not decayKinMomenta) {
699 printWarn <<
"at least one of the input data arrays is a null pointer: "
700 <<
" production kinematics: " <<
"momenta = " << prodKinMomenta << endl
701 <<
" decay kinematics: " <<
"momenta = " << decayKinMomenta << endl
702 <<
"skipping event." << endl;
707 if (decayTopo->readKinematicsData(*prodKinMomenta, *decayKinMomenta))
708 ampValues.push_back((*amplitude)());
710 printWarn <<
"problems reading event[" << eventIndex <<
"]" << endl;
716 tree.PrintCacheStats();
718 treePerfStats->SaveAs(treePerfStatOutFileName.c_str());
719 delete treePerfStats;