Skip to content

Commit

Permalink
Added individual source contributions to peaks for logging/tempalting…
Browse files Browse the repository at this point in the history
… act fit results.

Was previously logging raw source counts, at source, but not the sources contribution to peaks.
Also added logging a few other quantities, such as total attenuation, air attenuation.
For volumetric sources added some quantities to to indicate attenuations/efficiencies.
  • Loading branch information
wcjohns committed Dec 2, 2024
1 parent 9b88a7e commit c0dea39
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 129 deletions.
55 changes: 47 additions & 8 deletions InterSpec/GammaInteractionCalc.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ struct DistributedSrcCalc

GeometryType m_geometry;

size_t m_sourceIndex;
size_t m_materialIndex;
double m_detectorRadius;
double m_observationDist;

Expand Down Expand Up @@ -371,7 +371,7 @@ struct DistributedSrcCalc
*/
std::vector<std::tuple<std::array<double,3>,double,ShellType> > m_dimensionsTransLenAndType;

/** The activity per volume of the shielding.
/** The photons (i.e., sum of activities times br) per volume of the shielding.
Is not used during integration; used to multiple integral by to get number of expected peak counts.
*/
double m_srcVolumetricActivity;
Expand Down Expand Up @@ -414,10 +414,11 @@ struct PeakResultPlotInfo
};//struct PeakResultPlotInfo


/** A struct to capture the details of each source that contributed to a peak peak.
/**
A struct to capture the details of each source that contributed to a peak peak.
This is primarily to later turn to JSON, and allow customizing log files, through inja templating.
*/
*/
struct PeakDetailSrc
{
const SandiaDecay::Nuclide *nuclide = nullptr;
Expand All @@ -426,7 +427,7 @@ struct PeakDetailSrc
double energy = 0.0;
/** The number of this energy gamma, per second, for each Bq of parent nuclide. */
double br = 0.0;
double cps = 0.0;
double cpsAtSource = 0.0;
double age = 0.0;

/** For point sources, the activity of the point source.
Expand All @@ -445,8 +446,7 @@ struct PeakDetailSrc

bool isSelfAttenSource = false;//Not used - can be removed

double counts = 0.0;
//double countsUncert = 0.0;
double countsAtSource = 0.0;
double ageUncert = 0.0;//Not used - can be removed
//bool ageIsFit = false;
//bool canFitAge = false;
Expand All @@ -459,6 +459,9 @@ struct PeakDetailSrc
double massFraction = 0.0;//Not used - can be removed
double massFractionUncert = 0.0;//Not used - can be removed
bool isFittingMassFraction = false;//Not used - can be removed

/** The expected number of counts contributed by this source, to the peak. */
double modelContribToPeak = 0.0;
};//struct PeakDetailSrc


Expand All @@ -480,19 +483,52 @@ struct PeakDetail

std::string assignedNuclide;

/** Further information about the sources that contribute to this peak.
Please note that the `PeakDetailSrc` are not entirely filled out at creation, so do not rely on the member variables
being accurate until the end of the calculations.
*/
std::vector<PeakDetailSrc> m_sources;

/** The fractional attenuation by this material (e.g., no attenuation is 1.0. Not valid for volumetric sources.
The index of this vector is the same index as shielding in the model
*/
std::vector<double> m_attenuations;

/** The total attenuation factor (i.e., fraction no-interactions; 1.0 is no attenuation, 0.0 is total attentuation), that
all the shieldings cause.
Only valid for point sources.
*/
double m_totalShieldAttenFactor;
/** The attenuation, due to air, between the last shielding and the detector.
For volumetric sources, this is only approximate
*/
double m_airAttenFactor;

/** The total attenuation of the source from all shielding and air. For volumetric sources, this will only be approximate.
*/
double m_totalAttenFactor;

// TODO: for self-attenuating sources, could repeat the computation, put with only the source shell, then shell+1-other, then shell+different-1-other, and so on, to get the effect of each shell.

