127 ,
fFlatEngine(art::ServiceHandle<rndm::NuRandomService>()->createEngine(*
this,
"HepJamesRandom",
"GenRain"))
141 const int nbins(100);
142 double parent[nbins];
143 for (
size_t idx = 0; idx < nbins; ++idx) {
145 parent[idx] = cet::square(((
float) idx)/nbins);
149 produces< std::vector<simb::MCTruth> >();
152 _debug =
p.get<
unsigned short>(
"DebugMode",0);
154 _t0 =
p.get<
double>(
"G4Time");
156 if(_t0_sigma < 0) this->
abort(
"Cannot have a negative value for G4 time jitter");
162 _tpc_v =
p.get<std::vector<std::vector<unsigned short> > >(
"TPCRange");
163 auto const xrange =
p.get<std::vector<double> > (
"XRange");
164 auto const yrange =
p.get<std::vector<double> > (
"YRange");
165 auto const zrange =
p.get<std::vector<double> > (
"ZRange");
166 auto const part_cfg =
p.get<fhicl::ParameterSet>(
"ParticleParameter");
169 auto const pdg_v = part_cfg.get<std::vector<std::vector<int> > > (
"PDGCode");
170 auto const minmult_v = part_cfg.get<std::vector<unsigned short> > (
"MinMulti");
171 auto const maxmult_v = part_cfg.get<std::vector<unsigned short> > (
"MaxMulti");
172 auto const weight_v = part_cfg.get<std::vector<double> > (
"ProbWeight");
174 auto kerange_v = part_cfg.get<std::vector<std::vector<double> > > (
"KERange");
175 auto momrange_v = part_cfg.get<std::vector<std::vector<double> > > (
"MomRange");
177 if( (kerange_v.empty() && momrange_v.empty()) ||
178 (!kerange_v.empty() && !momrange_v.empty()) ) {
179 this->
abort(
"Only one of KERange or MomRange must be empty!");
182 bool use_mom =
false;
183 if(kerange_v.empty()){
184 kerange_v = momrange_v;
188 if( pdg_v.size() != kerange_v.size() ||
189 pdg_v.size() != minmult_v.size() ||
190 pdg_v.size() != maxmult_v.size() ||
191 pdg_v.size() != weight_v.size() )
192 this->
abort(
"configuration parameters have incompatible lengths!");
195 for(
auto const&
r : pdg_v ) {
if(
r.empty() ) this->
abort(
"PDG code not given!"); }
196 for(
auto const&
r : kerange_v) {
if(
r.size()!=2) this->
abort(
"Incompatible legnth @ KE vector!"); }
198 for(
size_t idx=0; idx<minmult_v.size(); ++idx) {
199 if(minmult_v[idx] > maxmult_v[idx]) this->
abort(
"Particle MinMulti > Particle MaxMulti!");
200 if(minmult_v[idx] > _multi_max) this->
abort(
"Particle MinMulti > overall MultiMax!");
204 if(_multi_max <
_multi_min) this->
abort(
"Overall MultiMax <= overall MultiMin!");
206 if(!xrange.empty() && xrange.size() >2) this->
abort(
"Incompatible legnth @ X vector!" );
207 if(!yrange.empty() && yrange.size() >2) this->
abort(
"Incompatible legnth @ Y vector!" );
208 if(!zrange.empty() && zrange.size() >2) this->
abort(
"Incompatible legnth @ Z vector!" );
211 double xmin,xmax,ymin,ymax,zmin,zmax;
212 xmin = ymin = zmin = 1.e20;
213 xmax = ymax = zmax = -1.e20;
215 auto geop = lar::providerFrom<geo::Geometry>();
216 for(
auto const& tpc_id : _tpc_v) {
217 assert(tpc_id.size() == 2);
218 size_t cid = tpc_id[0];
219 size_t tid = tpc_id[1];
220 auto const& cryostat = geop->Cryostat(cid);
221 assert(cryostat.HasTPC(tid));
223 auto const& tpc = cryostat.TPC(tid);
224 auto const& tpcabox = tpc.ActiveBoundingBox();
225 xmin = std::min(tpcabox.MinX(),
xmin);
226 ymin = std::min(tpcabox.MinY(), ymin);
227 zmin = std::min(tpcabox.MinZ(), zmin);
228 xmax = std::max(tpcabox.MaxX(), xmax);
229 ymax = std::max(tpcabox.MaxY(), ymax);
230 zmax = std::max(tpcabox.MaxZ(), zmax);
233 std::cout <<
"Using Cryostat " << tpc_id[0] <<
" TPC " << tpc_id[1]
234 <<
" ... X " << xmin <<
" => " << xmax
235 <<
" ... Y " << ymin <<
" => " << ymax
236 <<
" ... Z " << zmin <<
" => " << zmax
245 if(xrange.size()==2) {
_xrange[0] = xrange[0];
_xrange[1] = xrange[1]; }
246 if(yrange.size()==2) {
_yrange[0] = yrange[0];
_yrange[1] = yrange[1]; }
247 if(zrange.size()==2) {
_zrange[0] = zrange[0];
_zrange[1] = zrange[1]; }
250 _xrange[1] = xmax - _xrange[1];
252 _yrange[1] = ymax - _yrange[1];
254 _zrange[1] = zmax - _zrange[1];
257 assert(_xrange[0] <= _xrange[1]);
258 assert(_yrange[0] <= _yrange[1]);
259 assert(_zrange[0] <= _zrange[1]);
262 std::cout<<
"Particle generation world boundaries..."<<std::endl
263 <<
"X " << _xrange[0] <<
" => " << _xrange[1] << std::endl
264 <<
"Y " << _yrange[0] <<
" => " << _yrange[1] << std::endl
265 <<
"Z " << _zrange[0] <<
" => " << _zrange[1] << std::endl;
271 auto db = TDatabasePDG::Instance();
272 bool direct_inward =
p.get<
bool>(
"DirectInward",
true);
273 if (_cosmic_distribution && direct_inward) {
274 std::cout <<
"Cannot satisfy both CosmicDistribution and Inward Directioning at the same time" << std::endl;
275 throw std::exception();
277 for(
size_t idx=0; idx<pdg_v.size(); ++idx) {
278 auto const&
pdg = pdg_v[idx];
279 auto const& kerange = kerange_v[idx];
287 param.
multi[0] = minmult_v[idx];
288 param.
multi[1] = maxmult_v[idx];
289 param.
weight = weight_v[idx];
290 for(
size_t i=0; i<
pdg.size(); ++i)
291 param.
mass[i] =
db->GetParticle(param.
pdg[i])->Mass();
294 if(kerange[0]<0 || kerange[1]<0)
295 this->
abort(
"You provided negative energy? Fuck off Mr. Trump.");
304 << (param.
use_mom ?
" KE range ....... " :
" Mom range ....... ")
305 << param.
kerange[0] <<
" => " << param.
kerange[1] <<
" MeV" << std::endl
produces< sumdata::RunData, art::InRun >()
CLHEP::HepRandomEngine & fFlatEngine
std::array< double, 2 > _xrange
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
std::array< double, 2 > _zrange
std::vector< PartGenParam > _param_v
std::unique_ptr< CLHEP::RandFlat > fFlatRandom
std::array< double, 2 > _yrange
std::vector< double > mass
std::array< double, 2 > kerange
std::unique_ptr< CLHEP::RandGeneral > fCosmicAngleRandom
height to which particles are projected pnfs larsoft persistent physics cosmics Fermilab CORSIKA standard He_showers_ * db
std::unique_ptr< CLHEP::RandGauss > fNormalRandom
bool _cosmic_distribution
std::array< size_t, 2 > multi
void abort(const std::string msg) const
BEGIN_PROLOG could also be cout
std::vector< std::vector< unsigned short > > _tpc_v