IAP GITLAB
Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
corsika
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Air Shower Physics
corsika
Commits
b1e514a9
Commit
b1e514a9
authored
7 months ago
by
Felix Riehn
Browse files
Options
Downloads
Patches
Plain Diff
rename
parent
ebd43abf
No related branches found
Branches containing commit
No related tags found
1 merge request
!649
Resolve "hadronic interactions with Pythia"
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
corsika/detail/modules/pythia8/Interaction.inl
+0
-447
0 additions, 447 deletions
corsika/detail/modules/pythia8/Interaction.inl
corsika/modules/pythia8/Interaction.hpp
+0
-109
0 additions, 109 deletions
corsika/modules/pythia8/Interaction.hpp
with
0 additions
and
556 deletions
corsika/detail/modules/pythia8/Interaction.inl
deleted
100644 → 0
+
0
−
447
View file @
ebd43abf
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#pragma once
#include
<tuple>
#include
<stdexcept>
#include
<boost/filesystem/path.hpp>
#include
<fmt/core.h>
#include
<corsika/modules/pythia8/Interaction.hpp>
#include
<corsika/framework/geometry/FourVector.hpp>
#include
<corsika/framework/utility/COMBoost.hpp>
#include
<corsika/framework/core/EnergyMomentumOperations.hpp>
#include
<corsika/media/Environment.hpp>
#include
<corsika/media/NuclearComposition.hpp>
namespace
corsika
::
pythia8
{
inline
Interaction
::~
Interaction
()
{
CORSIKA_LOG_INFO
(
"Pythia::Interaction n= {}"
,
count_
);
}
inline
Interaction
::
Interaction
(
boost
::
filesystem
::
path
const
&
mpiInitFile
,
bool
const
print_listing
)
:
print_listing_
(
print_listing
)
,
pythiaMain_
{
CORSIKA_Pythia8_XML_DIR
,
false
}
,
pythiaColl_
{
CORSIKA_Pythia8_XML_DIR
,
false
}
{
auto
rndm
=
std
::
make_shared
<
corsika
::
pythia8
::
Random
>
();
pythiaColl_
.
setRndmEnginePtr
(
rndm
);
pythiaMain_
.
setRndmEnginePtr
(
rndm
);
CORSIKA_LOG_INFO
(
"Pythia8 MPI init file: {}"
,
mpiInitFile
.
native
());
// Main Pythia object for managing the cascade evolution.
// Can also do decays, but no hard processes.
pythiaMain_
.
readString
(
"ProcessLevel:all = off"
);
// Reduce statistics printout to relevant ones.
pythiaMain_
.
readString
(
"Stat:showProcessLevel = off"
);
pythiaMain_
.
readString
(
"Stat:showPartonLevel = off"
);
// Add Argon, since not in Particle data. id:all = name antiName
// spinType chargeType colType m0 mWidth mMin mMax tau0.
pythiaMain_
.
readString
(
"1000180400:all = 40Ar 40Arbar 1 54 0 "
"37.22474 0. 0. 0. 0."
);
// we can't test this block, LCOV_EXCL_START
if
(
!
pythiaMain_
.
init
())
throw
std
::
runtime_error
(
"Pythia::Interaction: Initialization failed!"
);
// LCOV_EXCL_STOP
// Secondary Pythia object for performing individual collisions.
// Variable incoming beam type and energy.
pythiaColl_
.
readString
(
"Beams:allowVariableEnergy = on"
);
pythiaColl_
.
readString
(
"Beams:allowIDAswitch = on"
);
// Set up for fixed-target collisions.
pythiaColl_
.
readString
(
"Beams:frameType = 3"
);
// arbitrary frame, need to define full 4-momenta
pythiaColl_
.
settings
.
parm
(
"Beams:pzA"
,
eMaxLab_
/
1
_GeV
);
pythiaColl_
.
readString
(
"Beams:pzB = 0."
);
// Must use the soft and low-energy QCD processes.
pythiaColl_
.
readString
(
"SoftQCD:all = on"
);
pythiaColl_
.
readString
(
"LowEnergyQCD:all = on"
);
// Decays to be done by pythiaMain_.
pythiaColl_
.
readString
(
"HadronLevel:Decay = off"
);
// Reduce printout and relax energy-momentum conservation.
pythiaColl_
.
readString
(
"Print:quiet = on"
);
pythiaColl_
.
readString
(
"Check:epTolErr = 0.1"
);
pythiaColl_
.
readString
(
"Check:epTolWarn = 0.0001"
);
pythiaColl_
.
readString
(
"Check:mTolErr = 0.01"
);
// Redure statistics printout to relevant ones.
pythiaColl_
.
readString
(
"Stat:showProcessLevel = off"
);
pythiaColl_
.
readString
(
"Stat:showPartonLevel = off"
);
bool
const
reuse
=
true
;
// could be made more flexible
// Reuse MPI initialization file if it exists; else create a new one.
if
(
reuse
)
pythiaColl_
.
readString
(
"MultipartonInteractions:reuseInit = 3"
);
else
pythiaColl_
.
readString
(
"MultipartonInteractions:reuseInit = 1"
);
pythiaColl_
.
settings
.
word
(
"MultipartonInteractions:initFile"
,
mpiInitFile
.
native
());
// initialize
// we can't test this block, LCOV_EXCL_START
if
(
!
pythiaColl_
.
init
())
throw
std
::
runtime_error
(
"Pythia::Interaction: Initialization failed!"
);
// LCOV_EXCL_STOP
}
inline
bool
Interaction
::
isValid
(
Code
const
projectileId
,
Code
const
targetId
,
HEPEnergyType
const
sqrtS
)
const
{
if
(
is_nucleus
(
projectileId
))
// not yet possible with Pythia
return
false
;
HEPEnergyType
const
labE
=
calculate_lab_energy
(
static_pow
<
2
>
(
sqrtS
),
get_mass
(
projectileId
),
get_mass
(
targetId
));
if
(
labE
<
eKinMinLab_
)
return
false
;
return
std
::
find
(
validTargets_
.
begin
(),
validTargets_
.
end
(),
targetId
)
!=
validTargets_
.
end
();
}
inline
bool
Interaction
::
canInteract
(
Code
const
pCode
)
const
{
return
is_hadron
(
pCode
)
&&
!
is_nucleus
(
pCode
);
// should be sufficient
}
inline
std
::
tuple
<
CrossSectionType
,
CrossSectionType
>
Interaction
::
getCrossSectionInelEla
(
Code
const
projectileId
,
Code
const
targetId
,
FourMomentum
const
&
projectileP4
,
FourMomentum
const
&
targetP4
)
const
{
HEPEnergyType
const
CoMenergy
=
is_nucleus
(
targetId
)
?
(
projectileP4
+
targetP4
/
get_nucleus_A
(
targetId
)).
getNorm
()
:
(
projectileP4
+
targetP4
).
getNorm
();
if
(
is_nucleus
(
targetId
)
||
is_nucleus
(
projectileId
))
{
CORSIKA_LOG_ERROR
(
"Pythia8::Interaction::getCrossSectionInelEla() called with nuclear projectile "
"or target"
);
return
std
::
make_tuple
(
CrossSectionType
::
zero
(),
CrossSectionType
::
zero
());
}
if
(
!
isValid
(
projectileId
,
targetId
,
CoMenergy
))
{
return
std
::
make_tuple
(
CrossSectionType
::
zero
(),
CrossSectionType
::
zero
());
}
// input particle PDG
auto
const
pdgCodeBeam
=
static_cast
<
int
>
(
get_PDG
(
projectileId
));
auto
const
pdgCodeTarget
=
static_cast
<
int
>
(
get_PDG
(
targetId
));
double
const
ecm_GeV
=
CoMenergy
*
(
1
/
1
_GeV
);
auto
const
sigTot
=
pythiaColl_
.
getSigmaTotal
(
pdgCodeBeam
,
pdgCodeTarget
,
ecm_GeV
)
*
1
_mb
;
auto
const
sigEla
=
pythiaColl_
.
getSigmaPartial
(
pdgCodeBeam
,
pdgCodeTarget
,
ecm_GeV
,
2
)
*
1
_mb
;
return
std
::
make_tuple
(
sigTot
-
sigEla
,
sigEla
);
}
CrossSectionType
Interaction
::
getCrossSection
(
Code
const
projectileId
,
Code
const
targetId
,
FourMomentum
const
&
projectileP4
,
FourMomentum
const
&
targetP4
)
const
{
if
(
!
is_nucleus
(
targetId
))
{
auto
const
[
sigProd
,
sigEla
]
=
getCrossSectionInelEla
(
projectileId
,
targetId
,
projectileP4
,
targetP4
);
return
sigProd
+
sigEla
;
}
else
if
(
get_nucleus_A
(
targetId
)
==
1
)
{
auto
const
[
sigProd
,
sigEla
]
=
getCrossSectionInelEla
(
projectileId
,
get_nucleus_Z
(
targetId
)
==
1
?
Code
::
Proton
:
Code
::
Neutron
,
projectileP4
,
targetP4
);
return
sigProd
+
sigEla
;
}
else
{
auto
const
[
sigProd
,
sigEla
]
=
getCrossSectionInelEla
(
projectileId
,
Code
::
Proton
,
projectileP4
,
targetP4
);
auto
const
sigTot
=
sigProd
+
sigEla
;
auto
const
nSubcoll
=
getAverageSubcollisions
(
targetId
,
sigTot
);
if
(
nSubcoll
==
0
)
{
// no parameterization available -> we can't handle this
return
CrossSectionType
::
zero
();
}
else
{
return
sigTot
*
get_nucleus_A
(
targetId
)
/
nSubcoll
;
}
}
}
double
Interaction
::
getAverageSubcollisions
(
Code
targetId
,
CrossSectionType
sigTot
)
const
{
if
(
targetId
==
Code
::
Proton
||
targetId
==
Code
::
Neutron
||
targetId
==
Code
::
Hydrogen
||
targetId
==
Code
::
AntiProton
||
targetId
==
Code
::
AntiNeutron
)
return
1
;
auto
const
Z
=
get_nucleus_Z
(
targetId
);
auto
const
A
=
get_nucleus_A
(
targetId
);
double
nCollAvg
;
if
(
Z
==
7
&&
A
==
14
)
nCollAvg
=
(
sigTot
<
31.
_mb
)
// this is from the paper
?
1.
+
0.017
/
1
_mb
*
sigTot
:
1.2
+
0.0105
/
1
_mb
*
sigTot
;
else
if
(
Z
==
8
&&
A
==
16
)
nCollAvg
=
(
sigTot
<
16.
_mb
)
// provided by Torbjörn Sjöstrand
?
1.
+
0.0245
/
1
_mb
*
sigTot
:
1.2
+
0.012
/
1
_mb
*
sigTot
;
else
if
(
Z
==
18
&&
A
==
40
)
nCollAvg
=
(
sigTot
<
10.
_mb
)
?
1.
+
0.050
/
1
_mb
*
sigTot
:
1.28
+
0.022
/
1
_mb
*
sigTot
;
else
{
CORSIKA_LOG_ERROR
(
fmt
::
format
(
"Pythia8 cross-sections not defined for ({},{}) nucleus"
,
A
,
Z
));
nCollAvg
=
0
;
}
return
nCollAvg
;
}
template
<
class
TView
>
inline
void
Interaction
::
doInteraction
(
TView
&
view
,
Code
const
projectileId
,
Code
const
targetId
,
FourMomentum
const
&
projectileP4
,
FourMomentum
const
&
targetP4
)
{
CORSIKA_LOG_DEBUG
(
"Pythia::Interaction: "
"doInteraction: {} interaction? "
,
projectileId
,
corsika
::
pythia8
::
Interaction
::
canInteract
(
projectileId
));
// define system
auto
const
sqrtS2
=
(
projectileP4
+
targetP4
).
getNormSqr
();
HEPEnergyType
const
sqrtS
=
sqrt
(
sqrtS2
);
HEPEnergyType
const
eProjectileLab
=
(
sqrtS2
-
static_pow
<
2
>
(
get_mass
(
projectileId
))
-
static_pow
<
2
>
(
get_mass
(
targetId
)))
/
(
2
*
get_mass
(
targetId
));
if
(
!
isValid
(
projectileId
,
targetId
,
sqrtS
))
{
throw
std
::
runtime_error
(
"invalid target,projectile,energy combination."
);
}
CORSIKA_LOG_DEBUG
(
"Interaction: ebeam lab: {} GeV"
,
eProjectileLab
/
1
_GeV
);
CORSIKA_LOG_DEBUG
(
"Interaction: "
" doInteraction: E(GeV): {}"
" Ecm(GeV): {}"
,
eProjectileLab
/
1
_GeV
,
sqrtS
/
1
_GeV
);
count_
++
;
int
const
idNow
=
static_cast
<
int
>
(
get_PDG
(
projectileId
));
// References to the two event records. Clear main event record.
Pythia8
::
Event
&
eventMain
=
pythiaMain_
.
event
;
Pythia8
::
Event
&
eventColl
=
pythiaColl_
.
event
;
COMBoost
const
labFrameBoost
{
targetP4
.
getSpaceLikeComponents
(),
get_mass
(
targetId
)};
auto
const
proj4MomLab
=
labFrameBoost
.
toCoM
(
projectileP4
);
auto
const
&
rotCS
=
labFrameBoost
.
getRotatedCS
();
auto
const
pProjLab
=
proj4MomLab
.
getSpaceLikeComponents
().
getComponents
(
rotCS
);
auto
constexpr
invGeV
=
1
/
1
_GeV
;
Pythia8
::
Vec4
const
pNow
{
pProjLab
.
getX
()
*
invGeV
,
pProjLab
.
getY
()
*
invGeV
,
pProjLab
.
getZ
()
*
invGeV
,
proj4MomLab
.
getTimeLikeComponent
()
*
invGeV
};
// Insert incoming particle in cleared main event record.
int
unsuccessful_iterations
{
0
};
do
{
// retry event generation if Pythia gets stuck
eventMain
.
clear
();
eventMain
.
append
(
90
,
-
11
,
0
,
0
,
1
,
1
,
0
,
0
,
pNow
,
pNow
.
mCalc
());
int
const
iHad
=
eventMain
.
append
(
idNow
,
12
,
0
,
0
,
0
,
0
,
0
,
0
,
pNow
,
get_mass
(
projectileId
)
*
(
1
/
1
_GeV
));
Pythia8
::
Vec4
const
vNow
{};
// production vertex
eventMain
[
iHad
].
vProd
(
vNow
);
auto
const
[
Anow
,
Znow
]
=
std
::
invoke
([
targetId
]()
{
if
(
targetId
==
Code
::
Proton
)
{
return
std
::
make_pair
(
1
,
1
);
}
else
if
(
targetId
==
Code
::
Neutron
)
{
return
std
::
make_pair
(
1
,
0
);
}
else
if
(
is_nucleus
(
targetId
))
{
return
std
::
make_pair
<
int
,
int
>
(
get_nucleus_A
(
targetId
),
get_nucleus_Z
(
targetId
));
}
else
{
// due to the earlier call to isValid(), we shouldn't end up here
// LCOV_EXCL_START
CORSIKA_LOG_ERROR
(
"invalid target {}; you shouldn't have gotten this far!"
,
targetId
);
return
std
::
make_pair
(
0
,
0
);
// LCOV_EXCL_STOP
}
});
// Set up for collisions on a nucleus.
int
np
=
Znow
;
int
nn
=
Anow
-
Znow
;
int
sizeOld
=
0
;
int
sizeNew
=
0
;
Pythia8
::
Vec4
const
dirNow
=
pNow
/
pNow
.
pAbs
();
Pythia8
::
Rndm
&
rndm
=
pythiaMain_
.
rndm
;
double
constexpr
mp
=
get_mass
(
Code
::
Proton
)
/
1
_GeV
;
double
const
sqrtSNN_GeV
=
(
pNow
+
Pythia8
::
Vec4
{
0
,
0
,
0
,
mp
}).
mCalc
();
auto
const
nCollAvg
=
getAverageSubcollisions
(
targetId
,
pythiaColl_
.
getSigmaTotal
(
idNow
,
2212
,
sqrtSNN_GeV
)
*
1
_mb
);
double
const
probMore
=
1.
-
1.
/
nCollAvg
;
// Loop over varying number of hit nucleons in target nucleus.
for
(
int
iColl
=
1
;
iColl
<=
Anow
;
++
iColl
)
{
if
(
iColl
>
1
&&
rndm
.
flat
()
>
probMore
)
break
;
// Pick incoming projectile: trivial for first subcollision, else ...
int
iProj
=
iHad
;
int
procType
=
0
;
// ... find highest-pLongitudinal particle from latest subcollision.
if
(
iColl
>
1
)
{
iProj
=
0
;
double
pMax
=
0.
;
for
(
int
i
=
sizeOld
;
i
<
sizeNew
;
++
i
)
if
(
eventMain
[
i
].
isFinal
()
&&
eventMain
[
i
].
isHadron
())
{
if
(
double
const
pp
=
Pythia8
::
dot3
(
dirNow
,
eventMain
[
i
].
p
());
pp
>
pMax
)
{
iProj
=
i
;
pMax
=
pp
;
}
}
// No further subcollision if no particle with enough energy.
// cannot be reliably provoked in tests
// LCOV_EXCL_START
if
(
iProj
==
0
||
eventMain
[
iProj
].
e
()
-
eventMain
[
iProj
].
m
()
<
eKinMinLab_
/
1
_GeV
)
break
;
// LCOV_EXCL_STOP
// Choose process; only SD or ND at perturbative energies.
double
const
eCMSub
=
(
eventMain
[
iProj
].
p
()
+
Pythia8
::
Vec4
{
0
,
0
,
0
,
mp
}).
mCalc
();
if
(
eCMSub
>
10.
)
procType
=
(
rndm
.
flat
()
<
probSD_
)
?
4
:
1
;
}
// Pick one p or n from target.
int
const
idProj
=
eventMain
[
iProj
].
id
();
bool
const
doProton
=
rndm
.
flat
()
<
(
np
/
double
(
np
+
nn
));
if
(
doProton
)
np
--
;
else
nn
--
;
int
const
idNuc
=
doProton
?
2212
:
2112
;
// Perform the projectile-nucleon subcollision.
pythiaColl_
.
setBeamIDs
(
idProj
,
idNuc
);
pythiaColl_
.
setKinematics
(
eventMain
[
iProj
].
p
(),
Pythia8
::
Vec4
());
if
(
!
pythiaColl_
.
next
(
procType
))
{
CORSIKA_LOG_WARN
(
"Pythia collision next() failed {} {} {}"
,
eventMain
[
iProj
].
p
(),
idProj
,
idNuc
);
eventMain
.
clear
();
++
unsuccessful_iterations
;
goto
event_repeat
;
// retry event, last remaining good use-case for goto
}
// Insert target nucleon. Mothers are (0,iProj) to mark who it
// interacted with. Always use proton mass for simplicity.
int
const
statusNuc
=
(
iColl
==
1
)
?
-
181
:
-
182
;
int
const
iNuc
=
eventMain
.
append
(
idNuc
,
statusNuc
,
0
,
iProj
,
0
,
0
,
0
,
0
,
0.
,
0.
,
0.
,
mp
,
mp
);
eventMain
[
iNuc
].
vProdAdd
(
vNow
);
// Update full energy of the event with the proton mass.
eventMain
[
0
].
e
(
eventMain
[
0
].
e
()
+
mp
);
eventMain
[
0
].
m
(
eventMain
[
0
].
p
().
mCalc
());
// Insert secondary produced particles (but skip intermediate partons)
// into main event record and shift to correct production vertex.
sizeOld
=
eventMain
.
size
();
for
(
int
iSub
=
3
;
iSub
<
eventColl
.
size
();
++
iSub
)
{
if
(
!
eventColl
[
iSub
].
isFinal
())
continue
;
int
const
iNew
=
eventMain
.
append
(
eventColl
[
iSub
]);
eventMain
[
iNew
].
mothers
(
iNuc
,
iProj
);
eventMain
[
iNew
].
vProdAdd
(
vNow
);
}
sizeNew
=
eventMain
.
size
();
// Update daughters of colliding hadrons and other history.
eventMain
[
iProj
].
daughters
(
sizeOld
,
sizeNew
-
1
);
eventMain
[
iNuc
].
daughters
(
sizeOld
,
sizeNew
-
1
);
eventMain
[
iProj
].
statusNeg
();
double
dTau
=
(
iColl
==
1
)
?
(
vNow
.
e
()
-
eventMain
[
iHad
].
tProd
())
*
eventMain
[
iHad
].
m
()
/
eventMain
[
iHad
].
e
()
:
0.
;
eventMain
[
iProj
].
tau
(
dTau
);
// End of loop over interactions in a nucleus.
}
break
;
//
event_repeat
:
;
}
while
(
unsuccessful_iterations
<
100
);
if
(
unsuccessful_iterations
>=
100
)
{
CORSIKA_LOG_CRITICAL
(
"Pythia event generation failed after 100 trials: projectile: {}, target: {}"
,
projectileId
,
targetId
);
throw
std
::
runtime_error
{
"Pythia event generation failed after 100 trials"
};
}
MomentumVector
Plab_final
{
labFrameBoost
.
getOriginalCS
()};
auto
Elab_final
=
HEPEnergyType
::
zero
();
for
(
Pythia8
::
Particle
const
&
p8p
:
eventMain
)
{
// skip particles that have decayed / are initial particles in pythia's event record
if
(
!
p8p
.
isFinal
())
continue
;
try
{
auto
const
volatile
id
=
static_cast
<
PDGCode
>
(
p8p
.
id
());
auto
const
pyId
=
convert_from_PDG
(
id
);
MomentumVector
const
pyPlab
(
rotCS
,
{
p8p
.
px
()
*
1
_GeV
,
p8p
.
py
()
*
1
_GeV
,
p8p
.
pz
()
*
1
_GeV
});
auto
const
pyP
=
labFrameBoost
.
fromCoM
(
FourVector
{
p8p
.
e
()
*
1
_GeV
,
pyPlab
});
HEPEnergyType
const
mass
=
get_mass
(
pyId
);
HEPEnergyType
const
Ekin
=
sqrt
(
pyP
.
getSpaceLikeComponents
().
getSquaredNorm
()
+
mass
*
mass
)
-
mass
;
// add to corsika stack
auto
pnew
=
view
.
addSecondary
(
std
::
make_tuple
(
pyId
,
Ekin
,
pyPlab
.
normalized
()));
Plab_final
+=
pnew
.
getMomentum
();
Elab_final
+=
pnew
.
getEnergy
();
}
// irreproducible in tests, LCOV_EXCL_START
catch
(
std
::
out_of_range
const
&
ex
)
{
CORSIKA_LOG_CRITICAL
(
"Pythia ID {} unknown in C8"
,
p8p
.
id
());
throw
ex
;
}
// LCOV_EXCL_STOP
}
eventMain
.
clear
();
CORSIKA_LOG_DEBUG
(
"conservation (all GeV): "
"Elab_final= {}"
", Plab_final= {}"
,
Elab_final
/
1
_GeV
,
(
Plab_final
/
1
_GeV
).
getComponents
());
}
}
// namespace corsika::pythia8
This diff is collapsed.
Click to expand it.
corsika/modules/pythia8/Interaction.hpp
deleted
100644 → 0
+
0
−
109
View file @
ebd43abf
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the GNU General Public
* Licence version 3 (GPL Version 3). See file LICENSE for a full version of
* the license.
*/
#pragma once
#include
<tuple>
#include
<boost/filesystem/path.hpp>
#include
<corsika/framework/utility/CorsikaData.hpp>
#include
<corsika/framework/core/ParticleProperties.hpp>
#include
<corsika/framework/core/PhysicalUnits.hpp>
#include
<corsika/framework/random/RNGManager.hpp>
#include
<corsika/framework/process/InteractionProcess.hpp>
#include
<corsika/modules/pythia8/Pythia8.hpp>
namespace
corsika
::
pythia8
{
class
Interaction
:
public
InteractionProcess
<
Interaction
>
{
public:
Interaction
(
boost
::
filesystem
::
path
const
&
mpiInitFile
=
corsika_data
(
"Pythia/main184.mpi"
),
bool
const
print_listing
=
false
);
~
Interaction
();
bool
canInteract
(
Code
const
)
const
;
bool
isValid
(
Code
const
projectileId
,
Code
const
targetId
,
HEPEnergyType
const
sqrtS
)
const
;
/**
* Returns inelastic AND elastic cross sections.
*
* These cross sections must correspond to the process described in doInteraction
* AND elastic scattering (sigma_tot = sigma_inel + sigma_el). Allowed targets are:
* nuclei or single nucleons (p,n,hydrogen). This "InelEla" method is used since
* Sibyll must be useful inside the NuclearInteraction model, which requires that.
*
* @param projectile is the Code of the projectile
* @param target is the Code of the target
* @param sqrtSnn is the center-of-mass energy (per nucleon pair)
* @param Aprojectil is the mass number of the projectils, if it is a nucleus
* @param Atarget is the mass number of the target, if it is a nucleus
*
* @return a tuple of: inelastic cross section, elastic cross section
*/
std
::
tuple
<
CrossSectionType
,
CrossSectionType
>
getCrossSectionInelEla
(
Code
const
projectile
,
Code
const
target
,
FourMomentum
const
&
projectileP4
,
FourMomentum
const
&
targetP4
)
const
;
/**
* Returns inelastic (production) cross section.
*
* This cross section must correspond to the process described in doInteraction.
* Allowed targets are: nuclei or single nucleons (p,n,hydrogen).
*
* @param projectile is the Code of the projectile
* @param target is the Code of the target
* @param sqrtSnn is the center-of-mass energy (per nucleon pair)
* @param Aprojectil is the mass number of the projectils, if it is a nucleus
* @param Atarget is the mass number of the target, if it is a nucleus
*
* @return inelastic cross section
* elastic cross section
*/
CrossSectionType
getCrossSection
(
Code
const
projectile
,
Code
const
target
,
FourMomentum
const
&
projectileP4
,
FourMomentum
const
&
targetP4
)
const
;
// non-const for now
/**
* In this function PYTHIA is called to produce one event. The
* event is copied (and boosted) into the shower lab frame.
*/
template
<
typename
TView
>
void
doInteraction
(
TView
&
output
,
Code
const
projectileId
,
Code
const
targetId
,
FourMomentum
const
&
projectileP4
,
FourMomentum
const
&
targetP4
);
/**
* return average number of sub-collisions in a nucleus, using the parameterizations
* of Sjöstrand and Utheim, EPJ C 82 (2022) 1, 21, arXiv:2108.03481 [hep-ph]
*
* @param targetId target (nucleus)
* @param sigTot projectile-nucleon (=proton) cross-secion
*/
double
getAverageSubcollisions
(
Code
targetId
,
CrossSectionType
sigTot
)
const
;
static
std
::
array
constexpr
validTargets_
{
Code
::
Oxygen
,
Code
::
Nitrogen
,
Code
::
Argon
,
Code
::
Hydrogen
,
Code
::
Proton
,
Code
::
Neutron
};
private
:
default_prng_type
&
RNG_
=
RNGManager
<>::
getInstance
().
getRandomStream
(
"pythia"
);
//~ bool const internalDecays_ = true;
int
count_
=
0
;
bool
const
print_listing_
=
false
;
Pythia8
::
Pythia
pythiaMain_
;
Pythia8
::
Pythia
mutable
pythiaColl_
;
// Pythia's getSigma...() are not marked const...
double
const
probSD_
=
0.3
;
// Fraction of single diffractive events beyond first collision in nucleus.
HEPEnergyType
const
eMaxLab_
=
1e18
_eV
;
HEPEnergyType
const
eKinMinLab_
=
0.2
_GeV
;
};
}
// namespace corsika::pythia8
#include
<corsika/detail/modules/pythia8/Interaction.inl>
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment