///////////////////////////////////////////////////////////////////
//
// JSFBeamGeneration
//
// Generate JLC beam momentum
//
//$Id: JSFBeamGeneration.cxx,v 1.2 2003/02/04 01:18:33 miyamoto Exp $
//
//////////////////////////////////////////////////////////////////
#include "TSystem.h"
#include "TFile.h"
#include "JSFBeamGeneration.h"
ClassImp(JSFBeamGeneration)
ClassImp(JSFBeamGenerationCain)
TFile *gJSFBeamFile;
JSFBeamGenerationCain *gJSFBeamGenerationCain;
JSFBeamGenerationCain *gjsfbs2dfunction;
extern "C" {
Double_t JSFBS2DFunction(Double_t *x, Double_t *p)
{
return gjsfbs2dfunction->BS2DFunction(x,p);
}
//___________________________________________________
TF2* JSFInitBS2DFunction(JSFBeamGenerationCain *bm)
{
gjsfbs2dfunction=bm;
TF2 *bsfunc=new TF2("JSFBS2DFunction", JSFBS2DFunction,
bm->GetBndOrder(),0.0,bm->GetBndOrder(),0.0,bm->GetPCntSize());
bsfunc->SetParameters(bm->GetPCnt());
return bsfunc;
}
//___________________________________________________
void jsfbeamgen_(const Double_t *xebm, const Double_t *xebp,
const Double_t *xbsm, const Double_t *xbsp,
Double_t *xm, Double_t *xp, Double_t *weight)
{
Double_t wgt=gJSFBeamGenerationCain->GetWeight(*xebm, *xebp,
*xbsm, *xbsp, *xm, *xp);
*weight=wgt;
}
//___________________________________________________
void jsfbeaminit_(Int_t *itype, Int_t *ibtyp, Double_t *bmwidth)
{
//(Usage)
// Generate beam energy, eminus and eplus
// energy is in unit of GeV.
//
Char_t *bsname[16]={"x250_n63", "jlca300", "jlca500", "jlcy300", "jlcy500",
"trc250", "trc300", "trc350", "trc400",
"trc450", "trc500", "trc1000"};
Char_t bsfile[256];
sprintf(bsfile,"%s/data/bsdata/%s.root",
gSystem->Getenv("JSFROOT"),bsname[*itype]);
TDirectory *cdir=gDirectory;
gJSFBeamFile=new TFile(bsfile);
gJSFBeamGenerationCain=(JSFBeamGenerationCain*)gJSFBeamFile->Get(bsname[*itype]);
if( *ibtyp == 1 ) {
gJSFBeamGenerationCain->SetIBParameters(*bmwidth,
JSFBeamGenerationCain::kUniform);
}
gJSFBeamGenerationCain->Print();
gJSFBeamGenerationCain->MakeBSMap();
cdir->cd();
}
}
//______________________________________________________
JSFBeamGeneration::JSFBeamGeneration()
{
fNGenerated=0;
fBeamDataFormat=0;
fLuminosity=0;
fNominalE=0;
fEEInitial=0;
fEPInitial=0;
fParameterName="dummy";
}
//______________________________________________________
JSFBeamGeneration::JSFBeamGeneration(Int_t format, Double_t lum, Double_t nominalE, Char_t *name)
{
fNGenerated=0;
fBeamDataFormat=format;
fNominalE=nominalE;
fLuminosity=lum;
fEEInitial=fNominalE;
fEPInitial=fNominalE;
fParameterName=name;
}
//_____________________________________________________
void JSFBeamGeneration::Print()
{
printf("JSFBeamGeneration n");
printf(" Initial Energy Spread : %g (relative)n",GetIBWidth());
printf(" Beamstrahlung : %sn",GetParameterName().Data());
printf(" Nominal Beam Energy = %g (GeV)n",GetNominalEnergy());
printf(" Luminosity = %g (x10^{33})n",fLuminosity);
}
//______________________________________________________
void JSFBeamGeneration::Generate(Double_t &eminus, Double_t &eplus)
{
IncrementEventNumber();
GenEnergySpread(fEEInitial, fEPInitial);
GenBeamStrahlung(eminus, eplus);
}
//_______________________________________________________
void JSFBeamGeneration::GenEnergySpread(Double_t &eminus, Double_t &eplus)
{
eminus=fNominalE;
eplus =fNominalE;
}
//_______________________________________________________
void JSFBeamGeneration::GenBeamStrahlung(Double_t &eminus, Double_t &eplus)
{
eminus=GetInitialElectronEnergy();
eplus =GetInitialPositronEnergy();
}
//______________________________________________________
void JSFBeamGeneration::Generate(TLorentzVector &ecm, TLorentzVector &vtx)
{
IncrementEventNumber();
GenEnergySpread(fEEInitial, fEPInitial);
GenBeamStrahlung(ecm, vtx);
}
//_______________________________________________________
void JSFBeamGeneration::GenBeamStrahlung(TLorentzVector &pecm, TLorentzVector &pvtx)
{
Double_t esum =GetInitialElectronEnergy()+GetInitialPositronEnergy();
Double_t pzsum=GetInitialElectronEnergy()-GetInitialPositronEnergy();
pecm.SetPxPyPzE(0.0, 0.0, pzsum, esum);
pvtx.SetPxPyPzE(0.0, 0.0, 0.0, 0.0);
}
//______________________________________________________
JSFBeamGenerationCain::JSFBeamGenerationCain()
{
for(Int_t i=0;i<3;i++){ fLumRatio[i]=0.0; }
fBndOrder=-5.0;
for(Int_t i=0;i<3;i++){ fPEdge1[i]=0.0; }
fNEdge2=0;
fPEdge2=NULL;
fNfits=0;
fNpmax=0;
fPCnt=NULL;
fIBType=kGauss;
fIBType=kUniform;
fIBWidth=0.0;
fBS2DFunction=NULL;
fMdiv=0;
fMapsize=0;
fMxmin=NULL;
fMxmax=NULL;
fMymin=NULL;
fMymax=NULL;
fMaint=NULL;
fMvmax=NULL;
}
//______________________________________________________
JSFBeamGenerationCain::~JSFBeamGenerationCain()
{
if ( fPEdge2 ) { delete fPEdge2; }
if ( fPCnt ) { delete fPCnt; }
if ( fBS2DFunction ) { delete fBS2DFunction; }
if ( fMxmin ) { delete fMxmin; }
if ( fMxmax ) { delete fMxmax; }
if ( fMymin ) { delete fMymin; }
if ( fMymax ) { delete fMymax; }
if ( fMaint ) { delete fMaint; }
if ( fMvmax ) { delete fMvmax; }
}
//______________________________________________________
void JSFBeamGenerationCain::SetBSParameters(const Int_t beamdataformat, const TString parametername,
const Double_t luminosity, const Double_t nominalE, const Double_t lumratio[3],
const Double_t bndorder, const Double_t pedge1[3], const Double_t edgelimit,
const Int_t fnedge2, const Double_t pedge2[], const Int_t nfits,
const Int_t npmax, const Double_t pcnt[])
{
fBeamDataFormat=beamdataformat;
fParameterName=parametername;
fLuminosity=luminosity;
fNominalE=nominalE;
printf(" fNominalE in JSFBeamGeneration is %gn",fNominalE);
fBndOrder=bndorder;
for(Int_t i=0;i<3;i++){ fLumRatio[i]=lumratio[i]; }
for(Int_t i=0;i<3;i++){ fPEdge1[i]=pedge1[i]; }
fPEdgeLimit=edgelimit;
fNEdge2=fnedge2;
fPEdge2=new Double_t[fNEdge2];
for(Int_t i=0;i<fNEdge2;i++){ fPEdge2[i]=pedge2[i]; }
fNfits=nfits;
fNpmax=npmax;
fPCntSize=fNfits*fNpmax;
fPCnt=new Double_t[fNfits*fNpmax];
for(Int_t i=0;i<fNfits*fNpmax;i++){ fPCnt[i]=pcnt[i]; }
fBS2DFunction=JSFInitBS2DFunction(this);
printf(" fNominalE in JSFBeamGeneration is %gn",fNominalE);
printf(" GetNominalEnergy is %gn",GetNominalEnergy());
printf(" Address of this object is %xn",(UInt_t)this);
}
//_____________________________________________________
void JSFBeamGenerationCain::SetIBParameters( const Double_t width, const EIBType type)
{
fIBType=type;
fIBWidth=width;
}
//_____________________________________________________
void JSFBeamGenerationCain::SetIBParameters(const Double_t nominalE,
const Double_t width, const EIBType type )
{
fIBType=type;
fIBWidth=width;
fNominalE=nominalE;
}
//_____________________________________________________
void JSFBeamGenerationCain::Print()
{
JSFBeamGeneration::Print();
TString btname[2];
btname[0]="Uniform";
btname[1]="Gauss";
printf(" Type of Initial beam energy spread : %sn",btname[GetIBType()-1].Data());
printf(" Relative luminosity of each region (%g, %g, %g n",
fLumRatio[0], fLumRatio[1], fLumRatio[2]);
}
//_____________________________________________________
void JSFBeamGenerationCain::GenEnergySpread(Double_t &eminus, Double_t &eplus)
{
if( GetIBWidth() <= 0.0 ) {
eminus=GetNominalEnergy();
eplus =GetNominalEnergy();
return;
}
switch( GetIBType() ) {
case kUniform:
eminus=GetNominalEnergy()*(1+2*GetIBWidth()*(0.5-GetRndm()));
eplus =GetNominalEnergy()*(1+2*GetIBWidth()*(0.5-GetRndm()));
break;
case kGauss:
eminus=GetNominalEnergy()*GetGauss(1.0, GetIBWidth());
eplus =GetNominalEnergy()*GetGauss(1.0, GetIBWidth());
break;
default:
printf("Error at JSFBeamGenerationCain::GenEnergySpreadn");
printf("Initial Beam type %d was not defined.n",GetIBType());
}
}
//_______________________________________________________
void JSFBeamGenerationCain::GenBeamStrahlung(Double_t &eminus, Double_t &eplus)
{
Double_t rnd1=GetRndm();
// When both beam does not have energy loss.
if( rnd1 < GetLumRatio(0) ) {
Double_t bndord=TMath::Power(10, GetBndOrder());
eminus=GetInitialElectronEnergy()*(1-bndord*GetRndm());
eplus =GetInitialPositronEnergy()*(1-bndord*GetRndm());
}
// When either electron or positron has energy logg
else if( rnd1 < GetLumRatio(1) ) {
Double_t bndord=TMath::Power(10, GetBndOrder());
if( GetRndm() < 0.5 ) {
eminus=GetInitialElectronEnergy()*(1-bndord*GetRndm());
eplus=GenBSEnergy1(GetInitialPositronEnergy());
}
else {
eminus=GenBSEnergy1(GetInitialElectronEnergy());
eplus =GetInitialPositronEnergy()*(1-bndord*GetRndm());
}
}
//
// Bot electron and positron has evergy loss.
else {
if ( GenBSEnergy2(eminus, eplus) ) { return ; }
printf("Error in JSFBeamGeneration::GenBeamStruhlung.");
printf("Failed to generate an event.n");
return ;
}
return;
}
//_______________________________________________________
Double_t JSFBeamGenerationCain::GetWeight(const Double_t xebm, const Double_t xebp,
const Double_t xbsm, const Double_t xbsp,
Double_t &xeminus, Double_t &xeplus)
{
// Using the input four random number, generate beam energy, eminus and eplus.
// Pointer to bases object is used to get additional random number
// xebm, xebp, xbsm, xbsp must be uniform random number between 0 to 1.
//
// Output energies, xeminus, xeplus are scaled energy [0,1+alpha]
Double_t weight=-1.0;
// First generate initial beam energy
if( GetIBType() != kUniform ) {
printf("Fatal error in JSFBeamGenerationCain::GetWeight") ;
printf("Initial beam shape other than uniform is not supported yetn");
return weight;
}
Double_t em=1+2*GetIBWidth()*(0.5-xebm);
Double_t ep=1+2*GetIBWidth()*(0.5-xebp);
// Decide beamstraulung spectrum.
// Assume eminus and eplus symmetry
Double_t xbnd=TMath::Sqrt(GetLumRatio(0));
weight=0.0;
if( xbsm < xbnd && xbsp < xbnd ) {
xeminus=em;
xeplus =ep;
weight=1.0;
}
//
// When either electron or positron has energy logg
else if ( xbsm < xbnd ) {
Double_t scrnd=(xbsp-xbnd)/(1.0-xbnd);
xeminus=em;
xeplus=GenBSEnergy1(ep, scrnd);
weight=(GetLumRatio(1)-GetLumRatio(0))/(2*xbnd*(1-xbnd));
}
else if ( xbsp < xbnd ) {
Double_t scrnd=(xbsm-xbnd)/(1.0-xbnd);
xeminus=GenBSEnergy1(em, scrnd);
xeplus=ep;
weight=(GetLumRatio(1)-GetLumRatio(0))/(2*xbnd*(1-xbnd));
}
//
// Bot electron and positron has evergy loss.
else {
Double_t scrndp=(xbsp-xbnd)/(1.0-xbnd);
Double_t scrndm=(xbsm-xbnd)/(1.0-xbnd);
weight=GetBSEnergy2Weight(scrndm, scrndp, xeminus, xeplus);
xeminus*=em;
xeplus*=ep;
weight*=(1.0-GetLumRatio(1))/((1-xbnd)*(1-xbnd));
}
return weight;
}
//_______________________________________________________
void JSFBeamGenerationCain::GenBeamStrahlung(TLorentzVector &pecm, TLorentzVector &pvtx)
{
Double_t eminus, eplus;
GenBeamStrahlung(eminus, eplus);
Double_t esum =eminus+eplus;
Double_t pzsum=eminus-eplus;
pecm.SetPxPyPzE(0.0, 0.0, pzsum, esum);
pvtx.SetPxPyPzE(0.0, 0.0, 0.0, 0.0);
}
//_______________________________________________________
Double_t JSFBeamGenerationCain::GenBSEnergy1(const Double_t eini, const Double_t xrand)
{
Double_t x=( xrand < 0.0 ? x=GetRndm() : x=xrand );
Double_t ebl;
if( x < fPEdgeLimit ) {
ebl=fPEdge1[0]*x*x + fPEdge1[1]*x + fPEdge1[2];
}
else {
ebl=fPEdge2[0];
for(Int_t i=1;i<9;i++){
ebl+= fPEdge2[i]*TMath::Power(x,i);
}
ebl*=TMath::Power(x, fPEdge2[9]);
}
Double_t eb=eini*(1-TMath::Power(10, ebl));
return eb;
}
//_______________________________________________________
Bool_t JSFBeamGenerationCain::GenBSEnergy2(Double_t &eminus, Double_t &eplus)
{
// When both electron and positron have energy loss.
Double_t eini=GetInitialElectronEnergy();
Double_t pini=GetInitialPositronEnergy();
Double_t xrnd=GetRndm();
for(Int_t i=0;i<fMapsize;i++){
if( fMaint[i] > xrnd ) {
Double_t xmin=fMxmin[i];
Double_t xmax=fMxmax[i];
Double_t ymin=fMymin[i];
Double_t ymax=fMymax[i];
Int_t maxloop=500;
for(Int_t j=0;j<maxloop;j++){
Double_t x=xmin+(xmax-xmin)*GetRndm();
Double_t y=ymin+(ymax-ymin)*GetRndm();
Double_t val=fBS2DFunction->Eval(x,y)/fMvmax[i];
Double_t xxrnd=GetRndm();
if( val > xxrnd ) {
eminus=eini*(1.0-TMath::Power(10.0,x));
eplus =pini*(1.0-TMath::Power(10.0,y));
return kTRUE;
}
}
printf(" Cannot generate E-beam after %d loopn",maxloop);
return kFALSE;
}
}
printf(" Unable to find proper bsmap binn");
return kFALSE;
}
//_______________________________________________________
Double_t JSFBeamGenerationCain::GetBSEnergy2Weight(const Double_t xbsm, const Double_t xbsp,
Double_t &eminus, Double_t &eplus)
{
// When both electron and positron have energy loss.
Double_t a=xbsm*fBndOrder;
Double_t b=xbsp*fBndOrder;
eminus=1.0 - TMath::Power(10.0, a);
eplus =1.0 - TMath::Power(10.0, b);
Double_t scale=fBndOrder*fBndOrder;
Double_t weight=scale*fBS2DFunction->Eval(a,b)/fTotalInt;
return weight;
}
//__________________________________________________
Double_t JSFBeamGenerationCain::BS1DFunction(Double_t *x, Double_t *p)
{
Double_t x1=x[0]+p[1];
Double_t t1=TMath::CosH( p[2]*(x[0]+p[4]) ) -1.0;
Double_t t2=TMath::Exp(p[3]*x1);
Double_t val1=p[0]*t1*t2;
if( x[0] > -p[4] ) { val1 = 0.0 ; }
return val1;
}
//_________________________________________________
Double_t JSFBeamGenerationCain::BS2DFunction(Double_t *xi, Double_t *par)
{
Double_t x=xi[0];
Double_t y=xi[1];
Double_t p[5];
p[0]=BS1DFunction(&y, &par[0]);
for(Int_t i=1;i<5;i++){
p[i]=PolFunc6(&y, &par[i*fNpmax]);
}
Double_t val=BS1DFunction(&x, p);
if( val < 0.0 ) { val = 0.0 ; }
return val;
}
//__________________________________________________
Double_t JSFBeamGenerationCain::PolFunc6(Double_t *xi, Double_t *par)
{
Double_t x=xi[0];
Double_t val=((((( par[6]*x + par[5] )*x + par[4] ) * x +
par[3] ) * x + par[2] )*x + par[1])*x + par[0] ;
return val;
}
//___________________________________________________
void JSFBeamGenerationCain::MakeBSMap()
{
// Create a data for beam generation.
if( !fBS2DFunction ) {
fBS2DFunction=JSFInitBS2DFunction(this);
}
Double_t totalint=fBS2DFunction->Integral(GetBndOrder(),0.0,GetBndOrder(),0.0);
fMdiv=-(Int_t)GetBndOrder();
fMapsize=fMdiv*fMdiv;
fMxmin=new Double_t[fMapsize];
fMxmax=new Double_t[fMapsize];
fMymin=new Double_t[fMapsize];
fMymax=new Double_t[fMapsize];
fMaint=new Double_t[fMapsize];
fMvmax=new Double_t[fMapsize];
Double_t xmin,xmax,ymin,ymax,xstp,ystp;
xstp=1.0; ystp=1.0;
Double_t ssum=0.0;
Int_t ip=0;
for(Int_t ix=0;ix<fMdiv;ix++){
xmin=GetBndOrder()+ix*xstp;
xmax=xmin+xstp;
for(Int_t iy=0;iy<fMdiv;iy++){
ymin=GetBndOrder()+iy*ystp;
ymax=ymin+ystp;
Double_t s=fBS2DFunction->Integral(xmin,xmax,ymin,ymax,1.0E-30);
ssum+=s;
fMxmin[ip]=xmin;
fMxmax[ip]=xmax;
fMymin[ip]=ymin;
fMymax[ip]=ymax;
fMaint[ip]=ssum/totalint;
ip++;
}
}
fTotalInt=totalint;
if( TMath::Abs(ssum/totalint-1.0) > 0.001 ) {
printf("Fatal error at JSFBeamGenerattion::MakeBSMapn");
printf(" Too much difference in total integration ");
printf(" and sum of each bins. Something is wrong.n");
exit(-1);
}
if( ip != fMapsize ) {
printf(" Error in JSFBeamGenerationCain::MakeBSMap ..# of map data(%d)",ip);
printf(" exceeds defined size of map (%d)n",fMapsize);
exit(-1);
}
// Set maximum of each area
Double_t nscan=2*fMdiv;
for(Int_t i=0;i<fMapsize;i++){
Double_t vmax=0.0;
Double_t vstp=0.0;
for(Double_t x=fMxmin[i];x<=fMxmax[i];
x+=(fMxmax[i]-fMxmin[i])/nscan) {
for(Double_t y=fMymin[i];y<=fMymax[i];
y+=(fMymax[i]-fMymin[i])/nscan) {
Double_t val=fBS2DFunction->Eval(x,y);
if( val > vmax ) {
if( val-vmax > vstp ) { vstp = val-vmax; }
vmax=val;
}
}
}
fMvmax[i]=vmax+vstp;
}
}
ROOT page - Home page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.