6 #include "G4ProcessTable.hh" 7 #include "G4ProcTblElement.hh" 8 #include "G4MuonMinus.hh" 9 #include "G4MuonPlus.hh" 10 #include "G4ProductionCutsTable.hh" 11 #include <CLHEP/Units/SystemOfUnits.h> 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()));
188 G4double
num = 1. -
x +
x *
x / 3.;
204 G4double Mel = 5.1E-04;
206 G4double Mpr = 0.938;
207 G4double
d = 0.164 /
pow((
params->AA), 2. / 3.);
208 G4double ap = 773.0 / Mel /
pow((
params->ZZ), 2. / 3.);
209 G4double
a = 111.0 / Mel /
pow((
params->ZZ), 1. / 3.);
211 (1.0 +
t /
d) / (1.0 +
t /
d);
212 G4double G2in = (
params->ZZ) * ap * ap * ap * ap *
t *
t / (1.0 + ap * ap *
t) / (1.0 + ap * ap *
t) /
213 (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) /
214 (1.0 +
t / 0.71) / (1.0 +
t / 0.71) / (1.0 +
t / 0.71) *
215 (1.0 +
t * (MUp * MUp - 1.0) / 4.0 / Mpr / Mpr) * (1.0 +
t * (MUp * MUp - 1.0) / 4.0 / Mpr / Mpr);
216 G4double G2 = G2el + G2in;
219 G4double Under = G2 * (
t - ttmin) /
t /
t;
225 const G4ParticleDefinition*, G4double E0, G4double
Z, G4double
A, G4double
cut, G4double)
228 G4double
cross = 0.0;
229 if (E0 < CLHEP::keV || E0 <
cut) {
233 E0 = E0 / CLHEP::GeV;
238 gsl_integration_workspace*
w = gsl_integration_workspace_alloc(1000);
258 gsl_integration_workspace_free(
w);
261 gsl_integration_workspace* dxspace = gsl_integration_workspace_alloc(1000);
272 gsl_integration_workspace_free(dxspace);
274 G4double GeVtoPb = 3.894E08;
275 G4double alphaEW = 1.0 / 137.0;
276 G4double epsilBench = 1;
278 cross = GeVtoPb * 4. * alphaEW * alphaEW * alphaEW * epsilBench * epsilBench * ChiRes * DsDx * CLHEP::picobarn;
288 G4double kineticEnergy,
295 G4int nElements = material->GetNumberOfElements();
296 const G4ElementVector* theElementVector = material->GetElementVector();
297 const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
298 G4DataVector* dv =
new G4DataVector();
299 G4double
cross = 0.0;
301 for (G4int
i = 0;
i < nElements;
i++) {
302 cross += theAtomNumDensityVector[
i] *
304 particle, kineticEnergy, (*theElementVector)[
i]->GetZ(), (*theElementVector)[
i]->GetN(),
cut);
305 dv->push_back(
cross);
311 const G4MaterialCutsCouple* couple,
312 const G4DynamicParticle*
dp,
318 G4bool
state =
false;
319 G4String
pname =
"muDBrem";
320 G4ProcessTable* ptable = G4ProcessTable::GetProcessTable();
327 G4double E0 =
dp->GetTotalEnergy();
328 G4double
tmax =
min(maxEnergy, E0);
333 E0 = E0 / CLHEP::GeV;
336 double EAcc, Pt,
P, PhiAcc;
337 if (
method ==
"forward_only") {
342 PhiAcc =
data.fEl->Phi();
352 PhiAcc =
data.fEl->Phi();
358 }
else if (
method ==
"cm_scaling") {
359 TLorentzVector* el =
new TLorentzVector(
data.fEl->X(),
data.fEl->Y(),
data.fEl->Z(),
data.fEl->E());
360 double ediff =
data.E - E0;
361 TLorentzVector* newcm =
new TLorentzVector(
data.cm->X(),
data.cm->Y(),
data.cm->Z() - ediff,
data.cm->E() - ediff);
362 el->Boost(-1. *
data.cm->BoostVector());
363 el->Boost(newcm->BoostVector());
372 P =
dp->GetTotalMomentum();
373 Pt =
sqrt(
dp->Get4Momentum().px() *
dp->Get4Momentum().px() +
dp->Get4Momentum().py() *
dp->Get4Momentum().py());
374 PhiAcc =
dp->Get4Momentum().phi();
377 EAcc = EAcc * CLHEP::GeV;
379 G4double muon_mass_mev =
muonMass * CLHEP::GeV;
380 G4double momentum =
sqrt(EAcc * EAcc - muon_mass_mev * muon_mass_mev);
381 G4ThreeVector newDirection;
382 double ThetaAcc = std::asin(Pt /
P);
384 newDirection.rotateUz(
dp->GetMomentumDirection());
385 newDirection.setMag(momentum);
387 G4ThreeVector direction = (
dp->GetMomentum() - newDirection);
388 G4DynamicParticle* dphoton =
new G4DynamicParticle(
theAPrime, direction);
389 vdp->push_back(dphoton);
392 G4double finalKE = EAcc - muon_mass_mev;
395 bool makeSecondary =
true;
399 G4DynamicParticle*
mu =
400 new G4DynamicParticle(const_cast<G4ParticleDefinition*>(
particle), newDirection.unit(), finalKE);
414 const G4Material* material = couple->GetMaterial();
415 G4int nElements = material->GetNumberOfElements();
416 const G4ElementVector* theElementVector = material->GetElementVector();
418 const G4Element* elm =
nullptr;
423 G4double rval = G4UniformRand() * ((*dv)[nElements]);
425 elm = (*theElementVector)[nElements];
426 for (G4int
i = 0;
i < nElements; ++
i) {
427 if (rval <= (*dv)[
i]) {
428 elm = (*theElementVector)[
i];
433 elm = (*theElementVector)[0];
436 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)
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