]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TEvtGen/EvtGen/EvtGenModels/EvtVectorIsr.cpp
Converting TEvtGen to native cmake
[u/mrichter/AliRoot.git] / TEvtGen / EvtGen / EvtGenModels / EvtVectorIsr.cpp
diff --git a/TEvtGen/EvtGen/EvtGenModels/EvtVectorIsr.cpp b/TEvtGen/EvtGen/EvtGenModels/EvtVectorIsr.cpp
new file mode 100644 (file)
index 0000000..40223d6
--- /dev/null
@@ -0,0 +1,427 @@
+//--------------------------------------------------------------------------
+//
+// Environment:
+//      This software is part of the EvtGen package developed jointly
+//      for the BaBar and CLEO collaborations.  If you use all or part
+//      of it, please give an appropriate acknowledgement.
+//
+// Copyright Information: See EvtGen/COPYRIGHT
+//      Copyright (C) 1998      Caltech, UCSB
+//
+// Module: EvtVectorIsr.cc
+//
+// Description: 
+//   This is a special decay model to generate e+e- -> phi gamma + soft gammas
+//   using soft collinear ISR calculation from AfkQed
+//   This is implemented as a decay of the VPHO.
+//
+// Modification history:
+//
+//    Joe Izen        Oct, 2005             Soft Colinear Photons (secondary ISR) ported from AfkQed
+//    Joe Izen        Dec  16, 2002         Fix cos_theta distribution - prevents boom at cos_theta=+/-1 
+//    RYD/Adriano     June 16, 1998         Module created
+//
+//------------------------------------------------------------------------
+//
+#include "EvtGenBase/EvtPatches.hh"
+#include <stdlib.h>
+
+#include <math.h>
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+
+
+#include "EvtGenBase/EvtParticle.hh"
+#include "EvtGenBase/EvtPhotonParticle.hh"
+#include "EvtGenBase/EvtRandom.hh"
+#include "EvtGenBase/EvtPDL.hh"
+#include "EvtGenBase/EvtAbsLineShape.hh"
+#include "EvtGenModels/EvtVectorIsr.hh"
+#include "EvtGenBase/EvtReport.hh"
+#include "EvtGenBase/EvtConst.hh"
+#include "EvtGenBase/EvtAbsLineShape.hh"
+#include <string>
+#include "EvtGenBase/EvtVector4C.hh"
+
+EvtVectorIsr::~EvtVectorIsr() {}
+
+std::string EvtVectorIsr::getName(){
+
+  return "VECTORISR";     
+}
+
+EvtDecayBase* EvtVectorIsr::clone(){
+
+  return new EvtVectorIsr;
+}
+
+void EvtVectorIsr::init(){
+
+  // check that there are 2 arguments
+  
+  checkNDaug(2);
+  
+  checkSpinParent(EvtSpinType::VECTOR);
+  checkSpinDaughter(0,EvtSpinType::VECTOR);
+  checkSpinDaughter(1,EvtSpinType::PHOTON);
+
+  int narg = getNArg();
+  if ( narg > 4 ) checkNArg(4);
+
+  csfrmn=1.;
+  csbkmn=1.;
+  fmax=1.2;
+  firstorder=false;
+
+  if ( narg > 0 ) csfrmn=getArg(0);
+  if ( narg > 1 ) csbkmn=getArg(1);
+  if ( narg > 2 ) fmax=getArg(2);
+  if ( narg > 3 ) firstorder=true;
+}
+
+
+void EvtVectorIsr::initProbMax(){
+
+  noProbMax();
+}
+
+void EvtVectorIsr::decay( EvtParticle *p ){
+
+  //the elctron mass
+  double electMass=EvtPDL::getMeanMass(EvtPDL::getId("e-"));
+
+  static EvtId gammaId=EvtPDL::getId("gamma");
+
+  EvtParticle *phi;
+  EvtParticle *gamma;
+
+  //4-mom of the two colinear photons to the decay of the vphoton
+  EvtVector4R p4softg1(0.,0.,0.,0.);
+  EvtVector4R p4softg2(0.,0.,0.,0.);
+
+
+  //get pointers to the daughters set
+  //get masses/initial phase space - will overwrite the
+  //p4s below to get the kinematic distributions correct
+  p->initializePhaseSpace(getNDaug(),getDaugs());
+  phi=p->getDaug(0);
+  gamma=p->getDaug(1);
+
+  //Generate soft colinear photons and the electron and positron energies after emission.
+  //based on method of AfkQed and notes of Vladimir Druzhinin.
+  //
+  //function ckhrad(eb,q2m,r1,r2,e01,e02,f_col)
+  //eb:      energy of incoming electrons in CM frame
+  //q2m:     minimum invariant mass of the virtual photon after soft colinear photon emission
+  //returned arguments
+  //e01,e02: energies of e+ and e- after soft colinear photon emission
+  //fcol:    weighting factor for Born cross section for use in an accept/reject test.
+
+
+  double wcm=p->mass();
+  double eb=0.5*wcm;
+
+  //TO guarantee the collinear photons are softer than the ISR photon, require q2m > m*wcm
+  double q2m=phi->mass()*wcm;
+  double f_col(0.);
+  double e01(0.);
+  double e02(0.);
+  double ebeam=eb;
+  double wcm_new = wcm;
+  double s_new = wcm*wcm;
+
+  double fran = 1.;
+  double f = 0;
+  int m = 0;
+  double largest_f=0;//only used when determining max weight for this vector particle mass
+    
+  if (!firstorder){
+    while (fran > f){
+      m++;    
+    
+      int n=0;
+      while (f_col == 0.){
+       n++;
+       ckhrad(eb,q2m,e01,e02,f_col);
+       if (n > 10000){
+         report(INFO,"EvtGen") << "EvtVectorIsr is having problems. Called ckhrad 10000 times.\n";
+         assert(0);
+       }
+      }
+    
+      //Effective beam energy after soft photon emission (neglecting electron mass)
+      ebeam = sqrt(e01*e02);
+      wcm_new = 2*ebeam;
+      s_new = wcm_new*wcm_new;
+    
+      //The Vector mass should never be greater than wcm_new
+      if (phi->mass() > wcm_new){
+       report(INFO,"EvtGen") << "EvtVectorIsr finds Vector mass="<<phi->mass()<<" > Weff=" << wcm_new<<".  Should not happen\n";
+       assert(0);
+      }
+      //Determine Born cross section @ wcm_new for e+e- -> gamma V.  We aren't interested in the absolute normalization
+      //Just the functional dependence. Assuming a narrow resonance when determining cs_Born
+      double cs_Born = 1.;
+      if (EvtPDL::getMaxRange(phi->getId()) > 0.) {
+       double x0 = 1 - EvtPDL::getMeanMass(phi->getId())*EvtPDL::getMeanMass(phi->getId())/s_new;
+      
+       //L = log(s/(electMass*electMass)  
+       double L = 2.*log(wcm_new/electMass);
+      
+       // W(x0) is actually 2*alpha/pi times the following
+       double W = (L-1.)*(1. - x0 +0.5*x0*x0);
+      
+       //Born cross section is actually 12*pi*pi*Gammaee/EvtPDL::getMeanMass(phi->getId()) times the following
+       //(we'd need the full W(x0) as well)
+       cs_Born = W/s_new;
+      }
+    
+      f = cs_Born*f_col;
+
+      //if fmax was set properly, f should NEVER be larger than fmax
+      if (f > fmax && fmax > 0.){
+         report(INFO,"EvtGen") << "EvtVectorIsr finds a problem with fmax, the maximum weight setting\n"
+            << "fmax is the third decay argument in the .dec file. VectorIsr attempts to set it reasonably if it wasn't provided\n"
+            << "To determine a more appropriate value, build GeneratorQAApp, and set the third argument for this decay <0.\n"
+            << "If you haven't been providing the first 2 arguments, set them to be 1. 1.). The program will report\n"
+            << "the largest weight it finds.  You should set fmax to be slightly larger.\n"
+            << "Alternatively try the following values for various vector particles: "
+            << "phi->1.15   J/psi-psi(4415)->0.105\n"
+            << "The current value of f and fmax for " << EvtPDL::name(phi->getId()) << " are " << f << "  " << fmax << "\n"
+            << "Will now assert\n";
+       assert(0);
+      }
+
+      if (fmax > 0.) {
+       fran = fmax*EvtRandom::Flat(0.0,1.0);
+      }
+    
+      else {
+       //determine max weight for this vector particle mass
+       if (f>largest_f) {
+         largest_f = f;
+         report(INFO,"EvtGen")  << m << " " <<  EvtPDL::name(phi->getId()) << " "
+              << "vector_mass " 
+              << " " << EvtPDL::getMeanMass(phi->getId()) << "  fmax should be at least " << largest_f 
+              << ".        f_col cs_B = " << f_col << " " << cs_Born 
+              << std::endl;
+       }
+       if (m%10000 == 0) {  
+         report(INFO,"EvtGen") << m << " " <<  EvtPDL::name(phi->getId()) << " "
+              << "vector_mass " 
+              << " " << EvtPDL::getMeanMass(phi->getId()) << "  fmax should be at least " << largest_f 
+              << ".        f_col cs_B = " << f_col << " " << cs_Born 
+              << std::endl;
+       }
+      
+       f_col = 0.;
+       f = 0.;
+       //determine max weight for this vector particle mass
+      }
+    
+      if (m > 100000){
+      
+       if (fmax > 0.) report(INFO,"EvtGen") << "EvtVectorIsr is having problems. Check the fmax value - the 3rd argument in the .dec file\n"
+                                            << "Recommended values for various vector particles: "
+                                            << "phi->1.15   J/psi-psi(4415)->0.105   "
+                                            << "Upsilon(1S,2S,3S)->0.14\n";
+       assert(0);
+      }
+    }//while (fran > f)
+  
+  }//if (firstorder)
+  
+  //Compute parameters for boost to/from the system after colinear radiation
+
+  double bet_l;
+  double gam_l;
+  double betgam_l;
+  
+  double csfrmn_new;
+  double csbkmn_new;
+
+  if (firstorder){
+    bet_l = 0.;
+    gam_l = 1.;
+    betgam_l = 0.;
+    csfrmn_new = csfrmn;
+    csbkmn_new = csbkmn;
+  } else {  
+    double xx       = e02/e01;
+    double sq_xx    = sqrt(xx);
+    bet_l    = (1.-xx)/(1.+xx);
+    gam_l    = (1.+xx)/(2.*sq_xx);
+    betgam_l = (1.-xx)/(2.*sq_xx);
+  
+    //Boost photon cos_theta limits in lab to limits in the system after colinear rad
+    csfrmn_new=(csfrmn - bet_l)/(1. - bet_l*csfrmn);
+    csbkmn_new=(csbkmn - bet_l)/(1. - bet_l*csbkmn);
+  }
+//    //generate kinematics according to Bonneau-Martin article
+//    //Nucl. Phys. B27 (1971) 381-397
+
+  // For backward compatibility with .dec files before SP5, the backward cos limit for
+  //the ISR photon is actually given as *minus* the actual limit. Sorry, this wouldn't be
+  //my choice.  -Joe
+
+   //gamma momentum in the vpho restframe *after* soft colinear radiation
+  double pg = (s_new - phi->mass()*phi->mass())/(2.*wcm_new);
+
+
+  //calculate the beta of incoming electrons after  colinear rad in the frame where e= and e- have equal momentum
+  double beta=electMass/ebeam; //electMass/Ebeam = 1/gamma
+  beta=sqrt(1. - beta*beta);   //sqrt (1 - (1/gamma)**2)
+
+  double ymax=log((1.+beta*csfrmn_new)/(1.-beta*csfrmn_new));
+  double ymin=log((1.-beta*csbkmn_new)/(1.+beta*csbkmn_new));
+
+  // photon theta distributed as  2*beta/(1-beta**2*cos(theta)**2)
+  double y=(ymax-ymin)*EvtRandom::Flat(0.0,1.0) + ymin;
+  double cs=exp(y);
+  cs=(cs - 1.)/(cs + 1.)/beta;
+  double sn=sqrt(1-cs*cs);
+
+  double fi=EvtRandom::Flat(EvtConst::twoPi);
+
+  //four-vector for the phi
+  double phi_p0 = sqrt(phi->mass()*phi->mass()+pg*pg);
+  double phi_p3 = -pg*cs;
+
+
+  //boost back to frame before colinear radiation.
+  EvtVector4R p4phi(gam_l*phi_p0 + betgam_l*phi_p3,
+                   -pg*sn*cos(fi),
+                   -pg*sn*sin(fi),
+                   betgam_l*phi_p0 + gam_l*phi_p3);
+
+  double isr_p0 = pg;
+  double isr_p3 = -phi_p3;
+  EvtVector4R p4gamma(gam_l*isr_p0 + betgam_l*isr_p3,
+                     -p4phi.get(1),
+                     -p4phi.get(2),
+                     betgam_l*isr_p0 + gam_l*isr_p3);
+
+  
+  //four-vectors of the collinear photons
+  if (!firstorder) {
+    p4softg1.set(0, eb-e02);    p4softg1.set(3, e02-eb);
+    p4softg2.set(0, eb-e01);    p4softg2.set(3, eb-e01);
+  }
+  
+  //save momenta for particles
+  phi->init( getDaug(0),p4phi);
+  gamma->init( getDaug(1),p4gamma);
+
+
+  //add the two colinear photons as vphoton daughters
+  EvtPhotonParticle *softg1=new EvtPhotonParticle;;
+  EvtPhotonParticle *softg2=new EvtPhotonParticle;;
+  softg1->init(gammaId,p4softg1);
+  softg2->init(gammaId,p4softg2);
+  softg1->addDaug(p);
+  softg2->addDaug(p);
+
+  //try setting the spin density matrix of the phi
+  //get polarization vector for phi in its parents restframe.
+  EvtVector4C phi0=phi->epsParent(0);
+  EvtVector4C phi1=phi->epsParent(1);
+  EvtVector4C phi2=phi->epsParent(2);
+
+  //get polarization vector for a photon in its parents restframe.
+  EvtVector4C gamma0=gamma->epsParentPhoton(0);
+  EvtVector4C gamma1=gamma->epsParentPhoton(1);
+
+  EvtComplex r1p=phi0*gamma0;
+  EvtComplex r2p=phi1*gamma0;
+  EvtComplex r3p=phi2*gamma0;
+
+
+  EvtComplex r1m=phi0*gamma1;
+  EvtComplex r2m=phi1*gamma1;
+  EvtComplex r3m=phi2*gamma1;
+
+  EvtComplex rho33=r3p*conj(r3p)+r3m*conj(r3m);
+  EvtComplex rho22=r2p*conj(r2p)+r2m*conj(r2m);
+  EvtComplex rho11=r1p*conj(r1p)+r1m*conj(r1m);
+
+  EvtComplex rho13=r3p*conj(r1p)+r3m*conj(r1m);
+  EvtComplex rho12=r2p*conj(r1p)+r2m*conj(r1m);
+  EvtComplex rho23=r3p*conj(r2p)+r3m*conj(r2m);
+
+  EvtComplex rho31=conj(rho13);
+  EvtComplex rho32=conj(rho23);
+  EvtComplex rho21=conj(rho12);
+
+
+  EvtSpinDensity rho;
+  rho.setDim(3);
+
+  rho.set(0,0,rho11);
+  rho.set(0,1,rho12);
+  rho.set(0,2,rho13);
+  rho.set(1,0,rho21);
+  rho.set(1,1,rho22);
+  rho.set(1,2,rho23);
+  rho.set(2,0,rho31);
+  rho.set(2,1,rho32);
+  rho.set(2,2,rho33);
+
+  setDaughterSpinDensity(0);
+  phi->setSpinDensityForward(rho);
+
+  return ;
+}
+
+double EvtVectorIsr::ckhrad1(double xx, double a, double b){
+  //port of AfkQed/ckhrad.F function ckhrad1
+  double yy = xx*xx; 
+  double zz = 1. - 2*xx + yy; 
+  return  0.5* (1. + yy + zz/(a-1.) + 0.25*b*( -0.5*(1. + 3*yy)*log(xx)) - zz  );
+}
+
+void EvtVectorIsr::ckhrad(const double& e_beam,const double& q2_min,double& e01,double& e02,double& f){
+  //port of AfkQed/ckhrad.F subroutine ckhrad
+  const double adp   = 1. / 137.0359895 / EvtConst::pi;
+  const double pi2   = EvtConst::pi*EvtConst::pi;
+  //  const double dme   = 0.00051099906;
+  const double dme   = EvtPDL::getMeanMass(EvtPDL::getId("e-"));
+
+  double r1=EvtRandom::Flat();//Generates Flat from 0 - 1
+  double r2=EvtRandom::Flat();
+
+  double sss    = 4.*e_beam*e_beam;
+  double biglog = log(sss/(dme*dme));
+  double beta   = 2.*adp*(biglog - 1.);
+  double betae_lab = beta;
+  double p3     = adp*(pi2/3. - 0.5);
+  double p12    = adp*adp * (11./8. - 2.*pi2/3.);
+  double coefener =  1. + 0.75*betae_lab + p3;
+  double coef1 = coefener + 0.125*pi2*beta*beta;
+  double coef2 = p12* biglog*biglog;
+  double facts  = coef1 + coef2; 
+  
+  double y1_min = 0;
+  double e1min  = 0.25 * q2_min/e_beam; 
+  double y1_max = pow( 1. - e1min/e_beam, 0.5*beta );
+  double y1     = y1_min +r1 *(y1_max - y1_min);
+  e01           = e_beam *(1. - pow(y1, 2./beta) );
+  
+  double y2_min = 0.;
+  double e2min  = 0.25 * q2_min/e01; 
+  double y2_max = pow( 1. - e2min/e_beam, 0.5*beta);
+  double y2     = y2_min +r2 *(y2_max - y2_min);
+  e02           = e_beam *(1. - pow(y2, 2./beta) );
+  
+
+  double xx1 = e01/e_beam;
+  double xx2 = e02/e_beam;
+
+  f = y1_max * y2_max * ckhrad1(xx1,biglog,betae_lab) * ckhrad1(xx2,biglog,betae_lab) * facts;
+
+  return;
+ }
+