12 #include "TDatabasePDG.h" 24 #include "art_root_io/TFileService.h" 25 #include "art_root_io/TFileDirectory.h" 29 #include "nurandom/RandomUtils/NuRandomService.h" 34 #include "nugen/EventGeneratorBase/evgenbase.h" 41 #include "CLHEP/Random/RandFlat.h" 42 #include "CLHEP/Random/RandPoissonQ.h" 70 double wrapvar(
const double var,
const double low,
const double high);
71 double wrapvarBoxNo(
const double var,
const double low,
const double high,
int& boxno);
116 fToffset(
p.get<
double >(
"TimeOffset",0.)),
117 fBuffBox(
p.get< std::vector< double > >(
"BufferBox",{0.0, 0.0, 0.0, 0.0, 0.0, 0.0})),
125 ->
createEngine(*
this,
"HepJamesRandom",
"gen",
p, {
"Seed",
"SeedGenerator" })),
127 ->
createEngine(*
this,
"HepJamesRandom",
"pois",
p,
"SeedPoisson"))
131 throw cet::exception(
"CORSIKAGendp") <<
"ShowerInputFiles and ShowerFluxConstants have different or invalid sizes!"<<
"\n";
145 produces< std::vector<simb::MCTruth> >();
146 produces< sumdata::RunData, art::InRun >();
152 sqlite3_close(
fdb[i]);
161 dummyvec[0] = vec[0];
162 dummyvec[1] = vec[1];
163 dummyvec[2] = vec[3];
164 vec[0] = dummyvec[1];
165 vec[1] = -dummyvec[0];
166 vec[2] = dummyvec[2];
172 const double indxyz[],
183 const double dxyz[3]={-indxyz[0],-indxyz[1],-indxyz[2]};
189 if (dxyz[0] > 0.0) { dx = (xhi-xyz[0])/dxyz[0]; }
190 else if (dxyz[0] < 0.0) { dx = (xlo-xyz[0])/dxyz[0]; }
191 if (dxyz[1] > 0.0) { dy = (yhi-xyz[1])/dxyz[1]; }
192 else if (dxyz[1] < 0.0) { dy = (ylo-xyz[1])/dxyz[1]; }
193 if (dxyz[2] > 0.0) { dz = (zhi-xyz[2])/dxyz[2]; }
194 else if (dxyz[2] < 0.0) { dz = (zlo-xyz[2])/dxyz[2]; }
199 if (dx < dy && dx < dz) d = dx;
200 else if (dy < dz && dy < dx) d = dy;
201 else if (dz < dx && dz < dy) d = dz;
204 for (
int i = 0; i < 3; ++i) {
205 xyzout[i] = xyz[i] + dxyz[i]*
d;
218 const char* ifdh_debug_env =
std::getenv(
"IFDH_DEBUG_LEVEL");
219 if ( ifdh_debug_env ) {
220 mf::LogInfo(
"CORSIKAGendp") <<
"IFDH_DEBUG_LEVEL: " << ifdh_debug_env<<
"\n";
221 fIFDH->set_debug(ifdh_debug_env);
229 std::vector<std::pair<std::string,long>> selectedflist;
236 mf::LogInfo(
"CorsikaGendp") <<
"Selected"<<selectedflist.back().first<<
"\n";
241 std::vector<std::pair<std::string,long>>
flist;
245 std::cout << path <<
" " << pattern <<
std::endl;
250 flist =
fIFDH->findMatchingFiles(path,pattern);
255 auto wildcardPosition = pattern.find(
"*");
256 pattern = pattern.substr( 0, wildcardPosition );
261 if ((dir = opendir( path.c_str() )) != NULL)
263 while ((ent = readdir (dir)) != NULL)
266 std::pair<std::string,long>
name;
269 if( parsename.substr(0, wildcardPosition) ==
pattern )
271 name.first= path+
"/"+parsename;
273 flist.push_back( name );
284 unsigned int selIndex=-1;
289 else if(flist.size()>1)
291 selIndex= (
unsigned int) (
flat()*(flist.size()-1)+0.5);
298 selectedflist.push_back(flist[selIndex]);
300 <<
"\nFound "<< flist.size() <<
" candidate files" 301 <<
"\nChoosing file number "<< selIndex <<
"\n" 302 <<
"\nSelected "<<selectedflist.back().first<<
"\n";
307 std::vector<std::string> locallist;
308 for(
unsigned int i=0; i<selectedflist.size(); i++){
310 <<
"Fetching: "<<selectedflist[i].first<<
" "<<selectedflist[i].second<<
"\n";
312 MF_LOG_DEBUG(
"Gen311") <<
"Fetched; local path: "<<fetchedfile;
313 locallist.push_back(fetchedfile);
316 for(
unsigned int i=0; i<locallist.size(); i++){
318 int res=sqlite3_open(locallist[i].c_str(),&
fdb[i]);
320 throw cet::exception(
"Gen311") <<
"Error opening db: (" <<locallist[i].c_str()<<
") ("<<res<<
"): " << sqlite3_errmsg(
fdb[i]) <<
"; memory used:<<"<<sqlite3_memory_used()<<
"/"<<sqlite3_memory_highwater(0)<<
"\n";
322 mf::LogInfo(
"Gen311")<<
"Attached db "<< locallist[i]<<
"\n";
328 return (var - (high - low) * floor(var/(high-low))) + low;
333 boxno=
int(floor(var/(high-low)));
334 return (var - (high - low) * floor(var/(high-low))) + low;
341 const std::string kStatement(
"select min(t) from particles");
346 if ( sqlite3_prepare(
fdb[i], kStatement.c_str(), -1, &statement, 0 ) == SQLITE_OK ){
348 res = sqlite3_step(statement);
349 if ( res == SQLITE_ROW ){
350 t=sqlite3_column_double(statement,0);
351 mf::LogInfo(
"CORSIKAGendp")<<
"For showers input "<< i<<
" found particles.min(t)="<<t<<
"\n";
354 throw cet::exception(
"CORSIKAGendp") <<
"Unexpected sqlite3_step return value: (" <<res<<
"); "<<
"ERROR:"<<sqlite3_errmsg(
fdb[i])<<
"\n";
357 throw cet::exception(
"CORSIKAGendp") <<
"Error preparing statement: (" <<kStatement<<
"); "<<
"ERROR:"<<sqlite3_errmsg(
fdb[i])<<
"\n";
378 for (
unsigned int bnd = 0; bnd<6; bnd++){
379 mf::LogVerbatim(
"CORSIKAGendp")<<
"Cryo Boundary: "<<bnd<<
"="<<bounds[bnd]<<
" ( + Buffer="<<
fBuffBox[bnd]<<
")\n";
394 <<
"Area extended by : "<<fShowerAreaExtension
397 <<
"\nShowers to be distributed with random XZ shift: "<<
fRandomXZShift<<
" cm" 398 <<
"\nShowers to be distributed over area: "<<showersArea<<
" m^2" 399 <<
"\nShowers to be distributed over time: "<<
fSampleTime<<
" s" 400 <<
"\nShowers to be distributed with time offset: "<<
fToffset<<
" s" 401 <<
"\nShowers to be distributed at y: "<<
fShowerBounds[3]<<
" cm" 406 const std::string kStatement(
"select erange_high,erange_low,eslope,nshow from input");
407 double upperLimitOfEnergyRange=0.,lowerLimitOfEnergyRange=0.,energySlope=0.,oneMinusGamma=0.,EiToOneMinusGamma=0.,EfToOneMinusGamma=0.;
416 if ( sqlite3_prepare(
fdb[i], kStatement.c_str(), -1, &statement, 0 ) == SQLITE_OK ){
418 res = sqlite3_step(statement);
419 if ( res == SQLITE_ROW ){
420 upperLimitOfEnergyRange=sqlite3_column_double(statement,0);
421 lowerLimitOfEnergyRange=sqlite3_column_double(statement,1);
422 energySlope = sqlite3_column_double(statement,2);
423 fMaxShowers.push_back(sqlite3_column_int(statement,3));
424 oneMinusGamma = 1 + energySlope;
425 EiToOneMinusGamma =
pow(lowerLimitOfEnergyRange, oneMinusGamma);
426 EfToOneMinusGamma =
pow(upperLimitOfEnergyRange, oneMinusGamma);
427 mf::LogVerbatim(
"CORSIKAGendp")<<
"For showers input "<< i<<
" found e_hi="<<upperLimitOfEnergyRange<<
", e_lo="<<lowerLimitOfEnergyRange<<
", slope="<<energySlope<<
", k="<<
fShowerFluxConstants[i]<<
"\n";
429 throw cet::exception(
"CORSIKAGendp") <<
"Unexpected sqlite3_step return value: (" <<res<<
"); "<<
"ERROR:"<<sqlite3_errmsg(
fdb[i])<<
"\n";
432 throw cet::exception(
"CORSIKAGendp") <<
"Error preparing statement: (" <<kStatement<<
"); "<<
"ERROR:"<<sqlite3_errmsg(
fdb[i])<<
"\n";
439 <<
" the number of showers per event is "<<(
int)NShowers<<
"\n";
456 static TDatabasePDG* pdgt = TDatabasePDG::Instance();
460 const TString kStatement(
"select shower,pdg,px,py,pz,x,z,t,e from particles where shower in (select id from showers ORDER BY substr(id*%f,length(id)+2) limit %d) ORDER BY substr(shower*%f,length(shower)+2)");
471 geom->
WorldBox(&x1, &x2, &y1, &y2, &z1, &z2);
475 double fBoxDelta=1.e-5;
485 geom->
WorldBox(&y1, &y2, &x1, &x2, &z1, &z2);
500 double px,
py,
pz,
x=0,
y=0,
z,tParticleTime,etot,showerTime=0.,showerTimex=0.,showerTimez=0.,showerXOffset=0.,showerZOffset=0.,
t;
505 while(nShowerCntr>0){
510 nShowerQry=nShowerCntr;
513 double thisrnd=
flat();
514 TString kthisStatement=
TString::Format(kStatement.Data(),thisrnd,nShowerQry,thisrnd);
515 MF_LOG_DEBUG(
"CORSIKAGendp")<<
"Executing: "<<kthisStatement;
516 if ( sqlite3_prepare(
fdb[i], kthisStatement.Data(), -1, &statement, 0 ) == SQLITE_OK ){
520 res = sqlite3_step(statement);
521 if ( res == SQLITE_ROW ){
522 shower=sqlite3_column_int(statement,0);
523 if(shower!=lastShower){
532 pdg=sqlite3_column_int(statement,1);
535 TParticlePDG* pdgp = pdgt->GetParticle(pdg);
536 if (pdgp) m = pdgp->Mass();
542 py = sqlite3_column_double(statement,4);
543 px=sqlite3_column_double(statement,3);
547 px=sqlite3_column_double(statement,4);
548 py=sqlite3_column_double(statement,3);
550 pz=-sqlite3_column_double(statement,2);
551 etot=sqlite3_column_double(statement,8);
554 int boxnoX=0,boxnoZ=0;
558 tParticleTime=sqlite3_column_double(statement,7);
584 double dx[3]={
px,
py,pz};
596 TLorentzVector
pos(xyzo[0],xyzo[1],xyzo[2],t);
597 TLorentzVector mom(px,py,pz,etot);
602 }
else if ( res == SQLITE_DONE ){
605 throw cet::exception(
"CORSIKAGendp") <<
"Unexpected sqlite3_step return value: (" <<res<<
"); "<<
"ERROR:"<<sqlite3_errmsg(
fdb[i])<<
"\n";
609 throw cet::exception(
"CORSIKAGendp") <<
"Error preparing statement: (" <<kthisStatement<<
"); "<<
"ERROR:"<<sqlite3_errmsg(
fdb[i])<<
"\n";
611 nShowerCntr=nShowerCntr-nShowerQry;
640 std::unique_ptr< std::vector<simb::MCTruth> > truthcol(
new std::vector<simb::MCTruth>);
649 mf::LogInfo(
"CORSIKAGendp")<<
"GetSample number of particles returned: "<<pretruth.
NParticles()<<
"\n";
655 for(
int i = 0; i < pretruth.
NParticles(); ++i){
657 const TLorentzVector& v4 = particle.
Position();
658 const TLorentzVector& p4 = particle.
Momentum();
659 double x0[3] = {v4.X(), v4.Y(), v4.Z() };
660 double dx[3] = {p4.Px(), p4.Py(), p4.Pz()};
670 for (
unsigned int cb=0; cb<6; cb++){
671 bounds[cb] = bounds[cb]+
fBuffBox[cb];
675 bool intersects_cryo =
false;
676 for (
int bnd=0; bnd!=6; ++bnd) {
678 double p2[3] = {bounds[bnd], x0[1] + (dx[1]/dx[0])*(bounds[bnd] - x0[0]), x0[2] + (dx[2]/dx[0])*(bounds[bnd] - x0[0])};
679 if ( p2[1] >= bounds[2] && p2[1] <= bounds[3] &&
680 p2[2] >= bounds[4] && p2[2] <= bounds[5] ) {
681 intersects_cryo =
true;
685 else if (bnd>=2 && bnd<4) {
686 double p2[3] = {x0[0] + (dx[0]/dx[1])*(bounds[bnd] - x0[1]), bounds[bnd], x0[2] + (dx[2]/dx[1])*(bounds[bnd] - x0[1])};
687 if ( p2[0] >= bounds[0] && p2[0] <= bounds[1] &&
688 p2[2] >= bounds[4] && p2[2] <= bounds[5] ) {
689 intersects_cryo =
true;
694 double p2[3] = {x0[0] + (dx[0]/dx[2])*(bounds[bnd] - x0[2]), x0[1] + (dx[1]/dx[2])*(bounds[bnd] - x0[2]), bounds[bnd]};
695 if ( p2[0] >= bounds[0] && p2[0] <= bounds[1] &&
696 p2[1] >= bounds[2] && p2[1] <= bounds[3] ) {
697 intersects_cryo =
true;
703 if (intersects_cryo){
711 mf::LogInfo(
"CORSIKAGendp")<<
"Number of particles from getsample crossing cryostat + bounding box: "<<truth.
NParticles()<<
"\n";
713 truthcol->push_back(truth);
base_engine_t & createEngine(seed_t seed)
std::vector< double > fNShowersPerEvent
Number of showers to put in each event of duration fSampleTime; one per showerinput.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
const TLorentzVector & Position(const int i=0) const
double fShowerBounds[6]
Boundaries of area over which showers are to be distributed.
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
CORSIKAGendp(fhicl::ParameterSet const &pset)
Encapsulate the construction of a single cyostat.
Collect all the geometry header files together.
std::vector< std::string > fShowerInputFiles
Set of CORSIKA shower data files to use.
void SetOrigin(simb::Origin_t origin)
double fShowerAreaExtension
Extend distribution of corsika particles in x,z by this much (e.g. 1000 will extend 10 m in -x...
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void WorldBox(double *xlo, double *xhi, double *ylo, double *yhi, double *zlo, double *zhi) const
Fills the arguments with the boundaries of the world.
double fSampleTime
Duration of sample [s].
EDProducer(fhicl::ParameterSet const &pset)
std::vector< int > fMaxShowers
CLHEP::HepRandomEngine & fPoisEngine
void openDBs(std::string const &module_label)
struct sqlite3_stmt sqlite3_stmt
double wrapvar(const double var, const double low, const double high)
void GetSample(simb::MCTruth &)
void ProjectToBoxEdge(const double xyz[], const double dxyz[], const double xlo, const double xhi, const double ylo, const double yhi, const double zlo, const double zhi, double xyzout[])
void DoRotation(double vec[])
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
double fToffset_corsika
Timing offset to account for propagation time through atmosphere, populated from db.
void CryostatBoundaries(double *boundaries, geo::CryostatID const &cid) const
Returns the boundaries of the specified cryostat.
art framework interface to geometry description
int fShowerInputs
Number of shower inputs to process from.
#define DEFINE_ART_MODULE(klass)
void reconfigure(fhicl::ParameterSet const &p)
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
CLHEP::HepRandomEngine & fGenEngine
std::string getenv(std::string const &name)
double fToffset
Time offset of sample, defaults to zero (no offset) [s].
void produce(art::Event &evt)
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
std::vector< double > fShowerFluxConstants
Set of flux constants to be associated with each shower data file.
BoundingBox bounds(int x, int y, int w, int h)
bool fUseIFDH
< use ifdh protocol?
const simb::MCParticle & GetParticle(int i) const
std::vector< double > fBuffBox
Buffer box extensions to cryostat in each direction (6 of them: x_lo,x_hi,y_lo,y_hi,z_lo,z_hi) [cm].
void Add(simb::MCParticle const &part)
double wrapvarBoxNo(const double var, const double low, const double high, int &boxno)
void beginRun(art::Run &run)
double fProjectToHeight
Height to which particles will be projected [cm].
const TLorentzVector & Momentum(const int i=0) const
double fRandomXZShift
Each shower will be shifted by a random amount in xz so that showers won't repeatedly sample the same...
Event generator information.
A module to check the results from the Monte Carlo generator.
ifdh_ns::ifdh * fIFDH
(optional) flux file handling
LArSoft geometry interface.
sqlite3 * fdb[5]
Pointers to sqlite3 database object, max of 5.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)