Skip to content

Commit

Permalink
Fix ScintillationData operator bool; Minor reorg
Browse files Browse the repository at this point in the history
  • Loading branch information
stognini committed Mar 22, 2024
1 parent 4968e68 commit 7539913
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 45 deletions.
24 changes: 10 additions & 14 deletions src/celeritas/optical/ScintillationData.hh
Expand Up @@ -118,17 +118,16 @@ struct ScintillationData

//// MEMBER DATA ////

//! Index between OpticalMaterialId and MaterialId
Collection<OpticalMaterialId, W, M, MaterialId> matid_to_optmatid;
//! Index between ScintillationParticleId and ParticleId
Collection<ScintillationParticleId, W, M, ParticleId> pid_to_scintpid;

//! Resolution scale for each material
Collection<real_type, W, M, OpticalMaterialId> resolution_scale;

//! Material-only scintillation spectrum data
MaterialItems materials; //!< [OpticalMaterialId]

//! Index between ScintillationParticleId and ParticleId
Collection<ScintillationParticleId, W, M, ParticleId> pid_to_scintpid;
//! Cache number of scintillation particles; Used by this->spectrum_index
size_type num_scint_particles{};
//! Particle and material scintillation spectrum data
ParticleItems particles; //!< [ParticleScintSpectrumId]
//! Backend storage for ParticleScintillationSpectrum::yield_vector
Expand All @@ -137,17 +136,15 @@ struct ScintillationData
//! Components for either material or particle items
Items<ScintillationComponent> components;

//! Cache number of scintillation particles; Used by this->spectrum_index
size_type num_scint_particles{};

//// MEMBER FUNCTIONS ////

//! Whether all data are assigned and valid
explicit CELER_FUNCTION operator bool() const
{
return !matid_to_optmatid.empty() && !pid_to_scintpid.empty()
&& (!materials.empty() || !particles.empty())
&& num_scint_particles > 0;
return !resolution_scale.empty()
&& (materials.empty() != particles.empty())
&& (!pid_to_scintpid.empty() == !particles.empty())
&& (!pid_to_scintpid.empty() == (num_scint_particles > 0));
}