struct VolumeSrc
{
bool trace; // Trace or intrinsic

/** The integral of the efficiency to make it to the detector, over the source area.
i.e., the shielding area times average efficiency to make it to the detector face.
Does not include detector intrinsic efficiency.
*/
double integral;

/** The volume of the shielding. */
double volume;

/** `integral / volume` */
double averageEfficiencyPerSourceGamma;

/** The gammas per second, per unit-volume, for this source energy.
This value times `VolumeSrc::integral` gives the expected number of gammas, at this energy, to strike the detector face.
*/
double srcVolumetricActivity;

bool inSituExponential; //Not used - can be removed
Expand All @@ -512,7 +548,10 @@ struct PeakDetail
numSigmaOff( 0.0 ), observedOverExpected( 0.0 ),
//modelInto4Pi( 0.0f ), modelInto4PiCps( 0.0f ),
detSolidAngle( 0.0 ), detIntrinsicEff( 0.0 ), detEff( 0.0 ),
backgroundCounts( 0.0f ), backgroundCountsUncert( 0.0f )
backgroundCounts( 0.0f ), backgroundCountsUncert( 0.0f ),
assignedNuclide{}, m_sources{}, m_attenuations{},
m_totalShieldAttenFactor( 1.0 ), m_airAttenFactor( 1.0 ),
m_totalAttenFactor( 1.0 )
{
}
};//struct PeakDetail
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,6 @@ <h2 style="color: orange;">Warnings</h2>

{% if exists("Sources") %}
<div id="PeakContributions" style="margin-top: 25px">
<span style="color: red; font-weight: bold;">(Gamma contribution counts currently not correct!)</span>
<ul style="list-style-type: none; padding: 0; margin: 0;">
## for src in Sources
<li style="margin-top: 10px;"> Peak contributions from {{ src.Nuclide }}:
Expand All @@ -398,12 +397,19 @@ <h2 style="color: orange;">Warnings</h2>
<thead>
<tr>
<th>Energy (keV)</th>
<th>Signal Counts</th>
<th>Observed Counts</th>
<th>&Delta;Counts</th>
<th>Model Sum</th>
<th>Pred. Model Sum</th>
<th>Det. Intrinsic Eff.</th>
<th>Det. Solid Angle.</th>
<th>Det. Eff.</th>
<th>Shield Atten. Factor</th>
<th>Air Atten. Factor</th>
<th>Total Atten. Factor</th>
<th>Nuclide</th>
<th>&gamma; Energy</th>
<th>&gamma; Counts</th>
<th>Pred. &gamma;</th>
<th>&gamma; into 4pi</th>
</tr>
</thead>

Expand All @@ -414,7 +420,12 @@ <h2 style="color: orange;">Warnings</h2>
<td>{{ printCompact(peak.SignalCounts,5) }}</td>
<td>{{ printCompact(peak.SignalCountsUncert,5) }}</td>
<td>{{ printCompact(peak.PredictedCounts,5) }}</td>

