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