evtgen is hosted by Hepforge, IPPP Durham
EvtGen  2.0.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
EvtVectorIsr.cpp
Go to the documentation of this file.
1 
2 /***********************************************************************
3 * Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4 * *
5 * This file is part of EvtGen. *
6 * *
7 * EvtGen is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * EvtGen is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19 ***********************************************************************/
20 
22 
24 #include "EvtGenBase/EvtConst.hh"
25 #include "EvtGenBase/EvtPDL.hh"
27 #include "EvtGenBase/EvtPatches.hh"
29 #include "EvtGenBase/EvtRandom.hh"
30 #include "EvtGenBase/EvtReport.hh"
32 
33 #include <iomanip>
34 #include <iostream>
35 #include <math.h>
36 #include <sstream>
37 #include <stdlib.h>
38 #include <string>
39 
40 std::string EvtVectorIsr::getName()
41 {
42  return "VECTORISR";
43 }
44 
46 {
47  return new EvtVectorIsr;
48 }
49 
51 {
52  // check that there are 2 arguments
53 
54  checkNDaug( 2 );
55 
59 
60  int narg = getNArg();
61  if ( narg > 4 )
62  checkNArg( 4 );
63 
64  csfrmn = 1.;
65  csbkmn = 1.;
66  fmax = 1.2;
67  firstorder = false;
68 
69  if ( narg > 0 )
70  csfrmn = getArg( 0 );
71  if ( narg > 1 )
72  csbkmn = getArg( 1 );
73  if ( narg > 2 )
74  fmax = getArg( 2 );
75  if ( narg > 3 )
76  firstorder = true;
77 }
78 
80 {
81  noProbMax();
82 }
83 
85 {
86  //the elctron mass
87  double electMass = EvtPDL::getMeanMass( EvtPDL::getId( "e-" ) );
88 
89  static EvtId gammaId = EvtPDL::getId( "gamma" );
90 
91  EvtParticle* phi;
92  EvtParticle* gamma;
93 
94  //4-mom of the two colinear photons to the decay of the vphoton
95  EvtVector4R p4softg1( 0., 0., 0., 0. );
96  EvtVector4R p4softg2( 0., 0., 0., 0. );
97 
98  //get pointers to the daughters set
99  //get masses/initial phase space - will overwrite the
100  //p4s below to get the kinematic distributions correct
102  phi = p->getDaug( 0 );
103  gamma = p->getDaug( 1 );
104 
105  //Generate soft colinear photons and the electron and positron energies after emission.
106  //based on method of AfkQed and notes of Vladimir Druzhinin.
107  //
108  //function ckhrad(eb,q2m,r1,r2,e01,e02,f_col)
109  //eb: energy of incoming electrons in CM frame
110  //q2m: minimum invariant mass of the virtual photon after soft colinear photon emission
111  //returned arguments
112  //e01,e02: energies of e+ and e- after soft colinear photon emission
113  //fcol: weighting factor for Born cross section for use in an accept/reject test.
114 
115  double wcm = p->mass();
116  double eb = 0.5 * wcm;
117 
118  //TO guarantee the collinear photons are softer than the ISR photon, require q2m > m*wcm
119  double q2m = phi->mass() * wcm;
120  double f_col( 0. );
121  double e01( 0. );
122  double e02( 0. );
123  double ebeam = eb;
124  double wcm_new = wcm;
125  double s_new = wcm * wcm;
126 
127  double fran = 1.;
128  double f = 0;
129  int m = 0;
130  double largest_f =
131  0; //only used when determining max weight for this vector particle mass
132 
133  if ( !firstorder ) {
134  while ( fran > f ) {
135  m++;
136 
137  int n = 0;
138  while ( f_col == 0. ) {
139  n++;
140  ckhrad( eb, q2m, e01, e02, f_col );
141  if ( n > 10000 ) {
142  EvtGenReport( EVTGEN_INFO, "EvtGen" )
143  << "EvtVectorIsr is having problems. Called ckhrad 10000 times.\n";
144  assert( 0 );
145  }
146  }
147 
148  //Effective beam energy after soft photon emission (neglecting electron mass)
149  ebeam = sqrt( e01 * e02 );
150  wcm_new = 2 * ebeam;
151  s_new = wcm_new * wcm_new;
152 
153  //The Vector mass should never be greater than wcm_new
154  if ( phi->mass() > wcm_new ) {
155  EvtGenReport( EVTGEN_INFO, "EvtGen" )
156  << "EvtVectorIsr finds Vector mass=" << phi->mass()
157  << " > Weff=" << wcm_new << ". Should not happen\n";
158  assert( 0 );
159  }
160 
161  //Determine Born cross section @ wcm_new for e+e- -> gamma V. We aren't interested in the absolute normalization
162  //Just the functional dependence. Assuming a narrow resonance when determining cs_Born
163  double cs_Born = 1.;
164  if ( EvtPDL::getMaxRange( phi->getId() ) > 0. ) {
165  double x0 = 1 - EvtPDL::getMeanMass( phi->getId() ) *
166  EvtPDL::getMeanMass( phi->getId() ) / s_new;
167 
168  //L = log(s/(electMass*electMass)
169  double L = 2. * log( wcm_new / electMass );
170 
171  // W(x0) is actually 2*alpha/pi times the following
172  double W = ( L - 1. ) * ( 1. - x0 + 0.5 * x0 * x0 );
173 
174  //Born cross section is actually 12*pi*pi*Gammaee/EvtPDL::getMeanMass(phi->getId()) times the following
175  //(we'd need the full W(x0) as well)
176  cs_Born = W / s_new;
177  }
178 
179  f = cs_Born * f_col;
180 
181  //if fmax was set properly, f should NEVER be larger than fmax
182  if ( f > fmax && fmax > 0. ) {
183  EvtGenReport( EVTGEN_INFO, "EvtGen" )
184  << "EvtVectorIsr finds a problem with fmax, the maximum weight setting\n"
185  << "fmax is the third decay argument in the .dec file. VectorIsr attempts to set it reasonably if it wasn't provided\n"
186  << "To determine a more appropriate value, build GeneratorQAApp, and set the third argument for this decay <0.\n"
187  << "If you haven't been providing the first 2 arguments, set them to be 1. 1.). The program will report\n"
188  << "the largest weight it finds. You should set fmax to be slightly larger.\n"
189  << "Alternatively try the following values for various vector particles: "
190  << "phi->1.15 J/psi-psi(4415)->0.105\n"
191  << "The current value of f and fmax for "
192  << EvtPDL::name( phi->getId() ) << " are " << f << " "
193  << fmax << "\n"
194  << "Will now assert\n";
195  assert( 0 );
196  }
197 
198  if ( fmax > 0. ) {
199  fran = fmax * EvtRandom::Flat( 0.0, 1.0 );
200  }
201 
202  else {
203  //determine max weight for this vector particle mass
204  if ( f > largest_f ) {
205  largest_f = f;
206  EvtGenReport( EVTGEN_INFO, "EvtGen" )
207  << m << " " << EvtPDL::name( phi->getId() ) << " "
208  << "vector_mass "
209  << " " << EvtPDL::getMeanMass( phi->getId() )
210  << " fmax should be at least " << largest_f
211  << ". f_col cs_B = " << f_col << " " << cs_Born
212  << std::endl;
213  }
214  if ( m % 10000 == 0 ) {
215  EvtGenReport( EVTGEN_INFO, "EvtGen" )
216  << m << " " << EvtPDL::name( phi->getId() ) << " "
217  << "vector_mass "
218  << " " << EvtPDL::getMeanMass( phi->getId() )
219  << " fmax should be at least " << largest_f
220  << ". f_col cs_B = " << f_col << " " << cs_Born
221  << std::endl;
222  }
223 
224  f_col = 0.;
225  f = 0.;
226  //determine max weight for this vector particle mass
227  }
228 
229  if ( m > 100000 ) {
230  if ( fmax > 0. )
231  EvtGenReport( EVTGEN_INFO, "EvtGen" )
232  << "EvtVectorIsr is having problems. Check the fmax value - the 3rd argument in the .dec file\n"
233  << "Recommended values for various vector particles: "
234  << "phi->1.15 J/psi-psi(4415)->0.105 "
235  << "Upsilon(1S,2S,3S)->0.14\n";
236  assert( 0 );
237  }
238  } //while (fran > f)
239 
240  } //if (firstorder)
241 
242  //Compute parameters for boost to/from the system after colinear radiation
243 
244  double bet_l;
245  double gam_l;
246  double betgam_l;
247 
248  double csfrmn_new;
249  double csbkmn_new;
250 
251  if ( firstorder ) {
252  bet_l = 0.;
253  gam_l = 1.;
254  betgam_l = 0.;
255  csfrmn_new = csfrmn;
256  csbkmn_new = csbkmn;
257  } else {
258  double xx = e02 / e01;
259  double sq_xx = sqrt( xx );
260  bet_l = ( 1. - xx ) / ( 1. + xx );
261  gam_l = ( 1. + xx ) / ( 2. * sq_xx );
262  betgam_l = ( 1. - xx ) / ( 2. * sq_xx );
263 
264  //Boost photon cos_theta limits in lab to limits in the system after colinear rad
265  csfrmn_new = ( csfrmn - bet_l ) / ( 1. - bet_l * csfrmn );
266  csbkmn_new = ( csbkmn - bet_l ) / ( 1. - bet_l * csbkmn );
267  }
268 
269  // //generate kinematics according to Bonneau-Martin article
270  // //Nucl. Phys. B27 (1971) 381-397
271 
272  // For backward compatibility with .dec files before SP5, the backward cos limit for
273  //the ISR photon is actually given as *minus* the actual limit. Sorry, this wouldn't be
274  //my choice. -Joe
275 
276  //gamma momentum in the vpho restframe *after* soft colinear radiation
277  double pg = ( s_new - phi->mass() * phi->mass() ) / ( 2. * wcm_new );
278 
279  //calculate the beta of incoming electrons after colinear rad in the frame where e= and e- have equal momentum
280  double beta = electMass / ebeam; //electMass/Ebeam = 1/gamma
281  beta = sqrt( 1. - beta * beta ); //sqrt (1 - (1/gamma)**2)
282 
283  double ymax = log( ( 1. + beta * csfrmn_new ) / ( 1. - beta * csfrmn_new ) );
284  double ymin = log( ( 1. - beta * csbkmn_new ) / ( 1. + beta * csbkmn_new ) );
285 
286  // photon theta distributed as 2*beta/(1-beta**2*cos(theta)**2)
287  double y = ( ymax - ymin ) * EvtRandom::Flat( 0.0, 1.0 ) + ymin;
288  double cs = exp( y );
289  cs = ( cs - 1. ) / ( cs + 1. ) / beta;
290  double sn = sqrt( 1 - cs * cs );
291 
292  double fi = EvtRandom::Flat( EvtConst::twoPi );
293 
294  //four-vector for the phi
295  double phi_p0 = sqrt( phi->mass() * phi->mass() + pg * pg );
296  double phi_p3 = -pg * cs;
297 
298  //boost back to frame before colinear radiation.
299  EvtVector4R p4phi( gam_l * phi_p0 + betgam_l * phi_p3, -pg * sn * cos( fi ),
300  -pg * sn * sin( fi ), betgam_l * phi_p0 + gam_l * phi_p3 );
301 
302  double isr_p0 = pg;
303  double isr_p3 = -phi_p3;
304  EvtVector4R p4gamma( gam_l * isr_p0 + betgam_l * isr_p3, -p4phi.get( 1 ),
305  -p4phi.get( 2 ), betgam_l * isr_p0 + gam_l * isr_p3 );
306 
307  //four-vectors of the collinear photons
308  if ( !firstorder ) {
309  p4softg1.set( 0, eb - e02 );
310  p4softg1.set( 3, e02 - eb );
311  p4softg2.set( 0, eb - e01 );
312  p4softg2.set( 3, eb - e01 );
313  }
314 
315  //save momenta for particles
316  phi->init( getDaug( 0 ), p4phi );
317  gamma->init( getDaug( 1 ), p4gamma );
318 
319  //add the two colinear photons as vphoton daughters
320  EvtPhotonParticle* softg1 = new EvtPhotonParticle;
321  ;
322  EvtPhotonParticle* softg2 = new EvtPhotonParticle;
323  ;
324  softg1->init( gammaId, p4softg1 );
325  softg2->init( gammaId, p4softg2 );
326  softg1->addDaug( p );
327  softg2->addDaug( p );
328 
329  //try setting the spin density matrix of the phi
330  //get polarization vector for phi in its parents restframe.
331  EvtVector4C phi0 = phi->epsParent( 0 );
332  EvtVector4C phi1 = phi->epsParent( 1 );
333  EvtVector4C phi2 = phi->epsParent( 2 );
334 
335  //get polarization vector for a photon in its parents restframe.
336  EvtVector4C gamma0 = gamma->epsParentPhoton( 0 );
337  EvtVector4C gamma1 = gamma->epsParentPhoton( 1 );
338 
339  EvtComplex r1p = phi0 * gamma0;
340  EvtComplex r2p = phi1 * gamma0;
341  EvtComplex r3p = phi2 * gamma0;
342 
343  EvtComplex r1m = phi0 * gamma1;
344  EvtComplex r2m = phi1 * gamma1;
345  EvtComplex r3m = phi2 * gamma1;
346 
347  EvtComplex rho33 = r3p * conj( r3p ) + r3m * conj( r3m );
348  EvtComplex rho22 = r2p * conj( r2p ) + r2m * conj( r2m );
349  EvtComplex rho11 = r1p * conj( r1p ) + r1m * conj( r1m );
350 
351  EvtComplex rho13 = r3p * conj( r1p ) + r3m * conj( r1m );
352  EvtComplex rho12 = r2p * conj( r1p ) + r2m * conj( r1m );
353  EvtComplex rho23 = r3p * conj( r2p ) + r3m * conj( r2m );
354 
355  EvtComplex rho31 = conj( rho13 );
356  EvtComplex rho32 = conj( rho23 );
357  EvtComplex rho21 = conj( rho12 );
358 
359  EvtSpinDensity rho;
360  rho.setDim( 3 );
361 
362  rho.set( 0, 0, rho11 );
363  rho.set( 0, 1, rho12 );
364  rho.set( 0, 2, rho13 );
365  rho.set( 1, 0, rho21 );
366  rho.set( 1, 1, rho22 );
367  rho.set( 1, 2, rho23 );
368  rho.set( 2, 0, rho31 );
369  rho.set( 2, 1, rho32 );
370  rho.set( 2, 2, rho33 );
371 
373  phi->setSpinDensityForward( rho );
374 
375  return;
376 }
377 
378 double EvtVectorIsr::ckhrad1( double xx, double a, double b )
379 {
380  //port of AfkQed/ckhrad.F function ckhrad1
381  double yy = xx * xx;
382  double zz = 1. - 2 * xx + yy;
383  return 0.5 * ( 1. + yy + zz / ( a - 1. ) +
384  0.25 * b * ( -0.5 * ( 1. + 3 * yy ) * log( xx ) ) - zz );
385 }
386 
387 void EvtVectorIsr::ckhrad( const double& e_beam, const double& q2_min,
388  double& e01, double& e02, double& f )
389 {
390  //port of AfkQed/ckhrad.F subroutine ckhrad
391  const double adp = 1. / 137.0359895 / EvtConst::pi;
392  const double pi2 = EvtConst::pi * EvtConst::pi;
393  // const double dme = 0.00051099906;
394  const double dme = EvtPDL::getMeanMass( EvtPDL::getId( "e-" ) );
395 
396  double r1 = EvtRandom::Flat(); //Generates Flat from 0 - 1
397  double r2 = EvtRandom::Flat();
398 
399  double sss = 4. * e_beam * e_beam;
400  double biglog = log( sss / ( dme * dme ) );
401  double beta = 2. * adp * ( biglog - 1. );
402  double betae_lab = beta;
403  double p3 = adp * ( pi2 / 3. - 0.5 );
404  double p12 = adp * adp * ( 11. / 8. - 2. * pi2 / 3. );
405  double coefener = 1. + 0.75 * betae_lab + p3;
406  double coef1 = coefener + 0.125 * pi2 * beta * beta;
407  double coef2 = p12 * biglog * biglog;
408  double facts = coef1 + coef2;
409 
410  double y1_min = 0;
411  double e1min = 0.25 * q2_min / e_beam;
412  double y1_max = pow( 1. - e1min / e_beam, 0.5 * beta );
413  double y1 = y1_min + r1 * ( y1_max - y1_min );
414  e01 = e_beam * ( 1. - pow( y1, 2. / beta ) );
415 
416  double y2_min = 0.;
417  double e2min = 0.25 * q2_min / e01;
418  double y2_max = pow( 1. - e2min / e_beam, 0.5 * beta );
419  double y2 = y2_min + r2 * ( y2_max - y2_min );
420  e02 = e_beam * ( 1. - pow( y2, 2. / beta ) );
421 
422  double xx1 = e01 / e_beam;
423  double xx2 = e02 / e_beam;
424 
425  f = y1_max * y2_max * ckhrad1( xx1, biglog, betae_lab ) *
426  ckhrad1( xx2, biglog, betae_lab ) * facts;
427 
428  return;
429 }
static std::string name(EvtId i)
Definition: EvtPDL.cpp:382
void setSpinDensityForward(const EvtSpinDensity &rho)
Definition: EvtParticle.hh:337
double getArg(unsigned int j)
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
Evt3Rank3C conj(const Evt3Rank3C &t2)
Definition: Evt3Rank3C.cpp:172
std::string getName() override
static const double twoPi
Definition: EvtConst.hh:27
static double getMeanMass(EvtId i)
Definition: EvtPDL.cpp:314
virtual EvtVector4C epsParentPhoton(int i)
double ckhrad1(double xx, double a, double b)
EvtId getId() const
void init() override
void set(int i, double d)
Definition: EvtVector4R.hh:167
EvtId * getDaugs()
Definition: EvtDecayBase.hh:66
void ckhrad(const double &e_beam, const double &q2_min, double &e01, double &e02, double &f)
Definition: EvtId.hh:27
static const double pi
Definition: EvtConst.hh:26
double get(int i) const
Definition: EvtVector4R.hh:162
void init(EvtId part_n, double e, double px, double py, double pz)
double initializePhaseSpace(unsigned int numdaughter, EvtId *daughters, bool forceResetMasses=false, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
virtual EvtVector4C epsParent(int i) const
void decay(EvtParticle *p) override
void checkNDaug(int d1, int d2=-1)
void checkSpinParent(EvtSpinType::spintype sp)
static double Flat()
Definition: EvtRandom.cpp:72
void addDaug(EvtParticle *node)
void checkNArg(int a1, int a2=-1, int a3=-1, int a4=-1)
static EvtId getId(const std::string &name)
Definition: EvtPDL.cpp:287
void checkSpinDaughter(int d1, EvtSpinType::spintype sp)
double mass() const
int getNDaug() const
Definition: EvtDecayBase.hh:65
EvtComplex exp(const EvtComplex &c)
Definition: EvtComplex.hh:240
void setDaughterSpinDensity(int daughter)
EvtDecayBase * clone() override
EvtParticle * getDaug(int i)
Definition: EvtParticle.cpp:91
static double getMaxRange(EvtId i)
Definition: EvtPDL.cpp:347
void set(int i, int j, const EvtComplex &rhoij)
void initProbMax() override
void setDim(int n)
int getNArg() const
Definition: EvtDecayBase.hh:68
EvtId getDaug(int i) const
Definition: EvtDecayBase.hh:67