#include "hseed.h" #include "TROOT.h" #include "TString.h" #include "TSystem.h" #include "TFile.h" #include "TNtuple.h" #include "TRandom.h" #include #include #include #include #include using namespace std; typedef struct { Double_t ELab; Double_t momLab; Double_t px; Double_t py; Double_t pz; Double_t thetaScatLab; } particle; typedef struct { Double_t m0 ; Double_t me ; Double_t Pi ; Double_t piFac; Double_t twoPi; Double_t RandMax1 ; Double_t LargeRandNorm; void init(){ m0 = 931.5; //in Mev, mass unit ion me = 0.511; //in MeV, electron Pi = 3.14159; piFac = Pi/180.; twoPi = 2.*Pi; RandMax1 = (Double_t)RAND_MAX + 1; // global var LargeRandNorm = 1.0/Double_t(RAND_MAX*RandMax1); // global var } } constants; typedef struct { Int_t nElectronsEmitted; // no of electrons kicked out of target = sigmaElectron/sigmaIon*targetThickness/nuclearReactionLength //---------------------------------------- // read from input file vector refMom; vector probMom; Double_t probMomMax; //---------------------------------------- //---------------------------------------- // precalculated vars used in different places Double_t thetaScatMin; Double_t deltaThetaScat; Double_t dsdthetaMaxNorm; Double_t refMomMin; Double_t deltaRefMom ; Double_t beta0; //---------------------------------------- } globals; typedef struct { Bool_t doFilter ; Bool_t writeNtuple ; Double_t FilterMom ; //MEV Int_t nIonPerEvent ; // -> simulate -950 - +800 ns drifttime range Double_t Zion ; // Au Double_t Ebeam ; // MeV/nucleon Bool_t KshellFlag ; //emission from K shell Bool_t cutoffFlag ; // cutoff in scattering angle Int_t nBoundElectronsK ; // number of strongly bound electrons still attached to Au ion, less after each foil Int_t nBoundElectronsL ; // number of strongly bound electrons still attached to Au ion, less after each foil Int_t kScat ; //loop over scatter process at given momentum } config; Int_t readInput(TString filenameIn, vector& refMom, vector& probMom, Double_t& probMomMax ) { ifstream input(filenameIn.Data()); if (input.fail()) { cout<<"file "<>mom>>prob; if (!input.fail()){ probMom.push_back(prob); refMom.push_back(mom); if (prob>probMomMax) probMomMax = prob; } } input.close(); return 0; } Int_t precalculation(config& cfg,globals& g,constants& c) { Double_t refMomMax = g.refMom[g.refMom.size()-1]; g.refMomMin = g.refMom[0]; // global var g.deltaRefMom = refMomMax-g.refMomMin; // global var Double_t gamma0 = (cfg.Ebeam+c.m0)/c.m0; g.beta0 = sqrt(gamma0*gamma0-1.0)/gamma0; // global var Double_t mom0 = g.beta0*gamma0*c.me; Double_t Eshell =0;; if(cfg.KshellFlag) { Eshell = (cfg.Zion-1.)*(cfg.Zion-1.)*0.0136/1000. + c.me; // appr. screening for at least 2 k-shell electrons } else { Eshell = (cfg.Zion-3.)*(cfg.Zion-3.)*0.0136/4./1000. + c.me; // appr. screening for at least 2 LI-shell electrons +2 K electrons } Double_t meanMom = sqrt(Eshell*Eshell-c.me*c.me); Double_t deltaMomFac = 1.-0.5*meanMom*meanMom/mom0/mom0; //meanMom is minimum momentum transfer if(deltaMomFac < -1.) { cout<<"no electon emission possible\n"; return 1; } g.thetaScatMin = acos(deltaMomFac); // global var minimum momentum transfer for bound electron if (cfg.cutoffFlag) { if(g.thetaScatMin < 18.*c.piFac) g.thetaScatMin=18.*c.piFac; // artificial cutoff } else { if(g.thetaScatMin < 4.*c.piFac) g.thetaScatMin=4.*c.piFac; // take screening into account (very crude) } g.deltaThetaScat = c.Pi - g.thetaScatMin; // global var Double_t stheta = sin(g.thetaScatMin/2.); Double_t dsdthetaMax = sin(g.thetaScatMin)/mom0/g.beta0/(stheta*stheta*stheta*stheta); //sin(theta) converts dOmega to dTheta g.dsdthetaMaxNorm = dsdthetaMax*c.LargeRandNorm; // global var cout<<"mom="<SetSeed(seed); srand(seed); cout<<"Running "<cd(); detuple=new TNtuple("DeltaEle","DeltaEle","momLab:eLab:theta"); } //---------------------------------------- vector event; // holds all electrons of one beam ion interaction event.reserve(1000); Int_t nEvt=0; for (Int_t i = 0; i < maxEvents; i ++) { // event loop if (i%100==0 ) cout<<"event "<=g.nElectronsEmitted) nScat = g.nElectronsEmitted - k; //------------------------------------------------------------- // mom distribution UInt_t n=0; Double_t mom = 0 ; Double_t probMomRef = 0; do { mom = gRandom->Rndm()*g.deltaRefMom + g.refMomMin; for (n=1;nRndm()*g.probMomMax > probMomRef); //------------------------------------------------------------- // mom=0.; // test without momentum distribution for (Int_t l=0;lRndm()*c.Pi; //in cm system sTheta=sin(theta); } while(gRandom->Rndm() > sTheta); //------------------------------------------------------------- Double_t momYCm = mom*sTheta; // projectile frame, projectile hit by target electrons Double_t momZCm = mom*cos(theta); Double_t betaZCm = 1./sqrt(c.me/momZCm*c.me/momZCm + 1.); if(momZCm < 0.) betaZCm = -betaZCm; betaZCm = (g.beta0 + betaZCm)/(1. + g.beta0*betaZCm); //Lorentz-Transformation, recycling variables Double_t gammaZCm = 1./sqrt(1. - betaZCm*betaZCm); momZCm = betaZCm*gammaZCm*c.me; Double_t momCm = sqrt(momZCm*momZCm + momYCm*momYCm); Double_t betaCm = momCm/sqrt(momCm*momCm + c.me*c.me); Double_t thetaCm = acos(momZCm/momCm); //------------------------------------------------------------- Double_t dsdtheta = 0; Double_t thetaScat= 0; do { thetaScat = gRandom->Rndm()*g.deltaThetaScat + g.thetaScatMin; //in cm system sTheta = sin(thetaScat/2.); dsdtheta = sin(thetaScat)/momCm/betaCm/(sTheta*sTheta*sTheta*sTheta); //sin(theta) converts dOmega to dTheta } while ((Double_t(rand())*c.RandMax1 + Double_t(rand()))*g.dsdthetaMaxNorm > dsdtheta); //------------------------------------------------------------- Double_t phiScat = gRandom->Rndm()*c.twoPi; Double_t px = momCm*sin(phiScat)*sin(thetaScat); Double_t py = momCm*cos(phiScat)*sin(thetaScat); Double_t pz = momCm*cos(thetaScat); // rotate back to lab system by thetaCm and phiCm (not yet callculated) // rotate back around x-axis by thetaCm (could be y-axis as well since phi is arbitrary) Double_t px0 = px; Double_t py0 = py*cos(-thetaCm) - pz*sin(-thetaCm); Double_t pz0 = py*sin(-thetaCm) + pz*cos(-thetaCm); // rotate back by phi around z-axis, recycle px, py, pz Double_t phiCm = gRandom->Rndm()*c.twoPi; px = px0*cos(-phiCm) - py0*sin(-phiCm); py = px0*sin(-phiCm) + py0*cos(-phiCm); // go from projectile to target frame via Lorentz transformation betaZCm = 1./sqrt(c.me/pz0*c.me/pz0 + 1.); if(pz0 > 0.) betaZCm = -betaZCm; // transformation is backwards Double_t betaZLab = (g.beta0 + betaZCm)/(1. + g.beta0*betaZCm); Double_t gammaZLab = 1./sqrt(1. - betaZLab*betaZLab); pz = betaZLab*gammaZLab*c.me; Double_t momLab = sqrt(px*px + py*py + pz*pz); Double_t thetaScatLab = asin(sqrt(px*px+py*py)/momLab); if(pz<0.) thetaScatLab = c.Pi-thetaScatLab; Double_t ELab = sqrt(momLab*momLab + c.me*c.me); //---------------------------------------- // fill particle to current event if(momLab > cfg.FilterMom || !cfg.doFilter){ particle part; part.ELab = ELab/1000.; part.momLab = momLab; part.px = px/1000.; part.py = py/1000.; part.pz = pz/1000.; part.thetaScatLab =thetaScatLab; event.push_back(part); } //---------------------------------------- } // end scatter loop } // end emitted electrons loop } // end ion loop //---------------------------------------- // write event if(event.size()>0){ Int_t flag=3; // FILE FORMATS // // the format of the evt input file is given // by the flag in the header // // Header: // // i i f f i // eventNumber,nParticle,ebeam [GeV],impactParameter [fm],flag // // Particle: units : Etot [GeV] // // flag notations: flag = s1 + s2*10 // s2 == s1 ==> userVal added, // s1 < 0 ==> indexParent added // s2 = flag/10 // s1 = flag - s2*10 // flag s1 s2 f f f f f f f f i i i i f f // 1 1 0 Etot,px,py,pz, ID, ,weight // 11 1 1 Etot,px,py,pz, ID, ,weight,userVal // 2 2 0 Etot,px,py,pz, ID,sourceID,parentID, ,weight // 22 2 2 Etot,px,py,pz, ID,sourceID,parentID, ,weight,userVal // -2 -2 0 Etot,px,py,pz, ID,sourceID,parentID,indexParent ,weight // -22 -2 2 Etot,px,py,pz, ID,sourceID,parentID, ,weight,userVal // 3 3 0 Etot,px,py,pz ,vx,vy,vz, ID,sourceID,parentID, ,weight // 33 3 3 Etot,px,py,pz ,vx,vy,vz, ID,sourceID,parentID,indexParent ,weight,userVal // -3 -3 0 Etot,px,py,pz ,vx,vy,vz, ID,sourceID,parentID,indexParent ,weight // -33 -3 3 Etot,px,py,pz ,vx,vy,vz, ID,sourceID,parentID,indexParent ,weight,userVal // 4 4 0 Etot,px,py,pz, tof ,vx,vy,vz, ID,sourceID,parentID, ,weight // 44 4 4 Etot,px,py,pz, tof ,vx,vy,vz, ID,sourceID,parentID,indexParent ,weight,userVal // -4 -4 0 Etot,px,py,pz, tof ,vx,vy,vz, ID,sourceID,parentID,indexParent ,weight // -44 -4 4 Etot,px,py,pz, tof ,vx,vy,vz, ID,sourceID,parentID,indexParent ,weight,userVal //------------------------------------------------------------------------------------ ++nEvt; output<Fill(data); } } } event.clear(); //---------------------------------------- } // end eventloop output.close(); cout<<"Events="<cd(); detuple->Write(); tupOutput->Save(); tupOutput->Close(); } return 0; }