6 #include "G4ProcessTable.hh" 7 #include "G4ProcTblElement.hh" 8 #include "G4MuonMinus.hh" 9 #include "G4MuonPlus.hh" 10 #include "G4ProductionCutsTable.hh" 11 #include "G4SystemOfUnits.hh" 16 #include <gsl/gsl_math.h> 17 #include <gsl/gsl_integration.h> 22 const G4double biasFactor,
23 const G4ParticleDefinition*
p,
39 muonMass = G4MuonMinus::MuonMinusDefinition()->GetPDGMass() / CLHEP::GeV;
48 for (
size_t i = 0;
i <
n;
i++) {
57 if ((
p == G4MuonPlus::MuonPlus()) || (
p == G4MuonMinus::MuonMinus())) {
71 const G4ProductionCutsTable* theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
74 G4int numOfCouples = theCoupleTable->GetTableSize();
76 G4int nc =
cuts.size();
85 if (numOfCouples > 0) {
86 for (G4int
i = 0;
i < numOfCouples;
i++) {
87 G4double cute = DBL_MAX;
90 const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(
i);
91 const G4Material* material = couple->GetMaterial();
107 TFile*
f = TFile::Open(
mgfile.c_str());
108 TTree*
tree = (TTree*)
f->Get(
"Events");
109 TLorentzVector* mvec =
new TLorentzVector();
110 TLorentzVector* avec =
new TLorentzVector();
111 TLorentzVector* nvec =
new TLorentzVector();
112 tree->SetBranchAddress(
"IncidentParticle", &mvec);
113 tree->SetBranchAddress(
"APrime", &avec);
114 tree->SetBranchAddress(
"Nucleus", &nvec);
115 int entries =
tree->GetEntries();
116 int start =
int(G4UniformRand() * entries);
121 tree->GetEntry(
i - entries);
124 evnt.
fEl = (TLorentzVector*)mvec->Clone();
125 evnt.
cm = (TLorentzVector*)avec->Clone();
126 *evnt.
cm = *evnt.
cm + *evnt.
fEl;
127 TLorentzVector* ebeam = (TLorentzVector*)nvec->Clone();
128 *ebeam = *ebeam + *evnt.
cm;
129 evnt.
E = round(ebeam->Z() * 10.) / 10.;
130 if (
mgdata.count(evnt.
E) == 0) {
133 mgdata[evnt.
E].push_back(evnt);
140 for (
const auto& iter :
mgdata) {
141 energies.push_back(std::make_pair(iter.first, iter.second.size()));
152 double samplingE =
energies[0].first;
161 if ((E0 <= samplingE) || (
i >=
energies.size())) {
190 G4double
num = 1. -
x +
x *
x / 3.;
206 G4double Mel = 5.1E-04;
208 G4double Mpr = 0.938;
209 G4double
d = 0.164 /
pow((
params->AA), 2. / 3.);
210 G4double ap = 773.0 / Mel /
pow((
params->ZZ), 2. / 3.);
211 G4double
a = 111.0 / Mel /
pow((
params->ZZ), 1. / 3.);
213 (1.0 +
t /
d) / (1.0 +
t /
d);
214 G4double G2in = (
params->ZZ) * ap * ap * ap * ap *
t *
t / (1.0 + ap * ap *
t) / (1.0 + ap * ap *
t) /
215 (1.0 +
t / 0.71) / (1.0 +
t / 0.71) / (1.0 +
t / 0.71) / (1.0 +
t / 0.71) / (1.0 +
t / 0.71) /
216 (1.0 +
t / 0.71) / (1.0 +
t / 0.71) / (1.0 +
t / 0.71) *
217 (1.0 +
t * (MUp * MUp - 1.0) / 4.0 / Mpr / Mpr) * (1.0 +
t * (MUp * MUp - 1.0) / 4.0 / Mpr / Mpr);
218 G4double G2 = G2el + G2in;
221 G4double Under = G2 * (
t - ttmin) /
t /
t;
227 const G4ParticleDefinition*, G4double E0, G4double
Z, G4double
A, G4double
cut, G4double)
230 G4double
cross = 0.0;
231 if (E0 < keV || E0 <
cut) {
235 E0 = E0 / CLHEP::GeV;
240 gsl_integration_workspace*
w = gsl_integration_workspace_alloc(1000);
260 gsl_integration_workspace_free(
w);
263 gsl_integration_workspace* dxspace = gsl_integration_workspace_alloc(1000);
278 gsl_integration_workspace_free(dxspace);
280 G4double GeVtoPb = 3.894E08;
281 G4double alphaEW = 1.0 / 137.0;
282 G4double epsilBench = 1;
284 cross = GeVtoPb * 4. * alphaEW * alphaEW * alphaEW * epsilBench * epsilBench * ChiRes * DsDx * CLHEP::picobarn;
288 E0 = E0 * CLHEP::GeV;
295 G4double kineticEnergy,
302 G4int nElements = material->GetNumberOfElements();
303 const G4ElementVector* theElementVector = material->GetElementVector();
304 const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
305 G4DataVector* dv =
new G4DataVector();
306 G4double
cross = 0.0;
308 for (G4int
i = 0;
i < nElements;
i++) {
309 cross += theAtomNumDensityVector[
i] *
311 particle, kineticEnergy, (*theElementVector)[
i]->GetZ(), (*theElementVector)[
i]->GetN(),
cut);
312 dv->push_back(
cross);
318 const G4MaterialCutsCouple* couple,
319 const G4DynamicParticle*
dp,
325 G4bool
state =
false;
326 G4String
pname =
"muDBrem";
327 G4ProcessTable* ptable = G4ProcessTable::GetProcessTable();
334 G4double E0 =
dp->GetTotalEnergy();
340 E0 = E0 / CLHEP::GeV;
343 double EAcc, Pt,
P, PhiAcc;
344 if (
method ==
"forward_only") {
349 PhiAcc =
data.fEl->Phi();
359 PhiAcc =
data.fEl->Phi();
365 }
else if (
method ==
"cm_scaling") {
366 TLorentzVector* el =
new TLorentzVector(
data.fEl->X(),
data.fEl->Y(),
data.fEl->Z(),
data.fEl->E());
367 double ediff =
data.E - E0;
368 TLorentzVector* newcm =
new TLorentzVector(
data.cm->X(),
data.cm->Y(),
data.cm->Z() - ediff,
data.cm->E() - ediff);
369 el->Boost(-1. *
data.cm->BoostVector());
370 el->Boost(newcm->BoostVector());
379 P =
dp->GetTotalMomentum();
380 Pt =
sqrt(
dp->Get4Momentum().px() *
dp->Get4Momentum().px() +
dp->Get4Momentum().py() *
dp->Get4Momentum().py());
381 PhiAcc =
dp->Get4Momentum().phi();
384 EAcc = EAcc * CLHEP::GeV;
386 G4double muon_mass_mev =
muonMass * CLHEP::GeV;
387 G4double momentum =
sqrt(EAcc * EAcc - muon_mass_mev * muon_mass_mev);
388 G4ThreeVector newDirection;
389 double ThetaAcc = std::asin(Pt /
P);
391 newDirection.rotateUz(
dp->GetMomentumDirection());
392 newDirection.setMag(momentum);
394 G4ThreeVector direction = (
dp->GetMomentum() - newDirection);
395 G4DynamicParticle* dphoton =
new G4DynamicParticle(
theAPrime, direction);
396 vdp->push_back(dphoton);
399 G4double finalKE = EAcc - muon_mass_mev;
402 bool makeSecondary =
true;
406 G4DynamicParticle*
mu =
407 new G4DynamicParticle(const_cast<G4ParticleDefinition*>(
particle), newDirection.unit(), finalKE);
421 const G4Material* material = couple->GetMaterial();
422 G4int nElements = material->GetNumberOfElements();
423 const G4ElementVector* theElementVector = material->GetElementVector();
425 const G4Element* elm =
nullptr;
430 G4double rval = G4UniformRand() * ((*dv)[nElements]);
432 elm = (*theElementVector)[nElements];
433 for (G4int
i = 0;
i < nElements; ++
i) {
434 if (rval <= (*dv)[
i]) {
435 elm = (*theElementVector)[
i];
440 elm = (*theElementVector)[0];
443 SetCurrentElement(elm);
std::map< double, std::vector< frame > > mgdata
Basic3DVector cross(const Basic3DVector &v) const
Vector product, or "cross" product, with a vector of same type.
std::vector< std::pair< double, int > > energies
bool isMuon(const Candidate &part)
Sin< T >::type sin(const T &t)
G4ParticleDefinition * theAPrime
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double tkin, G4double Z, G4double, G4double cut, G4double maxE=DBL_MAX) override
G4ParticleChangeForLoss * fParticleChange
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
Class creating the A' particle in Geant.
void SetMethod(std::string)
U second(std::pair< T, U > const &p)
TkSoA const *__restrict__ CAHitNtupletGeneratorKernelsGPU::QualityCuts cuts
Class provided to simulate the dark brem cross section and interaction.
Cos< T >::type cos(const T &t)
static G4double chi(double t, void *pp)
G4muDarkBremsstrahlungModel(const G4String &scalefile, const G4double biasFactor, const G4ParticleDefinition *p=nullptr, const G4String &nam="eDBrem")
void SampleSecondaries(std::vector< G4DynamicParticle *> *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
static const double tmax[3]
unsigned long long uint64_t
static G4double DsigmaDx(double x, void *pp)
Class providing the Dark Bremsstrahlung process class.
std::pair< OmniClusterRef, TrackingParticleRef > P
char data[epos_bytes_allocation]
std::vector< G4DataVector * > partialSumSigma
static G4APrime * APrime(double apmass=1000)
~G4muDarkBremsstrahlungModel() override
void SetParticle(const G4ParticleDefinition *p)
frame GetMadgraphData(double E0)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
G4DataVector * ComputePartialSumSigma(const G4Material *material, G4double tkin, G4double cut)
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *couple)
Power< A, B >::type pow(const A &a, const B &b)
const G4ParticleDefinition * particle