12 #include "messagefacility/MessageLogger/MessageLogger.h"
13 #include "nurandom/RandomUtils/NuRandomService.h"
18 constexpr
int MAX_BOX_ITERATIONS = 10000;
23 const fhicl::Table<evgen::ActiveVolumeVertexSampler::Config>& conf,
24 rndm::NuRandomService& rand_service,
const geo::Geometry& geom,
25 const std::string& generator_name)
26 : fVertexType(vertex_type_t::kSampled), fGeneratorName(generator_name),
35 rndm::NuRandomService::seed_t tpc_seed = rand_service.registerEngine(
36 [
this](rndm::NuRandomService::EngineId
const& ,
37 rndm::NuRandomService::seed_t lar_seed) ->
void
39 auto seed =
static_cast<uint_fast64_t
>(lar_seed);
44 std::seed_seq seed_sequence{
seed};
45 fTPCEngine.seed(seed_sequence);
47 fGeneratorName, conf.get_PSet(), {
"seed" }
52 uint_fast64_t tpc_cast_seed =
static_cast<uint_fast64_t
>(tpc_seed);
53 std::seed_seq tpc_seed_sequence{tpc_cast_seed};
54 fTPCEngine.seed(tpc_seed_sequence);
68 const auto& tpc = geom.
TPC(tpc_index);
69 double minX = tpc.
MinX();
70 double maxX = tpc.MaxX();
71 double minY = tpc.MinY();
72 double maxY = tpc.MaxY();
73 double minZ = tpc.MinZ();
74 double maxZ = tpc.MaxZ();
75 std::uniform_real_distribution<double>::param_type x_range(minX, maxX);
76 std::uniform_real_distribution<double>::param_type y_range(minY, maxY);
77 std::uniform_real_distribution<double>::param_type z_range(minZ, maxZ);
80 std::uniform_real_distribution<double> uniform_dist;
85 <<
"Sampled primary vertex in TPC #" << tpc_index <<
", x = " << x
86 <<
", y = " << y <<
", z = " <<
z;
93 int num_iterations = 0;
97 std::uniform_real_distribution<double>::param_type x_range(
fXmin,
fXmax);
98 std::uniform_real_distribution<double>::param_type y_range(
fYmin,
fYmax);
99 std::uniform_real_distribution<double>::param_type z_range(
fZmin,
fZmax);
102 std::uniform_real_distribution<double> uniform_dist;
107 while ( !ok && num_iterations < MAX_BOX_ITERATIONS ) {
116 size_t num_tpcs = geom.
NTPC();
117 for (
size_t iTPC = 0; iTPC < num_tpcs; ++iTPC) {
118 const auto& tpc = geom.
TPC(iTPC);
119 double minX = tpc.
MinX();
120 double maxX = tpc.MaxX();
121 double minY = tpc.MinY();
122 double maxY = tpc.MaxY();
123 double minZ = tpc.MinZ();
124 double maxZ = tpc.MaxZ();
125 if ( x >= minX && x <= maxX && y >= minY && y <= maxY && z >= minZ && z <= maxZ ) {
134 if ( !ok )
throw cet::exception(
"ActiveVolumeVertexSampler " +
fGeneratorName)
135 <<
"Failed to sample a vertex within a TPC active volume after " << MAX_BOX_ITERATIONS
139 <<
"Sampled primary vertex at x = " << x <<
", y = " << y
152 const fhicl::Table<evgen::ActiveVolumeVertexSampler::Config>& conf,
155 auto type = conf().type_();
156 if (
type ==
"sampled") {
158 fVertexType = vertex_type_t::kSampled;
162 std::vector<double> tpc_masses;
163 size_t num_tpcs = geom.
NTPC();
164 for (
size_t iTPC = 0; iTPC < num_tpcs; ++iTPC) {
172 fTPCDist.reset(
new std::discrete_distribution<size_t>(tpc_masses.begin(),
175 else if (
type ==
"fixed") {
179 auto vertex_pos = conf().position_();
180 double Vx = vertex_pos.at(0);
181 double Vy = vertex_pos.at(1);
182 double Vz = vertex_pos.at(2);
184 fVertexPosition.SetXYZT(Vx, Vy, Vz, 0.);
186 else if (
type ==
"box") {
188 fVertexType = vertex_type_t::kBox;
189 auto min_pos = conf().min_position_();
190 auto max_pos = conf().max_position_();
192 fXmin = min_pos.at(0);
193 fYmin = min_pos.at(1);
194 fZmin = min_pos.at(2);
196 fXmax = max_pos.at(0);
197 fYmax = max_pos.at(1);
198 fZmax = max_pos.at(2);
201 fCheckActive =
false;
203 conf().check_active_( fCheckActive );
206 else throw cet::exception(
"ActiveVolumeVertexSampler " + fGeneratorName)
207 <<
"Invalid vertex type '" <<
type <<
"' requested. Allowed values are"
208 <<
" 'sampled' and 'fixed'";
process_name opflash particleana ie ie ie z
vertex_type_t fVertexType
TLorentzVector fVertexPosition
process_name opflash particleana ie x
vertex position fixed manually - no fitting done
double MinX() const
Returns the world x coordinate of the start of the box.
TLorentzVector sample_vertex_pos(const geo::Geometry &geom)
double ActiveMass() const
ActiveVolumeVertexSampler(const fhicl::Table< Config > &conf, rndm::NuRandomService &rand_service, const geo::Geometry &geom, const std::string &generator_name)
Algorithm that samples vertex locations uniformly within the active volume of a detector. It is fully experiment-agnostic and multi-TPC aware.
process_name opflash particleana ie ie y
The geometry of one entire detector, as served by art.
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
std::unique_ptr< std::discrete_distribution< size_t > > fTPCDist
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
std::string fGeneratorName
art framework interface to geometry description
Encapsulate the construction of a single detector plane.
std::mt19937_64 fTPCEngine