Belle II Software  release-06-01-15
Treps3B.cc
1 // -*- C++ -*-
2 //
3 // Package: <package>
4 // Module: Treps3B
5 //
6 // Description: <two-line class summary>
7 // Two-photon Monte Carlo Generator TREPS Ver.3 (translated and modified
8 // from TREPS2 of FORTRAN version
9 // For BASF Application
10 // Implimentation:
11 // <Notes on implimentation>
12 //
13 // Author: Sadaharu Uehara
14 // Created: Jul.16 1997
15 // $Id$
16 //
17 // Revision history
18 //
19 //
20 // Modified: To use RandFlat instead of bare HepRandom
21 // 9-MAY-2000 S.Uehara
22 // RETURNED TO THE OLD RANDOM-NUMBER GENERATOR 14-MAY-2000
23 // $Log$
24 
25 
26 
27 // system include files
28 #include <iostream>
29 #include <iomanip>
30 #include <fstream>
31 #include <string.h>
32 #include <math.h>
33 #include <TVector3.h>
34 #include <TLorentzVector.h>
35 #include <TRandom.h>
36 #include <stdlib.h>
37 
38 // user include files
39 #include <generators/treps/Treps3B.h>
40 
41 #include <framework/logging/Logger.h>
42 
43 namespace Belle2 {
50  //
51  // constructor
52  //
53  TrepsB::TrepsB(void) :
54  sutool(), w(0.), ntot(0), nsave(0), ebeam(0.), q2max(0.), cost_cut(0.), pt_cut(0.), cost_flag(0), pt_flag(0),
55  qzmin(0.), qptmin(0.), parti(nullptr), parts(nullptr), ephi(0.), etheta(0.), s(0.), imode(0), dmin(0.), dmax(0.),
56  ffmax(0.), rs(0.), vmax(0.), pppp(nullptr), wf(0.), inmode(0), wtcount(0), totalCrossSectionForMC(0.), ndecay(0),
57  pmodel(0), fmodel(0), ievent(0), treh1(nullptr), treh2(nullptr), treh3(nullptr), treh4(nullptr), treh5(nullptr),
58  treh6(nullptr), npart(0), partgen(nullptr), zdis(nullptr), zpdis(nullptr), zsdis(nullptr)
59  {
60  for (int i = 0; i < 5000; ++i) {
61  wtcond[i] = 0.;
62  wthead[i] = 0;
63  }
64  }
65 
66  //
67  // member functions
68  //
69  void TrepsB::initp(void)
70  // read parameter-input file and load the parameters
71  {
72 
73  B2INFO("Treps: Parameters are read from the file, " << parameterFile);
74  B2INFO("Treps: W list is read from the file, " << wlistFile);
75  B2INFO("Treps: Differential cross section list is read from the file, " << diffcrosssectionFile);
76 
77  partgen = new Part_gen [30];
78  parti = new Part_cont [10];
79  parts = new Part_cont [20];
80  pppp = new TLorentzVector [30];
81 
82  std::ifstream infile(parameterFile);
83  if (!infile) {
84  B2FATAL("Can't open input file: " << parameterFile);
85  } else {
86  // read particle properties
87  infile >> ndecay >> pmodel >> fmodel ; //Physics model pmodel, Form factor model added
88 
89  if (ndecay < 2) {
90  B2FATAL("decay particles must be >=2 : " << ndecay) ;
91  exit(1);
92  }
93 
94  int ndecs = 0 ;
95 
96  int icodex, ndecx ;
97  double pmassx, pchargx, pwidthx ;
98 
99  for (int i = 0 ; i < ndecay ; i++) {
100  sutool.nextline(infile);
101 
102  infile >> icodex >> pmassx >> pchargx >> ndecx >> pwidthx ;
103 
104  parti[i] = Part_cont(icodex, pmassx, pchargx, ndecx, pwidthx);
105 
106  if (ndecx >= 2) ndecs += ndecx ;
107  }
108 
109  for (int j = 0 ; j < ndecs ; j++) {
110  sutool.nextline(infile);
111 
112  infile >> icodex >> pmassx >> pchargx ;
113  Part_cont _pp = Part_cont(icodex, pmassx, pchargx);
114  parts[j] = _pp ;
115  }
116 
117  // Boost of the total system
118  double tsws4 = pfeb.Mag() + pfpb.Mag() ;
119  TVector3 tsws = TVector3(-(pfeb + pfpb));
120  double emsys = tsws4 * tsws4 - tsws.Mag2() ;
121 
122  peb = TLorentzVector(pfeb, pfeb.Mag());
123 
124  ppb = TLorentzVector(pfpb, pfpb.Mag());
125 
126  TLorentzVector ppp = peb;
127  ppp.Boost(tsws.x() / tsws4, tsws.y() / tsws4, tsws.z() / tsws4);
128  ephi = ppp.Phi();
129  etheta = ppp.Theta();
130 
131  tsws = -tsws ;
132  tswsb = (1. / tsws4) * tsws;
133 
134  // output input parameters
135  //*********************************
136  B2INFO("") ;
137  B2INFO("****** Treps3 Input Parameters in Initialization ******");
138  B2INFO(" Beam energy in e+e- cm system (GeV): " << ebeam);
139  B2INFO(" e- lab. momentum: " << pfeb.x() << " " << pfeb.y() << " " << pfeb.z());
140  B2INFO(" e+ lab. momentum: " << pfpb.x() << " " << pfpb.y() << " " << pfpb.z());
141  B2INFO(" Q2 max (GeV2): " << q2max);
142  B2INFO(" Save-condition (|cos(theta_cm)|): " << cost_cut << ", "
143  << cost_flag);
144  B2INFO(" (pt (GeV/c)): " << pt_cut << ", "
145  << pt_flag);
146  B2INFO(" Number of decay particles: " << ndecay);
147  B2INFO(" Physics model: " << pmodel);
148  B2INFO(" Form-factor model: " << fmodel);
149 
150 
151  B2INFO(" P/S code mass charge decs width");
152 
153  for (int i = 0 ; i < ndecay ; i++) {
154  B2INFO(" P " << std::setw(6) << parti[i].icode
155  << std::setw(11) << std::setprecision(4) << parti[i].pmass
156  << std::setw(6) << std::setprecision(2) << parti[i].pcharg
157  << std::setw(4) << parti[i].ndec
158  << std::setw(11) << std::setprecision(4) << parti[i].pwidth
159  );
160  }
161  for (int i = 0 ; i < ndecs ; i++) {
162  B2INFO(" S " << std::setw(6) << parts[i].icode
163  << std::setw(11) << std::setprecision(4) << parts[i].pmass
164  << std::setw(6) << std::setprecision(2) << parts[i].pcharg);
165  }
166  B2INFO("*******************************************************");
167  //*********************************
168 
169  if (abs(emsys - 4 * ebeam * ebeam) > 0.001) {
170  B2FATAL(" Wrong beam fractional momenta ");
171  exit(1) ;
172  }
173 
174  // other impotant variables
175  s = 4.*ebeam * ebeam ;
176  ntot = 0 ;
177  nsave = 0;
178  }
179 
180  }
181 
182  void TrepsB::create_hist(void)
183  {
184  treh1 = new TH1F("PZSUMCM", "PZSUMCM", 100, -10., 10.);
185  treh2 = new TH1F("PTSUMCM", "PTSUMCM", 100, 0., 1.);
186  treh3 = new TH1F("EALLCM", "EALLCM", 100, 0., 20.);
187  treh4 = new TH1F("PZSUMLAB", "PZSUMLAB", 100, -10., 10.);
188  treh5 = new TH1F("PTSUMLAB", "PTSUMLAB", 100, 0., 1.);
189  treh6 = new TH1F("WFINAL", "WFINAL", 100, 0., 5.);
190 
191  zdis = new TH1F("kin3_z", "kin3_z", 40, -1., 1.);
192  zpdis = new TH1F("kin3_zp", "kin3_zp", 40, -1., 1.);
193  zsdis = new TH1F("kin3_zs", "kin3_zs", 40, -1., 1.);
194 
195  }
196 
197  void TrepsB::wtable()
198  {
199  totalCrossSectionForMC = 0.;
200 
201  // Load Differential Cross Section table
202  std::ifstream infile(diffcrosssectionFile);
203  if (!infile) {
204  B2FATAL("Can't open W-list input file") ;
205  } else {
206  double i_w; // W [GeV]
207  double diffCrossSection; // Number of events for given W
208 
209  double previousW = 0.;
210  double previousDCS = 0.; // Diff(erential) Cross Section
211  while (infile >> i_w >> diffCrossSection) {
212  if (i_w > 9000. || i_w < 0.) continue;
213  diffCrossSectionOfW[i_w] = diffCrossSection;
214 
215  // Calculate total cross section up to the bin.
216  // This will be used for importance sampling. NOT CORRECT cross section
217  if (diffCrossSection > previousDCS and previousDCS != 0) {
218  // If current diffCrossSection is higher than previous and not first time, use diffCrossSection
219  totalCrossSectionForMC += (i_w - previousW) * diffCrossSection * 1.01; // For safety, 1 % higher value is set
220  } else {
221  // If previous diffCrossSection is higher than current or first time, use previousDCS
222  totalCrossSectionForMC += (i_w - previousW) * previousDCS * 1.01;// For safety, 1 % higher value is set
223  }
224  // Store current cross section with w
225  WOfCrossSectionForMC[totalCrossSectionForMC] = i_w;
226 
227  previousW = i_w;
228  previousDCS = diffCrossSection;
229  }
230 
231  B2DEBUG(20, " wtable loaded");
232  }
233  }
234 
235  double TrepsB::wtable(int mode)
236  {
237  double prew = 0.;
238  if (mode == 0) {
239 
240  // initialization and load table
241 
242  for (int i = 0 ; i < 5000 ; i++) {
243  wthead[i] = 999999999;
244  wtcond[i] = 0.0;
245  }
246 
247  B2DEBUG(20, " wtable mode=0 initialized");
248 
249  // Load Wlist_table
250 
251  std::ifstream infile(wlistFile);
252  if (!infile) {
253  B2FATAL("Can't open W-list input file") ;
254  } else {
255  double w1;
256  int n1;
257  int hpoint, nwpoint;
258  int inmodein;
259 
260  hpoint = 1;
261  nwpoint = 0;
262 
263  infile >> inmodein;
264  inmode = inmodein;
265 
266  while (!infile.eof() && inmode == 0) {
267  sutool.nextline(infile);
268  infile >> w1 >> n1 ;
269  if (w1 > 9000. || w1 < 0.) continue;
270 
271  if (nwpoint == 0) wthead[0] = 1;
272  wtcond[nwpoint] = w1;
273  nwpoint++ ;
274  hpoint += n1;
275  B2DEBUG(20, w1 << " GeV " << n1 << " events " << hpoint - 1 << "events in total");
276  wthead[nwpoint] = hpoint;
277  }
278  while (!infile.eof() && (inmode == 1 || inmode == 2)) {
279  sutool.nextline(infile);
280  infile >> w1 >> n1 ;
281  if (w1 > 9000. || w1 < 0.) continue;
282  wf = w1;
283  w = (double)wf;
284  updateW();
285  if (inmode == 1)
286  B2INFO(w << " " << twlumi() << " //W(GeV) and Two-photon lumi. func.(wide)(1/GeV)");
287  else
288  B2INFO(w << " " << twlumi_n() << " //W(GeV) and Two-photon lumi. func.(narrow)(nb/keV/(2J+1))");
289 
290  }
291 
292  B2DEBUG(20, wthead[0] << " " << wtcond[0]);
293  B2DEBUG(20, " wtable mode=0 loaded");
294  }
295  return 0.0 ;
296  } else if (mode == 1) {
297  // Get W
298  int i = 0;
299 
300  do {
301  if (wtcount >= wthead[i]) prew = wtcond[i];
302  i++;
303  } while (wthead[i] < 999999999);
304 
305 
306  return prew;
307  } else {
308  B2FATAL("Undefined mode for wtable. Can be 1 or 0. Called with " << mode) ;
309  }
310  }
311 
312 
313 
314  void TrepsB::setW(double ww)
315  {
316  // set W parameter
317  w = ww;
318  updateW();
319  }
320 
321 
322  void TrepsB::updateW(void)
323  {
324  if (q2max < 0.0) q2max = s - w * w - 2.0 * me * w ;
325  rs = w * w / s ;
326  double zmax = 1.0 - me / ebeam ;
327  double ymin = rs / zmax ;
328  dmin = ymin - zmax ;
329  dmax = -dmin ;
330  // added by S.U on Sep.29,1997
331  imode = 0;
332 
333  double xxx = tpgetd(0, rs, dmin, dmax, q2max);
334  B2DEBUG(20, "Local variable xxx=" << xxx << " created but not used");
335  tpgetz(0);
336 
337  B2DEBUG(20, "In Treps, W has been set to be " << std::setprecision(5) <<
338  w << " GeV");
339  }
340 
341  double TrepsB::twlumi()
342  {
343  // calculate and return two-photon luminosity function
344  imode = 1;
345  double xxx = simpsn1(dmin, dmax, 10000);
346  return xxx * w * 0.5 / ebeam / ebeam ;
347  }
348 
349  double TrepsB::twlumi_n()
350  {
351  // calculate and return two-photon luminosity function
352  // for very narrow resonance
353  return twlumi() * twopi * twopi / w / w * 0.38938 ;
354  }
355 
356  double TrepsB::tpgetd(int mode, double _rs, double _dmin, double _dmax,
357  double _q2max)
358  {
359 
360  if (mode == 0) {
361  // calc mode
362  ffmax = 0. ;
363  int n = 10000 ;
364  for (int i = 1; i <= n ; i++) {
365  double d = _dmin + (_dmax - _dmin) / (double)n * (double)i;
366  double r = (2.0 + d * d / _rs + sqrt(pow((2.0 + d * d / _rs), 2) - 4.0)) * 0.5 ;
367  if (d < 0.0)
368  r = (2.0 + d * d / _rs - sqrt(pow((2.0 + d * d / _rs), 2) - 4.0)) * 0.5 ;
369  double ff = tpxint(r, _rs, _q2max) / (0.5 * sqrt(_rs / r) * (1.0 + 1.0 / r));
370  if (ff > ffmax) ffmax = ff ;
371  }
372  return 0.0;
373  } else {
374  // Generate mode
375  double d, ff;
376  do {
377  d = _dmin + (_dmax - _dmin) * gRandom->Uniform();
378  double r;
379  if (d > 0.0) {
380  r = (2. + d * d / _rs + sqrt((2. + d * d / _rs) * (2. + d * d / _rs) - 4.)) * 0.5 ;
381  } else {
382  r = (2. + d * d / _rs - sqrt((2. + d * d / _rs) * (2. + d * d / _rs) - 4.)) * 0.5 ;
383  }
384  ff = tpxint(r, _rs, _q2max) / (0.5 * sqrt(_rs / r) * (1. + 1. / r));
385  } while (gRandom->Uniform()*ffmax > ff);
386  return d;
387  }
388  }
389 
390  double TrepsB::tpgetz(int mode)
391  {
392  double z;
393 
394  if (mode == 0) {
395  vmax = 0.0 ;
396  // max val. search
397  for (int i = -1000 ; i <= 1000 ; i++) {
398  z = (double)i * 0.001 ;
399  double v = tpangd(z, w);
400  if (v > vmax) vmax = v;
401  }
402  } else {
403  do { z = (gRandom->Uniform() - 0.5) * 2. ; }
404  while (vmax * gRandom->Uniform() >= tpangd(z, w));
405  }
406 
407  return z;
408  }
409 
410  int TrepsB::event_gen(int iev)
411  {
412  // generates one event
413  B2DEBUG(20, "W = " << w);
414  imode = 0 ;
415  int npoint;
416 
417  do {
418  double d = tpgetd(1, rs, dmin, dmax, q2max);
419  double r ;
420  if (d > 0.0) {
421  r = (2.0 + d * d / rs + sqrt(pow((2.0 + d * d / rs), 2) - 4.0)) * 0.5;
422  } else {
423  r = (2.0 + d * d / rs - sqrt(pow((2.0 + d * d / rs), 2) - 4.0)) * 0.5;
424  }
425 
426  double z = sqrt(rs / r);
427  double y = sqrt(rs * r);
428 
429  double q2p, q2m, q2min, sf ;
430 
431  do {
432  do {
433  q2p = tpgetq(s, z, q2max) ;
434  q2m = tpgetq(s, z, q2max) ;
435  q2min = me * me * pow(w, 4) / s / (s - w * w);
436  sf = ((s * s + (s - w * w) * (s - w * w)) / 2. / s / s - (s - w * w) * q2min / s / q2p)
437  * ((s * s + (s - w * w) * (s - w * w)) / 2. / s / s - (s - w * w) * q2min / s / q2m);
438  } while (gRandom->Uniform() > sf);
439  } while (gRandom->Uniform() > tpform(q2p, w)*tpform(q2m, w));
440 
441  int ivirt = 0;
442 
443  TVector3 tv1, tv2, tv3, tv4;
444 
445  if (q2m < q2zero || q2p < q2zero) {
446  // single tag approx.
447  double q2;
448  if (q2m > q2p) {
449  q2 = q2m + q2p;
450  ivirt = -1 ;
451  } else {
452  q2 = q2p + q2m ;
453  ivirt = 1 ;
454  z = y ;
455  }
456 
457  if (q2m < q2zero && q2p < q2zero) {
458  // real-real approx.
459  q2 = 0.0 ;
460  ivirt = 0 ;
461  }
462 
463  double rk2 = z * ebeam ;
464  double rk1 = 0.25 / rk2 * (w * w + q2 - rk2 * q2 / ebeam);
465  double rk13 = q2 / 2.0 / ebeam + rk1 ;
466  double qqqq = rk1 * rk1 - rk13 * rk13 + q2;
467  if (ivirt == 0) qqqq = 0.0 ;
468 
469  if (qqqq < 0.0) continue ;
470 
471  double rk11 = -sqrt(qqqq);
472  tv1 = TVector3(-rk11, 0., sqrt(ebeam * ebeam - me * me) - rk13);
473  tv2 = TVector3(0., 0., -(sqrt(ebeam * ebeam - me * me) - rk2));
474  tv3 = TVector3(-rk11, 0.,
475  -(sqrt(ebeam * ebeam - me * me) - rk13));
476  tv4 = TVector3(0., 0., sqrt(ebeam * ebeam - me * me) - rk2);
477 
478  } else {
479  // double-tag case
480  ivirt = -1 ;
481  if (q2p > q2m) {
482  ivirt = 1;
483  double qtmp = q2p ;
484  q2p = q2m;
485  q2m = qtmp ;
486  z = y ;
487  }
488  double rk2 = z * ebeam ;
489  double aaaa = 4.*rk2 + q2p / ebeam ;
490  double bbbb = w * w + q2m + q2p - q2m * q2p / 2. / ebeam / ebeam - q2m * rk2 / ebeam ;
491  double cccc = 4.*q2m * q2p * (1. - rk2 / ebeam - q2p / 4. / ebeam / ebeam);
492  double rphi = gRandom->Uniform() * twopi;
493  double rsrs = 1. + aaaa / cccc / pow(cos(rphi), 2) *
494  (4.*aaaa * ebeam * ebeam - aaaa * q2m - 4.*bbbb * ebeam);
495  if (rsrs < 0.0) continue ;
496  double rk1 = (2.*aaaa * bbbb + cccc * pow(cos(rphi), 2) / ebeam *
497  (sqrt(rsrs) - 1.)) / 2. / aaaa / aaaa;
498  if ((bbbb - aaaa * rk1)*cos(rphi) > 0.0)
499  rk1 = (2.*aaaa * bbbb + cccc * pow(cos(rphi), 2) / ebeam *
500  (-sqrt(rsrs) - 1.)) / 2. / aaaa / aaaa;
501  if ((bbbb - aaaa * rk1)*cos(rphi) > 0.0) continue ;
502 
503  tv1 = TVector3(sqrt(q2m * (1. - rk1 / ebeam - q2m / 4. / ebeam / ebeam)),
504  0.,
505  sqrt(ebeam * ebeam - me * me) - (q2m / 2. / ebeam + rk1));
506  tv2 = TVector3(sqrt(q2p * (1. - rk2 / ebeam - q2p / 4. / ebeam / ebeam)) * cos(rphi),
507  sqrt(q2p * (1. - rk2 / ebeam - q2p / 4. / ebeam / ebeam)) * sin(rphi),
508  - (sqrt(ebeam * ebeam - me * me) - (q2p / 2. / ebeam + rk2)));
509  tv3 = TVector3(sqrt(q2m * (1. - rk1 / ebeam - q2m / 4. / ebeam / ebeam)),
510  0.,
511  -(sqrt(ebeam * ebeam - me * me) - (q2m / 2. / ebeam + rk1)));
512  tv4 = TVector3(sqrt(q2p * (1. - rk2 / ebeam - q2p / 4. / ebeam / ebeam)) * cos(rphi),
513  sqrt(q2p * (1. - rk2 / ebeam - q2p / 4. / ebeam / ebeam)) * sin(rphi),
514  sqrt(ebeam * ebeam - me * me) - (q2p / 2. / ebeam + rk2));
515 
516  }
517 
518  if (gRandom->Uniform() > 0.5) {
519  pe = TLorentzVector(tv1, sqrt(tv1.Mag2() + me * me));
520  pp = TLorentzVector(tv2, sqrt(tv2.Mag2() + me * me));
521  } else {
522  pp = TLorentzVector(tv3, sqrt(tv3.Mag2() + me * me));
523  pe = TLorentzVector(tv4, sqrt(tv4.Mag2() + me * me));
524  }
525  // two-photon system generated. Rotates it for general directions
526  double dphi = gRandom->Uniform() * twopi ;
527  pe.RotateZ(dphi);
528  pp.RotateZ(dphi);
529 
530  TVector3 ws3 = -(pe + pp).Vect();
531  TLorentzVector ws = TLorentzVector(ws3, sqrt(ws3.Mag2() + w * w));
532 
533  TVector3 wsb = (1. / ws.T()) * ws3 ;
534 
535  // decide of 4-momenta of particles in the two-photon system
536 
537  // particle masses
538  tpgetm(parti, ndecay);
539 
540  // angular distribution
541  if (ndecay == 2) {
542  // two-body
543  double zz = tpgetz(1);
544  double phi = twopi * gRandom->Uniform();
545  int jcode;
546  double m1 = parti[0].pmassp;
547  double m2 = parti[1].pmassp;
548  double pm = sutool.p2bdy(w, m1, m2, jcode);
549  if (jcode == 0) continue ;
550  pppp[0] = TLorentzVector(pm * sqrt(1. - zz * zz) * cos(phi),
551  pm * sqrt(1. - zz * zz) * sin(phi),
552  pm * zz, sqrt(pm * pm + m1 * m1));
553 
554  pppp[1] = TLorentzVector(-(pppp[0].Vect()),
555  sqrt(pm * pm + m2 * m2));
556 
557  pppp[0].Boost(wsb);
558  pppp[1].Boost(wsb);
559 
560  } else {
561  // more than two body
562  double* massa = new double [ndecay];
563  for (int i = 0; i < ndecay ; i++) massa[i] = parti[i].pmassp ;
564 
565  int jcode = sutool.pdecy(w, massa , wsb, pppp, ndecay);
566  if (jcode == 0) continue;
567 
568  delete [] massa ;
569  }
570  // more decay
571  npoint = 0;
572  int nlist = 0;
573  int jcode = 0;
574 
575  for (int i = 1 ; i <= ndecay ; i++) {
576  if (parti[i - 1].ndec <= 1) {
577  npoint++ ;
578  partgen[npoint - 1].part_prop = parti[i - 1];
579  partgen[npoint - 1].p = pppp[i - 1];
580  jcode = 1;
581  } else {
582  nlist++ ;
583  npoint++ ;
584 
585  double* massa = new double [ parti[i - 1].ndec ];
586  for (int j = 0; j < parti[i - 1].ndec ; j++)
587  massa[j] = parts[nlist - 1 + j].pmass ;
588  TVector3 pppb = (1. / pppp[i - 1].T()) * pppp[i - 1].Vect();
589  TLorentzVector* ppptmp = new TLorentzVector [ parti[i - 1].ndec ];
590 
591  jcode = sutool.pdecy(parti[i - 1].pmassp, massa, pppb, ppptmp,
592  parti[i - 1].ndec);
593  for (int j = 0; j < parti[i - 1].ndec ; j++)
594  partgen[npoint - 1 + j].p = ppptmp[j] ;
595 
596  delete [] ppptmp ;
597  delete [] massa ;
598 
599  if (jcode == 0) break ;
600 
601  for (int k = nlist ; k <= nlist + parti[i - 1].ndec - 1 ; k++) {
602  partgen[npoint - 1].part_prop = parts[k - 1];
603  npoint++ ;
604  }
605  nlist += parti[i - 1].ndec - 1 ;
606  npoint--;
607 
608  }
609  }
610  if (jcode == 0) continue ;
611 
612  int iret = tpuser(pe, pp, partgen, npoint);
613  if (iret <= 0) continue ;
614  break;
615  } while (true);
616  //************* Generation end ********************
617  // variable for the kinematical check
618  TLorentzVector pfinal = TLorentzVector(0., 0., 0., 0.);
619  for (int i = 0 ; i < npoint ; i++)pfinal += partgen[i].p ;
620  TLorentzVector pcm = pe + pp + pfinal;
621  double ptsumcm = sqrt(pfinal.X() * pfinal.X() + pfinal.Y() * pfinal.Y());
622  double pzsumcm = pfinal.Z();
623  double eall = pcm.T();
624  double wcal = sqrt(pfinal.T() * pfinal.T() -
625  ptsumcm * ptsumcm - pzsumcm * pzsumcm);
626  treh1->Fill((float)pzsumcm, 1.0);
627  treh2->Fill((float)ptsumcm, 1.0);
628  treh3->Fill((float)eall, 1.0);
629  treh6->Fill((float)wcal, 1.0);
630 
631  // cos(theta)-pt cut
632  int rcode = 1 ;
633  for (int i = 0 ; i < npoint ; i++) {
634  double zz = partgen[i].p.CosTheta();
635  if (abs(zz) > cost_cut && abs(partgen[i].part_prop.pcharg) > qzmin) rcode = 0;
636  double ptp = sqrt(pow(partgen[i].p.X(), 2) + pow(partgen[i].p.Y(), 2));
637  if (ptp < pt_cut && abs(partgen[i].part_prop.pcharg) > qptmin) rcode = 0;
638  }
639  //************* final boost ***********
640  sutool.rotate(pe, etheta, ephi);
641  pe.Boost(tswsb);
642  sutool.rotate(pp, etheta, ephi);
643  pp.Boost(tswsb);
644  for (int i = 0; i < npoint ; i++) {
645  sutool.rotate(partgen[i].p, etheta, ephi);
646  partgen[i].p.Boost(tswsb);
647  }
648 
649  TLorentzVector plab(0., 0., 0., 0.);
650  for (int i = 0; i < npoint ; i++) plab += partgen[i].p ;
651 
652  treh4->Fill((float)(plab.Z()), 1.0);
653  treh5->Fill((float)(sqrt(plab.X()*plab.X() + plab.Y()*plab.Y())), 1.0);
654 
655  // std::cout << iev << std::endl;
656  ievent = iev;
657  npart = npoint;
658 
659  if (rcode == 0) return 0;
660 
661  trkpsh(iev, pe, pp, partgen, npoint);
662  nsave++ ;
663  return 1;
664  }
665 
666  double TrepsB::tpgetq(double _s, double z, double _q2max)
667  {
668  B2DEBUG(20, "Parameter _s=" << _s << " given but not used");
669  // get one Q2 value
670  double q2min = me * me * z * z / (1. - z);
671  double rk = 1. / log(_q2max / q2min);
672  double ccc = rk * log(q2min);
673  double rr = gRandom->Uniform();
674  double xx = (rr + ccc) / rk ;
675 
676  return exp(xx);
677  }
678 
679  void TrepsB::tpgetm(Part_cont* part, int _ndecay)
680  {
681  // get a mass value from Breit-Wigner distribution
682  // const double tmax = 1.3258 ; // 2Gamma
683  const double tmax = 1.4289 ; // 3.5Gamma
684 
685  for (int i = 0; i < _ndecay ; i++) {
686  if (part[i].pwidth < 0.001) {
687  part[i].pmassp = part[i].pmass ;
688  } else {
689  part[i].pmassp = part[i].pmass + 0.5 * part[i].pwidth *
690  tan(2.*tmax * (gRandom->Uniform() - 0.5));
691  if (part[i].pmassp < 0.0) part[i].pmassp = 0.0 ;
692  }
693  }
694  }
695 
696 
697  //
698  // const member functions
699  //
700 
701  void TrepsB::terminate() const
702  {
703 
704  B2DEBUG(20, nsave << " events saved.");
705  // trfile->write();
706  //std::cout << "Histograms are written in "<< filnam_hist << std::endl;
707  }
708 
709  double TrepsB::tpdfnc(double d) const
710  {
711  // New (Working) version 2016 April S.Uehara
712  const double alpppi = 0.002322816 ;
713  double y0 = (d + sqrt(d * d + 4.*rs)) * 0.5;
714  double z0 = y0 - d;
715  double xminy = log(me * me * y0 * y0 / (1.0 - y0));
716  double xminz = log(me * me * z0 * z0 / (1.0 - z0));
717  double xmax = log(q2max) ;
718  double integy = simpsny(d, xminy, xmax, 1000);
719  double integz = simpsnz(d, xminz, xmax, 1000);
720  double integrd = (integy + (-1. + y0) / y0) * (integz + (-1. + z0) / z0) / sqrt(d * d + 4.*rs)
721  * alpppi * alpppi;
722 
723  return integrd;
724  }
725 
726  double TrepsB::simpsny(double d, double xl, double xh, int n) const
727  {
728  int nn = n / 2 * 2 ;
729  double h = (xh - xl) / (double)nn ;
730  double _s = tpdfy(d, xl) + tpdfy(d, xh) ;
731  for (int i = 1 ; i <= nn - 1 ; i += 2) {
732  double x = xl + (double)i * h ;
733  _s += 4.0 * tpdfy(d, x) ;
734  }
735  for (int i = 2 ; i <= nn - 2 ; i += 2) {
736  double x = xl + (double)i * h ;
737  _s += 2.0 * tpdfy(d, x) ;
738  }
739  return h * _s / 3.0 ;
740  }
741 
742  double TrepsB::tpdfy(double d, double x) const
743  {
744  double q2 = exp(x);
745  double y = ((d - q2 / s) + sqrt(d * d - 2.*q2 / s * d + 4.*q2 / s + 4.*rs)) * 0.5;
746  double integrq = (1. + (1. - y) * (1. - y)) / y * (1. - (-d + 2.) * q2 / (d * d + 4.*rs) / s) * 0.5;
747  if (y - d >= 1.) integrq = 0.; // z=y-d
748  return integrq * tplogf(x);
749  }
750 
751  double TrepsB::simpsnz(double d, double xl, double xh, int n) const
752  {
753  int nn = n / 2 * 2 ;
754  double h = (xh - xl) / (double)nn ;
755  double _s = tpdfz(d, xl) + tpdfz(d, xh) ;
756  for (int i = 1 ; i <= nn - 1 ; i += 2) {
757  double x = xl + (double)i * h ;
758  _s += 4.0 * tpdfz(d, x) ;
759  }
760  for (int i = 2 ; i <= nn - 2 ; i += 2) {
761  double x = xl + (double)i * h ;
762  _s += 2.0 * tpdfz(d, x) ;
763  }
764  return h * _s / 3.0 ;
765  }
766 
767  double TrepsB::tpdfz(double d, double x) const
768  {
769  double q2 = exp(x);
770  double z = ((-d - q2 / s) + sqrt(d * d - 2.*q2 / s * d + 4.*q2 / s + 4.*rs)) * 0.5;
771  double integrq = (1. + (1. - z) * (1. - z)) / z * (1. - (-d + 2.) * q2 / (d * d + 4.*rs) / s) * 0.5;
772  if (z + d >= 1.) integrq = 0.; //y=z+d
773  return integrq * tplogf(x);
774  }
775 
776 
777  double TrepsB::tpxint(double r, double _rs, double _q2max) const
778  {
779  // const double alpppi = 0.002322816 ;
780 
781  double y = sqrt(r * _rs);
782  double z = sqrt(_rs / r);
783  return tpf(y, _q2max) * tpf(z, _q2max) * 0.5 / r ;
784  }
785 
786  double TrepsB::tpf(double z, double _q2max) const
787  {
788  const double alpppi = 0.002322816 ;
789  double tpfx ;
790  if (imode == 0) {
791  tpfx = 1. / z * ((1. + (1. - z) * (1. - z)) * log(_q2max * (1. - z) / me / me / z / z) * 0.5
792  - 1.0 + z) * alpppi ;
793  } else {
794  double xmin = log(me * me * z * z / (1.0 - z));
795  double xmax = log(_q2max) ;
796  tpfx = 1. / z * ((1. + (1. - z) * (1. - z)) * simpsn2(xmin, xmax, 1000) * 0.5
797  - 1.0 + z) * alpppi ;
798  }
799  return tpfx ;
800  }
801 
802  double TrepsB::simpsn1(double xl, double xh, int n) const
803  {
804  int nn = n / 2 * 2 ;
805  double h = (xh - xl) / (double)nn ;
806  double _s = tpdfnc(xl) + tpdfnc(xh) ;
807  for (int i = 1 ; i <= nn - 1 ; i += 2) {
808  double x = xl + (double)i * h ;
809  _s += 4.0 * tpdfnc(x) ;
810  }
811  for (int i = 2 ; i <= nn - 2 ; i += 2) {
812  double x = xl + (double)i * h ;
813  _s += 2.0 * tpdfnc(x) ;
814  }
815  return h * _s / 3.0 ;
816  }
817 
818  double TrepsB::simpsn2(double xl, double xh, int n) const
819  {
820  int nn = n / 2 * 2 ;
821  double h = (xh - xl) / (double)nn ;
822  double _s = tplogf(xl) + tplogf(xh) ;
823  for (int i = 1 ; i <= nn - 1 ; i += 2) {
824  double x = xl + (double)i * h ;
825  _s += 4.0 * tplogf(x) ;
826  }
827  for (int i = 2 ; i <= nn - 2 ; i += 2) {
828  double x = xl + (double)i * h ;
829  _s += 2.0 * tplogf(x) ;
830  }
831  return h * _s / 3.0 ;
832  }
833 
834  double TrepsB::tplogf(double x) const
835  {
836  double q2 = exp(x);
837  return tpform(q2, w) ;
838  }
839 
840 
841  double TrepsB::tpform(double _q2, double _w) const
842  {
843  //form factor effect
844  B2DEBUG(20, "Parameters _q2=" << _q2 << " and _w=" << _w << " are given but not used");
845  double dis = 1.0 ;
846  return dis ;
847  }
848 
849  double TrepsB::tpangd(double _z, double _w)
850  {
851  B2DEBUG(20, "Parameters _z=" << _z << " and _w=" << _w << " are given but not used");
852  double c = 1.0 ;
853  return c;
854  }
855 
856  int TrepsB::tpuser(TLorentzVector _pe, TLorentzVector _pp,
857  Part_gen* part, int _npart)
858  {
859  // user decision routine for extra generation conditions.
860  // Return positive integer for the generation, otherwise, this event will
861  // be canceled.
862  // CAUTION!: The 4-momenta of particles are represented in the e+e- c.m. system
863  //
864  B2DEBUG(20, "User decision routine for extra generation condition is not used."
865  << " _pe(" << _pe.Px() << "," << _pe.Py() << "," << _pe.Pz() << "), "
866  << " _pp(" << _pp.Px() << "," << _pp.Py() << "," << _pp.Pz() << "), "
867  << " *part at " << part << " and _npart = " << _npart << " are given but not used");
868  return 1 ;
869  }
870 
871  void TrepsB::trkpsh(int iev,
872  TLorentzVector _pe, TLorentzVector _pp,
873  Part_gen* part, int n) const
874  {
875  B2DEBUG(20, "iev = " << iev << " _pe(" << _pe.Px() << "," << _pe.Py() << "," << _pe.Pz() << "), "
876  << " _pp(" << _pp.Px() << "," << _pp.Py() << "," << _pp.Pz() << "), "
877  << " *part at " << part << " and n = " << n << " are given but not used");
878  }
879 
880  void TrepsB::print_event() const
881  {
882 
883  const int& iev = ievent;
884  const int& n = npart;
885  const Part_gen* part = partgen;
886 
887  TLorentzVector pf(0., 0., 0., 0.);
888  for (int i = 0 ; i < n; i++) pf += part[i].p ;
889  TLorentzVector psum = pf + pe + pp ;
890 
891  double q2e = -((pe - peb).Mag2());
892  double q2p = -((pp - ppb).Mag2());
893  double www = pf.Mag();
894 
895  B2DEBUG(20, "");
896  B2DEBUG(20, "**************** Event# = " << iev << " ******************");
897  for (int i = 0; i < n; i++) {
898  B2DEBUG(20, std::setw(2) << i + 1 << std::setw(11) << std::setprecision(4) << part[i].p.X() <<
899  std::setw(11) << std::setprecision(4) << part[i].p.Y() <<
900  std::setw(11) << std::setprecision(4) << part[i].p.Z() <<
901  std::setw(11) << std::setprecision(4) << part[i].p.T() <<
902  std::setw(7) << part[i].part_prop.icode <<
903  std::setw(11) << std::setprecision(4) << part[i].part_prop.pmass <<
904  std::setw(6) << std::setprecision(2) << part[i].part_prop.pcharg);
905  }
906  B2DEBUG(20, std::setw(2) << "e-" << std::setw(11) << std::setprecision(4) << pe.X() <<
907  std::setw(11) << std::setprecision(4) << pe.Y() <<
908  std::setw(11) << std::setprecision(4) << pe.Z() <<
909  std::setw(11) << std::setprecision(4) << pe.T() <<
910  " " <<
911  std::setw(11) << std::setprecision(4) << me <<
912  std::setw(6) << std::setprecision(2) << -1.0);
913 
914  B2DEBUG(20, std::setw(2) << "e+" << std::setw(11) << std::setprecision(4) << pp.X() <<
915  std::setw(11) << std::setprecision(4) << pp.Y() <<
916  std::setw(11) << std::setprecision(4) << pp.Z() <<
917  std::setw(11) << std::setprecision(4) << pp.T() <<
918  " " <<
919  std::setw(11) << std::setprecision(4) << me <<
920  std::setw(6) << std::setprecision(2) << 1.0);
921 
922  B2DEBUG(20, "-----------------------------------------------");
923  B2DEBUG(20, std::setw(2) << "S:" << std::setw(11) << std::setprecision(4) << psum.X() <<
924  std::setw(11) << std::setprecision(4) << psum.Y() <<
925  std::setw(11) << std::setprecision(4) << psum.Z() <<
926  std::setw(11) << std::setprecision(4) << psum.T());
927  B2DEBUG(20, " Q2:(" << q2e << ", " << q2p << ")" <<
928  " W: " << www <<
929  " ptlab: " << sqrt(pf.X()*pf.X() + pf.Y()*pf.Y()) <<
930  " pzlab: " << pf.Z());
931  }
932 
933  void TrepsB::tpkin3(Part_gen* part,
934  int index1, int index2, int index3, double& z, double& m12, double& zp,
935  double& phip, double& zs, double& phis, double& phi0)
936  {
937 
938  TLorentzVector p1, p2, p3; //a->(1,2), b=3
939  p1 = part[index1].p;
940  p2 = part[index2].p;
941  p3 = part[index3].p;
942 
943  TVector3 tpcm = (-1. / (p1.T() + p2.T() + p3.T())) * (p1 + p2 + p3).Vect();
944 
945  p1.Boost(tpcm); p2.Boost(tpcm); p3.Boost(tpcm);
946 
947  // Now, we are at two-photon c.m.s.
948 
949  TLorentzVector pa = p1 + p2;
950 
951  m12 = pa.M();
952  z = pa.CosTheta();
953  phi0 = pa.Phi();
954 
955  sutool.rotate(p1, 0., phi0);
956  sutool.rotate(p2, 0., phi0);
957  sutool.rotate(p3, 0., phi0);
958 
959  // Now, we are in x-z plane of 12
960 
961  pa = p1 + p2;
962  TVector3 pacm = (-1. / pa.T()) * pa.Vect();
963  TVector3 az = (1. / (pa.Vect()).Mag()) * pa.Vect();
964  p1.Boost(pacm); p2.Boost(pacm);
965 
966  // Now, we are at 12 c.m.s.
967 
968  zp = p1.CosTheta(); phip = p1.Phi();
969 
970  TVector3 ay = TVector3(0., 1., 0.);
971  TVector3 ax = ay.Cross(az);
972 
973  zs = az.Dot(p1.Vect()) / (p1.Vect()).Mag();
974  TVector3 azk = az.Cross(p1.Vect());
975  double cosphis = ay.Dot(azk) * (1. / azk.Mag());
976  double sinphis = ax.Dot(azk) * (-1. / azk.Mag());
977  phis = atan2(sinphis, cosphis);
978 
979  }
980 
981  void TrepsB::tpkin4(Part_gen* part,
982  int index1, int index2, int index3, int index4,
983  double& z, double& m12, double& zp,
984  double& phip, double& zs, double& phis,
985  double& m34, double& zpp,
986  double& phipp, double& zss, double& phiss,
987  double& phi0)
988  {
989 
990  TLorentzVector p1, p2, p3, p4; //a->(1,2), b->(3,4)
991  p1 = part[index1].p;
992  p2 = part[index2].p;
993  p3 = part[index3].p;
994  p4 = part[index4].p;
995 
996  TVector3 tpcm = (-1. / (p1.T() + p2.T() + p3.T() + p4.T())) * (p1 + p2 + p3 + p4).Vect();
997 
998  p1.Boost(tpcm); p2.Boost(tpcm); p3.Boost(tpcm); p4.Boost(tpcm);
999 
1000  // Now, we are at two-photon c.m.s.
1001 
1002  TLorentzVector pa = p1 + p2;
1003 
1004  m12 = pa.M();
1005  z = pa.CosTheta();
1006  phi0 = pa.Phi();
1007 
1008  sutool.rotate(p1, 0., phi0);
1009  sutool.rotate(p2, 0., phi0);
1010  sutool.rotate(p3, 0., phi0);
1011  sutool.rotate(p4, 0., phi0);
1012 
1013  // Now, we are in x-z plane of 12
1014 
1015  pa = p1 + p2;
1016  TVector3 pacm = (-1. / pa.T()) * pa.Vect();
1017  TVector3 az = (1. / (pa.Vect()).Mag()) * pa.Vect();
1018  p1.Boost(pacm); p2.Boost(pacm);
1019 
1020  // Now, we are at 12 c.m.s.
1021 
1022  zp = p1.CosTheta(); phip = p1.Phi();
1023 
1024  TVector3 ay = TVector3(0., 1., 0.);
1025  TVector3 ax = ay.Cross(az);
1026 
1027  zs = az.Dot(p1.Vect()) / (p1.Vect()).Mag();
1028  TVector3 azk = az.Cross(p1.Vect());
1029  double cosphis = ay.Dot(azk) * (1. / azk.Mag());
1030  double sinphis = ax.Dot(azk) * (-1. / azk.Mag());
1031  phis = atan2(sinphis, cosphis);
1032 
1033  // next go to 34
1034 
1035  TLorentzVector pb = p3 + p4;
1036 
1037  m34 = pb.M();
1038 
1039  TVector3 pbcm = (-1. / pb.T()) * pb.Vect();
1040  p3.Boost(pbcm); p4.Boost(pbcm);
1041 
1042  // Now, we are at 34 c.m.s.
1043 
1044  zpp = p3.CosTheta(); phipp = p3.Phi();
1045 
1046  // 2004.02.29 Here, I change the definision of zss and phiss
1047  // Use the same system as 3
1048 
1049  zss = az.Dot(p3.Vect()) / (p3.Vect()).Mag();
1050  TVector3 bzk = az.Cross(p3.Vect());
1051  double cosphiss = ay.Dot(bzk) * (1. / bzk.Mag());
1052  double sinphiss = ax.Dot(bzk) * (-1. / bzk.Mag());
1053  phiss = atan2(sinphiss, cosphiss);
1054 
1055  }
1056  void TrepsB::tpkin5(Part_gen* part,
1057  int index1, int index2, int index3, int index4, int index5,
1058  double& z, double& m12, double& zp,
1059  double& phip, double& zs, double& phis,
1060  TVector3& ps3, TVector3& ps4, TVector3& ps5,
1061  double& phi0)
1062  {
1063 
1064  TLorentzVector p1, p2, p3, p4, p5; //a->(1,2), b->(3,4, 5)
1065  p1 = part[index1].p;
1066  p2 = part[index2].p;
1067  p3 = part[index3].p;
1068  p4 = part[index4].p;
1069  p5 = part[index5].p;
1070 
1071  TVector3 tpcm = (-1. / (p1.T() + p2.T() + p3.T() + p4.T() + p5.T())) * (p1 + p2 + p3 + p4 + p5).Vect();
1072 
1073  p1.Boost(tpcm); p2.Boost(tpcm); p3.Boost(tpcm); p4.Boost(tpcm); p5.Boost(tpcm);
1074 
1075  // Now, we are at two-photon c.m.s.
1076 
1077  TLorentzVector pa = p1 + p2;
1078 
1079  m12 = pa.M();
1080  z = pa.CosTheta();
1081  phi0 = pa.Phi();
1082 
1083  sutool.rotate(p1, 0., phi0);
1084  sutool.rotate(p2, 0., phi0);
1085  sutool.rotate(p3, 0., phi0);
1086  sutool.rotate(p4, 0., phi0);
1087  sutool.rotate(p5, 0., phi0);
1088 
1089  pa = p1 + p2;
1090  TVector3 pacm = (-1. / pa.T()) * pa.Vect();
1091  TVector3 az = (1. / pa.Vect().Mag()) * pa.Vect();
1092  p1.Boost(pacm); p2.Boost(pacm);
1093 
1094  // Now, we are at 12 c.m.s.
1095 
1096  zp = p1.CosTheta(); phip = p1.Phi();
1097 
1098  TVector3 ay = TVector3(0., 1., 0.);
1099  TVector3 ax = ay.Cross(az);
1100 
1101 
1102  zs = az.Dot(p1.Vect()) / p1.Vect().Mag();
1103  TVector3 azk = az.Cross(p1.Vect());
1104  double cosphis = ay.Dot(azk) * (1. / azk.Mag());
1105  double sinphis = ax.Dot(azk) * (-1. / azk.Mag());
1106  phis = atan2(sinphis, cosphis);
1107 
1108  // next go to 345
1109 
1110  TLorentzVector pb = p3 + p4 + p5;
1111 
1112 
1113  TVector3 pbcm = (-1. / pb.T()) * pb.Vect();
1114  p3.Boost(pbcm); p4.Boost(pbcm); p5.Boost(pbcm);
1115  ps3 = p3.Vect(); ps4 = p4.Vect(); ps5 = p5.Vect();
1116 
1117  // Now, we are at 345 c.m.s.
1118  // double mm = 0.1396*0.1396;
1119  }
1120 
1122 } // namespace Belle2
Abstract base class for different kinds of events.