50 #include <sys/types.h>
53 #include <boost/progress.hpp>
55 #include "TStopwatch.h"
59 #include "TClonesArray.h"
60 #include "TLorentzVector.h"
62 #include "reportingUtils.hpp"
66 using namespace boost;
74 vector<TTree*>& pwaTrees,
75 const string& dirBaseName =
"/tmp/",
76 const unsigned int nmbMassBins = 50,
77 const double massBinWidth = 50,
78 const double massRangeMin = 500,
79 const string& treeName =
"rootPwaEvtTree")
81 printInfo <<
"creating mass bin directories/files in '" << dirBaseName <<
"':" << endl;
83 for (
unsigned int i = 0;
i < pwaTrees.size(); ++
i)
87 for (
unsigned int i = 0; i < pwaFiles.size(); ++
i)
93 pwaFiles.resize(nmbMassBins, 0);
94 pwaTrees.resize(nmbMassBins, 0);
96 for (
unsigned int i = 0; i < nmbMassBins; ++
i) {
97 const double binMin = massRangeMin + i * massBinWidth;
98 const double binMax = binMin + massBinWidth;
101 n << binMin <<
"." << binMax;
102 const string dirName = dirBaseName +
"/" + n.str();
103 mkdir(dirName.c_str(), S_IRWXU | S_IRWXG);
105 const string pwaFileName = dirName +
"/" + n.str() +
".root";
106 TFile* pwaFile = TFile::Open(pwaFileName.c_str(),
"RECREATE");
107 if (not pwaFile or pwaFile->IsZombie()) {
108 printWarn <<
"problems creating file '" << pwaFileName <<
"'" << endl;
111 pwaFiles[
i] = pwaFile;
112 pwaTrees[
i] =
new TTree(treeName.c_str(), treeName.c_str());
113 if (not pwaTrees[i]) {
114 printWarn <<
"problems creating tree '" << treeName <<
"' " <<
"in file "
115 <<
"'" << pwaFileName <<
"'" << endl;
118 pwaTrees[
i]->SetDirectory(pwaFile);
119 printSucc <<
"created tree '" << treeName <<
"' in file " <<
"'" << pwaFileName
131 const TLorentzVector& beamLv,
133 const TLorentzVector& piZero0,
134 const TLorentzVector& piZero1,
135 const TLorentzVector& piMinus,
138 const unsigned int nmbMassBins = 50,
139 const double massBinWidth = 50,
140 const double massRangeMin = 500,
141 const string& prodKinMomentaLeafName =
"prodKinMomenta",
142 const string& decayKinMomentaLeafName =
"decayKinMomenta",
143 const bool debug =
false)
146 const double mass = 1000 * XMass;
148 if ((mass < massRangeMin) or (mass > (massRangeMin + nmbMassBins * massBinWidth)))
150 const unsigned int bin = (
unsigned int) ((mass - massRangeMin) / massBinWidth);
151 if (not pwaTrees[bin]) {
152 printWarn <<
"null pointer for tree for mass bin [" << massRangeMin + bin * massBinWidth <<
", "
153 << massRangeMin + (bin + 1) * massBinWidth <<
"]" << endl;
158 printDebug <<
"filling tree for bin " << bin <<
" = ["
159 << massRangeMin + bin * massBinWidth <<
", "
160 << massRangeMin + (bin + 1) * massBinWidth <<
"] MeV/c^2" << endl;
163 static TClonesArray* prodKinMomenta =
new TClonesArray(
"TVector3");
164 static TClonesArray* decayKinMomenta =
new TClonesArray(
"TVector3");
167 TTree* outTree = pwaTrees[
bin];
168 if (outTree->SetBranchAddress(prodKinMomentaLeafName.c_str(), &prodKinMomenta) < 0) {
169 printWarn <<
"could not connect variable to branch '" << prodKinMomentaLeafName <<
"'. "
170 <<
"skipping." << endl;
173 if (outTree->SetBranchAddress(decayKinMomentaLeafName.c_str(), &decayKinMomenta) < 0) {
174 printWarn <<
"could not connect variable to branch '" << prodKinMomentaLeafName <<
"'. "
175 <<
"skipping." << endl;
180 prodKinMomenta->Clear ();
181 decayKinMomenta->Clear();
185 new ((*prodKinMomenta)[0]) TVector3(beamLv.Vect());
190 new ((*decayKinMomenta)[0]) TVector3(piZero0.Vect());
191 new ((*decayKinMomenta)[1]) TVector3(piZero1.Vect());
192 new ((*decayKinMomenta)[2]) TVector3(piMinus.Vect());
203 const string& dirName =
"./test",
204 const long int maxNmbEvents = -1,
205 const unsigned int nmbMassBins = 50,
206 const double massBinWidth = 40,
207 const double massRangeMin = 500,
208 const string& uDstTreeName =
"pwaDataTree",
209 const string& pwaTreeName =
"rootPwaEvtTree",
210 const long int treeCacheSize = 25000000,
211 const bool debug =
false)
213 const string prodKinPartNamesObjName =
"prodKinParticles";
214 const string prodKinMomentaLeafName =
"prodKinMomenta";
215 const string decayKinPartNamesObjName =
"decayKinParticles";
216 const string decayKinMomentaLeafName =
"decayKinMomenta";
221 printInfo <<
"reading uDST file(s) '" << inFileNamePattern <<
"'" << endl
222 <<
" writing " << nmbMassBins <<
" mass bins in mass interval "
223 <<
"[" << massRangeMin <<
", " << massRangeMin + nmbMassBins * massBinWidth <<
"] "
224 <<
"MeV/c^2 to '" << dirName <<
"'" << endl
225 <<
" reading uDST data from tree '" << uDstTreeName <<
"'" << endl
226 <<
" writing PWA data to tree '" << pwaTreeName <<
"'" << endl;
229 TChain uDstChain(uDstTreeName.c_str());
230 if (uDstChain.Add(inFileNamePattern.c_str()) < 1)
231 printWarn <<
"no events in uDST input file(s) '" << inFileNamePattern <<
"'" << endl;
232 const long int nmbEventsUdstChain = uDstChain.GetEntries();
233 uDstChain.GetListOfFiles()->ls();
237 TLorentzVector* photons[4] = {0, 0, 0, 0};
238 TLorentzVector* piMinus = 0;
239 TLorentzVector* beam = 0;
240 TLorentzVector* recoil = 0;
241 uDstChain.SetBranchAddress(
"gamma1", &(photons[0]));
242 uDstChain.SetBranchAddress(
"gamma2", &(photons[1]));
243 uDstChain.SetBranchAddress(
"gamma3", &(photons[2]));
244 uDstChain.SetBranchAddress(
"gamma4", &(photons[3]));
245 uDstChain.SetBranchAddress(
"pi_out", &piMinus);
246 uDstChain.SetBranchAddress(
"pi_in", &beam);
247 uDstChain.SetBranchAddress(
"proton", &recoil);
248 uDstChain.SetCacheSize(treeCacheSize);
249 uDstChain.AddBranchToCache(
"gamma1",
true);
250 uDstChain.AddBranchToCache(
"gamma2",
true);
251 uDstChain.AddBranchToCache(
"gamma3",
true);
252 uDstChain.AddBranchToCache(
"gamma4",
true);
253 uDstChain.AddBranchToCache(
"pi_out",
true);
254 uDstChain.AddBranchToCache(
"pi_in",
true);
255 uDstChain.AddBranchToCache(
"proton",
true);
256 uDstChain.StopCacheLearningPhase();
260 vector<TFile*> pwaDataFiles;
261 vector<TTree*> pwaDataTrees;
262 if (not
createMassBinFiles(pwaDataFiles, pwaDataTrees, dirName, nmbMassBins, massBinWidth,
263 massRangeMin, pwaTreeName)) {
264 printErr <<
"there were problems creating the mass bin directories/files. aborting." << endl;
267 printSucc <<
"created " << pwaDataFiles.size() <<
" directories/files" << endl;
271 TClonesArray prodKinPartNames (
"TObjString", 1);
272 TClonesArray decayKinPartNames(
"TObjString", 3);
275 new (prodKinPartNames [0]) TObjString(
"pi-");
276 new (decayKinPartNames[0]) TObjString(
"pi0");
277 new (decayKinPartNames[1]) TObjString(
"pi0");
278 new (decayKinPartNames[2]) TObjString(
"pi-");
281 for (
unsigned int i = 0;
i < pwaDataFiles.size(); ++
i) {
282 pwaDataFiles[
i]->cd();
283 prodKinPartNames.Write (prodKinPartNamesObjName.c_str (), TObject::kSingleKey);
284 decayKinPartNames.Write(decayKinPartNamesObjName.c_str(), TObject::kSingleKey);
286 printSucc <<
"wrote particle name arrays to all files. "
287 <<
"beam = 'pi-', decay = {'pi0', 'pi0', 'pi-'}." << endl;
292 TClonesArray* prodKinMomenta =
new TClonesArray(
"TVector3");
293 TClonesArray* decayKinMomenta =
new TClonesArray(
"TVector3");
294 const int splitLevel = 99;
295 const int bufSize = 256000;
296 for (
unsigned int i = 0;
i < pwaDataTrees.size(); ++
i) {
297 pwaDataTrees[
i]->Branch(prodKinMomentaLeafName.c_str(),
"TClonesArray", &prodKinMomenta,
298 bufSize, splitLevel);
299 pwaDataTrees[
i]->Branch(decayKinMomentaLeafName.c_str(),
"TClonesArray", &decayKinMomenta,
300 bufSize, splitLevel);
302 printSucc <<
"created branches for all trees" << endl;
306 const long int nmbEvents = ((maxNmbEvents > 0) ? maxNmbEvents : nmbEventsUdstChain);
307 printInfo <<
"writing events into mass bin files" << endl
308 <<
" looping over " << nmbEvents <<
" tree entries" << endl;
309 unsigned long int countEvWritten = 0;
311 for (
long int eventIndex = 0; eventIndex < nmbEvents; ++eventIndex) {
313 if ((uDstChain.LoadTree(eventIndex) < 0) or (uDstChain.GetEntry(eventIndex) == 0)) {
314 printWarn <<
"error reading event " << eventIndex <<
" from tree. skipping." << endl;
321 const TLorentzVector piZeros[2] = {*(photons[0]) + *(photons[1]), *(photons[2]) + *(photons[3])};
323 const TLorentzVector X = piZeros[0] + piZeros[1] + *piMinus;
325 const double t = (*beam - X) * (*beam - X);
326 const double tPrime = fabs(t) - fabs((X.M() * X.M() - beam->M() * beam->M())*(X.M() * X.M() - beam->M() * beam->M())
327 / (4 * (beam->Vect() * beam->Vect())));
329 if ((tPrime < 0.1) or (tPrime > 1.0))
332 const double fsEnergy = X.E() + recoil->E() - recoil->M();
333 const double scaleFactor = fsEnergy / beam->E();
334 const TLorentzVector beamScaled(beam->Vect() * scaleFactor, fsEnergy);
335 if (
writeEvent(pwaDataTrees, beamScaled, piZeros[0], piZeros[1], *piMinus,
336 X.M(), nmbMassBins, massBinWidth, massRangeMin,
337 prodKinMomentaLeafName, decayKinMomentaLeafName,
debug))
343 long unsigned int countTreeEvents = 0;
344 for (
unsigned int i = 0;
i < nmbMassBins; ++
i) {
345 pwaDataTrees[
i]->GetCurrentFile()->Write();
346 long unsigned int nmbEvents = pwaDataTrees[
i]->GetEntries();
347 printSucc <<
"written " << setw(10) << nmbEvents <<
" events to file " <<
"'"
348 << pwaDataTrees[
i]->GetCurrentFile()->GetName() <<
"'" << endl;
349 countTreeEvents += nmbEvents;
350 pwaDataTrees[
i]->GetCurrentFile()->Close();
352 pwaDataFiles.clear();
353 pwaDataTrees.clear();
355 printInfo <<
"wrote " << min(countEvWritten, countTreeEvents)
356 <<
" out of " << nmbEvents <<
" events" <<endl;
358 printInfo <<
"this job consumed: ";