42 #include "TLorentzVector.h"
44 #include "TClonesArray.h"
46 #include "libconfig.h++"
48 #include "reportingUtils.hpp"
59 using namespace libconfig;
67 cerr <<
"usage:" << endl
69 <<
" -n # [-a # -m # -M # -B # -s #] -o <file> -w <file> -k <path> -i <file> -r <file>" << endl
71 <<
" -n # (max) number of events to generate (default: 100)" << endl
72 <<
" -a # (max) number of attempts to do (default: infinity)" << endl
73 <<
" -m # maxWeight" << endl
74 <<
" -o <file> ROOT output file (if not specified, generated automatically)" << endl
75 <<
" -w <file> wavelist file (contains production amplitudes)" << endl
76 <<
" -w <file.root> to use TFitBin tree as input" << endl
77 <<
" -c <0/1> if 1 a comgeant eventfile (.fort.26) is written with same naming as the root file (default 1)" << endl
78 <<
" -k <path> path to keyfile directory (all keyfiles have to be there)" << endl
79 <<
" -i <file> integral file" << endl
80 <<
" -r <file> reaction config file" << endl
81 <<
" -s # set seed " << endl
82 <<
" -M # lower boundary of mass range in MeV (overwrites values from config file) " << endl
83 <<
" -B # width of mass bin in MeV" << endl
89 int main(
int argc,
char** argv)
92 unsigned int nevents = 100;
93 unsigned int max_attempts = 0;
94 string output_file =
"";
95 string output_evt =
"";
96 string output_wht =
"";
97 string output_comgeant =
"";
98 string integrals_file;
100 string wavelist_file;
101 string path_to_keyfiles =
"./";
103 double maxWeight = 0;
106 int massBinWidth = 0;
107 bool overwriteMass =
false;
108 bool writeComGeantout =
false;
111 while ((c = getopt(argc, argv,
"n:a:o:w:k:i:r:m:s:M:B:h:c")) != -1) {
114 nevents =
atoi(optarg);
117 max_attempts =
atoi(optarg);
123 output_file = optarg;
126 wavelist_file = optarg;
129 integrals_file = optarg;
133 path_to_keyfiles = optarg;
136 reactionFile = optarg;
139 maxWeight = atof(optarg);
142 writeComGeantout =
true;
145 massLower =
atoi(optarg);
149 massBinWidth =
atoi(optarg);
166 reactConf.readFile(reactionFile.c_str());
171 double weight, impweight;
172 TClonesArray*
p =
new TClonesArray(
"TLorentzVector");
179 double Mom = reactConf.lookup(
"beam.momentum");
180 double MomSigma = reactConf.lookup(
"beam.sigma_momentum");
181 double BeamPartMass = 0.13957018;
182 if(reactConf.exists(
"beam.mass")){
183 BeamPartMass = reactConf.lookup(
"beam.mass");
185 double DxDz = reactConf.lookup(
"beam.DxDz");
186 double DxDzSigma = reactConf.lookup(
"beam.sigma_DxDz");
187 double DyDz = reactConf.lookup(
"beam.DyDz");
188 double DyDzSigma = reactConf.lookup(
"beam.sigma_DyDz");
190 double targetz = reactConf.lookup(
"target.pos.z");
191 double targetd = reactConf.lookup(
"target.length");
192 double targetr = reactConf.lookup(
"target.radius");
193 double mrecoil = reactConf.lookup(
"target.mrecoil");
195 double tprime_min(0.);
196 double tprime_max(numeric_limits<double>::max());
197 reactConf.lookupValue(
"finalstate.t_min", tprime_min);
198 reactConf.lookupValue(
"finalstate.t_max", tprime_max);
200 double mmin = reactConf.lookup(
"finalstate.mass_min");
201 double mmax = reactConf.lookup(
"finalstate.mass_max");
203 mmin = massLower/1000.0;
204 mmax = (massLower+massBinWidth)/1000.0;
207 double* tslope = NULL;
208 double* inv_m = NULL;
210 if(reactConf.lookup(
"finalstate.t_slope").isArray()) {
211 ntslope = reactConf.lookup(
"finalstate.t_slope").getLength();
212 if(reactConf.lookup(
"finalstate.inv_m").getLength() != ntslope) {
213 cout <<
" Error: please check number of t' values and the corresponding invariant masses in the Configuration File! " << endl;
216 tslope =
new double[ntslope];
217 inv_m =
new double[ntslope];
218 cout <<
" found array of t' slopes. Reading " << ntslope <<
" of values ";
219 for(
int i = 0;
i < ntslope;
i++) {
220 tslope[
i] = reactConf.lookup(
"finalstate.t_slope")[
i];
221 inv_m[
i] = reactConf.lookup(
"finalstate.inv_m")[
i];
224 cout <<
" done. " << endl;
226 tslope =
new double[1];
227 tslope[0] = reactConf.lookup(
"finalstate.t_slope");
230 double binCenter = 500 * (mmin + mmax);
234 string histfilename_primvertex =
"";
235 if(reactConf.lookupValue(
"primvertex.histfilename", histfilename_primvertex)) {
237 histfilename_primvertex,
242 if (!primaryVtxGen->
check()) {
243 cerr <<
" Error: histogram filename with beam properties not loaded! " << endl;
244 delete primaryVtxGen;
245 primaryVtxGen = NULL;
249 if(!reactConf.lookupValue(
"beam.charge",qbeam)) {
253 if (output_file ==
"") {
254 stringstream _filename;
255 _filename << massLower <<
"." << massLower+massBinWidth <<
".genbod.root";
256 cout <<
" created output filename: " << _filename.str() << endl;
257 output_file = _filename.str();
259 output_evt = output_file;
260 output_evt.replace(output_evt.find(
".root"),5,
".evt");
261 output_wht = output_file;
262 output_wht.replace(output_wht.find(
".root"),5,
".wht");
263 output_comgeant = output_file;
264 output_comgeant.erase(output_comgeant.find(
".root"),5);
265 output_comgeant.append(
".fort.26");
268 TFile* outfile = TFile::Open(output_file.c_str(),
"RECREATE");
269 TH1D* hWeights =
new TH1D(
"hWeights",
"PW Weights",100,0,100);
270 TTree* outtree =
new TTree(
"pwevents",
"pwevents");
272 outtree->Branch(
"weight",&weight,
"weight/d");
273 outtree->Branch(
"impweight",&impweight,
"impweight/d");
274 outtree->Branch(
"p",&p);
275 outtree->Branch(
"beam",&beam);
276 outtree->Branch(
"vertex", &vertex);
277 outtree->Branch(
"q",&q);
278 outtree->Branch(
"qbeam",&qbeam,
"qbeam/I");
279 outtree->Branch(
"tprime", &tprime);
284 cerr <<
"Seed=" << seed << endl;
286 difPS.
SetBeam(Mom,MomSigma,DxDz,DxDzSigma,DyDz,DyDzSigma);
287 difPS.
SetTarget(targetz,targetd,targetr,mrecoil);
291 if(tprime_min >= 0.) {
294 cout <<
" Error: tprime_min must be positive " << tprime_min << endl;
296 if(tprime_max >= 0.) {
303 if(reactConf.lookupValue(
"importance.mass",impMass) &&
304 reactConf.lookupValue(
"importance.width",impWidth))
306 int act = reactConf.lookup(
"importance.active");
312 const Setting&
root = reactConf.getRoot();
313 const Setting& fspart = root[
"finalstate"][
"particles"];
314 int nparticles = fspart.getLength();
316 for(
int ifs=0; ifs<nparticles; ++ifs) {
317 const Setting &part = fspart[ifs];
319 part.lookupValue(
"g3id",
id);
321 part.lookupValue(
"charge",myq);
323 part.lookupValue(
"mass",m);
329 map<string, breitWignerProductionAmp*> bwAmps;
330 if(reactConf.exists(
"resonances")) {
331 const Setting &bws = root[
"resonances"][
"breitwigners"];
333 int nbw = bws.getLength();
334 printInfo <<
"found " << nbw <<
" Breit-Wigners in config" << endl;
336 for(
int ibw = 0; ibw < nbw; ++ibw) {
337 const Setting &bw = bws[ibw];
341 bw.lookupValue(
"jpcme", jpcme);
342 bw.lookupValue(
"mass", mass);
343 bw.lookupValue(
"width", width);
344 bw.lookupValue(
"coupling_Re", cRe);
345 bw.lookupValue(
"coupling_Im", cIm);
346 complex<double> coupl(cRe, cIm);
347 cout <<
" JPCME = " << jpcme <<
", mass = " << mass <<
" GeV/c^2, "
348 <<
"width = " << width <<
" GeV/c^2, coupling = " << coupl << endl;
354 if(wavelist_file.find(
".root") != string::npos) {
355 cerr <<
"Using TFitBin as input!" << endl;
356 TFile* fitresults = TFile::Open(wavelist_file.c_str(),
"READ");
358 if(!fitresults || fitresults->IsZombie()) {
359 cerr <<
"Cannot open start fit results file " << wavelist_file << endl;
364 fitresults->GetObject(
"pwa", tree);
366 cerr <<
"Cannot find fitbin tree '" <<
"pwa" <<
"' " << endl;
369 tree->SetBranchAddress(
"fitbin", &Bin);
371 unsigned int iBest = 0;
373 for(
unsigned int i = 0;
i < tree->GetEntriesFast(); ++
i) {
375 if(fabs(binCenter - Bin->mass()) <= fabs(binCenter - mBest)) {
380 cerr <<
"Using data from Mass bin m=" << mBest << endl;
381 tree->GetEntry(iBest);
383 string tmpname = tmpnam(NULL);
384 ofstream tmpfile(tmpname.c_str());
385 Bin->printAmpsGenPW(tmpfile);
387 wavelist_file=tmpname;
392 ifstream wavefile(wavelist_file.c_str());
393 while(wavefile.good()) {
398 wavefile >> wavename >> RE >> IM;
400 if(wavename.Contains(
"flat") || wavename.Length()<2) {
403 if(RE == 0 && IM == 0) {
407 if(wavename(0) ==
'V') {
409 rank = 2 *
atoi(wavename(1,1).Data());
411 refl = wavename(9)==
'+' ? 0 : 1;
412 wavename = wavename(3, wavename.Length());
415 TString jpcme = wavename(2,5);
417 wavename.ReplaceAll(
".amp",
".key");
418 wavename.Prepend(path_to_keyfiles.c_str());
420 complex<double> amp(RE, IM);
421 cerr << wavename <<
" " << amp <<
" r=" << rank/2
422 <<
" eps=" << refl <<
" qn=" << jpcme << endl;
423 wavefile.ignore(256,
'\n');
426 if(bwAmps[jpcme.Data()] != NULL) {
427 pamp = bwAmps[jpcme.Data()];
428 cerr <<
"Using BW for " << jpcme << endl;
430 weighter.
addWave(wavename.Data(), pamp, amp, rank+refl);
433 weighter.
addWave(wavename.Data(), pamp, complex<double>(1, 0), rank+refl);
439 ifstream intfile(integrals_file.c_str());
440 while(intfile.good()) {
443 intfile >> filename >>
mass;
445 intfile.ignore(256,
'\n');
450 double maxweight = -1;
451 unsigned int attempts = 0;
454 unsigned int tenpercent = (
unsigned int)(nevents / 10);
457 ofstream evtout(output_evt.c_str());
459 if(writeComGeantout) {
460 evtgeant.open(output_comgeant.c_str());
462 ofstream evtwht(output_wht.c_str());
463 evtwht << setprecision(10);
465 while(i < nevents && ((max_attempts > 0 && attempts < max_attempts) || max_attempts == 0))
473 if (writeComGeantout) {
474 difPS.
event(str, evtgeant);
480 for(
int ip = 0; ip < nparticles; ++ip){
481 new ((*p)[ip]) TLorentzVector(*difPS.
GetDecay(ip));
494 evtwht << impweight << endl;
498 weight = weighter.
weight(e);
499 if(weight > maxweight) {
502 hWeights->Fill(weight);
505 cout << weight << endl;
507 if(gRandom->Uniform() > weight / maxWeight) {
516 if(i > 0 && (i % tenpercent == 0)) {
517 cerr <<
"\x1B[2K" <<
"\x1B[0E" <<
"[" << (double)i/(
double)nevents*100. <<
"%]";
525 cerr <<
"Maxweight: " << maxweight << endl;
526 cerr <<
"Attempts: " << attempts << endl;
527 cerr <<
"Created Events: " << i << endl;
528 cerr <<
"Efficiency: " << (double)i / (
double)attempts << endl;
537 if(writeComGeantout) {