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,
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);
117 for (
int i = start;
i <
int(start + entries / 10.);
i++) {
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.;
191 G4double denom = (params->
MMA) * (params->
MMA) * (1. -
x) / x + (params->
MMu) * (params->
MMu) * x;
192 G4double DsDx = beta * num / denom;
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.);
212 G4double G2el = (params->
ZZ) * (params->
ZZ) * a * a * a * a * t * t / (1.0 + a * a *
t) / (1.0 + a * a * t) /
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;
219 G4double ttmin = (params->
MMA) * (params->
MMA) * (params->
MMA) * (params->
MMA) / 4.0 / (params->
EE0) / (params->
EE0);
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) {
240 gsl_integration_workspace*
w = gsl_integration_workspace_alloc(1000);
243 G4double tmin =
MA *
MA *
MA *
MA / (4. * E0 * E0);
257 gsl_integration_qags(&F, tmin, tmax, 0, 1
e-7, 1000, w, &result, &error);
260 gsl_integration_workspace_free(w);
263 gsl_integration_workspace* dxspace = gsl_integration_workspace_alloc(1000);
275 gsl_integration_qags(&G, xmin, xmax, 0, 1
e-7, 1000, dxspace, &res, &err);
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;
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();
328 ptable->SetProcessActivation(pname, state);
334 G4double E0 = dp->GetTotalEnergy();
335 G4double
tmax =
min(maxEnergy, E0);
343 double EAcc,
Pt,
P, PhiAcc;
344 if (
method ==
"forward_only") {
349 PhiAcc = data.
fEl->Phi();
351 while (Pt * Pt + muonMass * muonMass > EAcc * EAcc)
355 EAcc = (data.
fEl->E() -
muonMass) / (data.
E - muonMass -
MA) * (E0 - muonMass -
MA);
356 EAcc = muonMass + EAcc;
358 P =
sqrt(EAcc * EAcc - muonMass * muonMass);
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();
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
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)
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")
unsigned long long int rval
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]
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
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
Basic3DVector cross(const Basic3DVector &v) const
Vector product, or "cross" product, with a vector of same type.