22 std::filesystem::path output =
"opalx-linear-breit-wheeler-spectrum.csv";
23 std::string particle =
"electron";
24 std::string observable =
"energy";
26 bool finitePhotonBeam =
false;
27 std::size_t samples = 250000;
29 double wavelength_m = 1.0e-9;
30 double highEnergyPhotonEnergyGeV = 0.5;
31 double photonSigmaThetaRad = 1.0e-3;
32 double photonRelativeEnergySpread = 0.0;
33 double photonSigmaPositionM = 0.0;
34 double photonSigmaSM = 0.0;
35 double laserRayleighM = 1.0e-6;
37 bool overlapWeighting =
false;
38 std::size_t bins = 80;
39 double minValue = 0.0;
40 double maxValue = 0.5;
41 double thetaMaxRad = 0.0045;
44 CliOptions parseArguments(
int argc,
char** argv) {
46 for (
int i = 1; i < argc; ++i) {
47 const std::string arg(argv[i]);
48 if (arg ==
"--particle") {
49 options.particle = argv[++i];
50 }
else if (arg ==
"--observable") {
51 options.observable = argv[++i];
52 }
else if (arg ==
"--joint") {
54 }
else if (arg ==
"--finite-photon-beam") {
55 options.finitePhotonBeam =
true;
56 }
else if (arg ==
"--samples") {
57 options.samples =
static_cast<std::size_t
>(std::stoull(argv[++i]));
58 }
else if (arg ==
"--seed") {
59 options.seed = std::stoi(argv[++i]);
60 }
else if (arg ==
"--wavelength") {
61 options.wavelength_m = std::stod(argv[++i]);
62 }
else if (arg ==
"--high-energy-photon") {
63 options.highEnergyPhotonEnergyGeV = std::stod(argv[++i]);
64 }
else if (arg ==
"--photon-sigma-theta") {
65 options.photonSigmaThetaRad = std::stod(argv[++i]);
66 }
else if (arg ==
"--photon-relative-energy-spread") {
67 options.photonRelativeEnergySpread = std::stod(argv[++i]);
68 }
else if (arg ==
"--photon-sigma-position") {
69 options.photonSigmaPositionM = std::stod(argv[++i]);
70 }
else if (arg ==
"--photon-sigma-s") {
71 options.photonSigmaSM = std::stod(argv[++i]);
72 }
else if (arg ==
"--laser-rayleigh") {
73 options.laserRayleighM = std::stod(argv[++i]);
74 }
else if (arg ==
"--laser-sigma-t") {
75 options.laserSigmaTM = std::stod(argv[++i]);
76 }
else if (arg ==
"--overlap-weighting") {
77 options.overlapWeighting =
true;
78 }
else if (arg ==
"--bins") {
79 options.bins =
static_cast<std::size_t
>(std::stoull(argv[++i]));
80 }
else if (arg ==
"--min") {
81 options.minValue = std::stod(argv[++i]);
82 }
else if (arg ==
"--max") {
83 options.maxValue = std::stod(argv[++i]);
84 }
else if (arg ==
"--theta-max") {
85 options.thetaMaxRad = std::stod(argv[++i]);
86 }
else if (arg ==
"-h" || arg ==
"--help") {
87 std::cout <<
"Usage: LinearBreitWheelerBenchmark [output.csv] [--particle "
89 <<
" [--observable energy|theta] [--joint] [--finite-photon-beam] "
90 "[--overlap-weighting] [--samples N] [--seed S] [--bins N]"
91 <<
" [--high-energy-photon E] [--photon-sigma-theta S] "
92 "[--photon-relative-energy-spread S]"
93 <<
" [--photon-sigma-position S] [--photon-sigma-s S] [--laser-rayleigh "
94 "S] [--laser-sigma-t S]"
95 <<
" [--min V] [--max V] [--theta-max V]\n";
97 }
else if (!arg.empty() && arg[0] ==
'-') {
98 throw std::runtime_error(
"Unknown option: " + arg);
100 options.output = arg;
115 if (particle ==
"positron") {
122 if (observable ==
"theta") {
129int main(
int argc,
char** argv) {
130 const CliOptions options = parseArguments(argc, argv);
134 const auto state = parseFinalState(options.particle);
137 if (options.finitePhotonBeam) {
146 config.
sigmaX_m = options.photonSigmaPositionM;
147 config.
sigmaY_m = options.photonSigmaPositionM;
148 config.
sigmaS_m = options.photonSigmaSM;
160 const auto histogram =
162 config, state, options.samples);
178 config, state, options.samples);
182 std::cout <<
"Wrote OPALX linear Breit-Wheeler joint benchmark to " << options.output
187 const auto observable = parseObservable(options.observable);
190 std::ofstream output(options.output);
191 output <<
"# value,weight\n";
193 if (options.finitePhotonBeam) {
194 const double laserPhotonEnergyGeV =
204 config.
sigmaX_m = options.photonSigmaPositionM;
205 config.
sigmaY_m = options.photonSigmaPositionM;
206 config.
sigmaS_m = options.photonSigmaSM;
212 for (std::size_t i = 0; i < options.samples; ++i) {
213 const auto beamState =
222 constexpr double overlapWeight = 1.0;
224 beamState.energyGeV, laserPhotonEnergyGeV, beamState.direction,
229 output << value <<
',' << overlapWeight <<
'\n';
232 const double laserPhotonEnergyGeV =
235 options.highEnergyPhotonEnergyGeV, laserPhotonEnergyGeV,
236 makeDirection(0.0, 0.0, 1.0), makeDirection(0.0, 0.0, -1.0));
237 for (std::size_t i = 0; i < options.samples; ++i) {
241 output << value <<
",1\n";
246 std::cout <<
"Wrote OPALX linear Breit-Wheeler sampled benchmark to " << options.output <<
'\n';
ippl::Vector< T, Dim > Vector_t
int main(int argc, char **argv)
Vector_t< double, 3 > laserDirection
double highEnergyPhotonEnergyGeV
double sampledObservable(const Physics::LinearBreitWheeler::SampledEvent &event, FinalState state, Observable observable)
double relativeEnergySpread
JointHistogram sampleFinitePhotonBeamJointHistogram(const FinitePhotonBeamJointConfig &config, FinalState state, std::size_t sampleCount, std::uint64_t streamIndex=0)
Sample the joint Breit-Wheeler laboratory distribution in energy and polar angle.
void writeJointHistogramCSV(const JointHistogram &histogram, const std::filesystem::path &outputPath)
Vector_t< double, 3 > highEnergyDirection
double relativeEnergySpread
Vector_t< double, 3 > referenceHighEnergyDirection
SampledPhotonBeamState samplePhotonBeamState(const Vector_t< double, 3 > &referenceDirection, double sigmaThetaXRad, double sigmaThetaYRad, double sigmaX_m, double sigmaY_m, double sigmaS_m, double centralEnergyGeV, double relativeEnergySpread, std::mt19937_64 &engine)
Vector_t< double, 3 > referenceHighEnergyDirection
JointHistogram sampleJointHistogram(const JointHistogramConfig &config, FinalState state, std::size_t sampleCount, std::uint64_t streamIndex=0)
Vector_t< double, 3 > laserDirection
double centralHighEnergyPhotonEnergyGeV
SampledPhotonBeamState sampleOverlapPhotonBeamState(const FinitePhotonBeamConfig &config, std::mt19937_64 &engine)
Vector_t< double, 3 > laserDirection
double centralHighEnergyPhotonEnergyGeV
Configuration for folding the linear Breit-Wheeler kernel over a finite incoming photon beam.
int seed
The current random seed.
SampledEvent sampleEvent(const SamplingKernel &kernel, std::mt19937_64 &engine)
Sample one unpolarized linear Breit-Wheeler event.
SamplingKernel makeSamplingKernel(double highEnergyPhotonEnergyGeV, double laserPhotonEnergyGeV, const Vector_t< double, 3 > &highEnergyDirection, const Vector_t< double, 3 > &laserDirection)
Build a cached sampling kernel for repeated sampled events.
std::mt19937_64 makeHostRandomEngine(std::uint64_t streamIndex)
Build a deterministic host RNG from Options::seed.
double photonEnergyFromWavelengthGeV(double wavelength_m)
Convert a laser wavelength to a single-photon energy.
constexpr double c
The velocity of light in m/s.