<td>{{ printCompact(peak.DetectorIntrinsicEff,5) }}</td>
<td>{{ printCompact(peak.DetectorSolidAngleFraction,5) }}</td>
<td>{{ printCompact(peak.DetectorEff,5) }}</td>
<td>{{ printCompact(peak.AttenuationByShieldingFactor,5) }}</td>
<td>{{ printCompact(peak.AttenuationByAirFactor,5) }}</td>
<td>{{ printCompact(peak.AttenuationTotalFactor,5) }}</td>
{% if existsIn(peak,"ThisNucsGammasForPeak") %}
## for src in peak.ThisNucsGammasForPeak
{% if loop.is_first %}
Expand All @@ -424,16 +435,24 @@ <h2 style="color: orange;">Warnings</h2>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
{% endif %}
<td>{{ src.Nuclide }}</td>
<td>{{ printFixed(src.Energy_keV,3) }}</td>
<td>{{ printCompact(src.CountsContributedToPeak,6) }}</td>
<td>{{ printCompact(src.PredictedCounts,6) }}</td>
<td>{{ printCompact(src.SourcePhotons,6) }}</td>
</tr>
##endfor
{% else %}
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{% endif %}
##endfor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Sources:
For {{ src.Nuclide }} at age {{ src.Age }}{% if src.AgeIsFit %} +- {{ src.AgeUncert }} {% endif %} with activity {{ src.Activity }}{% if src.ActivityIsFit %} +- {{ src.ActivityUncert }} {% endif %}{% if src.IsTraceSource %}(src.TraceDisplayActivity{% if src.ActivityIsFit %} +- {{ src.TraceDisplayActivityUncert }} {% endif %}){% endif %}:
## for peak in src.PeaksThisNucContributesTo
## for gamma in peak.ThisNucsGammasForPeak
Peak attributed to {{ peak.DecayParticleEnergy }} keV received {{ gamma.CpsContributedToPeak }} from {{ gamma.Energy }} keV line{% if existsIn(gamma,"DecayCorrection") %} (decay correction {{ gamma.DecayCorrection }}){% endif %}, which has I={{ gamma.BranchingRatio }}
Peak attributed to {{ peak.DecayParticleEnergy }} keV received {{ gamma.PredictedCounts }} from {{ gamma.Energy }} keV line{% if existsIn(gamma,"DecayCorrection") %} (decay correction {{ gamma.DecayCorrection }}){% endif %}, which has I={{ gamma.BranchingRatio }}
##endfor
##endfor
##endfor
Expand Down
30 changes: 21 additions & 9 deletions src/BatchInfoLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,10 @@ void add_basic_src_details( const GammaInteractionCalc::SourceDetails &src,
peak_json["CpsUncert"] = peak.cpsUncert;
peak_json["ShieldAttenuations"] = peak.m_attenuations;

peak_json["AttenuationByShieldingFactor"] = peak.m_totalShieldAttenFactor;
peak_json["AttenuationByAirFactor"] = peak.m_airAttenFactor;
peak_json["AttenuationTotalFactor"] = peak.m_totalAttenFactor;

if( peak.backgroundCounts > 0.0 )
{
peak_json["BackgroundCounts"] = peak.backgroundCounts;
Expand Down Expand Up @@ -736,11 +740,14 @@ void add_basic_src_details( const GammaInteractionCalc::SourceDetails &src,
gamma_json["BranchingRatio"] = ps.br;
gamma_json["BranchingRatioStr"] = SpecUtils::printCompact( ps.br, 5 );

gamma_json["CpsContributedToPeak"] = ps.cps;
gamma_json["CpsContributedToPeakStr"] = SpecUtils::printCompact( ps.cps, 5 );
gamma_json["PredictedCounts"] = ps.modelContribToPeak;
gamma_json["PredictedCountsStr"] = SpecUtils::printCompact(ps.modelContribToPeak, 4);

gamma_json["SourcePhotonsCps"] = ps.cpsAtSource;
gamma_json["SourcePhotonsCpsStr"] = SpecUtils::printCompact( ps.cpsAtSource, 5 );

gamma_json["CountsContributedToPeak"] = ps.counts;
gamma_json["CountsContributedToPeakStr"] = SpecUtils::printCompact( ps.counts, 5 );
gamma_json["SourcePhotons"] = ps.countsAtSource;
gamma_json["SourcePhotonsStr"] = SpecUtils::printCompact( ps.countsAtSource, 5 );

gamma_json["HasDecayCorrection"] = (ps.decayCorrection > 0.0);
if( ps.decayCorrection > 0.0 )
Expand Down Expand Up @@ -1127,15 +1134,18 @@ void add_basic_src_details( const GammaInteractionCalc::SourceDetails &src,
src_json["Energy"] = string(buffer);
src_json["Energy_keV"] = pksrc.energy;

src_json["Cps"] = pksrc.cps;
src_json["CpsStr"] = SpecUtils::printCompact(pksrc.cps, 4);
src_json["SourcePhotonsCps"] = pksrc.cpsAtSource;
src_json["SourcePhotonsCpsStr"] = SpecUtils::printCompact(pksrc.cpsAtSource, 4);

src_json["BranchingRatio"] = pksrc.br;
src_json["BranchingRatioStr"] = SpecUtils::printCompact( pksrc.br, 5 );

snprintf( buffer, sizeof(buffer), "%.2f", pksrc.counts );
src_json["Counts"] = pksrc.counts;
src_json["CountsStr"] = string(buffer);
snprintf( buffer, sizeof(buffer), "%.2f", pksrc.countsAtSource );
src_json["SourcePhotons"] = pksrc.countsAtSource;
src_json["SourcePhotonsStr"] = string(buffer);

src_json["PredictedCounts"] = pksrc.modelContribToPeak;
src_json["PredictedCountsStr"] = SpecUtils::printCompact(pksrc.modelContribToPeak, 4);
}//for( const GammaInteractionCalc::PeakDetailSrc &pksrc : peak.m_sources )

// We could loop over the volumetric sources, and add info, but...
Expand All @@ -1144,6 +1154,8 @@ void add_basic_src_details( const GammaInteractionCalc::SourceDetails &src,
{
bool trace;
double integral;
double volume;
double averageEfficiencyPerSourceGamma;
double srcVolumetricActivity;
bool inSituExponential;
double inSituRelaxationLength;
Expand Down
Loading

0 comments on commit c0dea39

Please sign in to comment.