9 #include "ERElasticScattering.h" 15 #include <TLorentzRotation.h> 18 #include <TVirtualMC.h> 20 #include "G4IonTable.hh" 22 #include <FairRunSim.h> 23 #include <FairLogger.h> 25 using TMath::DegToRad;
26 using TMath::RadToDeg;
28 TGraph* thetaCDFGr = NULL;
29 TGraph* thetaInvCDFGr = NULL;
32 Double_t ThetaCDF(Double_t *x, Double_t *par) {
33 return thetaCDFGr->Eval(x[0]);
36 Double_t ThetaInvCDF(Double_t *x, Double_t *par) {
37 return thetaInvCDFGr->Eval(x[0]);
54 FairRunSim* run = FairRunSim::Instance();
71 LOG(FATAL) <<
"ERElasticScattering::SetLabThetaRange: In the relativistic case (4-th param = kTRUE) " 72 <<
"the average energy of the beam (5-th param) can't be zero." 73 <<
"For the relativistic case this energy must be set correct." << FairLogger::endl;
76 LOG(WARNING) <<
"ERElasticScattering::SetLabThetaRange: The average energy of the beam (5-th param) is not zero, " 77 <<
"but in non relativistic case (4-th param = kFALSE) " 78 <<
"the average energy of the beam is not used! This energy should be set to zero!" << FairLogger::endl;
88 Bool_t ERElasticScattering::Init() {
89 if (!ERDecay::Init()) {
95 LOG(FATAL) <<
"ERElasticScattering::Init: Target ion was not found in pdg database!" << FairLogger::endl;
99 LOG(DEBUG) <<
"ERElasticScattering::Init()" << FairLogger::endl;
109 LOG(FATAL) <<
"The input file which contains the CDF function can't be read!" << FairLogger::endl;
115 Bool_t ERElasticScattering::Stepping() {
116 if (!fDecayFinish && gMC->TrackPid() == fInputIonPDG->PdgCode() && TString(gMC->CurrentVolName()).Contains(fVolumeName)) {
117 gMC->SetMaxStep(fStep);
118 TLorentzVector curPos;
119 gMC->TrackPosition(curPos);
120 if (curPos.Z() >= fDecayPosZ) {
121 TLorentzVector fProjectileIonV;
122 gMC->TrackMomentum(fProjectileIonV);
125 Double_t pM2 = pow(pM, 2);
126 Double_t tM2 = pow(tM, 2);
128 Double_t projectileIonIonT = sqrt(pow(fProjectileIonV.P(), 2)+pM2) - pM;
130 LOG(DEBUG) <<
"ElasticScattering: " << fName << FairLogger::endl;
131 LOG(DEBUG) <<
" ProjectileIon ion with Ekin = " << projectileIonIonT
133 <<
" mom = (" << fProjectileIonV.Px() <<
"," << fProjectileIonV.Py() <<
"," << fProjectileIonV.Pz() <<
")" << FairLogger::endl;
135 Double_t invariant = pow((pM+tM), 2) + 2*tM*projectileIonIonT;
136 Double_t shorty = pow(invariant-pM2-tM2, 2);
137 Double_t Pcm = sqrt( (shorty-4*pM2*tM2) / (4*invariant) );
139 LOG(DEBUG) <<
" CM momentum: " << Pcm << FairLogger::endl;
140 LOG(DEBUG) <<
" CM Ekin: " << sqrt(pow(Pcm,2)+pM2) - pM << FairLogger::endl;
144 Double_t phi = fRnd->Uniform(
fPhiMin*DegToRad(),
fPhiMax*DegToRad());
148 phi = phi + 180.*DegToRad();
155 LOG(DEBUG) <<
" CM [CDFmin,CDFmax] = [" <<
fCDFmin <<
"," <<
fCDFmax <<
"]" << FairLogger::endl;
157 TLorentzVector out1V (Pcm*sin(theta)*cos(phi), Pcm*sin(theta)*sin(phi), Pcm*cos(theta), sqrt(pow(Pcm,2) + pM2));
158 TLorentzVector out2V (-out1V.Px(), -out1V.Py(), -out1V.Pz(), sqrt(pow(Pcm,2) + tM2));
159 LOG(DEBUG) <<
"BEFORE BOOST=======================================================" << FairLogger::endl;
160 LOG(DEBUG) <<
" CM Theta = " << theta*RadToDeg() <<
", phi = " << phi*RadToDeg() << FairLogger::endl;
161 LOG(DEBUG) <<
" CM out1 state(px,py,pz,E) = "<<out1V.Px()<<
", "<<out1V.Py()<<
", "<<out1V.Pz()
162 <<
", " << out1V.E() << FairLogger::endl;
163 LOG(DEBUG) <<
" CM out2 state(px,py,pz,E) = "<<out2V.Px()<<
", "<<out2V.Py()<<
", "<<out2V.Pz()
164 <<
", " << out2V.E() << FairLogger::endl;
165 LOG(DEBUG) <<
" CM out1 Ekin = "<< sqrt(pow(out1V.P(),2)+pM2) - pM << FairLogger::endl;
166 LOG(DEBUG) <<
" CM out2 Ekin = "<< sqrt(pow(out2V.P(),2)+tM2) - tM << FairLogger::endl;
168 TLorentzVector targetV(0,0,0,tM);
169 TLorentzVector cmV = targetV + fProjectileIonV;
170 TVector3 cmVBoost = cmV.BoostVector();
171 LOG(DEBUG) <<
" tM in targetV(0, 0, 0, tM): " << tM << FairLogger::endl;
172 LOG(DEBUG) <<
" cmV components: (" << cmV.Px() <<
", " << cmV.Py() <<
", " << cmV.Pz() <<
", " << cmV.E() <<
")" << FairLogger::endl;
173 LOG(DEBUG) <<
" Boosting with beta = " << cmV.Beta()
174 <<
", gamma = " << cmV.Gamma() << FairLogger::endl;
175 LOG(DEBUG) <<
" Module of cmV.BoostVector: " << sqrt(cmVBoost.Px()*cmVBoost.Px() + cmVBoost.Py()*cmVBoost.Py() + cmVBoost.Pz()*cmVBoost.Pz()) << FairLogger::endl;
176 LOG(DEBUG) <<
" cmV.BoostVector components: (" << cmVBoost.Px() <<
", " << cmVBoost.Py() <<
", " << cmVBoost.Pz() <<
")" << FairLogger::endl;
180 LOG(DEBUG) <<
" Rotation angles: theta = " << theta*RadToDeg() <<
", Phi = " << phi*RadToDeg() << FairLogger::endl;
183 out1V.RotateY(theta);
185 out1V.Boost(cmV.BoostVector());
188 out2V.RotateY(theta);
190 out2V.Boost(cmV.BoostVector());
192 LOG(DEBUG) <<
"AFTER BOOST=======================================================" << FairLogger::endl;
193 LOG(DEBUG) <<
" Lab theta projectile ion = " << out1V.Theta()*RadToDeg() <<
" phi = " << out1V.Phi()*RadToDeg() << FairLogger::endl;
194 LOG(DEBUG) <<
" Lab out1 T = "<< sqrt(pow(out1V.P(),2)+pM2) - pM << FairLogger::endl;
195 LOG(DEBUG) <<
" Lab out2 T = "<< sqrt(pow(out2V.P(),2)+tM2) - tM << FairLogger::endl;
196 LOG(DEBUG) <<
" Lab theta target ion = " << out2V.Theta()*RadToDeg() <<
" phi = " << out2V.Phi()*RadToDeg() << FairLogger::endl;
197 LOG(DEBUG) <<
" Lab out1 state(px,py,pz,E) = " << out1V.Px() <<
"," << out1V.Py() <<
"," << out1V.Pz()
198 <<
"," << out1V.E() << FairLogger::endl;
199 LOG(DEBUG) <<
" Lab out2 state(px,py,pz,E) = "<<out2V.Px()<<
","<<out2V.Py()<<
","<<out2V.Pz()
200 <<
"," << out2V.E() << FairLogger::endl;
202 AddParticleToStack(fInputIonPDG->PdgCode(), curPos,out1V);
205 fDecayFinish = kTRUE;
207 gMC->SetMaxStep(10000.);
219 LOG(DEBUG) <<
"ERElasticScattering::ThetaRangesLab2CM(pM = " << pM <<
", tM = " << tM <<
")" << FairLogger::endl;
221 Double_t ratio = pM/tM;
222 Double_t ratio2 = ratio*ratio;
227 fThetaMinCM = RadToDeg()*acos( -ratio*sin(rAng-rdThetaLab)*sin(rAng-rdThetaLab)
228 + cos(rAng-rdThetaLab)*sqrt(1.-ratio2*sin(rAng-rdThetaLab)*sin(rAng-rdThetaLab)) );
229 fThetaMaxCM = RadToDeg()*acos( -ratio*sin(rAng+rdThetaLab)*sin(rAng+rdThetaLab)
230 + cos(rAng+rdThetaLab)*sqrt(1.-ratio2*sin(rAng+rdThetaLab)*sin(rAng+rdThetaLab)) );
242 fThetaMinCM = 180. - 2.*RadToDeg()*rAng - RadToDeg()*rdThetaLab;
243 fThetaMaxCM = 180. - 2.*RadToDeg()*rAng + RadToDeg()*rdThetaLab;
248 LOG(FATAL) <<
"Unknown fDetectionIonType!" << FairLogger::endl;
284 if (VelocityOfCMRelOfLab > 1.) {
285 LOG(FATAL) <<
"In ERElasticScattering::ThetaRangesLab2CMRelativistic() the velocity of CM can't be > 1." << FairLogger::endl;
289 Double_t MomInCM = VelocityOfCMRelOfLab*tM / sqrt(1. - VelocityOfCMRelOfLab*VelocityOfCMRelOfLab);
292 Double_t z = VelocityOfCMRelOfLab*sqrt(pM*pM + MomInCM*MomInCM);
293 Double_t t = 1.-VelocityOfCMRelOfLab*VelocityOfCMRelOfLab;
294 Double_t B1Min = t*((MomInCM*MomInCM-z*z)*yMin*yMin + MomInCM*MomInCM*t);
295 Double_t B1Max = t*((MomInCM*MomInCM-z*z)*yMax*yMax + MomInCM*MomInCM*t);
296 if (B1Min < 0. || B1Max < 0.) {
297 LOG(FATAL) <<
"In ERElasticScattering::ThetaRangesLab2CMRelativistic() B1 can't be < 0." << FairLogger::endl;
301 Double_t B2Min = yMin*yMin*z;
302 Double_t B2Max = yMax*yMax*z;
303 Double_t B3Min = MomInCM*(yMin*yMin + t);
304 Double_t B3Max = MomInCM*(yMax*yMax + t);
305 Double_t CosThetaCMMin;
306 Double_t CosThetaCMMax;
309 CosThetaCMMin = (-B2Min+B1Min) / B3Min;
310 CosThetaCMMax = (-B2Max+B1Max) / B3Max;
313 CosThetaCMMin = (B2Min-B1Min) / B3Min;
314 CosThetaCMMax = (B2Max-B1Max) / B3Max;
317 LOG(FATAL) <<
"In ERElasticScattering::ThetaRangesLab2CMRelativistic() unknown fDetectionIonType!" << FairLogger::endl;
326 LOG(INFO) <<
"ElasticScattering " << fName <<
" initialized from theta distribution file" << FairLogger::endl;
328 TString path = TString(gSystem->Getenv(
"VMCWORKDIR")) +
"/input/" +
fThetaFileName;
332 LOG(FATAL) <<
"Can't open file " << path << FairLogger::endl;
336 Int_t nPoints = std::count(std::istreambuf_iterator<char>(f),
337 std::istreambuf_iterator<char>(),
'\n');
338 f.seekg(0, std::ios::beg);
339 TVectorD tet(nPoints);
340 TVectorD sigma(nPoints);
342 LOG(DEBUG2) <<
"nPoints = " << nPoints << FairLogger::endl;
347 if (i == nPoints)
break;
348 f >> tet(i) >> sigma(i);
349 LOG(DEBUG2) << i <<
": " << tet(i) <<
"\t" << sigma(i) << FairLogger::endl;
353 thetaCDFGr =
new TGraph(tet, sigma);
354 thetaInvCDFGr =
new TGraph(sigma, tet);
356 fThetaCDF =
new TF1(
"thetaCDF", ThetaCDF, 0., 180., 0);
357 fThetaInvCDF =
new TF1(
"thetaInvCDF", ThetaInvCDF, 0., 1., 0);
379 Bool_t ERElasticScattering::DefineOfIonsMasses() {
380 G4ParticleTable* table = G4ParticleTable::GetParticleTable();
382 LOG(FATAL) <<
"G4 Particle Table is not found!" << FairLogger::endl;
386 SetProjectileIonMass(1e-3*((G4ParticleDefinition*)table->FindParticle((G4int)fInputIonPDG->PdgCode()))->GetPDGMass());
390 LOG(FATAL) <<
"Can't difine Mass for projectile ion!" << FairLogger::endl;
395 LOG(FATAL) <<
"Can't difine Mass for target ion!" << FairLogger::endl;
Double_t fThetaMinCM
Theta minimum for primary ion in CM [Deg].
Double_t GetThetaCMMean() const
Returns mean of thetaCM by all events in run [Deg].
Double_t fCDFmin
ThetaCDF(fThetaMinCM) minimum.
Bool_t fRelativisticMode
kTRUE of a relativistic case is simulated and kFALSE if It isn't. kTRUE by default ...
void SetTargetIon(Int_t A, Int_t Z, Int_t Q)
Defines target ion parameters.
Double_t fPhiMax
Phi maximum for primary ion in CM [Deg].
void ThetaRangesLab2CMRelativistic()
The private method is to convert Lab theta range to CM for relativistic case.
void SetTargetIonMass(Double_t mass)
Defines target ion mass.
TF1 * fThetaCDF
Pointer to theta CDF function.
TF1 * fThetaInvCDF
Pointer to inversety theta CDF function.
ERInteractionParticipant fDetectionIonType
Ion status TODO.
ERElasticScattering(TString name)
Constructor with reaction name.
Double_t fCDFmax
ThetaCDF(fThetaMaxCM) maximum.
TString fTargetIonName
Target ion name.
void SetProjectileIonMass(Double_t mass)
Defines primary ion mass.
Double_t fPhiMin
Phi minimum for primary ion in CM [Deg].
Double_t GetProjectileIonMass() const
Returns projectile ion mass.
Double_t ThetaGen()
The private method is to generate theta value.
TParticlePDG * fTargetIonPDG
Target ion PDG.
void SetLabThetaRange(Double_t thetaCenter, Double_t dTheta, ERInteractionParticipant DetIonType=kPROJECTILE, Bool_t relMod=kTRUE, Double_t BeamAvE=0.)
Defines theta position for detector slot center in Lab.
Double_t fThetaRangedTheta
The half-width of the range of theta.
Double_t fThetaRangeCenter
Theta range's center.
Bool_t ThetaCDFRead()
The private method is to read ThetaCDF cumulative function file.
TString fThetaFileName
File name that contains theta CDF values.
Double_t fThetaCMSum
Sum of thetaCM by all events in run.
Double_t GetTargetIonMass() const
Returns target ion mass.
Double_t fBeamAverageEnergy
Avarage Energy of the beam.
void SetThetaRange(Double_t th1, Double_t th2, ERInteractionParticipant DetIonType=kPROJECTILE)
Defines range of theta value.
Double_t fThetaMaxCM
Theta maximum for primary ion in CM [Deg].
Int_t fInteractNumInTarget
Interactions counter in target (by all events in run)
void ThetaRangesLab2CM()
The private method is to convert Lab theta range to CM.
Class for the elastic scattering simulate.
virtual ~ERElasticScattering()
Destructor.