89 #include "art/Framework/Core/EDProducer.h"
90 #include "art/Framework/Core/ModuleMacros.h"
91 #include "art/Framework/Principal/Event.h"
92 #include "art/Framework/Principal/Run.h"
93 #include "art/Framework/Services/Registry/ServiceHandle.h"
94 #include "art_root_io/TFileService.h"
95 #include "canvas/Utilities/Exception.h"
96 #include "cetlib/pow.h"
97 #include "cetlib_except/exception.h"
98 #include "fhiclcpp/ParameterSet.h"
99 #include "messagefacility/MessageLogger/MessageLogger.h"
102 #include "nurandom/RandomUtils/NuRandomService.h"
105 #include "nusimdata/SimulationBase/MCParticle.h"
106 #include "nusimdata/SimulationBase/MCTruth.h"
117 #include "TGeoManager.h"
118 #include "TGeoMaterial.h"
119 #include "TGeoNavigator.h"
121 #include "TLorentzVector.h"
123 #include "TVector3.h"
125 #include "CLHEP/Random/RandFlat.h"
126 #include "CLHEP/Random/RandGaussQ.h"
133 explicit LightSource(fhicl::ParameterSet
const& pset);
144 std::set<std::string>
const& materialNames);
258 template <
typename Coll>
259 std::set<typename Coll::value_type>
260 makeSet(Coll
const& coll)
271 : art::EDProducer{pset}
272 , fSourceMode{pset.get<
int>(
"SourceMode")}
273 , fFillTree{pset.get<
bool>(
"FillTree")}
274 , fPosDist{pset.get<
int>(
"PosDist")}
275 ,
fTDist{pset.get<
int>(
"TDist")}
276 , fPDist{pset.get<
int>(
"PDist")}
277 , fSelectedMaterials{makeSet(pset.get<std::vector<std::string>>(
"SelectMaterials", {}))}
278 ,
fNMaxF{pset.get<
double>(
"NMaxFactor", 100.0)}
281 ,
fEngine(art::ServiceHandle<rndm::NuRandomService> {}->createEngine(*
this, pset,
"Seed"))
282 ,
fGeom(*lar::providerFrom<geo::Geometry const>())
288 produces<sumdata::RunData, art::InRun>();
289 produces<std::vector<simb::MCTruth>>();
291 if (fSourceMode == kFILE) {
292 fFileName = pset.get<std::string>(
"SteeringFile");
293 fInputFile.open(fFileName.c_str());
294 fInputFile.getline(fDummyString, 256);
296 else if (fSourceMode == kSCAN) {
297 fT = pset.get<
double>(
"T0");
298 fSigmaT = pset.get<
double>(
"SigmaT");
299 fN = pset.get<
int>(
"N");
301 fFirstVoxel = pset.get<
int>(
"FirstVoxel");
302 fLastVoxel = pset.get<
int>(
"LastVoxel");
304 fP = pset.get<
double>(
"P");
305 fSigmaP = pset.get<
double>(
"SigmaP");
307 fUseCustomRegion = pset.get<
bool>(
"UseCustomRegion");
308 fPointSource = pset.get<
bool>(
"PointSource",
false);
310 if (fUseCustomRegion) {
311 fRegionMin = pset.get<std::vector<double>>(
"RegionMin");
312 fRegionMax = pset.get<std::vector<double>>(
"RegionMax");
313 fXSteps = pset.get<
int>(
"XSteps");
314 fYSteps = pset.get<
int>(
"YSteps");
315 fZSteps = pset.get<
int>(
"ZSteps");
325 if (!fUseCustomRegion) {
326 art::ServiceHandle<phot::PhotonVisibilityService const> vis;
327 fThePhotonVoxelDef = vis->GetVoxelDef();
343 fSigmaX = fThePhotonVoxelDef.GetVoxelSize().X() / 2.0;
344 fSigmaY = fThePhotonVoxelDef.GetVoxelSize().Y() / 2.0;
345 fSigmaZ = fThePhotonVoxelDef.GetVoxelSize().Z() / 2.0;
349 fVoxelCount = fThePhotonVoxelDef.GetNVoxels();
351 if (fLastVoxel < 0) fLastVoxel = fVoxelCount;
353 mf::LogVerbatim(
"LightSource") <<
"Light Source : Determining voxel params : " << fVoxelCount
354 <<
" " << fSigmaX <<
" " << fSigmaY <<
" " << fSigmaZ;
357 throw cet::exception(
"LightSource")
358 <<
"EVGEN Light Source : Unrecognised light source mode\n";
362 art::ServiceHandle<art::TFileService const>
tfs;
363 fPhotonsGenerated = tfs->make<TTree>(
"PhotonsGenerated",
"PhotonsGenerated");
364 fPhotonsGenerated->Branch(
"X", &(fShotPos[0]),
"X/D");
365 fPhotonsGenerated->Branch(
"Y", &(fShotPos[1]),
"Y/D");
366 fPhotonsGenerated->Branch(
"Z", &(fShotPos[2]),
"Z/D");
367 fPhotonsGenerated->Branch(
"T", &(fShotPos[3]),
"T/D");
368 fPhotonsGenerated->Branch(
"PX", &(fShotMom[0]),
"PX/D");
369 fPhotonsGenerated->Branch(
"PY", &(fShotMom[1]),
"PY/D");
370 fPhotonsGenerated->Branch(
"PZ", &(fShotMom[2]),
"PZ/D");
371 fPhotonsGenerated->Branch(
"PT", &(fShotMom[3]),
"PT/D");
372 fPhotonsGenerated->Branch(
"EventID", &fEvID,
"EventID/I");
395 mf::LogWarning(
"LightSource") <<
"EVGEN Light Source : Warning, reached end of file,"
396 <<
" looping back to beginning";
402 throw cet::exception(
"LightSource") <<
"EVGEN Light Source : File error in "
427 throw cet::exception(
"LightSource") <<
"EVGEN : Light Source, unrecognised source mode\n";
430 auto truthcol = std::make_unique<std::vector<simb::MCTruth>>();
432 truthcol->push_back(
Sample());
433 int const nPhotons = truthcol->back().NParticles();
435 evt.put(std::move(truthcol));
439 vis = art::ServiceHandle<phot::PhotonVisibilityService>().
get();
441 catch (art::Exception
const&
e) {
444 if (e.categoryCode() != art::errors::ServiceNotFound)
throw;
448 mf::LogVerbatim(
"LightSource") <<
"Light source : Stowing voxel params ";
454 mf::LogVerbatim(
"LightSource")
455 <<
"EVGEN Light Source fully scanned detector. Starting over.";
463 mf::LogVerbatim(
"LightSource") <<
"Light source debug : Shooting at " <<
fCenter;
465 CLHEP::RandFlat flat(
fEngine, -1.0, 1.0);
466 CLHEP::RandGaussQ gauss(
fEngine);
471 mct.SetOrigin(simb::kSingleParticle);
473 unsigned long long int const nMax =
static_cast<unsigned long long int>(double(fN) *
fNMaxF);
474 unsigned long long int fired = 0ULL;
475 while (mct.NParticles() <
fN) {
476 if (fired >= nMax)
break;
480 1
e-9 * ((
fPDist ==
kGAUS) ? gauss.fire(fP, fSigmaP) : fP + fSigmaP * flat.fire());
485 if (fPointSource) { x =
fCenter; }
498 if (!filter.
accept(x))
continue;
505 t =
fT + fSigmaT * flat.fire();
511 fShotPos = TLorentzVector(x.X(), x.Y(), x.Z(), t);
514 double costh = flat.fire();
515 double sinth = std::sqrt(1.0 - cet::square(costh));
516 double phi = 2 * M_PI * flat.fire();
520 fShotMom = TLorentzVector(p * sinth * cos(phi), p * sinth * sin(phi), p * costh, p);
522 int trackid = -(mct.NParticles() +
524 std::string primary(
"primary");
527 simb::MCParticle part(trackid, PDG, primary);
535 mf::LogInfo(
"LightSource") <<
"Generated " << mct.NParticles() <<
" photons after " << fired
537 if (mct.NParticles() <
fN) {
540 mf::LogWarning(
"LightSource")
541 <<
"Warning: " << mct.NParticles() <<
" photons generated after " << fired <<
" tries, but "
542 << fN <<
" were requested.";
556 mf::LogDebug log(
"LightSource");
557 auto const& matList = *(manager.GetListOfMaterials());
558 log << matList.GetSize() <<
" elements/materials in the geometry:";
559 for (
auto const* obj : matList) {
560 auto const mat =
dynamic_cast<TGeoMaterial
const*
>(obj);
561 log <<
"\n '" << mat->GetName() <<
"' (Z=" << mat->GetZ() <<
" A=" << mat->GetA() <<
")";
565 std::set<std::string> missingMaterials;
567 if (!manager.GetMaterial(matName.c_str())) missingMaterials.insert(matName);
569 if (missingMaterials.empty())
return;
571 art::Exception
e(art::errors::Configuration);
572 e <<
"Requested filtering on " << missingMaterials.size()
573 <<
" materials which are not present in the geometry:";
574 for (
auto const& matName : missingMaterials)
575 e <<
"\n '" << matName <<
"'";
584 std::set<std::string>
const& materialNames)
585 : fManager(geom.ROOTGeoManager())
586 , fNavigator(fManager->AddNavigator())
587 , fMaterials(materialNames)
596 fManager->RemoveNavigator(fNavigator);
597 fNavigator =
nullptr;
604 TGeoNode
const* node = fNavigator->FindNode(point.X(), point.Y(), point.Z());
605 return node ? node->GetVolume()->GetMaterial() :
nullptr;
612 if (fMaterials.empty())
return true;
613 TGeoMaterial
const* material = materialAt(point);
614 MF_LOG_TRACE(
"LightSource") <<
"Material at " << point <<
": "
615 << (material ? material->GetName() :
"not found");
616 return material ? (fMaterials.count(material->GetName()) > 0) :
false;
625 >> fP >> fSigmaP >>
fN;
std::vector< double > fRegionMin
process_name opflash particleana ie ie ie z
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
MaterialPointFilter(geo::GeometryCore const &geom, std::set< std::string > const &materialNames)
Constructor: sets up the filter configuration.
process_name stream1 can override from command line with o or output services DetectorPropertiesService services DetectorPropertiesService services DetectorPropertiesService services DetectorPropertiesService physics analyzers pmtresponse NeutronTrackingCut services LArG4Parameters gaussian physics producers generator PDG
LightSource(fhicl::ParameterSet const &pset)
Utilities related to art service access.
process_name opflash particleana ie x
geo::GeometryCore const & fGeom
Geometry service provider (cached).
TGeoNavigator * fNavigator
Our own ROOT geometry navigator.
Representation of a region of space diced into voxels.
std::vector< double > fRegionMax
double const fNMaxF
Maximum number of attempted samplings (factor on top of fN).
TGeoManager * ROOTGeoManager() const
Access to the ROOT geometry description manager.
void checkMaterials() const
Throws an exception if any of the configured materials is not present.
bool operator()(geo::Point_t const &point)
void produce(art::Event &evt)
CLHEP::HepRandomEngine & fEngine
TTree * fPhotonsGenerated
void StoreLightProd(int VoxID, double N)
Access the description of detector geometry.
Definitions of voxel data structures.
process_name opflash particleana ie ie y
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
Definitions of geometry vector data types.
std::set< std::string > const & fMaterials
Names of materials to select.
Point GetCenter() const
Returns the center of the voxel (type Point).
auto end(FixedBins< T, C > const &) noexcept
fEngine(art::ServiceHandle< rndm::NuRandomService >() ->createEngine(*this, pset,"Seed"))
Filters a point according to the material at that point.
Description of geometry of one entire detector.
TGeoMaterial const * materialAt(geo::Point_t const &point)
Returns a pointer to the material of the volume at specified point.
TGeoMaterial const * findMaterial(std::string const &name) const
Returns a pointer to the material with the specified name.
void beginRun(art::Run &run)
sim::PhotonVoxelDef fThePhotonVoxelDef
auto begin(FixedBins< T, C > const &) noexcept
geo::Point_t fCenter
Central position of source [cm].
bool readParametersFromInputFile()
TGeoManager * fManager
ROOT geometry manager.
art::ServiceHandle< art::TFileService > tfs
A module for optical MC testing and library building.
bool accept(geo::Point_t const &point)
Returns whether the specified point can be accepted.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
art framework interface to geometry description
std::set< std::string > const fSelectedMaterials
Names of materials to consider scintillation from.
PhotonVoxel GetPhotonVoxel(int ID) const