//! Whether sampling must happen by particle type
Expand All @@ -173,14 +170,13 @@ struct ScintillationData
ScintillationData& operator=(ScintillationData<W2, M2> const& other)
{
CELER_EXPECT(other);
matid_to_optmatid = other.matid_to_optmatid;
pid_to_scintpid = other.pid_to_scintpid;
resolution_scale = other.resolution_scale;
materials = other.materials;
pid_to_scintpid = other.pid_to_scintpid;
num_scint_particles = other.num_scint_particles;
particles = other.particles;
reals = other.reals;
components = other.components;
num_scint_particles = other.num_scint_particles;
return *this;
}
};
Expand Down
53 changes: 25 additions & 28 deletions src/celeritas/optical/ScintillationParams.cc
Expand Up @@ -111,29 +111,13 @@ ScintillationParams::ScintillationParams(Input const& input)
{
CELER_EXPECT(input);
HostVal<ScintillationData> host_data;
CollectionBuilder build_optmatid(&host_data.matid_to_optmatid);
CollectionBuilder build_scintpid(&host_data.pid_to_scintpid);
CollectionBuilder build_resolutionscale(&host_data.resolution_scale);
CollectionBuilder build_compoments(&host_data.components);

if (!input.particles.empty())
{
// Store particle idss
for (auto const id : input.pid_to_scintpid)
{
build_scintpid.push_back(id);
if (id)
{
host_data.num_scint_particles++;
}
}
CELER_ENSURE(!host_data.pid_to_scintpid.empty());
CELER_ENSURE(host_data.num_scint_particles > 0);
}
CollectionBuilder build_components(&host_data.components);

// Store resolution scale
for (auto const& val : input.resolution_scale)
{
CELER_EXPECT(!input.resolution_scale.empty());
CELER_VALIDATE(val >= 0,
<< "invalid resolution_scale=" << val
<< " for scintillation (should be nonnegative)");
Expand All @@ -143,10 +127,10 @@ ScintillationParams::ScintillationParams(Input const& input)

if (input.particles.empty())
{
// Store material scintillation data
CELER_EXPECT(!input.materials.empty());
CollectionBuilder build_materials(&host_data.materials);

// Store material scintillation data
for (auto const& mat : input.materials)
{
// Check validity of input scintillation data
Expand All @@ -159,7 +143,7 @@ ScintillationParams::ScintillationParams(Input const& input)
mat_spec.yield = mat.yield;
auto comps = this->build_components(mat.components);
mat_spec.components
= build_compoments.insert_back(comps.begin(), comps.end());
= build_components.insert_back(comps.begin(), comps.end());
build_materials.push_back(std::move(mat_spec));
}
CELER_VALIDATE(input.materials.size() == input.resolution_scale.size(),
Expand All @@ -169,11 +153,23 @@ ScintillationParams::ScintillationParams(Input const& input)
}
else
{
// Store particle- and material-dependent scintillation data
// Index should loop over particles first, then materials. This
// ordering should improve memory usage, since we group the
// material list for each particle, and each particle (i.e. stream)
// traverses multiple materials
// Store particle data
CELER_EXPECT(!input.pid_to_scintpid.empty());
CollectionBuilder build_scintpid(&host_data.pid_to_scintpid);

// Store particle ids
for (auto const id : input.pid_to_scintpid)
{
build_scintpid.push_back(id);
if (id)
{
host_data.num_scint_particles++;
}
}
CELER_ENSURE(host_data.num_scint_particles > 0);

// Store particle spectra
CELER_EXPECT(!input.particles.empty());
GenericGridBuilder build_grid(&host_data.reals);
CollectionBuilder build_particles(&host_data.particles);

Expand All @@ -183,21 +179,22 @@ ScintillationParams::ScintillationParams(Input const& input)
part_spec.yield_vector = build_grid(spec.yield_vector);
auto comps = this->build_components(spec.components);
part_spec.components
= build_compoments.insert_back(comps.begin(), comps.end());
= build_components.insert_back(comps.begin(), comps.end());
build_particles.push_back(std::move(part_spec));
}
CELER_ENSURE(host_data.particles.size()
== host_data.num_scint_particles
* host_data.resolution_scale.size());
}

// Copy to device
mirror_ = CollectionMirror<ScintillationData>{std::move(host_data)};
CELER_ENSURE(mirror_);
}

//---------------------------------------------------------------------------//
/*
* Return a Celeritas ScintillationComponent from an imported one.
/*!
* Return a \c ScintillationComponent from a \c ImportScintComponent .
*/
std::vector<ScintillationComponent> ScintillationParams::build_components(
std::vector<ImportScintComponent> const& input_comp)
Expand Down
8 changes: 6 additions & 2 deletions src/celeritas/optical/ScintillationParams.hh
Expand Up @@ -38,10 +38,14 @@ class ScintillationParams final : public ParamsDataInterface<ScintillationData>
using VecOptMatId = std::vector<OpticalMaterialId>;
using VecSPId = std::vector<ScintillationParticleId>;

VecSPId pid_to_scintpid; //!< ParticleId to ScintillationParticleId

std::vector<double> resolution_scale;

//! Material-only spectra
std::vector<ImportMaterialScintSpectrum> materials;

//!< ParticleId to ScintillationParticleId
VecSPId pid_to_scintpid;
//! Particle and material spectra [ParticleScintillationSpectrumId]
std::vector<ImportParticleScintSpectrum> particles;

explicit operator bool() const
Expand Down
2 changes: 1 addition & 1 deletion test/celeritas/optical/Scintillation.test.cc
Expand Up @@ -57,7 +57,6 @@ class ScintillationTest : public OpticalTestBase
build_scintillation_params(bool scint_by_particle = false)
{
ScintillationParams::Input inp;
inp.pid_to_scintpid.push_back(ScintillationParticleId(0));
inp.resolution_scale.push_back(1);

// One material, three components
Expand All @@ -71,6 +70,7 @@ class ScintillationTest : public OpticalTestBase
else
{
// One particle, one component (based on lar-sphere.gdml)
inp.pid_to_scintpid.push_back(ScintillationParticleId(0));
ImportParticleScintSpectrum ipss;
ipss.yield_vector = this->build_particle_yield();
ipss.components = this->build_particle_components();
Expand Down

0 comments on commit 7539913

Please sign in to comment.