Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8725485
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
27 KB
Subscribers
None
View Options
diff --git a/Decay/Radiation/IFDipole.cc b/Decay/Radiation/IFDipole.cc
--- a/Decay/Radiation/IFDipole.cc
+++ b/Decay/Radiation/IFDipole.cc
@@ -1,709 +1,706 @@
// -*- C++ -*-
//
// IFDipole.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2011 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFDipole class.
//
#include "IFDipole.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
using namespace ThePEG::Helicity;
using namespace Herwig;
void IFDipole::persistentOutput(PersistentOStream & os) const {
os << _alpha << ounit(_emin,GeV) << _maxwgt
<< _mode << _maxtry << _energyopt << _betaopt;
}
void IFDipole::persistentInput(PersistentIStream & is, int) {
is >> _alpha >> iunit(_emin,GeV) >> _maxwgt
>> _mode >> _maxtry >> _energyopt >> _betaopt;
}
ClassDescription<IFDipole> IFDipole::initIFDipole;
// Definition of the static class description member.
void IFDipole::Init() {
static ClassDocumentation<IFDipole> documentation
("The IFDipole class implements the initial-final dipole for the SOPTHY algorithm");
static Switch<IFDipole,unsigned int> interfaceUnWeight
("UnWeight",
"Control the type of unweighting to perform, only one should be used the"
" other options are for debugging purposes.",
&IFDipole::_mode, 1, false, false);
static SwitchOption interfaceUnWeightNoUnweighting
(interfaceUnWeight,
"NoUnweighting",
"Perform no unweighting",
0);
static SwitchOption interfaceUnWeightAllWeights
(interfaceUnWeight,
"AllWeights",
"Include all the weights",
1);
static SwitchOption interfaceUnWeightNoJacobian
(interfaceUnWeight,
"NoJacobian",
"Only include the dipole and YFS weights",
2);
static SwitchOption interfaceUnWeightDipole
(interfaceUnWeight,
"Dipole",
"Only include the dipole weight",
3);
static SwitchOption interfaceUnWeightYFS
(interfaceUnWeight,
"YFS",
"Only include the YFS weight",
4);
static Parameter<IFDipole,unsigned int> interfaceMaximumTries
("MaximumTries",
"Maximum number of attempts to unweight",
&IFDipole::_maxtry, 500, 10, 100000,
false, false, Interface::limited);
static Parameter<IFDipole,Energy> interfaceMinimumEnergyRest
("MinimumEnergyRest",
"The minimum energy of the photons in the rest frame of the decaying particle",
&IFDipole::_emin, MeV, 1.*MeV, ZERO, 10000.0*MeV,
false, false, Interface::limited);
static Parameter<IFDipole,double> interfaceMaximumWeight
("MaximumWeight",
"The maximum weight for unweighting",
&IFDipole::_maxwgt, 2.0, 0.0, 100.0,
false, false, Interface::limited);
static Switch<IFDipole,unsigned int> interfaceEnergyCutOff
("EnergyCutOff",
"The type of cut-off on the photon energy to apply",
&IFDipole::_energyopt, 1, false, false);
static SwitchOption interfaceEnergyCutOffRestFrame
(interfaceEnergyCutOff,
"RestFrame",
"Apply cut-off in rest frame",
1);
static SwitchOption interfaceEnergyCutOff2
(interfaceEnergyCutOff,
"LabFrame",
"Apply cut-off in lab frame",
2);
static Switch<IFDipole,unsigned int> interfaceBetaOption
("BetaOption",
"Option for the inclusive of the higher beta coefficients",
&IFDipole::_betaopt, 1, false, false);
static SwitchOption interfaceBetaOptionNone
(interfaceBetaOption,
"None",
"No higher betas included",
0);
static SwitchOption interfaceBetaOptionCollinear
(interfaceBetaOption,
"Collinear",
"Include the collinear approx",
1);
static SwitchOption interfaceBetaOptionCollinearVirtA
(interfaceBetaOption,
"CollinearVirtualA",
"Include the collinear approx with virtual corrections",
2);
static SwitchOption interfaceBetaOptionCollinearVirtB
(interfaceBetaOption,
"CollinearVirtualB",
"Include the collinear approx with virtual corrections",
3);
static SwitchOption interfaceBetaOptionExact
(interfaceBetaOption,
"Exact",
"Include the exact higher order terms if available",
4);
}
ParticleVector IFDipole::generatePhotons(const Particle & p,ParticleVector children) {
// set parameters which won't change in the event loop
// masses of the particles
_m[0] = p.mass();
_m[1] = children[0]->mass();
_m[2] = children[1]->mass();
// momenta before radiation in lab
for(unsigned int ix=0;ix<2;++ix){_qlab[ix]=children[ix]->momentum();}
// get the charges of the particles in units of the positron charge
// chrg1 is the charge of the parent and chrg2 is the charge of the
// charged child. Also we create a map between the arguments of
// _q???[X] _m[X] etc so that
// _q???[_map[0]] and _m[_map[0]] are the momenta and masses of
// the charged child while
// _q???[_map[1]] and _m[_map[1]] are the momenta and masses of
// the neutral child.
_chrg1 = p.dataPtr()->iCharge()/3.0;
if(children[1]->dataPtr()->iCharge()/3.0==0.0) {
_chrg2 = children[0]->dataPtr()->iCharge()/3.0;
_map[0] = 0; _map[1] = 1;
}
else if(children[0]->dataPtr()->iCharge()/3.0==0.0) {
_chrg2 = children[1]->dataPtr()->iCharge()/3.0;
_map[0] = 1; _map[1] = 0;
}
// check the radiating particle is not massless
// if(children[1]->mass()<
if(children[_map[0]]->mass()<1e-4*GeV) {
ostringstream message;
message << "IFDipole::generatePhotons() trying to generate QED radiation from "
<< children[_map[0]]->dataPtr()->PDGName() << "\n with mass " << children[_map[0]]->mass()/GeV
<< "which is much smaller than the mass of the electron.\n"
<< "This is probably due to reading events from a LHEF,\nskipping radiation in this case.\n";
generator()->logWarning( Exception(message.str(), Exception::warning));
return children;
}
- cerr << "testing mass "
- << children[_map[0]]->mass()/GeV << " "
- << children[_map[0]]->dataPtr()->mass()/GeV << "\n";
// boost the momenta to the rest frame
Boost boostv(p.momentum().boostVector());
// boost the particles to the parent rest frame
// and set the initial momenta of the charged particles
// in the dipole rest frame: currently this is the same
// as the boson rest frame...
for(unsigned int ix=0;ix<2;++ix) {
// KMH - 08/11/05 - This used to be boostv instead of -boostv
// -boostv is the boost from the lab to the parent rest frame
// whereas boostv goes the other way!!!
children[ix]->deepBoost(-boostv);
_qprf[ix]=children[ix]->momentum();
}
// perform the unweighting
double wgt;
unsigned int ntry(0);
do {
wgt =makePhotons(boostv,children);
++ntry;
// Record warnings about large and weird weights in the .log file.
if(wgt>_maxwgt||wgt<0.0||isnan(wgt)) {
generator()->log() << "IFDipole.cc:\n";
if(wgt>_maxwgt) {
generator()->log() << "Weight exceeds maximum for decay!\n";
}
if(wgt<0.0) {
generator()->log() << "Weight is negative! \n";
}
if(isnan(wgt)) {
generator()->log() << "Weight is NAN! \n";
wgt = 0.;
}
generator()->log() << p.PDGName() << " "
<< children[0]->PDGName() << " "
<< children[1]->PDGName()
<< endl
<< " Current Maximum = " << _maxwgt
<< endl
<< " Current Weight = " << wgt
<< endl;
generator()->log() << "Photon Multiplicity : "
<< _multiplicity << endl
<< "Original Parent rest frame momenta: " << endl
<< "charged child: " << ounit(_qprf[_map[0]],GeV) << endl
<< "neutral child: " << ounit(_qprf[_map[1]],GeV) << endl
<< "Parent rest frame momenta: " << endl
<< "charged child: " << ounit(_qnewprf[_map[0]],GeV)<< endl
<< "neutral child: " << ounit(_qnewprf[_map[1]],GeV)<< endl
<< "photons : " << ounit(_bigLprf,GeV) << endl
<< "Weights : " << endl
<< "_dipolewgt : " << _dipolewgt << endl
<< "_yfswgt : " << _yfswgt << endl
<< "_jacobianwgt : " << _jacobianwgt << endl
<< "_mewgt : " << _mewgt << endl;
for(unsigned int ct=0;ct<_multiplicity;ct++) {
generator()->log() << "_cosphot[" << ct << "]: " << _cosphot[ct] << endl;
generator()->log() << "_sinphot[" << ct << "]: " << _sinphot[ct] << endl;
}
if(wgt>_maxwgt) {
if(wgt<15.0) {
generator()->log() << "Resetting maximum weight"
<< endl << " New Maximum = " << wgt << endl;
_maxwgt=wgt;
} else {
generator()->log() << "Maximum weight set to limit (15)" << endl;
_maxwgt=15.0;
}
}
}
} while (wgt<(_maxwgt*UseRandom::rnd()) && ntry<_maxtry);
if(ntry>=_maxtry) {
generator()->log() << "IFDipole Failed to generate QED radiation for the decay "
<< p.PDGName() << " -> "
<< children[0]->PDGName() << " "
<< children[1]->PDGName() << endl;
return children;
}
// produce products after radiation if needed
if(_multiplicity>0) {
// change the momenta of the children, they are currently
// in parent rest frame
for(unsigned int ix=0;ix<2;++ix) {
LorentzRotation boost(solveBoost(_qnewprf[ix],children[ix]->momentum()));
children[ix]->deepTransform(boost);
// boost back to the lab
// KMH - 08/11/05 - This used to be -boostv instead of boostv
// -boostv is the boost from the lab to the parent rest frame
// whereas boostv goes the other way!!!
children[ix]->deepBoost(boostv);
}
// add the photons to the event record
tcPDPtr photon=getParticleData(ParticleID::gamma);
for(unsigned int ix=0;ix<_multiplicity;++ix) {
PPtr newphoton=new_ptr(Particle(photon));
newphoton->set5Momentum(_llab[ix]);
children.push_back(newphoton);
}
return children;
}
// otherwise just return the orginial particles
// boosted back to lab
else {
for(unsigned int ix=0;ix<children.size();++ix)
children[ix]->deepBoost(boostv);
return children;
}
}
// member which generates the photons
double IFDipole::makePhotons(Boost boostv,ParticleVector children) {
// set the initial parameters
// number of photons (zero)
_multiplicity=0;
// zero size of photon vectors
_lprf.clear();
_llab.clear();
// zero size of angle storage
_sinphot.clear();
_cosphot.clear();
// zero total momenta of the photons
_bigLprf=Lorentz5Momentum();
// set the initial values of the reweighting factors to one
_dipolewgt = 1.0;
_yfswgt = 1.0;
_jacobianwgt = 1.0;
_mewgt = 1.0;
// set the maximum photon energy (exact - no approximations here).
double boost_factor = 1.0;
_emax=(0.5*(_m[0]-sqr(_m[1]+_m[2])/_m[0]))*boost_factor;
// calculate the velocities of the children (crude/overvalued)
double beta1(sqrt( (_qprf[_map[0]].e()+_m[_map[0]+1])
*(_qprf[_map[0]].e()-_m[_map[0]+1])
)
/_qprf[_map[0]].e());
double beta2(sqrt( (_qprf[_map[1]].e()+_m[_map[1]+1])
*(_qprf[_map[1]].e()-_m[_map[1]+1])
)
/_qprf[_map[1]].e());
// calculate 1-beta to avoid numerical problems
double ombeta1(sqr(_m[_map[0]+1]/_qprf[_map[0]].e())/(1.+beta1));
double ombeta2(sqr(_m[_map[1]+1]/_qprf[_map[1]].e())/(1.+beta2));
// calculate the average photon multiplicity
double aver(nbar(beta1,ombeta1));
// calculate the number of photons using the poisson
_multiplicity = UseRandom::rndPoisson(aver);
// calculate the first part of the YFS factor
_yfswgt/=crudeYFSFormFactor(beta1,ombeta1);
// generate the photon momenta with respect to q1
// keeping track of the weight
double dipoles(1.);
for(unsigned int ix=0;ix<_multiplicity;++ix)
{ dipoles *= photon(beta1,ombeta1); }
// calculate contributions to the dipole weights so far
_dipolewgt /=dipoles;
// now do the momentum reshuffling
Lorentz5Momentum pmom(ZERO,ZERO,ZERO,_m[0],_m[0]);
if(_multiplicity>0) {
// total energy and momentum of photons
Energy L0(_bigLprf.e()),modL(_bigLprf.rho());
// squared invariant mass of final state fermions...
Energy2 m122 = sqr(_m[0]-L0)-sqr(modL);
if(m122<sqr(_m[1]+_m[2])) return 0.;
// 3-momenta of charged particles
Energy modq(_qprf[_map[0]].rho());
// total photon momentum perpendicular to charged child...
Energy LT(_bigLprf.perp());
// kallen function...
Energy4 kallen = ( m122 - sqr(_m[1]+_m[2]) )
* ( m122 - sqr(_m[1]-_m[2]) );
// discriminant of rho...
Energy4 droot = kallen-4.*sqr(_m[_map[0]+1]*LT);
if(droot<ZERO) return 0.;
double disc = (_m[0]-L0) * sqrt(droot) / (2.*modq*(m122+LT*LT));
// calculate the energy rescaling factor
double rho = disc-_bigLprf.z()
* (m122+sqr(_m[_map[0]+1])-sqr(_m[_map[1]+1]))
/ (2.*modq*(m122+LT*LT));
// calculate the rescaled charged child momentum
_qnewprf[_map[0]]=rho*_qprf[_map[0]];
_qnewprf[_map[0]].setMass(_m[_map[0]+1]);
_qnewprf[_map[0]].rescaleEnergy();
// rotate the photons so in parent rest frame rather
// than angle measured w.r.t q1 first work out the rotation
SpinOneLorentzRotation rotation;
rotation.setRotateZ(-_qprf[_map[0]].phi());
rotation.rotateY(_qprf[_map[0]].theta());
rotation.rotateZ(_qprf[_map[0]].phi());
// rotate the total
_bigLprf*=rotation;
// rotate the photons
for(unsigned int ix=0;ix<_multiplicity;++ix){_lprf[ix]*=rotation;}
// calculate the rescaled neutral child momentum
_qnewprf[_map[1]]=pmom-_qnewprf[_map[0]]-_bigLprf;
_qnewprf[_map[1]].setMass(_m[_map[1]+1]);
_qnewprf[_map[1]].rescaleEnergy();
// calculate the new dipole weight
// Note this (weight) is Lorentz invariant
// calculate velocities and 1-velocites
beta1=sqrt( (_qnewprf[_map[0]].e()+_m[_map[0]+1])
*(_qnewprf[_map[0]].e()-_m[_map[0]+1]))
/_qnewprf[_map[0]].e();
beta2=sqrt( (_qnewprf[_map[1]].e()+_m[_map[1]+1])
*(_qnewprf[_map[1]].e()-_m[_map[1]+1]))
/_qnewprf[_map[1]].e();
ombeta1=sqr(_m[_map[0]+1]/_qnewprf[_map[0]].e())/(1.+beta1);
ombeta2=sqr(_m[_map[1]+1]/_qnewprf[_map[1]].e())/(1.+beta2);
for(unsigned int ix=0;ix<_multiplicity;++ix)
{_dipolewgt*=exactDipoleWeight(beta1,ombeta1,ix);}
// calculate the second part of the yfs form factor
_yfswgt*=exactYFSFormFactor(beta1,ombeta1,beta2,ombeta2);
// Now boost from the parent rest frame to the lab frame
SpinOneLorentzRotation boost(boostv);
// Boosting charged particles
for(unsigned int ix=0;ix<2;++ix){_qnewlab[ix]=boost*_qnewprf[ix];}
// Boosting total photon momentum
_bigLlab=boost*_bigLprf;
// Boosting individual photon momenta
for(unsigned int ix=0;ix<_multiplicity;++ix)
{_llab.push_back(boost*_lprf[ix]);}
// Calculating jacobian weight
_jacobianwgt = jacobianWeight();
// Calculating beta^1 weight
_mewgt = meWeight(children);
// Apply phase space vetos...
if(kallen<(4.*sqr(_m[_map[0]+1]*LT))||m122<sqr(_m[1]+_m[2])||rho<0.0) {
// generator()->log() << "Outside Phase Space" << endl;
// generator()->log() << "Photon Multiplicity: "
// << _multiplicity << endl
// << "Original Parent rest frame momenta: " << endl
// << "charged child: " << _qprf[_map[0]] << endl
// << "neutral child: " << _qprf[_map[1]] << endl
// << "rescaling : " << rho << endl
// << "Parent rest frame momenta: " << endl
// << "charged child: " << _qnewprf[_map[0]] << endl
// << "neutral child: " << _qnewprf[_map[1]] << endl
// << "photons : " << _bigLprf << endl
// << endl;
_dipolewgt = 0.0 ;
_yfswgt = 0.0 ;
_jacobianwgt = 0.0 ;
_mewgt = 0.0 ;
}
_qprf[_map[0]].rescaleEnergy();
_qprf[_map[1]].rescaleEnergy();
_qnewprf[_map[0]].rescaleEnergy();
_qnewprf[_map[1]].rescaleEnergy();
if( ((abs(_m[0]-_bigLprf.e()-_qnewprf[0].e()-_qnewprf[1].e())>0.00001*MeV)||
(abs( _bigLprf.x()+_qnewprf[0].x()+_qnewprf[1].x())>0.00001*MeV)||
(abs( _bigLprf.y()+_qnewprf[0].y()+_qnewprf[1].y())>0.00001*MeV)||
(abs( _bigLprf.z()+_qnewprf[0].z()+_qnewprf[1].z())>0.00001*MeV))
&&(_dipolewgt*_jacobianwgt*_yfswgt*_mewgt>0.0)) {
Lorentz5Momentum ptotal = _bigLprf+_qnewprf[0]+_qnewprf[1];
ptotal.setE(ptotal.e()-_m[0]);
generator()->log()
<< "Warning! Energy Not Conserved! tol = 0.00001 MeV"
<< "\nwgt = " << _dipolewgt*_yfswgt*_jacobianwgt*_mewgt
<< "\nrho = " << rho
<< "\nmultiplicity = " << _multiplicity
<< "\n_qprf[_map[0]] = " << _qprf[_map[0]]/GeV
<< "\n_qprf[_map[1]] = " << _qprf[_map[1]]/GeV
<< "\n_qnewprf[_map[0]] = " << _qnewprf[_map[0]]/GeV << " "
<< _qnewprf[_map[0]].m()/GeV << " " << _m[_map[0]+1]/GeV
<< "\n_qnewprf[_map[1]] = " << _qnewprf[_map[1]]/GeV << " "
<< _qnewprf[_map[1]].m()/GeV << " " << _m[_map[1]+1]/GeV
<< "\n_bigLprf = " << _bigLprf/GeV
<< "\n_bigLprf.m2() = " << _bigLprf.m2()/GeV2
<< "\n_total out -in = " << ptotal/GeV
<< "\nRejecting Event. " << "\n";
_dipolewgt = 0.0 ;
_yfswgt = 0.0 ;
_jacobianwgt = 0.0 ;
_mewgt = 0.0 ;
}
}
// otherwise copy momenta
else
{ for(unsigned int ix=0;ix<2;++ix) {
_qnewprf[ix]=_qprf[ix];
_qnewlab[ix]=_qlab[ix];
}
_jacobianwgt = 1.0;
// calculate the second part of the yfs form factor
_yfswgt*=exactYFSFormFactor(beta1,ombeta1,beta2,ombeta2);
_dipolewgt = 1.0;
}
// Virtual corrections for beta_0:
// These should be zero for the scalar case as there is no
// collinear singularity going by the dipoles above...
// Use mass of decaying particle...
if(_betaopt==2) {
if((children[_map[0]]->dataPtr()->iSpin())==2) {
_mewgt += (0.5*_alpha/pi)
* log(sqr(_m[0]
/_m[_map[0]+1])
);
}
}
// OR Use invariant mass of final state children...
if(_betaopt==3) {
if((children[_map[0]]->dataPtr()->iSpin())==2) {
_mewgt += (0.5*_alpha/pi)
* log((_qnewprf[0]+_qnewprf[1]).m2()
/sqr(_m[_map[0]+1])
);
}
}
// calculate the weight depending on the option
double wgt;
if(_mode==0){wgt=_maxwgt;}
else if(_mode==1){wgt=_mewgt*_jacobianwgt*_yfswgt*_dipolewgt;}
else if(_mode==2){wgt=_jacobianwgt*_yfswgt*_dipolewgt;}
else if(_mode==3){wgt=_yfswgt*_dipolewgt;}
else {wgt=_yfswgt;}
return wgt;
}
double IFDipole::photon(double beta1,double ombeta1)
{
// generate the azimuthal angle randomly in -pi->+pi
double phi(-pi+UseRandom::rnd()*2.*pi);
// generate the polar angle
double r(UseRandom::rnd());
double costh,sinth,ombc;
ombc = pow(1.+beta1,1.-r)*pow(ombeta1,r);
costh = 1./beta1*(1.-ombc);
sinth = sqrt(ombc*(2.-ombc)-(1.+beta1)*ombeta1*sqr(costh));
// generate the ln(energy) uniformly in ln(_emin)->ln(_emax)
Energy energy = pow(_emax/_emin,UseRandom::rnd())*_emin;
// calculate the weight (omit the pre and energy factors
// which would cancel later anyway)
double wgt = 2./ombc;
// store the angles
_cosphot.push_back(costh);
_sinphot.push_back(sinth);
// store the four vector for the photon
_lprf.push_back(Lorentz5Momentum(energy*sinth*cos(phi),energy*sinth*sin(phi),
energy*costh,energy,ZERO));
// add the photon momentum to the total
_bigLprf+=_lprf.back();
// return the weight
return wgt;
}
double IFDipole::meWeight(ParticleVector children)
{
unsigned int spin = children[_map[0]]->dataPtr()->iSpin();
double mewgt = 1.0;
double beta1=sqrt( (_qnewprf[_map[0]].e()+_m[_map[0]+1])
*(_qnewprf[_map[0]].e()-_m[_map[0]+1]))
/_qnewprf[_map[0]].e();
double ombeta1=sqr(_m[_map[0]+1]/_qnewprf[_map[0]].e())/(1.+beta1);
// option which does nothing
if(_betaopt==0){mewgt=1.;}
// collinear approx
else if(_betaopt==1||_betaopt==2||_betaopt==3)
{
double ombc;
InvEnergy2 dipole;
for(unsigned int i=0;i<_multiplicity;++i) {
double opbc;
if(_cosphot[i]<0.0)
{ opbc=ombeta1+beta1*sqr(_sinphot[i])/(1.-_cosphot[i]); }
// if cos is greater than zero use result accurate as cos->-1
else
{ opbc=1.+beta1*_cosphot[i]; }
// if cos is greater than zero use result accurate as cos->1
if(_cosphot[i]>0.0)
{ ombc=ombeta1+beta1*sqr(_sinphot[i])/(1.+_cosphot[i]); }
// if cos is less than zero use result accurate as cos->-1
else
{ ombc=1.-beta1*_cosphot[i]; }
if(((_qnewprf[_map[0]].z()>ZERO)&&(_qprf[_map[0]].z()<ZERO))||
((_qnewprf[_map[0]].z()<ZERO)&&(_qprf[_map[0]].z()>ZERO))) {
dipole = sqr(beta1*_sinphot[i]/(opbc*_lprf[i].e()));
} else {
dipole = sqr(beta1*_sinphot[i]/(ombc*_lprf[i].e()));
}
// here "dipole" is the exact dipole function divided by alpha/4pi^2.
if(spin==2) {
Energy magpi= sqrt( sqr(_qnewprf[_map[0]].x())
+ sqr(_qnewprf[_map[0]].y())
+ sqr(_qnewprf[_map[0]].z())
);
mewgt += sqr(_lprf[i].e())*_qnewprf[_map[0]].e()*ombc
/ (sqr(magpi*_sinphot[i])*(_qnewprf[_map[0]].e()+_lprf[i].e()));
}
else if(spin==3) {
Energy2 pik = _qnewprf[_map[0]].e()*_lprf[i].e()
- _qnewprf[_map[0]].x()*_lprf[i].x()
- _qnewprf[_map[0]].y()*_lprf[i].y()
- _qnewprf[_map[0]].z()*_lprf[i].z();
Energy2 pjk = _m[0]*_lprf[i].e();
Energy2 pipj = _m[0]*_qnewprf[_map[0]].e();
mewgt += (2.*pjk*pipj/(pik*sqr(pipj+pjk))
+2.*pjk/(pik*(pipj+pik))
)/dipole;
}
else {
mewgt = 1.0;
}
}
}
return mewgt;
}
double IFDipole::exactYFSFormFactor(double beta1,double ombeta1,
double beta2,double ombeta2) {
double Y = 0.0 ;
double b = beta1 ;
double omb = ombeta1;
double c = beta2 ;
double omc = ombeta2;
double arg1 = -omc/(2.*c);
double arg2 = -omb*omc/(2.*(b+c));
double arg3 = 2.*b/(1.+b);
if(_m[_map[1]+1]!=ZERO) {
Y = _chrg1*_chrg2*(_alpha/(2.*pi))*(
log(_m[0]*_m[_map[1]+1]/sqr(2.*_emin))
+log(_m[_map[0]+1]*_m[_map[1]+1]/sqr(2.*_emin))
-(1./b )*log((1.+b)/omb)*log(sqr(_m[_map[1]+1]/(2.*_emin)))
-(1./b )*log(omb/(1.+b))
-(0.5/b )*sqr(log(omb/(1.+b)))
+((b+c )/(b*omc))*log((b+c )/(b*omc))
-((c+b*c)/(b*omc))*log((c+b*c)/(b*omc))
+((b+c )/(b+b*c))*log((b+c )/(b+b*c))
-((c*omb)/(b+b*c))*log((c*omb)/(b+b*c))
+(0.5/b)*( sqr(log( (b+c)/(b*omc)))-sqr(log((c+b*c)/(b*omc)))
+ sqr(log((c*omb)/(b+b*c)))-sqr(log((b+ c)/(b+b*c)))
)
+(2./b )*( real(Math::Li2(arg1))
- real(Math::Li2(arg2))
- real(Math::Li2(arg3))
)
+(1./b )*log((b+c)/(b+b*c))*log((1.+c)/(2.*c))
-(1./b )*log((c*omb)/(b*(1.+c)))*log((1.+b)*(1.+c)/(2.*(b+c)))
-(1./b )*log((2.*c/b)*((b+c)/(omc*(1.+c))))*log((b+c)/(c*omb))
);
}
else if(_m[_map[1]+1]==ZERO) {
Y = _chrg1*_chrg2*(_alpha/(2.*pi))*(
log(sqr(_m[0]/(2.*_emin)))
+log(sqr(_m[_map[0]+1]/(2.*_emin)))
-(1./b )*log((1.+b)/omb)
*log((sqr(_m[0])-sqr(_m[_map[0]+1]))/sqr(2.*_emin))
-0.5*log(omb*(1.+b)/sqr(2.*b))
+((1.+b)/(2.*b))*log((1.+b)/(2.*b))
-( omb/(2.*b))*log( omb/(2.*b))
-(1./b )*log((1.-b)/(1.+b))
+1.
+(0.5/b)*sqr(log( omb/(2.*b)))
-(0.5/b)*sqr(log((1.+b)/(2.*b)))
-(0.5/b)*sqr(log((1.-b)/(1.+b)))
-(2. /b)*real(Math::Li2(arg3))
);
}
return exp(Y);
}
double IFDipole::jacobianWeight() {
// calculate the velocities of the children (crude/overvalued)
Energy mag1old = sqrt( (_qprf[_map[0]].e() +_m[_map[0]+1])
*(_qprf[_map[0]].e() -_m[_map[0]+1])
);
Energy mag1new = sqrt( (_qnewprf[_map[0]].e()+_m[_map[0]+1])
*(_qnewprf[_map[0]].e()-_m[_map[0]+1])
);
Energy magL = sqrt( sqr(_bigLprf.x())
+ sqr(_bigLprf.y())
+ sqr(_bigLprf.z())
);
// 14/12/05 - KMH - This was another mistake. This is supposed to be
// the angel between _qnewprf[_map[0]] and _bigLprf instead of
// between _qnewprf[0] and _bigLprf. Stupid. Hopefully this weight
// is correct now.
// double cos1L = (_qnewprf[0].x()*_bigLprf.x()
// +_qnewprf[0].y()*_bigLprf.y()
// +_qnewprf[0].z()*_bigLprf.z()
// )
// /(mag1new*magL);
double cos1L = (_qnewprf[_map[0]].x()*_bigLprf.x()
+_qnewprf[_map[0]].y()*_bigLprf.y()
+_qnewprf[_map[0]].z()*_bigLprf.z()
)
/(mag1new*magL);
return abs( (_m[0]*sqr(mag1new)/mag1old)
/ ( mag1new*(_m[0]-_bigLprf.e())
+_qnewprf[_map[0]].e()*magL*cos1L
)
);
}
LorentzRotation IFDipole::solveBoost(const Lorentz5Momentum & q,
const Lorentz5Momentum & p ) const {
Energy modp = p.vect().mag();
Energy modq = q.vect().mag();
double betam = (p.e()*modp-q.e()*modq)/(sqr(modq)+sqr(modp)+p.mass2());
Boost beta = -betam*q.vect().unit();
ThreeVector<Energy2> ax = p.vect().cross( q.vect() );
double delta = p.vect().angle( q.vect() );
LorentzRotation R;
using Constants::pi;
if ( ax.mag2()/GeV2/MeV2 > 1e-16 ) {
R.rotate( delta, unitVector(ax) ).boost( beta );
}
else {
if(p.mass()>ZERO) {
R.boost(p.findBoostToCM(),p.e()/p.mass());
R.boost(q.boostVector(),q.e()/q.mass());
}
else {
if(modp>modq) beta = -betam*p.vect().unit();
R.boost( beta );
}
}
return R;
}
void IFDipole::doinit() {
Interfaced::doinit();
// get the value fo alpha from the Standard Model object
_alpha=generator()->standardModel()->alphaEM();
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jan 21, 1:45 AM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4243514
Default Alt Text
(27 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment