Belle II Software development
Phokhara.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/phokhara/Phokhara.h>
10#include <framework/logging/Logger.h>
11
12#include <TDatabasePDG.h>
13#include <Math/Vector4D.h>
14#include <TRandom3.h>
15
16using namespace std;
17using namespace Belle2;
18
19extern "C" {
20
22 extern struct {
23 double bp1[4];
24 double bq1[4];
25 double bp2[6][10];
26 double bphot[4][2];
27 double wgt;
28 int bnphot;
29 int bnhad;
30 } belle2_phokhara_particles;
31
33 extern struct {
34 int error_flag;
35 } belle2_error_flag_;
36
38 double phokhara_rndm()
39 {
40 double r = gRandom->Rndm();
41 return r;
42 }
43
49 void phokhara_rndmarray(double* drvec, const int* lengt)
50 {
51 for (int i = 0; i < *lengt; ++i) {
52 drvec[i] = gRandom->Rndm();
53 }
54 }
55
57 void phokhara(int* mode, double* xpar, int* npar);
58
60// void phokhara_setinputfile_(const char* inputfilename, size_t* length);
61 void phokhara_set_parameter_file(const char* paramfilename);
62
64 void phokhara_error_trials_(const double* trials)
65 {
66 B2ERROR("PHOKHARA: Event rejected! Number of maximal trials (" << *trials << " << exceeded");
67 }
68
70 void phokhara_warning_weight_(const int* photmult, const double* weight, const double* max)
71 {
72 B2WARNING("PHOKHARA: Event weight (" << *weight << ") exceeds limit (" << *max << "), photon multiplicity: " << *photmult);
73 }
74
76 void phokhara_warning_negweight_(const int* photmult, const double* weight)
77 {
78 B2WARNING("PHOKHARA: Event weight (" << *weight << ") is negative, photon multiplicity: " << *photmult);
79 }
80
81}
82
84{
85 for (int i = 0; i < 100; ++i) {
86 m_npar[i] = 0;
87 m_xpar[i] = 0.0;
88 }
89
91}
92
94{
95
96}
97
99{
100// std::cout << "Phokhara::setDefaultSettings()" << std::endl;
101
102// these are the settings to reproduce the phokhara9.1 standalone result
103// m_cmsEnergy = 10.580 * Unit::GeV;
104// m_applyBoost = true;
105// m_finalState = 1;
106// m_nMaxTrials = 10000;
107// m_nSearchMax = 50000;
108// m_epsilon = 1.e-4;
109// m_LO = 1;
110// m_NLO = 0;
111// m_QED = 0;
112// m_IFSNLO = 0;
113// m_alpha = 1;
114// m_pionff = 0;
115// m_pionstructure = 0;
116// m_kaonff = 0;
117// m_narres = 0;
118// m_protonff = 1;
119// m_ScatteringAngleRangePhoton = make_pair(0.0, 180.0); //in [deg]
120// m_ScatteringAngleRangeFinalStates = make_pair(0.0, 180.0); //in [deg]
121// m_MinInvMassHadronsGamma = 0.;
122// m_MinInvMassHadrons = 0.2;
123// m_MaxInvMassHadrons = 0.5;
124// m_MinEnergyGamma = 4.0;
125
126 m_cmsEnergy = 0.0;
127 m_finalState = -1;
129 m_nMaxTrials = -1;
130 m_nSearchMax = -1;
131 m_epsilon = 1.e-4;
132 m_weighted = 0;
133 m_LO = -1;
134 m_NLO = -1;
135 m_fullNLO = -1;
136 m_QED = -1;
137 m_IFSNLO = -1;
138 m_alpha = -1;
139 m_pionff = -1;
140 m_pionstructure = -1;
141 m_kaonff = -1;
142 m_narres = -1;
143 m_protonff = -1;
144 m_ScatteringAngleRangePhoton = make_pair(0.0, 180.0); //in [deg]
145 m_ScatteringAngleRangeFinalStates = make_pair(0.0, 180.0); //in [deg]
150 m_MinEnergyGamma = 0.;
151 m_chi_sw = 0;
152 m_be_r = 0;
153 m_beamres = 0.;
154
155 m_pi = 0.;
157 m_alphaQED0 = 0.;
158 m_massElectron = 0.;
159 m_massMuon = 0.;
160 m_massW = 0.;
161 m_massZ = 0.;
162 m_widthZ = 0.;
163
164}
165
166void Phokhara::init(const std::string& paramFile)
167{
168 B2INFO("Phokhara::init, using paramater file: " << paramFile);
169
170 if (paramFile.empty()) B2FATAL("Phokhara: The specified param file is empty!");
171 phokhara_set_parameter_file(paramFile.c_str());
172
173// if (inputFile.empty()) B2FATAL("Phokhara: The specified input file is empty!")
174// fileLength = inputFile.size();
175// phokhara_setinputfile_(inputFile.c_str(), &fileLength);
176
178}
179
180
181double Phokhara::generateEvent(MCParticleGraph& mcGraph, ROOT::Math::XYZVector vertex, ROOT::Math::LorentzRotation boost)
182{
183
184 //Generate event
185 int mode = 1;
187 while (1) {
188 phokhara(&mode, m_xpar, m_npar);
189 double partMom[4] = {0, 0, 0, 0};
190 for (int iPart = 0; iPart < belle2_phokhara_particles.bnhad; ++iPart) {
191 for (int j = 0; j < 4; ++j)
192 partMom[j] += belle2_phokhara_particles.bp2[j][iPart];
193 }
194 double m2 = partMom[0] * partMom[0] - partMom[1] * partMom[1]
195 - partMom[2] * partMom[2] - partMom[3] * partMom[3];
196 if (m2 > m_MinInvMassHadrons)
197 break;
198 }
199 } else
200 phokhara(&mode, m_xpar, m_npar);
201
202 // Check error flag increment during phokhara execution
203 if (belle2_error_flag_.error_flag != 0) {
204 B2FATAL("Phokhara returned a non-zero exit code. Check the output of phokara.");
205 }
206 //Store the initial particles as virtual particles into the MCParticleGraph
207 double eMom[4] = {belle2_phokhara_particles.bp1[1], belle2_phokhara_particles.bp1[2], belle2_phokhara_particles.bp1[3], belle2_phokhara_particles.bp1[0]};
208 double pMom[4] = {belle2_phokhara_particles.bq1[1], belle2_phokhara_particles.bq1[2], belle2_phokhara_particles.bq1[3], belle2_phokhara_particles.bq1[0]};
209
210 storeParticle(mcGraph, eMom, 11, vertex, boost, false, true);
211 storeParticle(mcGraph, pMom, -11, vertex, boost, false, true);
212
213 //Store the real photons into the MCParticleGraph
214 for (int iPhot = 0; iPhot < belle2_phokhara_particles.bnphot; ++iPhot) {
215 double photMom[4] = {belle2_phokhara_particles.bphot[1][iPhot], belle2_phokhara_particles.bphot[2][iPhot], belle2_phokhara_particles.bphot[3][iPhot], belle2_phokhara_particles.bphot[0][iPhot]};
216 storeParticle(mcGraph, photMom, 22, vertex, boost, false, false);
217 }
218
219 //Store the other final state particles into the MCParticleGraph
221 if (belle2_phokhara_particles.bnhad != 2)
222 B2FATAL("Number of particles generated by PHOKHARA does not match the "
223 "requested final state (mu+ mu-).");
224 double partMom[4] = {belle2_phokhara_particles.bp2[1][0] + belle2_phokhara_particles.bp2[1][1],
225 belle2_phokhara_particles.bp2[2][0] + belle2_phokhara_particles.bp2[2][1],
226 belle2_phokhara_particles.bp2[3][0] + belle2_phokhara_particles.bp2[3][1],
227 belle2_phokhara_particles.bp2[0][0] + belle2_phokhara_particles.bp2[0][1]
228 };
229 storeParticle(mcGraph, partMom, 10022, vertex, boost, false, false);
230 } else {
231 for (int iPart = 0; iPart < belle2_phokhara_particles.bnhad; ++iPart) {
232 double partMom[4] = {belle2_phokhara_particles.bp2[1][iPart], belle2_phokhara_particles.bp2[2][iPart], belle2_phokhara_particles.bp2[3][iPart], belle2_phokhara_particles.bp2[0][iPart]};
233
234 storeParticle(mcGraph, partMom, belle2_phokhara_particles.bp2[4][iPart], vertex, boost, false, false);
235 }
236 }
237
238 //some PHOKHARA final states contain unstable particle
239 if (m_finalState == 9) { //Lambda, Lambdabar
240 int id = 2 + belle2_phokhara_particles.bnphot;
241
242 //get lambdabar -> p+ anti-p and lambda -> pi p
243 MCParticleGraph::GraphParticle* lambdabar = &mcGraph[id];
244 MCParticleGraph::GraphParticle* daughter1 = &mcGraph[id + 2];
245 daughter1->comesFrom(*lambdabar);
246 MCParticleGraph::GraphParticle* daughter2 = &mcGraph[id + 3];
247 daughter2->comesFrom(*lambdabar);
248
249 MCParticleGraph::GraphParticle* lambda = &mcGraph[id + 1];
250 daughter1 = &mcGraph[id + 4];
251 daughter1->comesFrom(*lambda);
252 daughter2 = &mcGraph[id + 5];
253 daughter2->comesFrom(*lambda);
254
257 }
258
259 if (m_weighted)
260 return belle2_phokhara_particles.wgt;
261 return 1.0;
262
263}
264
265
267{
268
269 int mode = 2;
270 phokhara(&mode, m_xpar, m_npar);
271
272// B2INFO("> Crosssection ")
273// B2INFO(">> xsec (weighted) = (" << bresults_.rescross << " +/- " << bresults_.rescrosserr << ") nb")
274// for (int i = 0; i < 3; i++) {
275// B2INFO(">>> " << i << " photon(s), xsec (weighted) = (" << bresults_.rescrossphot[i] << " +/- " << bresults_.rescrossphoterr[i] << ") nb, fraction = " << bresults_.rescrossphotfrac[i]*100.<< "%")
276// }
277//
278// B2INFO(">>> xsec (unweighted) = (" << bhitnmiss_.hnmcross << " +/- " << bhitnmiss_.hnmcrosserr << ") nb")
279// for (int i = 0; i < 3; i++) {
280// B2INFO(">>> " << i << " photon(s), xsec (unweighted) = (" << bhitnmiss_.hnmcrossphot[i] << " +/- " << bhitnmiss_.hnmcrossphoterr[i] << ") nb, fraction.= " << bhitnmiss_.hnmcrossphotfrac[i]*100.<< "%")
281// }
282//
283// B2INFO("> hit/miss efficiency")
284// for (int i = 0; i < 3; i++) {
285// B2INFO(">>> " << i << " photon(s),eff.= " << bhitnmiss_.hnmeff[i]*100.<< "%")
286// }
287}
288
289//=========================================================================
290// Protected methods
291//=========================================================================
292
294{
295
296 //--------------------
297 // Integer parameters
298 //--------------------
299 m_npar[1] = m_nMaxTrials;
300 m_npar[2] = m_nSearchMax;
301 m_npar[3] = m_weighted;
302 m_npar[20] = m_finalState;
303 m_npar[30] = m_LO;
304 m_npar[31] = m_NLO;
305 m_npar[32] = m_QED;
306 m_npar[33] = m_IFSNLO;
307 m_npar[34] = m_alpha;
308 m_npar[35] = m_pionff;
310 m_npar[37] = m_kaonff;
311 m_npar[38] = m_narres;
312 m_npar[39] = m_protonff;
313 m_npar[40] = m_fullNLO;
314 m_npar[50] = m_chi_sw;
315 m_npar[51] = m_be_r;
316 m_npar[60] = m_weighted;
317
318 //--------------------
319 // Double parameters
320 //--------------------
321 m_xpar[0] = m_cmsEnergy;
322 m_xpar[11] = m_epsilon;
323
328
333
334 m_xpar[30] = m_beamres;
335
336 int mode = -1; //use mode to control init/generation/finalize in FORTRAN code
337 phokhara(&mode, m_xpar, m_npar);
338 if (belle2_error_flag_.error_flag != 0) {
339 B2FATAL("Phokhara returned a non-zero exit code. Check the output of phokara.");
340 }
341}
342
343
344void Phokhara::storeParticle(MCParticleGraph& mcGraph, const double* mom, int pdg, ROOT::Math::XYZVector vertex,
345 ROOT::Math::LorentzRotation boost, bool isVirtual, bool isInitial)
346{
347
348 // Create particle
350
351 //all particles are primary!
353
354 //all particles are stable (if not, will be changed later)!
356
357 if (isVirtual) {
359 } else if (isInitial) {
361 }
362
363 //set photon flags
364 if (pdg == 22) {
367 }
368
369 part.setPDG(pdg);
370 part.setFirstDaughter(0);
371 part.setLastDaughter(0);
372 part.setMomentum(ROOT::Math::XYZVector(mom[0], mom[1], mom[2]));
373 // part.get4Vector() uses mass, need to set invariant mass for virtual photons
374 if ((m_finalState == 0) && m_replaceMuonsByVirtualPhoton && (pdg == 10022))
375 part.setMass(sqrt(mom[3] * mom[3] - mom[0] * mom[0] - mom[1] * mom[1] -
376 mom[2] * mom[2]));
377 else
378 part.setMass(TDatabasePDG::Instance()->GetParticle(pdg)->Mass());
379 part.setEnergy(mom[3]);
380
381 //boost
382 ROOT::Math::PxPyPzEVector p4 = part.get4Vector();
383 p4 = boost * p4;
384 part.set4Vector(p4);
385
386 //set vertex
387 if (!isInitial) {
388 ROOT::Math::XYZVector v3 = part.getProductionVertex();
389 v3 = v3 + vertex;
390 part.setProductionVertex(v3);
391 part.setValidVertex(true);
392 }
393}
Class to represent Particle data in graph.
void comesFrom(GraphParticle &mother)
Tells the graph that this particle is a decay product of mother.
void setFirstDaughter(int daughter)
Set the 1-based index of the first daughter, 0 means no daughters.
void setLastDaughter(int daughter)
Set the 1-based index of the last daughter, 0 means no daughters.
Class to build, validate and sort a particle decay chain.
@ c_IsFSRPhoton
bit 7: Particle is from finial state radiation
Definition: MCParticle.h:61
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
Definition: MCParticle.h:57
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:47
@ c_IsVirtual
bit 4: Particle is virtual and not going to Geant4.
Definition: MCParticle.h:55
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition: MCParticle.h:49
@ c_IsISRPhoton
bit 6: Particle is from initial state radiation
Definition: MCParticle.h:59
void setMass(float mass)
Set particle mass.
Definition: MCParticle.h:366
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
Definition: MCParticle.h:353
void setEnergy(float energy)
Set energy.
Definition: MCParticle.h:372
ROOT::Math::XYZVector getProductionVertex() const
Return production vertex position.
Definition: MCParticle.h:189
void setValidVertex(bool valid)
Set indication wether vertex and time information is valid or just default.
Definition: MCParticle.h:378
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
Definition: MCParticle.h:396
void removeStatus(unsigned short int bitmask)
Remove bitmask from current status.
Definition: MCParticle.h:360
ROOT::Math::PxPyPzEVector get4Vector() const
Return 4Vector of particle.
Definition: MCParticle.h:207
void setPDG(int pdg)
Set PDG code of the particle.
Definition: MCParticle.h:335
void set4Vector(const ROOT::Math::PxPyPzEVector &p4)
Sets the 4Vector of particle.
Definition: MCParticle.h:438
void setMomentum(const ROOT::Math::XYZVector &momentum)
Set particle momentum.
Definition: MCParticle.h:417
double m_beamres
beam resolution for chi2 studies
Definition: Phokhara.h:242
int m_pionstructure
for pi+pi- only: f0+f0(600): K+K- model(0), "no structure" model(1), no f0+f0(600)(2),...
Definition: Phokhara.h:228
int m_LO
LO: 1ph(0, default), Born: 0ph(1), only Born: 0ph(-1)
Definition: Phokhara.h:221
void init(const std::string &paramFile)
Initializes the generator.
Definition: Phokhara.cc:166
double m_alphaQED0
QED coupling constant at Q=0.
Definition: Phokhara.h:206
bool m_ForceMinInvMassHadronsCut
Force application of the above cut.
Definition: Phokhara.h:239
int m_finalState
final state, called 'pion' in Phokhara, dont get confused.
Definition: Phokhara.h:214
int m_npar[100]
Integer parameters for PHOKHARA.
Definition: Phokhara.h:264
double m_conversionFactor
Conversion factor for hbarc to nb.
Definition: Phokhara.h:205
std::pair< double, double > m_ScatteringAngleRangeFinalStates
Minimal/Maximal pions(muons,nucleons,kaons) momentum angle.
Definition: Phokhara.h:236
int m_QED
ISR only(0), ISR+FSR(1), ISR+INT+FSR(2)
Definition: Phokhara.h:224
void storeParticle(MCParticleGraph &mcGraph, const double *mom, int pdg, ROOT::Math::XYZVector vertex, ROOT::Math::LorentzRotation boost, bool isVirtual=false, bool isInitial=false)
Store a single generated particle into the MonteCarlo graph.
Definition: Phokhara.cc:344
void setDefaultSettings()
Sets the default settings for the PHOKHARA generator.
Definition: Phokhara.cc:98
Phokhara()
Constructor.
Definition: Phokhara.cc:83
int m_narres
narr_res: no narrow resonances (0), J/psi (1) and psi(2S) (2) only for m_finalState = 0,...
Definition: Phokhara.h:230
~Phokhara()
Destructor.
Definition: Phokhara.cc:93
double m_cmsEnergy
CMS Energy = 2*Ebeam [GeV].
Definition: Phokhara.h:218
int m_alpha
vacuum polarization switch: off (0), on (1,[by Fred Jegerlehner]), on (2,[by Thomas Teubner])
Definition: Phokhara.h:226
int m_chi_sw
chi_sw: Radiative return(0), Chi production(1), Radiative return + Chi production (2)
Definition: Phokhara.h:232
double m_epsilon
Soft/hard photon separator in units of CMS/2., called 'w' in Phokhara.
Definition: Phokhara.h:219
double m_massMuon
electron mass.
Definition: Phokhara.h:208
int m_pionff
FF_pion: KS PionFormFactor(0),GS old (1),GS new (2)
Definition: Phokhara.h:227
double m_massW
W mass [GeV] for on shell sin2theta and GF.
Definition: Phokhara.h:209
int m_protonff
ProtonFormFactor old(0), ProtonFormFactor new(1)
Definition: Phokhara.h:231
std::pair< double, double > m_ScatteringAngleRangePhoton
Minimal/Maximal photon angle/missing momentum angle.
Definition: Phokhara.h:235
double m_widthZ
Z width [GeV] (may be recalculated by EW library).
Definition: Phokhara.h:211
void term()
Terminates the generator.
Definition: Phokhara.cc:266
int m_IFSNLO
IFSNLO: no(0), yes(1)
Definition: Phokhara.h:225
int m_nSearchMax
Events used to search maximum of differential cross section.
Definition: Phokhara.h:217
int m_nMaxTrials
Events before loop is aborted.
Definition: Phokhara.h:216
double generateEvent(MCParticleGraph &mcGraph, ROOT::Math::XYZVector vertex, ROOT::Math::LorentzRotation boost)
Generates one single event.
Definition: Phokhara.cc:181
int m_be_r
be_r: without beam resolution(0), with beam resolution(1)
Definition: Phokhara.h:233
double m_MinInvMassHadronsGamma
minimum mass of the hadron-gamma system [GeV^2]
Definition: Phokhara.h:237
double m_xpar[100]
Double parameters for PHOKHARA.
Definition: Phokhara.h:265
double m_massZ
Z mass [GeV].
Definition: Phokhara.h:210
int m_kaonff
FF_kaon: KaonFormFactor constrained(0), KaonFormFactor unconstrained(1) KaonFormFactor old(2)
Definition: Phokhara.h:229
double m_pi
pi=3.1415....
Definition: Phokhara.h:204
double m_massElectron
muon mass.
Definition: Phokhara.h:207
int m_weighted
generate weighted events
Definition: Phokhara.h:220
int m_NLO
NLO, for 1ph only: off (0, default), on (1)
Definition: Phokhara.h:222
double m_MaxInvMassHadrons
maximum mass of the hadron system [GeV^2]
Definition: Phokhara.h:240
int m_fullNLO
NLO, full NLO : No(0), Yes(1)
Definition: Phokhara.h:223
double m_MinEnergyGamma
minimum gamma energy [GeV]
Definition: Phokhara.h:241
double m_MinInvMassHadrons
minimum mass of the hadron system [GeV^2]
Definition: Phokhara.h:238
void applySettings()
Apply the settings to the internal Fortran generator.
Definition: Phokhara.cc:293
bool m_replaceMuonsByVirtualPhoton
Replace muons by a virtual photon.
Definition: Phokhara.h:215
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.
STL namespace.