15using Kernel::DeltaEMode;
16using Kernel::PseudoRandomNumberGenerator;
33 const size_t maxScatterPtAttempts,
const bool regenerateTracksForEachLambda)
34 : m_beamProfile(beamProfile), m_scatterVol(setActiveRegion(interactionVolume, beamProfile)), m_nevents(nevents),
35 m_maxScatterAttempts(maxScatterPtAttempts), m_EMode(EMode),
36 m_regenerateTracksForEachLambda(regenerateTracksForEachLambda) {}
49 return interactionVolume;
70 const std::vector<double> &lambdas,
const double lambdaFixed,
71 std::vector<double> &attenuationFactors, std::vector<double> &attFactorErrors,
74 const auto nbins =
static_cast<int>(lambdas.size());
76 std::vector<double> wgtMean(attenuationFactors.size()), wgtM2(attenuationFactors.size());
79 std::shared_ptr<Geometry::Track> beforeScatter;
80 std::shared_ptr<Geometry::Track> afterScatter;
81 for (
int j = 0; j < nbins; ++j) {
87 std::tie(success, beforeScatter, afterScatter) =
95 const double lambdaStep = lambdas[j];
96 double lambdaIn(lambdaStep), lambdaOut(lambdaStep);
98 lambdaIn = lambdaFixed;
100 lambdaOut = lambdaFixed;
105 beforeScatter->calculateAttenuation(lambdaIn) * afterScatter->calculateAttenuation(lambdaOut);
106 attenuationFactors[j] += wgt;
108 double delta = wgt - wgtMean[j];
109 wgtMean[j] +=
delta /
static_cast<double>(i + 1);
110 wgtM2[j] +=
delta * (wgt - wgtMean[j]);
113 attFactorErrors[j] = sqrt(wgtM2[j] /
static_cast<double>(i));
118 throw std::runtime_error(
"Unable to generate valid track through "
119 "sample interaction volume after " +
121 " attempts. Try increasing the maximum "
122 "threshold or if this does not help then "
123 "please check the defined shape.");
129 std::transform(attenuationFactors.begin(), attenuationFactors.end(), attenuationFactors.begin(),
130 std::bind(std::divides<double>(), std::placeholders::_1,
static_cast<double>(
m_nevents)));
133 std::transform(attFactorErrors.begin(), attFactorErrors.end(), attFactorErrors.begin(),
134 [
this](
double v) ->
double { return v / sqrt(static_cast<double>(m_nevents)); });
Base class for all classes defining a beam profile.
virtual Ray generatePoint(Kernel::PseudoRandomNumberGenerator &rng) const =0
virtual Geometry::BoundingBox defineActiveRegion(const Geometry::BoundingBox &) const =0
Defines a base class for objects describing a volume where interactions of Tracks and Objects can tak...
virtual void setActiveRegion(const Geometry::BoundingBox ®ion)=0
virtual TrackPair calculateBeforeAfterTrack(Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &startPos, const Kernel::V3D &endPos, MCInteractionStatistics &stats) const =0
virtual const Geometry::BoundingBox getFullBoundingBox() const =0
const bool m_regenerateTracksForEachLambda
MCAbsorptionStrategy(IMCInteractionVolume &interactionVolume, const IBeamProfile &beamProfile, Kernel::DeltaEMode::Type EMode, const size_t nevents, const size_t maxScatterPtAttempts, const bool regenerateTracksForEachLambda)
Constructor.
const IBeamProfile & m_beamProfile
const IMCInteractionVolume & m_scatterVol
IMCInteractionVolume & setActiveRegion(IMCInteractionVolume &interactionVolume, const IBeamProfile &beamProfile)
Set the active region on the interaction volume as smaller of the sample bounding box and the beam cr...
const size_t m_maxScatterAttempts
virtual void calculate(Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &finalPos, const std::vector< double > &lambdas, const double lambdaFixed, std::vector< double > &attenuationFactors, std::vector< double > &attFactorErrors, MCInteractionStatistics &stats) override
Compute the correction for a final position of the neutron and wavelengths before and after scatterin...
const Kernel::DeltaEMode::Type m_EMode
Stores statistics relating to the tracks generated in MCInteractionVolume for a specific detector.
Defines a 1D pseudo-random number generator, i.e.
Helper class which provides the Collimation Length for SANS instruments.
std::string to_string(const wide_integer< Bits, Signed > &n)
Type
Define the available energy transfer modes It is important to assign enums proper numbers,...