Belle II Software  release-06-00-14
BabayagaNLO.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <generators/babayaganlo/BabayagaNLO.h>
10 #include <framework/gearbox/Unit.h>
11 #include <framework/logging/Logger.h>
12 #include <framework/dataobjects/EventMetaData.h>
13 #include <analysis/dataobjects/EventExtraInfo.h>
14 
15 #include <TDatabasePDG.h>
16 #include <TLorentzVector.h>
17 #include <TRandom3.h>
18 
19 #include <generators/utilities/InitialParticleGeneration.h>
20 
21 using namespace std;
22 using namespace Belle2;
23 
24 extern "C" {
25 
26  extern struct {
27  double bweight;
28  double bp1[4];
29  double bq1[4];
30  double bp2[4];
31  double bq2[4];
32  double bphot[4][100];
33  int bnphot;
34  } momset_;
35 
36  extern struct {
37  double bprescale;
38  } prescale_;
39 
40  //results for cross section and photon multiplicity
41  extern struct {
42  double rescross;
43  double rescrosserr;
44  double rescrossphot[40];
45  double rescrossphoterr[40];
46  double rescrossphotfrac[40];
47  double resnphmax;
48  } bresults_;
49 
50  //results and statistics for hit/miss
51  extern struct {
52  double hnmcross;
53  double hnmcrosserr;
54  double hnmeff;
55  double hnmsdifmax;
56  double hnmfmax;
57  double hnmmaxtriallimit;
58  double hnmmaxtrial;
59  } bhitnmiss_;
60 
61  //bias for hit/miss
62  extern struct {
63  double biashit;
64  double biashitpmiss;
65  double biasneghit;
66  double biasneghitmiss;
67  double sezover;
68  double errsezover;
69  double sezneg;
70  double errsezneg;
71  double nover;
72  double nneg;
73  } bbias_;
74 
75  //monitoring
76  extern struct {
77  double monsdif;
78  } bmonitoring_;
79 
81  double babayaganlo_rndm_(int*)
82  {
83  double r = gRandom->Rndm();
84  return r;
85  }
86 
88  double babayaganlo_getrandomcmsenergy_()
89  {
90  B2FATAL("babayaganlo_getrandomcmsenergy() is not implmented");
91  }
92 
94 // void main_belle2_(int* mode, double* xpar, int* npar, double *ecm);
95  void main_belle2_(int* mode, double* ecm, double* xpar, int* npar);
96 
98  void babayaga_setvpolnsk_(const char* vpolnskfilename, size_t* length);
99 
101  void babayaganlo_warning_overweight_(double* weight, double* max)
102  {
103  B2WARNING("Babayaga.NLO: Maximum weight " << *max << " to small, increase fmax to at least " << *weight);
104  }
105 
107  void babayaganlo_error_rejection_(double* ratio)
108  {
109  B2ERROR("Babayaga.NLO: Event rejected! Ratio of cross section error increase too large: " << *ratio);
110  }
111 
113  void babayaganlo_error_negative_(double* weight)
114  {
115  B2ERROR("Babayaga.NLO: Event has negative weight: " << *weight);
116  }
117 
119  void babayaganlo_result_nominalcmsenergy_(double* energy)
120  {
121  B2RESULT("Babayaga.NLO: Nominal CMS energy (GeV): " << *energy);
122  }
123 
124  void babayaganlo_result_weightedxsec_(double* xsec, double* xsecerr)
125  {
126  B2RESULT("Babayaga.NLO: Weighted cross section (nb): " << *xsec << " +/- " << *xsecerr);
127  }
128 
129  void babayaganlo_result_unweightedxsec_(double* xsec, double* xsecerr)
130  {
131  B2RESULT("Babayaga.NLO: Unweighted cross section (nb): " << *xsec << " +/- " << *xsecerr);
132  }
133 
134  void babayaganlo_result_unweightedxsec_biascorrected_(double* xsec, double* xsecerr)
135  {
136  B2RESULT("Babayaga.NLO: Unweighted cross section, bias corrected (nb): " << *xsec << " +/- " << *xsecerr);
137  }
138 
139  void babayaganlo_result_unweightedxsec_overweight_(double* xsec, double* xsecerr)
140  {
141  B2RESULT("Babayaga.NLO: Unweighted cross section overweight (nb): " << *xsec << " +/- " << *xsecerr);
142  }
143 
144  void babayaganlo_result_unweightedxsec_underweight_(double* xsec, double* xsecerr)
145  {
146  B2RESULT("Babayaga.NLO: Unweighted cross section underweight (nb): " << -*xsec << " +/- " << *xsecerr);
147  }
148 
149  void babayaganlo_result_hitormisseff_(double* eff)
150  {
151  B2RESULT("Babayaga.NLO: Hit or miss efficiency: " << *eff * 100. << " % ");
152  }
153 
154  void babayaganlo_result_nover_(int* nover)
155  {
156  B2RESULT("Babayaga.NLO: Points with w > fmax (bias): " << *nover);
157  }
158 
159  void babayaganlo_result_biashit_(double* biashit)
160  {
161  B2RESULT("Babayaga.NLO: Bias/hit: " << *biashit * 100. << " % ");
162  }
163 
164  void babayaganlo_result_biashitpmiss_(double* biashitpmiss)
165  {
166  B2RESULT("Babayaga.NLO: Bias/(hit+missed): " << *biashitpmiss * 100. << " % ");
167  }
168 
169  void babayaganlo_result_nneg_(int* nneg)
170  {
171  B2RESULT("Babayaga.NLO: Points with w > fmax (bias): " << *nneg);
172  }
173 
174  void babayaganlo_result_biasneghit_(double* biasneghit)
175  {
176  B2RESULT("Babayaga.NLO: Neg. bias/hit: " << *biasneghit * 100. << " % ");
177  }
178 
179  void babayaganlo_result_biasneghitmiss_(double* biasneghitmiss)
180  {
181  B2RESULT("Babayaga.NLO: Neg. bias/(hit+missed): " << *biasneghitmiss * 100. << " % ");
182  }
183 
184  void babayaganlo_result_maxweight_(double* sdifmax, double* fmax)
185  {
186  B2RESULT("Babayaga.NLO: Maximum weight (sdifmax): " << *sdifmax << ", user maximum weight(fmax): " << *fmax);
187  }
188 
189  void babayaganlo_result_vpmin_(double* xsec, double* xsecerr, double* frac)
190  {
191  B2RESULT("Babayaga.NLO: VP Uncertainty, minimum (nb): " << *xsec << " +/- " << *xsecerr << " (" << *frac << " %)");
192  }
193 
194  void babayaganlo_result_vpcentral_(double* xsec, double* xsecerr)
195  {
196  B2RESULT("Babayaga.NLO: VP Uncertainty, central (nb): " << *xsec << " +/- " << *xsecerr);
197  }
198 
199  void babayaganlo_result_vpmax_(double* xsec, double* xsecerr, double* frac)
200  {
201  B2RESULT("Babayaga.NLO: VP Uncertainty, maximum (nb): " << *xsec << " +/- " << *xsecerr << " ( " << *frac << " %)");
202  }
203 
204  void babayaganlo_finishedmaxsearch_(double* fmax)
205  {
206  B2INFO("Babayaga.NLO: Finished maximum search: " << *fmax << ", starting now unweighted generation");
207  }
208 
209  void babayaganlo_fatal_usercuts_()
210  {
211  B2FATAL("Babayaga.NLO: UserMode is selected but wrong user cuts are provided!");
212  }
213 
214  void babayaganlo_fatal_usercutsfs_()
215  {
216  B2FATAL("Babayaga.NLO: UserMode is only possible for ee final states!");
217  }
218 
219  void babayaganlo_fatal_usercutsprescale_()
220  {
221  B2FATAL("Babayaga.NLO: Prescale value must be larger than 0 (zero), hint: ~100 is reasonable!");
222  }
223 
224  void babayaganlo_fatal_weightedprescale_()
225  {
226  B2FATAL("Babayaga.NLO: Generator prescale is not allowed with usermode = weighted");
227  }
228 
229  void babayaganlo_result_weightsum_(double* wsum)
230  {
231  B2RESULT("Babayaga.NLO: Sum of weights: " << *wsum);
232  }
233 
234  void babayaganlo_result_intlum_(double* lum, double* lumerr)
235  {
236  B2RESULT("Babayaga.NLO: Luminosity equivalent (using calc. xsec) (fb-1): " << *lum << " +/- " << *lumerr);
237  }
238 
239  void babayaganlo_warning_prescaleweight_(double* weight)
240  {
241  B2WARNING("Babayaga.NLO: Prescale of less than one, increase prescale safety margin " << *weight);
242  }
243 
244  void babayaganlo_error_isnan1_(double* phsp, double* w)
245  {
246  B2ERROR("Babayaga.NLO: phsp (" << *phsp << ") or w (" << *w << ") are NAN, skipping event (nan1 type)");
247  }
248 
249  void babayaganlo_error_isnan2_(double* sdif)
250  {
251  B2ERROR("Babayaga.NLO: sdif (" << *sdif << ") is NAN, skipping event (nan2 type)");
252  }
253 
254 
255 
256 }
257 
258 BabayagaNLO::BabayagaNLO()
259 {
260  for (int i = 0; i < 100; ++i) {
261  m_npar[i] = 0;
262  m_xpar[i] = 0.0;
263  }
264 
265  m_sDif = 0.;
266 
267  setDefaultSettings();
268 }
269 
270 BabayagaNLO::~BabayagaNLO()
271 {
272 
273 }
274 
275 void BabayagaNLO::setDefaultSettings()
276 {
277 // m_cmsEnergy = -1.;
278  m_cmsEnergyNominal = -1.;
279 
280  m_applyBoost = true;
281 
282  m_finalState = "ee";
283  m_vacPol = "hlmnt";
284  m_order = "exp";
285  m_model = "matched";
286  m_mode = "unweighted";
287  m_userMode = "NONE";
288 
289  m_pi = 3.1415926535897932384626433832795029;
290  m_conversionFactor = 0.389379660e6;
291  m_alphaQED0 = 1.0 / 137.0359895;
292  m_massElectron = 0.51099906 * Unit::MeV;
293  m_massMuon = 105.65836900 * Unit::MeV;
294  m_massW = 80.385 * Unit::GeV;
295  m_massZ = 91.1882 * Unit::GeV;
296  m_widthZ = 2.4952 * Unit::GeV;
297  m_eMin = 0.1 * Unit::GeV;
298  m_epsilon = 5.e-7;
299  m_maxAcollinearity = 180.0;// * Unit::Deg;
300 
301  m_ScatteringAngleRange = make_pair(15.0, 165.0); //in [deg]
302  m_ScatteringAngleRangePhoton = make_pair(15.0, 165.0); //in [deg] (unused in original babayaga)
303 
304  m_nPhot = -1;
305  m_nSearchMax = 50000;
306  m_fMax = -1.;
307  m_EnergySpread = 5e-3;
308  m_VPUncertainty = false;
309  m_eemin = 0.0;
310  m_temin = 0.0;
311  m_egmin = 0.0;
312  m_tgmin = 0.0;
313  m_eeveto = 0.0;
314  m_teveto = 0.0;
315  m_egveto = 0.0;
316  m_tgveto = 0.0;
317  m_maxprescale = 1.0;
318 }
319 
320 void BabayagaNLO::initExtraInfo()
321 {
322  StoreObjPtr<EventExtraInfo> extrainfo;
323  extrainfo.registerInDataStore();
324 }
325 
326 void BabayagaNLO::init()
327 {
328  applySettings();
329 }
330 
331 
332 void BabayagaNLO::generateEvent(MCParticleGraph& mcGraph, double ecm, TVector3 vertex, TLorentzRotation boost)
333 {
334  //Generate event
335  int mode = 1;
336  main_belle2_(&mode, &ecm, m_xpar, m_npar);
337 
338  //Store the initial particles as virtual particles into the MCParticleGraph
339  storeParticle(mcGraph, momset_.bq1, 11, vertex, boost, true);
340  storeParticle(mcGraph, momset_.bp1, -11, vertex, boost, true);
341 
342  //Store the final state fermions or photons (for 'gg') as real particle into the MCParticleGraph
343  int pdg = 11;
344  int antipdg = -11;
345 
346  if (m_finalState == "gg") {
347  pdg = 22;
348  antipdg = 22;
349  } else if (m_finalState == "mm") {
350  pdg = 13;
351  antipdg = -13;
352  }
353 
354  storeParticle(mcGraph, momset_.bq2, pdg, vertex, boost, false, false, false);
355  storeParticle(mcGraph, momset_.bp2, antipdg, vertex, boost, false, false, false);
356 
357  //Store the real ISR and FSR photons into the MCParticleGraph
358  for (int iPhot = 0; iPhot < momset_.bnphot; ++iPhot) {
359  double photMom[4] = {momset_.bphot[0][iPhot], momset_.bphot[1][iPhot], momset_.bphot[2][iPhot], momset_.bphot[3][iPhot]};
360  storeParticle(mcGraph, photMom, 22, vertex, boost, false, false, true);
361  }
362 
363  //set event weight
364  StoreObjPtr<EventMetaData> eventMetaDataPtr("EventMetaData", DataStore::c_Event);
365  eventMetaDataPtr->setGeneratedWeight(momset_.bweight);
366 
367  //set event prescale
368  StoreObjPtr<EventExtraInfo> eventExtraInfo;
369  if (not eventExtraInfo.isValid())
370  eventExtraInfo.create();
371  if (eventExtraInfo->hasExtraInfo("GeneratedPrescale")) {
372  B2WARNING("EventExtraInfo with given name is already set! I won't set it again!");
373  } else {
374  float targetValue = prescale_.bprescale;
375  eventExtraInfo->addExtraInfo("GeneratedPrescale", targetValue);
376  }
377 
378 }
379 
380 
381 void BabayagaNLO::term()
382 {
383 
384  B2RESULT("Babayaga.NLO: Final state: " << m_finalState);
385  B2RESULT("Babayaga.NLO: Mode: " << m_mode);
386  B2RESULT("Babayaga.NLO: Order: " << m_order);
387  B2RESULT("Babayaga.NLO: Model: " << m_model);
388  B2RESULT("Babayaga.NLO: Vac. pol. (VP): " << m_vacPol);
389  B2RESULT("Babayaga.NLO: Usercuts: " << m_userMode);
390 
391  // all other results are displayed from fortran using a callback to C extern logging
392 
393  int mode = 2;
394  double ecm = -1.;
395  main_belle2_(&mode, &ecm, m_xpar, m_npar);
396 
397 }
398 
399 //=========================================================================
400 // Protected methods
401 //=========================================================================
402 
403 void BabayagaNLO::applySettings()
404 {
405  //--------------------
406  // Integer parameters
407  //--------------------
408  m_npar[0] = m_nPhot;
409  m_npar[1] = m_nSearchMax;
410  if (m_VPUncertainty) m_npar[5] = 1;
411  else m_npar[5] = 0;
412 
413  //--------------------
414  // Double parameters
415  //--------------------
416  m_xpar[0] = m_cmsEnergyNominal;
417  m_xpar[1] = m_pi;
418  m_xpar[2] = m_conversionFactor;
419  m_xpar[3] = m_alphaQED0;
420  m_xpar[4] = m_massElectron;
421  m_xpar[5] = m_massMuon;
422  m_xpar[6] = m_massW;
423  m_xpar[7] = m_massZ;
424  m_xpar[8] = m_widthZ;
425  m_xpar[9] = m_eMin;
426  m_xpar[10] = m_maxAcollinearity;
427  m_xpar[11] = m_epsilon;
428  m_xpar[20] = m_ScatteringAngleRange.first;
429  m_xpar[21] = m_ScatteringAngleRange.second;
430  m_xpar[30] = m_fMax;
431  m_xpar[40] = m_EnergySpread; // only for some internal checks, not the actual smaering!
432 
433  //user cuts
434  m_xpar[50] = m_eemin;
435  m_xpar[51] = m_temin;
436  m_xpar[52] = m_egmin;
437  m_xpar[53] = m_tgmin;
438  m_xpar[54] = m_eeveto;
439  m_xpar[55] = m_teveto;
440  m_xpar[56] = m_egveto;
441  m_xpar[57] = m_tgveto;
442  m_xpar[58] = m_maxprescale;
443 
444  //--------------------
445  // string parameters, wrapped to integers
446  //--------------------
447  if (m_finalState == "ee") m_npar[20] = 1;
448  else if (m_finalState == "gg") m_npar[20] = 2;
449  else if (m_finalState == "mm") m_npar[20] = 3;
450  else B2FATAL("Invalid final state: " << m_finalState);
451 
452  if (m_model == "matched") m_npar[21] = 1;
453  else if (m_model == "ps") m_npar[21] = 2;
454  else B2FATAL("Invalid matching model: " << m_model);
455 
456  if (m_order == "born") m_npar[22] = 1;
457  else if (m_order == "alpha") m_npar[22] = 2;
458  else if (m_order == "exp") m_npar[22] = 3;
459  else B2FATAL("Invalid QED order: " << m_order);
460 
461  if (m_vacPol == "off") m_npar[23] = 1;
462  else if (m_vacPol == "hadr5") m_npar[23] = 2;
463  else if (m_vacPol == "hlmnt") m_npar[23] = 3;
464  else B2FATAL("Invalid vacuum polarization code: " << m_vacPol);
465 
466  if (m_mode == "unweighted" || m_mode == "uw") m_npar[24] = 1;
467  else if (m_mode == "weighted" || m_mode == "w") m_npar[24] = 2;
468  else B2FATAL("Invalid mode: " << m_mode);
469 
470  if (m_userMode == "NONE") m_npar[25] = 1;
471  else if (m_userMode == "GAMMA") m_npar[25] = 2;
472  else if (m_userMode == "EGAMMA") m_npar[25] = 3;
473  else if (m_userMode == "ETRON") m_npar[25] = 4;
474  else if (m_userMode == "PRESCALE") m_npar[25] = 5;
475  else B2FATAL("Invalid user mode: " << m_userMode);
476 
477  // set the data file for the novosibirsk routine (not supported yet, but needs to be set)
478  size_t fileLength = m_NSKDataFile.size();
479  babayaga_setvpolnsk_(m_NSKDataFile.c_str(), &fileLength);
480 
481  //use mode to control init/generation/finalize in FORTRAN code
482  int mode = -1;
483  double ecm = -1.;
484  main_belle2_(&mode, &ecm, m_xpar, m_npar);
485 }
486 
487 
488 void BabayagaNLO::storeParticle(MCParticleGraph& mcGraph, const double* mom, int pdg, TVector3 vertex, TLorentzRotation boost,
489  bool isVirtual, bool isInitial, bool isISRFSR)
490 {
491 
492 // Create particle
494  if (isVirtual) {
495  part.setStatus(MCParticle::c_IsVirtual);
496  } else if (isInitial) {
497  part.setStatus(MCParticle::c_Initial);
498  }
499 
500  // all particle of a generator are primary
501  part.addStatus(MCParticle::c_PrimaryParticle);
502 
503  // all particles produced by BABAYAGA are stable
504  part.addStatus(MCParticle::c_StableInGenerator);
505 
506  // add ISR/FSR flags to all photons that are not the primary gg pair
507  if (isISRFSR) {
508  part.addStatus(MCParticle::c_IsISRPhoton);
509  part.addStatus(MCParticle::c_IsFSRPhoton);
510  }
511 
512  part.setPDG(pdg);
513  part.setFirstDaughter(0);
514  part.setLastDaughter(0);
515  part.setMomentum(TVector3(mom[0], mom[1], mom[2]));
516  part.setMass(TDatabasePDG::Instance()->GetParticle(pdg)->Mass());
517  part.setEnergy(mom[3]);
518 
519  //boost
520  TLorentzVector p4 = part.get4Vector();
521  p4 = boost * p4;
522  part.set4Vector(p4);
523 
524  //set vertex
525  if (!isInitial) {
526  TVector3 v3 = part.getProductionVertex();
527  v3 = v3 + vertex;
528  part.setProductionVertex(v3);
529  part.setValidVertex(true);
530  }
531 }
Class to represent Particle data in graph.
Class to build, validate and sort a particle decay chain.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.