diff --git a/Analyses/src/CollectionSizeAnalyzer_module.cc b/Analyses/src/CollectionSizeAnalyzer_module.cc index 5160d4a871..26f825897e 100644 --- a/Analyses/src/CollectionSizeAnalyzer_module.cc +++ b/Analyses/src/CollectionSizeAnalyzer_module.cc @@ -66,7 +66,6 @@ namespace mu2e { struct Config { using Name=fhicl::Name; using Comment=fhicl::Comment; - //using Atom=fhicl::Atom; fhicl::Atom useModuleLabel{Name("useModuleLabel"), Comment("Include input module label into collection name in the plots") }; fhicl::Atom useInstanceName{Name("useInstanceName"), Comment("Include input instance name into collection name in the plots")}; fhicl::Atom useProcessName{Name("useProcessName"), Comment("Include input process name into collection name in the plots")}; diff --git a/Analyses/src/GenEventCountReader_module.cc b/Analyses/src/GenEventCountReader_module.cc index 29b4eae64b..40b8138ebf 100644 --- a/Analyses/src/GenEventCountReader_module.cc +++ b/Analyses/src/GenEventCountReader_module.cc @@ -30,18 +30,29 @@ namespace mu2e { unsigned numSubRuns_; bool makeHistograms_; public: - explicit GenEventCountReader(const fhicl::ParameterSet& pset); + + struct Config { + fhicl::Atom makeHistograms{ + fhicl::Name("makeHistograms"), + fhicl::Comment("Write out number of events and subruns as histograms, in addition to printing them out. "), + true + }; + }; + + using Parameters = art::EDAnalyzer::Table; + explicit GenEventCountReader(const Parameters& conf); + virtual void analyze(const art::Event&) override {} virtual void endSubRun(const art::SubRun& sr) override; virtual void endJob() override; }; //================================================================ - GenEventCountReader::GenEventCountReader(const fhicl::ParameterSet& pset) - : art::EDAnalyzer(pset) + GenEventCountReader::GenEventCountReader(const Parameters& conf) + : art::EDAnalyzer(conf) , numEvents_(0) , numSubRuns_(0) - , makeHistograms_(pset.get("makeHistograms", true)) + , makeHistograms_(conf().makeHistograms()) {} //================================================================ diff --git a/Analyses/src/GenParticlesAnalyzer_module.cc b/Analyses/src/GenParticlesAnalyzer_module.cc index 588eebff12..7a09257fb5 100644 --- a/Analyses/src/GenParticlesAnalyzer_module.cc +++ b/Analyses/src/GenParticlesAnalyzer_module.cc @@ -21,7 +21,15 @@ namespace mu2e { class GenParticlesAnalyzer : public art::EDAnalyzer { public: - explicit GenParticlesAnalyzer(fhicl::ParameterSet const& pset); + struct Config { + fhicl::Atom inputs{ + fhicl::Name("inputs"), + fhicl::Comment("The InputTag of a GenParticle collection to analyze. ") + }; + }; + + using Parameters = art::EDAnalyzer::Table; + explicit GenParticlesAnalyzer(const Parameters& conf); void beginRun(const art::Run&) override; void analyze(const art::Event& e) override; @@ -31,9 +39,9 @@ namespace mu2e { GeneratorSummaryHistograms genSummary_; }; - GenParticlesAnalyzer::GenParticlesAnalyzer(const fhicl::ParameterSet& pset) : - art::EDAnalyzer(pset), - inputs_(pset.get("inputs")), + GenParticlesAnalyzer::GenParticlesAnalyzer(const Parameters& conf) : + art::EDAnalyzer(conf), + inputs_(conf().inputs()), genSummary_() {} diff --git a/Analyses/src/SimParticleDaughterSelector_module.cc b/Analyses/src/SimParticleDaughterSelector_module.cc index 1fa9fa0232..6452f22c3e 100644 --- a/Analyses/src/SimParticleDaughterSelector_module.cc +++ b/Analyses/src/SimParticleDaughterSelector_module.cc @@ -44,7 +44,23 @@ namespace mu2e { class SimParticleDaughterSelector : public art::EDProducer { public: - explicit SimParticleDaughterSelector(fhicl::ParameterSet const& pset); + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + fhicl::Atom particleInput{ Name("particleInput"), Comment("The input collection.") }; + fhicl::Sequence processes{ Name("processes"), + Comment("A list of production process names, like \"DIO\", \"NuclearCapture\".\n" + "SimParticles with the given production codes will be written to the output.\n" + "If the process list is empty, all particles are passed to the output.\n" + "You can use this mode to produce diagnostic histograms that will contain\nthe names of possible processes." + ) + }; + }; + + using Parameters = art::EDProducer::Table; + explicit SimParticleDaughterSelector(const Parameters& conf); + void produce(art::Event& evt) override; private: art::InputTag particleInput_; @@ -56,15 +72,14 @@ namespace mu2e { }; //================================================================ - SimParticleDaughterSelector::SimParticleDaughterSelector(const fhicl::ParameterSet& pset) - : EDProducer{pset} - , particleInput_(pset.get("particleInput")) + SimParticleDaughterSelector::SimParticleDaughterSelector(const Parameters& conf) + : EDProducer{conf} + , particleInput_(conf().particleInput()) , haccepted_(tfs()->make("accepted", "Accepted pdgId and process code pairs", 1, 0., 1.)) , hignored_(tfs()->make("ignored", "Ignored pdgId and process code pairs", 1, 0., 1.)) { produces(); - - const auto& processes = pset.get >("processes"); + const auto& processes = conf().processes(); for(const auto& proc: processes) { procs_.insert(ProcessCode::findByName(proc).id()); } diff --git a/Analyses/src/StatusG4Analyzer_module.cc b/Analyses/src/StatusG4Analyzer_module.cc index 9eccb5b803..ff96b386ca 100644 --- a/Analyses/src/StatusG4Analyzer_module.cc +++ b/Analyses/src/StatusG4Analyzer_module.cc @@ -32,14 +32,24 @@ namespace mu2e { TH1D *hCPUTime_ = nullptr; TH1D *hCPUTimeWide_ = nullptr; public: - explicit StatusG4Analyzer(const fhicl::ParameterSet& pset); + + struct Config { + fhicl::Atom input { + fhicl::Name("input"), + fhicl::Comment("The InputTag of the StatusG4 object to analyze.") + }; + }; + + using Parameters = art::EDAnalyzer::Table; + explicit StatusG4Analyzer(const Parameters& conf); + virtual void analyze(const art::Event& event); }; //================================================================ - StatusG4Analyzer::StatusG4Analyzer(const fhicl::ParameterSet& pset) - : art::EDAnalyzer(pset) - , input_(pset.get("input")) + StatusG4Analyzer::StatusG4Analyzer(const Parameters& conf) + : art::EDAnalyzer(conf) + , input_(conf().input()) { art::ServiceHandle tfs; hStatusValue_ = tfs->make("statusValue", "Non-zero values of the G4 status", 20, 0., 20.); diff --git a/Analyses/src/StoppedParticlesDumper_module.cc b/Analyses/src/StoppedParticlesDumper_module.cc index c0cf9defa4..236c7686b6 100644 --- a/Analyses/src/StoppedParticlesDumper_module.cc +++ b/Analyses/src/StoppedParticlesDumper_module.cc @@ -40,7 +40,6 @@ namespace mu2e { namespace { - typedef std::vector VS; typedef std::vector VspMC; // This should be minimal info, we'll want to load this @@ -73,14 +72,61 @@ namespace mu2e { //================================================================ class StoppedParticlesDumper : public art::EDAnalyzer { public: - explicit StoppedParticlesDumper(fhicl::ParameterSet const& pset); + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom dumpSimParticleLeaves { + Name("dumpSimParticleLeaves"), + Comment("The mode selector. Set it to true to dump info on all the leaves\n" + "of a SimParticleCollection. If it is set to false, the input should\n" + "be of the SimParticlePtrCollection type, and its full content will be included.\n" + ), + false + }; + + fhicl::Atom inputCollection { + Name("inputCollection"), + Comment("InputTag of the collection to use.") + }; + + fhicl::Atom writeProperTime { + Name("writeProperTime"), + Comment("Compute and write out normalized proper time tau of particles.\n" + "This quantity is defined in such a way that exp(-tau) is the survival\n" + "probability of the particle. It is used in cases when the decay\n" + "process is disabled during the simulation." + ), + false + }; + + fhicl::Sequence decayOffPDGCodes { + Name("decayOffPDGCodes"), + Comment("A list of PDG IDs of particles that had their decay process turned off during\n" + "the simulation. This must be specified if and only if writeProperTime is requested."), + [this](){ return writeProperTime(); } + }; + + fhicl::Sequence hitCollections { + Name("hitCollections"), + Comment("A list of StepPointMCCollection-s via which different stages of simulation\n" + "are connected. Must be specified if and only if writeProperTime is requested."), + [this](){ return writeProperTime(); } + }; + + }; + + using Parameters = art::EDAnalyzer::Table; + explicit StoppedParticlesDumper(const Parameters& conf); + void beginJob() override; void analyze(const art::Event& evt) override; private: bool dumpSimParticleLeaves_; art::InputTag input_; bool writeProperTime_; - VS hitColls_; + std::vector hitColls_; std::vector decayOffCodes_; @@ -92,16 +138,17 @@ namespace mu2e { }; //================================================================ - StoppedParticlesDumper::StoppedParticlesDumper(const fhicl::ParameterSet& pset) : - art::EDAnalyzer(pset), - dumpSimParticleLeaves_(pset.get("dumpSimParticleLeaves", false)), - input_(pset.get("inputCollection")), - writeProperTime_(pset.get("writeProperTime")), - hitColls_( writeProperTime_ ? pset.get("hitCollections") : VS() ), + StoppedParticlesDumper::StoppedParticlesDumper(const Parameters& conf) : + art::EDAnalyzer(conf), + dumpSimParticleLeaves_(conf().dumpSimParticleLeaves()), + input_(conf().inputCollection()), + writeProperTime_(conf().writeProperTime()), nt_() { if(writeProperTime_) { - decayOffCodes_ = pset.get >("decayOffPDGCodes"); + hitColls_ = conf().hitCollections(); + decayOffCodes_ = conf().decayOffPDGCodes(); + // must sort to use binary_search in SimParticleGetTau std::sort(decayOffCodes_.begin(), decayOffCodes_.end()); } diff --git a/Analyses/src/StoppedParticlesFinder_module.cc b/Analyses/src/StoppedParticlesFinder_module.cc index 03bff4c9cf..32340ff577 100644 --- a/Analyses/src/StoppedParticlesFinder_module.cc +++ b/Analyses/src/StoppedParticlesFinder_module.cc @@ -35,7 +35,50 @@ namespace mu2e { class StoppedParticlesFinder : public art::EDProducer { public: - explicit StoppedParticlesFinder(fhicl::ParameterSet const& pset); + + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom particleInput{ Name("particleInput"), Comment("The particle input collection.") }; + + fhicl::Atom physVolInfoInput{ Name("physVolInfoInput"), Comment("The PhysicalVolumeInfoMultiCollection input.") }; + + fhicl::Sequence particleTypes{ + Name("particleTypes"), + Comment("A list of PDG IDs of particles to include in the stopped particle search.") + }; + + fhicl::Atom stoppingMaterial{ + Name("stoppingMaterial"), + Comment("A non-emtpy string here will select particles that stopped in the given material. Otherwise see vetoedMaterials below."), + "" + }; + + fhicl::Sequence vetoedMaterials{ Name("vetoedMaterials"), + Comment("Used only if stoppingMaterial is set to an emtpy string.\n" + "Particles stopping in materials that DO NOT match any on this list will be selected."), + [this](){ return stoppingMaterial().empty(); } + }; + + fhicl::Atom particleOffsetThreshold{ Name("particleOffsetThreshold"), + Comment("Ignore particles with numbers below the threshold. This should be used\n" + "to limit the selection to stops in just the latest simulation stage." + ), + 0 + }; + + fhicl::Atom verbosityLevel{ Name("verbosityLevel"), + Comment("Controls the printouts. Levels 0 through 3 are used.\nHigher levels are more verbose."), + 0 + }; + + }; + + using Parameters = art::EDProducer::Table; + explicit StoppedParticlesFinder(const Parameters& conf); + void beginSubRun(art::SubRun& sr) override; void produce(art::Event& evt) override; void endJob() override; @@ -45,10 +88,10 @@ namespace mu2e { std::string stoppingMaterial_; std::vector vetoedMaterials_; - int verbosityLevel_; - unsigned offsetThreshold_; // to select particles from the current simulation stage + int verbosityLevel_; + typedef std::set PDGCodeSet; PDGCodeSet particleTypes_; @@ -65,14 +108,13 @@ namespace mu2e { }; //================================================================ - StoppedParticlesFinder::StoppedParticlesFinder(const fhicl::ParameterSet& pset) - : EDProducer{pset} - , particleInput_(pset.get("particleInput")) - , physVolInfoInput_(pset.get("physVolInfoInput")) - , stoppingMaterial_(pset.get("stoppingMaterial", "")) - , vetoedMaterials_(pset.get >("vetoedMaterials", std::vector())) - , verbosityLevel_(pset.get("verbosityLevel", 0)) - , offsetThreshold_(pset.get("particleOffsetThreshold", 0)) + StoppedParticlesFinder::StoppedParticlesFinder(const Parameters& conf) + : EDProducer{conf} + , particleInput_(conf().particleInput()) + , physVolInfoInput_(conf().physVolInfoInput()) + , stoppingMaterial_(conf().stoppingMaterial()) + , offsetThreshold_(conf().particleOffsetThreshold()) + , verbosityLevel_(conf().verbosityLevel()) , hStopMaterials_(art::ServiceHandle()->make("stopmat", "Stopping materials", 1, 0., 1.)) , vols_() , numTotalParticles_() @@ -81,7 +123,11 @@ namespace mu2e { { produces(); - auto pt(pset.get >("particleTypes")); + if(stoppingMaterial_.empty()) { + vetoedMaterials_ = conf().vetoedMaterials(); + } + + auto pt(conf().particleTypes()); for(const auto& pid : pt) { particleTypes_.insert(PDGCode::type(pid)); } @@ -103,12 +149,6 @@ namespace mu2e { mf::LogInfo("Info")< trackInput{ Name("trackInput"), Comment("The input collection.") }; + }; + + using Parameters = art::EDProducer::Table; + explicit TrackSummaryMaker(const Parameters& conf); + void produce(art::Event& evt) override; private: art::InputTag trackInput_; }; //================================================================ - TrackSummaryMaker::TrackSummaryMaker(const fhicl::ParameterSet& pset) - : art::EDProducer{pset} - , trackInput_(pset.get("trackInput")) + TrackSummaryMaker::TrackSummaryMaker(const Parameters& conf) + : art::EDProducer{conf} + , trackInput_(conf().trackInput()) { produces(); produces(); diff --git a/CommonMC/src/GenerateMuonLife_module.cc b/CommonMC/src/GenerateMuonLife_module.cc index 8503dac688..164342d8d3 100644 --- a/CommonMC/src/GenerateMuonLife_module.cc +++ b/CommonMC/src/GenerateMuonLife_module.cc @@ -34,10 +34,32 @@ namespace mu2e { class GenerateMuonLife : public art::EDProducer { - public: - explicit GenerateMuonLife(const fhicl::ParameterSet& pset); + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom meanLife{ + Name("meanLife"), + Comment("A negative value (default) means use the muon life time in the stopping target material\n" + "as given by the GlobalConstantsService. The particle life time can be overridden\n" + "by providing a positive number here, e.g. for simulating stopped pion daughters." + ), + -1. + }; + + fhicl::Sequence InputTimeMaps { + Name("InputTimeMaps"), + Comment("Pre-exising time offsets that should be transferred to the output."), + std::vector() + }; + + fhicl::Atom verbosityLevel{ Name("verbosityLevel"), Comment("Levels 0, 1, and 11 increase the number of printouts.."), 0 }; + }; + + using Parameters = art::EDProducer::Table; + explicit GenerateMuonLife(const Parameters& conf); virtual void produce(art::Event& e) override; @@ -46,38 +68,30 @@ namespace mu2e { double mean_; int verbosityLevel_; std::vector > inmaps_; // optional input maps - - static double getMean(const fhicl::ParameterSet& pset); }; //================================================================ - GenerateMuonLife::GenerateMuonLife(const fhicl::ParameterSet& pset) - : EDProducer{pset} + GenerateMuonLife::GenerateMuonLife(const Parameters& conf) + : EDProducer{conf} , rexp_(createEngine( art::ServiceHandle()->getSeed() )) - , mean_(getMean(pset)) - , verbosityLevel_(pset.get("verbosityLevel", 0)) - { - std::vector inmaps = pset.get >("InputTimeMaps",std::vector()); - for(auto const& tag : inmaps ){ - inmaps_.push_back(consumes(tag)); - } - consumesMany(); - produces(); - if(verbosityLevel_ > 0) { - std::cout<<"GenerateMuonLife initialized with meanLife = "< inmaps = conf().InputTimeMaps(); + for(auto const& tag : inmaps ){ + inmaps_.push_back(consumes(tag)); + } + consumesMany(); + produces(); - //================================================================ - double GenerateMuonLife::getMean(const fhicl::ParameterSet& pset) { - double res(0); - if(!pset.get_if_present("meanLife", res)) { - // use the default - GlobalConstantsHandle phyPar; - res = phyPar->getDecayTime(); + if(mean_ <= 0.) { + GlobalConstantsHandle phyPar; + mean_ = phyPar->getDecayTime(); + } + if(verbosityLevel_ > 0) { + std::cout<<"GenerateMuonLife initialized with meanLife = "< part(ih, iter.first.asUint()); - // don't re-simulate if particle is already present. This can happen if there is an input map - if(res->find(part) == res->end()){ - - if(part->genParticle()->generatorId() == GenId::StoppedParticleReactionGun || - part->genParticle()->generatorId() == GenId::dioTail || - part->genParticle()->generatorId().isConversion() || - part->genParticle()->generatorId() == GenId::ExternalRMC || - part->genParticle()->generatorId() == GenId::InternalRMC ) - - { - (*res)[part] = rexp_.fire(mean_); - } - else - { - (*res)[part] = 0; - } - } - } + // don't re-simulate if particle is already present. This can happen if there is an input map + if(res->find(part) == res->end()){ + + if(part->genParticle()->generatorId() == GenId::StoppedParticleReactionGun || + part->genParticle()->generatorId() == GenId::dioTail || + part->genParticle()->generatorId().isConversion() || + part->genParticle()->generatorId() == GenId::ExternalRMC || + part->genParticle()->generatorId() == GenId::InternalRMC ) + + { + (*res)[part] = rexp_.fire(mean_); + } + else + { + (*res)[part] = 0; + } + } + } } } diff --git a/CommonMC/src/GenerateProtonTimes_module.cc b/CommonMC/src/GenerateProtonTimes_module.cc index 66f941a5e0..23dfcc44e3 100644 --- a/CommonMC/src/GenerateProtonTimes_module.cc +++ b/CommonMC/src/GenerateProtonTimes_module.cc @@ -6,7 +6,7 @@ #include #include -#include "fhiclcpp/ParameterSet.h" +#include "fhiclcpp/types/OptionalTable.h" #include "messagefacility/MessageLogger/MessageLogger.h" #include "CLHEP/Random/RandGaussQ.h" @@ -33,16 +33,55 @@ namespace mu2e { public: - explicit GenerateProtonTimes(const fhicl::ParameterSet& pset); + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::OptionalTable randPDFparameters { Name("randPDFparameters") }; + + fhicl::Sequence ignoredGenIds { + Name("ignoredGenIds"), + Comment("A non-empty list means: generate time offsets for all particles\n" + "except those produced by the listed generators. If this list is emtpy,\n" + "the applyToGenIds parameter below is enabled." + ), + std::vector{"cosmicToy", "cosmicDYB", "cosmic"} + }; + + fhicl::Sequence applyToGenIds { + Name("applyToGenIds"), + Comment("The whitelist mode: assign time offsets just to particles made by one of the\n" + "listed generators. This setting is only active in the case ignoredGenIds is emtpy.\n" + ), + [this](){ return ignoredGenIds().empty(); } + }; + + fhicl::Sequence InputTimeMaps { + Name("InputTimeMaps"), + Comment("Pre-exising time offsets that should be transferred to the output."), + std::vector() + }; + + fhicl::Atom FixedModule { + Name("FixedModule"), + Comment("Input tag of a FixedTimeMap from RPC generation, if any."), + art::InputTag() + }; + + fhicl::Atom verbosityLevel{ Name("verbosityLevel"), Comment("Levels 0, 1, and 11 increase the number of printouts.."), 0 }; + }; + + using Parameters = art::EDProducer::Table; + explicit GenerateProtonTimes(const Parameters& conf); virtual void beginRun(art::Run& r) override; virtual void produce (art::Event& e) override; private: art::RandomNumberGenerator::base_engine_t& engine_; - fhicl::ParameterSet protonPset_; + ProtonPulseRandPDF::Config protonPulseConf_; int verbosityLevel_; - std::string fixedTime_; + art::InputTag fixedTime_; typedef std::set GenIdSet; GenIdSet ignoredGenIds_; @@ -56,14 +95,13 @@ namespace mu2e { }; //================================================================ - GenerateProtonTimes::GenerateProtonTimes(fhicl::ParameterSet const& pset) - : EDProducer{pset} + GenerateProtonTimes::GenerateProtonTimes(const Parameters& conf) + : EDProducer{conf} , engine_(createEngine(art::ServiceHandle()->getSeed()) ) - , protonPset_( pset.get("randPDFparameters", fhicl::ParameterSet() ) ) - , verbosityLevel_(pset.get("verbosityLevel", 0)) - , fixedTime_(pset.get("FixedModule","")) + , verbosityLevel_(conf().verbosityLevel()) + , fixedTime_(conf().FixedModule()) { - std::vector inmaps = pset.get >("InputTimeMaps",std::vector()); + std::vector inmaps = conf().InputTimeMaps(); for(auto const& tag : inmaps ){ inmaps_.push_back(consumes(tag)); } @@ -73,27 +111,22 @@ namespace mu2e { typedef std::vector VS; - const auto ig(pset.get("ignoredGenIds", VS{"cosmicToy", "cosmicDYB", "cosmic"})); + const auto ig(conf().ignoredGenIds()); for(const auto i: ig) { ignoredGenIds_.insert(GenId::findByName(i).id()); } - const auto ia(pset.get("applyToGenIds", VS())); + const auto ia(conf().applyToGenIds()); for(const auto i: ia) { applyToGenIds_.insert(GenId::findByName(i).id()); } - if(!applyToGenIds_.empty() && !ignoredGenIds_.empty()) { - throw cet::exception("BADCONFIG") - <<"If applyToGenIds is set, ignoredGenIds should be empty. Got: applyToGenIds = [ " - < 0) { if(applyToGenIds_.empty()) { @@ -129,10 +162,9 @@ namespace mu2e { std::vector > colls; event.getManyByType(colls); art::Handle ftmHandle; - if (fixedTime_.size() > 0) + if (!fixedTime_.empty()) event.getByLabel(fixedTime_, ftmHandle); - // Generate and record offsets for all primaries for(const auto& ih : colls) { for(const auto& iter : *ih) { @@ -149,7 +181,7 @@ namespace mu2e { : (applyToGenIds_.find(genId.id()) != applyToGenIds_.end()); (*res)[part] = apply ? protonPulse_->fire() : 0.; - if (fixedTime_.size() > 0){ + if (!fixedTime_.empty()){ (*res)[part] = apply ? ftmHandle->time() : 0; } } else if(verbosityLevel_ > 2) { diff --git a/EventGenerator/inc/ExtMonFNALGun.hh b/EventGenerator/inc/ExtMonFNALGun.hh deleted file mode 100644 index 4d70612a2a..0000000000 --- a/EventGenerator/inc/ExtMonFNALGun.hh +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef EXTMONFNALGUN_HH -#define EXTMONFNALGUN_HH - -// $Id: ExtMonFNALGun.hh,v 1.2 2012/11/01 23:44:24 gandr Exp $ -// $Author: gandr $ -// $Date: 2012/11/01 23:44:24 $ -// -// A generator to conveniently generate particles in the acceptance of -// the ExtMonFNAl filter. The particles are generated at the entrance -// to the filter channel, in a cone around the axis of the first -// collimator. -// -// -// Original author Andrei Gaponenko, 2012 -// -// The position is given in the Mu2e coordinate system. -// - -#include "fhiclcpp/ParameterSet.h" - -#include "EventGenerator/inc/ParticleGunImpl.hh" -#include "MCDataProducts/inc/GenParticle.hh" - -#include "CLHEP/Vector/Rotation.h" -#include "CLHEP/Vector/ThreeVector.h" - -// Forward references. -namespace art{ class Run; } - -namespace mu2e { - - class ExtMonFNALGun { - - public: - explicit ExtMonFNALGun(CLHEP::HepRandomEngine& engine, const fhicl::ParameterSet& pset); - - // adds generated particles to the collection - virtual void generate(GenParticleCollection& out); - - private: - ParticleGunImpl m_gun; - - CLHEP::HepRotation m_rotation; - CLHEP::Hep3Vector m_translation; - - void initGeom(const std::string& refPoint); - - // From local coordinates used by our m_gun to mu2e frame - GenParticle transform(const GenParticle& in) const; - - CLHEP::Hep3Vector h3v(const std::vector& v); - }; - -} // end namespace mu2e, - -#endif /* EXTMONFNALGUN_HH */ diff --git a/EventGenerator/inc/ExtMonFNALGunImpl.hh b/EventGenerator/inc/ExtMonFNALGunImpl.hh new file mode 100644 index 0000000000..07b55d1c41 --- /dev/null +++ b/EventGenerator/inc/ExtMonFNALGunImpl.hh @@ -0,0 +1,137 @@ +#ifndef ExtMonFNALGunImpl_hh +#define ExtMonFNALGunImpl_hh + +// A generator to conveniently generate particles in the acceptance of +// the ExtMonFNAl filter. The particles are generated at the entrance +// to the filter channel, in a cone around the axis of the first +// collimator. +// +// +// Original author Andrei Gaponenko, 2012 +// +// The position is given in the Mu2e coordinate system. +// + +#include "fhiclcpp/types/Atom.h" +#include "fhiclcpp/types/OptionalAtom.h" +#include "fhiclcpp/types/TupleAs.h" + +#include "EventGenerator/inc/ParticleGunImpl.hh" +#include "MCDataProducts/inc/GenParticle.hh" + +#include "CLHEP/Vector/Rotation.h" +#include "CLHEP/Vector/ThreeVector.h" + +// Forward references. +namespace art{ class Run; } + +namespace mu2e { + + class ExtMonFNALBuilding; + + class ExtMonFNALGunImpl { + + public: + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + using Hep3Vector_t = CLHEP::Hep3Vector(double, double, double); + + fhicl::Atom multiplicity { + Name("multipliticy"), + Comment("The number of generated particles is sampled from the Poisson\n" + "distribution with mean==multiplicity for mulitplicity>0,\n" + "or is fixed to |multiplicity| for negative integer inputs." + ), + -1 + }; + + fhicl::Atom pdgId { + Name("pdgId"), + Comment("PDG ID of the produced GenParticles"), + 2212 // proton + }; + + fhicl::OptionalAtom pmin { + Name("pmin"), + Comment("Override generated particle min momentum. The default is the nominal ExtMon signal momentum.") + }; + + fhicl::OptionalAtom pmax { + Name("pmax"), + Comment("Override generated particle max momentum. The default is the nominal ExtMon signal momentum.") + }; + + fhicl::Atom coneAngleMin { + Name("coneAngleMin"), + Comment("Angle, in radians, w.r.t. the reference axis.\n" + "Particle momenta point between cones with min and max given angles."), + 0. + }; + + fhicl::Atom coneAngleMax { + Name("coneAngleMax"), + Comment("Angle, in radians, w.r.t. the reference axis.\n" + "Particle momenta point between cones with min and max given angles."), + 0. + }; + + fhicl::Atom tmin { Name("tmin"), Comment("Earliest generated time."), 0. }; + fhicl::Atom tmax { Name("tmax"), Comment("Latest generated time."), 0. }; + + fhicl::TupleAs offset { + Name("offset"), + Comment("The 3D offset of the center of generated particle origin distribution from the reference point."), + CLHEP::Hep3Vector(0.,0.,0.) + }; + + fhicl::TupleAs halfSize { + Name("halfSize"), + Comment("The origin of generated particles is sampled uniformly inside a box of the give half size."), + CLHEP::Hep3Vector(0.,0.,0.) + }; + + fhicl::Atom histDirName { + Name("histDirName"), + Comment("A non-empty string will activate histogramming and write out results into the named ROOT subdir."), + "" + }; + + fhicl::Atom reference { + Name("reference"), + Comment("Particle origin reference point. Allowed values are:\n" + "filter, detector, productionTargetEntrance, productionTargetExit, productionTargetCenter." + ) + }; + + fhicl::Atom verbosityLevel { + Name("verbosityLevel"), + Comment("A number from 0 to 3, larger values mean more printouts."), + 0 + }; + + }; + + explicit ExtMonFNALGunImpl(CLHEP::HepRandomEngine& engine, const Config& conf); + + // adds generated particles to the collection + virtual void generate(GenParticleCollection& out); + + private: + ParticleGunImpl m_gun; + + CLHEP::HepRotation m_rotation; + CLHEP::Hep3Vector m_translation; + + void initGeom(const std::string& refPoint); + + // From local coordinates used by our m_gun to mu2e frame + GenParticle transform(const GenParticle& in) const; + + static double getpmin(const Config& conf, const ExtMonFNALBuilding& emb); + static double getpmax(const Config& conf, const ExtMonFNALBuilding& emb); + }; + +} // end namespace mu2e, + +#endif /* ExtMonFNALGunImpl_hh */ diff --git a/EventGenerator/src/ExtMonFNALGun.cc b/EventGenerator/src/ExtMonFNALGunImpl.cc similarity index 64% rename from EventGenerator/src/ExtMonFNALGun.cc rename to EventGenerator/src/ExtMonFNALGunImpl.cc index 55b1888a44..13f1014f63 100644 --- a/EventGenerator/src/ExtMonFNALGun.cc +++ b/EventGenerator/src/ExtMonFNALGunImpl.cc @@ -1,4 +1,4 @@ -#include "EventGenerator/inc/ExtMonFNALGun.hh" +#include "EventGenerator/inc/ExtMonFNALGunImpl.hh" #include "GeometryService/inc/GeomHandle.hh" #include "ExtinctionMonitorFNAL/Geometry/inc/ExtMonFNALBuilding.hh" @@ -15,34 +15,49 @@ namespace mu2e { //================================================================ - ExtMonFNALGun::ExtMonFNALGun(CLHEP::HepRandomEngine& engine, const fhicl::ParameterSet& pset) + ExtMonFNALGunImpl::ExtMonFNALGunImpl(CLHEP::HepRandomEngine& engine, const Config& conf) : m_gun(engine, - pset.get("multiplicity"), - PDGCode::type(pset.get("pdgId")), + conf.multiplicity(), + PDGCode::type(conf.pdgId()), - pset.get("pmin", GeomHandle()->filterMagnet().nominalMomentum()), - pset.get("pmax", GeomHandle()->filterMagnet().nominalMomentum()), + //pset.get("pmax", GeomHandle()->filterMagnet().nominalMomentum()), + getpmin(conf, *GeomHandle()), + getpmax(conf, *GeomHandle()), - RandomUnitSphereParams(-cos(pset.get("coneAngleMin")), - -cos(pset.get("coneAngleMax")), + RandomUnitSphereParams(-cos(conf.coneAngleMin()), + -cos(conf.coneAngleMax()), 0., 2*M_PI), - pset.get("tmin", 0.), - pset.get("tmax", 0.), + conf.tmin(), + conf.tmax(), - h3v(pset.get >("offset")), - h3v(pset.get >("halfSize")), + conf.offset(), + conf.halfSize(), - pset.get("histDirName"), + conf.histDirName(), - pset.get("verbosityLevel",0) + conf.verbosityLevel() ) { - initGeom(pset.get("reference")); + initGeom(conf.reference()); } //================================================================ - void ExtMonFNALGun::initGeom(const std::string& ref) { + double ExtMonFNALGunImpl::getpmin(const Config& conf, const ExtMonFNALBuilding& emb) { + double p = emb.filterMagnet().nominalMomentum(); + conf.pmin(p); + return p; + } + + //================================================================ + double ExtMonFNALGunImpl::getpmax(const Config& conf, const ExtMonFNALBuilding& emb) { + double p = emb.filterMagnet().nominalMomentum(); + conf.pmax(p); + return p; + } + + //================================================================ + void ExtMonFNALGunImpl::initGeom(const std::string& ref) { if(ref == "filter") { m_rotation = GeomHandle()->collimator1RotationInMu2e(); m_translation = GeomHandle()->filterEntranceInMu2e(); @@ -74,21 +89,7 @@ namespace mu2e { } //================================================================ - CLHEP::Hep3Vector ExtMonFNALGun::h3v(const std::vector& v) { - CLHEP::Hep3Vector res; - if(!v.empty()) { - if(v.size() != 3) { - throw cet::exception("BADCONFIG") - <<"Error converting to CLHEP::Hep3Vector: input size="< conf_; - // ExtMonFNALGun has a non-movable member ParticleGunImpl, thus hold them by pointers - typedef std::vector > PGuns; - PGuns guns_; - CLHEP::HepRandomEngine& engine_; + // ExtMonFNALGun has a non-movable member ParticleGunImpl, thus hold them by pointers + std::vector > guns_; + CLHEP::HepRandomEngine& engine_; - void produce(art::Event& event) override; - void beginRun(art::Run& run) override; - public: - explicit ExtMonFNALGun(fhicl::ParameterSet const& pset); + void produce(art::Event& event) override; + void beginRun(art::Run& run) override; + public: + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + fhicl::Sequence > guns { + Name("guns"), + Comment("A list of ExtMon guns to call.") + }; }; - ExtMonFNALGun::ExtMonFNALGun(fhicl::ParameterSet const& pset) - : EDProducer{pset} - , pset_(pset) - , engine_{createEngine(art::ServiceHandle{}->getSeed())} + using Parameters = art::EDProducer::Table; + explicit ExtMonFNALGun(const Parameters& conf); + }; + + ExtMonFNALGun::ExtMonFNALGun(const Parameters& conf) + : EDProducer{conf} + , conf_(conf().guns()) + , engine_{createEngine(art::ServiceHandle{}->getSeed())} { produces(); + if(conf_.empty()) { + throw cet::exception("BADCONFIG")<<"Error: no ExtMon guns defined.\n"; + } } - void ExtMonFNALGun::beginRun(art::Run&) { - typedef std::vector VGPars; - VGPars vgp(pset_.get("guns")); - - guns_.reserve(vgp.size()); - for(unsigned i=0; i output(new GenParticleCollection); - for(auto& gun : guns_) { - gun->generate(*output); - } - event.put(std::move(output)); + void ExtMonFNALGun::produce(art::Event& event) { + std::unique_ptr output(new GenParticleCollection); + for(auto& gun : guns_) { + gun->generate(*output); } + event.put(std::move(output)); + } - } // namespace ExtMonFNAL } // namespace mu2e -DEFINE_ART_MODULE(mu2e::ExtMonFNAL::ExtMonFNALGun); +DEFINE_ART_MODULE(mu2e::ExtMonFNALGun); diff --git a/EventGenerator/src/GenEventCounter_module.cc b/EventGenerator/src/GenEventCounter_module.cc index 866cfaff90..04e40fad36 100644 --- a/EventGenerator/src/GenEventCounter_module.cc +++ b/EventGenerator/src/GenEventCounter_module.cc @@ -27,14 +27,16 @@ namespace mu2e { class GenEventCounter : public art::EDProducer { GenEventCount::count_t seenEvents_; public: - explicit GenEventCounter(const fhicl::ParameterSet& pset); + struct Config {}; + using Parameters = art::EDProducer::Table; + explicit GenEventCounter(const Parameters& conf); virtual void produce(art::Event& event) override; virtual void endSubRun(art::SubRun& sr) override; }; //================================================================ - GenEventCounter::GenEventCounter(const fhicl::ParameterSet& pset) - : art::EDProducer{pset}, + GenEventCounter::GenEventCounter(const Parameters& conf) + : art::EDProducer{conf}, seenEvents_(0) { produces(); diff --git a/EventGenerator/src/InFlightParticleSampler_module.cc b/EventGenerator/src/InFlightParticleSampler_module.cc index d3e90f30d6..7835cd86c8 100644 --- a/EventGenerator/src/InFlightParticleSampler_module.cc +++ b/EventGenerator/src/InFlightParticleSampler_module.cc @@ -36,23 +36,44 @@ namespace mu2e { //================================================================ class InFlightParticleSampler : public art::EDProducer { - RootTreeSampler, IO::InFlightParticleD > particles_; + typedef RootTreeSampler, IO::InFlightParticleD > RTS; + RTS particles_; + const mu2e::ParticleDataTable *pdt_; int verbosityLevel_; public: - explicit InFlightParticleSampler(const fhicl::ParameterSet& pset); + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom verbosityLevel{ + Name("verbosityLevel"), + Comment("A positive value generates more printouts than the default."), + 0 + }; + + fhicl::Table particles { + Name("particles"), + Comment("RootTreeSampler settings") + }; + }; + + using Parameters = art::EDProducer::Table; + explicit InFlightParticleSampler(const Parameters& conf); + virtual void produce(art::Event& event); }; //================================================================ - InFlightParticleSampler::InFlightParticleSampler(const fhicl::ParameterSet& pset) - : EDProducer{pset} + InFlightParticleSampler::InFlightParticleSampler(const Parameters& conf) + : EDProducer{conf} , particles_(createEngine(art::ServiceHandle()->getSeed()), - pset.get("particles")) + conf().particles()) , pdt_(&*GlobalConstantsHandle()) - , verbosityLevel_(pset.get("verbosityLevel", 0)) + , verbosityLevel_(conf().verbosityLevel()) { produces(); diff --git a/EventGenerator/src/RPCGun_module.cc b/EventGenerator/src/RPCGun_module.cc index c1c07e6d7a..c4f96b1e66 100644 --- a/EventGenerator/src/RPCGun_module.cc +++ b/EventGenerator/src/RPCGun_module.cc @@ -92,8 +92,8 @@ namespace mu2e { TH1F* _hPosiMom {nullptr}; TH1F* _hMee; TH2F* _hMeeVsE; - TH1F* _hMeeOverE; // M(ee)/E(gamma) - TH1F* _hy; // splitting function + TH1F* _hMeeOverE; // M(ee)/E(gamma) + TH1F* _hy; // splitting function public: explicit RPCGun(const fhicl::ParameterSet& pset); @@ -120,44 +120,44 @@ namespace mu2e { , randomFlat_ (eng_) , randomUnitSphere_ (eng_, czmin_,czmax_,phimin_,phimax_) , pionCaptureSpectrum_(&randomFlat_,&randomUnitSphere_) - // , randomUnitSphere_(eng_) + // , randomUnitSphere_(eng_) , stops_(eng_, pset.get("pionStops")) , doHistograms_( pset.get("doHistograms",true ) ) , protonPset_( pset.get("randPDFparameters", fhicl::ParameterSet() ) ) - { - produces(); - produces(); - produces(); - - if(verbosityLevel_ > 0) { - std::cout<<"RPCGun: using = " - <(); + produces(); + produces(); + + if(verbosityLevel_ > 0) { + std::cout<<"RPCGun: using = " + < tfs; + art::TFileDirectory tfdir = tfs->mkdir( "RPCGun" ); + + _hmomentum = tfdir.make( "hmomentum", "Produced photon momentum", 100, 40., 140. ); - if ( doHistograms_ ) { - art::ServiceHandle tfs; - art::TFileDirectory tfdir = tfs->mkdir( "RPCGun" ); - - _hmomentum = tfdir.make( "hmomentum", "Produced photon momentum", 100, 40., 140. ); - - if(generateInternalConversion_){ - _hElecMom = tfdir.make("hElecMom" , "Produced electron momentum", 140, 0. , 140.); - _hPosiMom = tfdir.make("hPosiMom" , "Produced positron momentum", 140, 0. , 140.); - _hMee = tfdir.make("hMee" , "M(e+e-) " , 200,0.,200.); - _hMeeVsE = tfdir.make("hMeeVsE" , "M(e+e-) vs E" , 200,0.,200.,200,0,200); - _hMeeOverE = tfdir.make("hMeeOverE", "M(e+e-)/E " , 200, 0.,1); - _hy = tfdir.make("hy" , "y = (ee-ep)/|pe+pp|", 200,-1.,1.); + if(generateInternalConversion_){ + _hElecMom = tfdir.make("hElecMom" , "Produced electron momentum", 140, 0. , 140.); + _hPosiMom = tfdir.make("hPosiMom" , "Produced positron momentum", 140, 0. , 140.); + _hMee = tfdir.make("hMee" , "M(e+e-) " , 200,0.,200.); + _hMeeVsE = tfdir.make("hMeeVsE" , "M(e+e-) vs E" , 200,0.,200.,200,0,200); + _hMeeOverE = tfdir.make("hMeeOverE", "M(e+e-)/E " , 200, 0.,1); + _hy = tfdir.make("hy" , "y = (ee-ep)/|pe+pp|", 200,-1.,1.); + } } - } - } + } //================================================================ - + void RPCGun::beginRun(art::Run& run) { protonPulse_.reset( new ProtonPulseRandPDF( eng_, protonPset_ ) ); } @@ -174,7 +174,7 @@ namespace mu2e { if (tmin_ > 0){ while (true){ const auto& tstop = stops_.fire(); - timemap->SetTime(protonPulse_->fire()); + timemap->SetTime(protonPulse_->fire()); if (tstop.t+timemap->time() < 0 || tstop.t+timemap->time() > tmin_){ if (applySurvivalProbability_){ double weight = exp(-tstop.tauNormalized)*survivalProbScaling_; @@ -192,7 +192,7 @@ namespace mu2e { } } }else{ - timemap->SetTime(protonPulse_->fire()); + timemap->SetTime(protonPulse_->fire()); if (applySurvivalProbability_){ while (true){ const auto& tstop = stops_.fire(); @@ -217,40 +217,40 @@ namespace mu2e { if(!generateInternalConversion_){ output->emplace_back( PDGCode::gamma, - GenId::ExternalRPC, - pos, - CLHEP::HepLorentzVector( randomUnitSphere_.fire(energy), energy), - stop.t ); + GenId::ExternalRPC, + pos, + CLHEP::HepLorentzVector( randomUnitSphere_.fire(energy), energy), + stop.t ); event.put(std::move(output)); event.put(std::move(timemap)); } else { CLHEP::HepLorentzVector mome, momp; - pionCaptureSpectrum_.getElecPosiVectors(energy,mome,momp); + pionCaptureSpectrum_.getElecPosiVectors(energy,mome,momp); // Add particles to list auto output = std::make_unique(); output->emplace_back(PDGCode::e_minus, GenId::InternalRPC,pos,mome,stop.t); output->emplace_back(PDGCode::e_plus , GenId::InternalRPC,pos,momp,stop.t); event.put(move(output)); event.put(std::move(timemap)); - + if(doHistograms_){ _hElecMom ->Fill(mome.vect().mag()); _hPosiMom ->Fill(momp.vect().mag()); - + double mee = (mome+momp).m(); _hMee->Fill(mee); _hMeeVsE->Fill(energy,mee); _hMeeOverE->Fill(mee/energy); - + CLHEP::Hep3Vector p = mome.vect()+momp.vect(); double y = (mome.e()-momp.e())/p.mag(); - + _hy->Fill(y); } } -// Calculate survival probability + // Calculate survival probability const double weight = exp(-stop.tauNormalized); std::unique_ptr pw(new EventWeight(weight)); event.put(std::move(pw)); diff --git a/EventGenerator/src/StoppedParticleG4Gun_module.cc b/EventGenerator/src/StoppedParticleG4Gun_module.cc index b18da3424b..6ef96fd402 100644 --- a/EventGenerator/src/StoppedParticleG4Gun_module.cc +++ b/EventGenerator/src/StoppedParticleG4Gun_module.cc @@ -48,21 +48,43 @@ namespace mu2e { double mass_; int verbosityLevel_; - RootTreeSampler stops_; + typedef RootTreeSampler RTS; + RTS stops_; public: - explicit StoppedParticleG4Gun(const fhicl::ParameterSet& pset); + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom pdgId { Name("pdgId"), Comment("PDG ID of the particle to place.")}; + + fhicl::Atom verbosityLevel{ + Name("verbosityLevel"), + Comment("A positive value generates more printouts than the default."), + 0 + }; + + fhicl::Table muonStops { + Name("muonStops"), + Comment("RootTreeSampler settings") + }; + }; + + using Parameters = art::EDProducer::Table; + explicit StoppedParticleG4Gun(const Parameters& conf); + virtual void produce(art::Event& event); }; //================================================================ - StoppedParticleG4Gun::StoppedParticleG4Gun(const fhicl::ParameterSet& pset) - : EDProducer{pset} - , pdgId_(PDGCode::type(pset.get("pdgId"))) + StoppedParticleG4Gun::StoppedParticleG4Gun(const Parameters& conf) + : EDProducer{conf} + , pdgId_(PDGCode::type(conf().pdgId())) , mass_(GlobalConstantsHandle()->particle(pdgId_).ref().mass().value()) - , verbosityLevel_(pset.get("verbosityLevel", 0)) + , verbosityLevel_(conf().verbosityLevel()) , stops_(createEngine(art::ServiceHandle()->getSeed()), - pset.get("muonStops")) + conf().muonStops()) { produces(); diff --git a/Filters/src/CompressPhysicalVolumes_module.cc b/Filters/src/CompressPhysicalVolumes_module.cc index dbd6104e84..42cf33b7a0 100644 --- a/Filters/src/CompressPhysicalVolumes_module.cc +++ b/Filters/src/CompressPhysicalVolumes_module.cc @@ -44,24 +44,43 @@ namespace mu2e { void endSubRun(art::SubRun& sr) override; public: - explicit CompressPhysicalVolumes(const fhicl::ParameterSet& pset); + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom volumesInput { + Name("volumesInput"), + Comment("The collection to compress") + }; + + fhicl::Sequence hitInputs { + Name("hitInputs"), + Comment("A list of StepPointMCCollections; physical volumes referred to by corresponding SimParticles will be kept.") + }; + + fhicl::Sequence particleInputs { + Name("particleInputs"), + Comment("A list of SimParticleCollections; physical volumes referred to by the particles will be kept.") + }; + }; + + using Parameters = art::EDProducer::Table; + explicit CompressPhysicalVolumes(const Parameters& conf); }; //================================================================ - CompressPhysicalVolumes::CompressPhysicalVolumes(const fhicl::ParameterSet& pset) - : art::EDProducer{pset}, - volumesToken_{consumes(pset.get("volumesInput"))} + CompressPhysicalVolumes::CompressPhysicalVolumes(const Parameters& conf) + : art::EDProducer{conf}, + volumesToken_{consumes(conf().volumesInput())} { produces(); - typedef std::vector VS; - const VS hi(pset.get("hitInputs")); - for(const auto& i : hi) { + for(const auto& i : conf().hitInputs()) { hitTokens_.emplace_back(consumes(i)); } - const VS pi(pset.get("particleInputs")); - for(const auto& i : pi) { + for(const auto& i : conf().particleInputs()) { particleTokens_.emplace_back(consumes(i)); } } diff --git a/Filters/src/FilterG4Out_module.cc b/Filters/src/FilterG4Out_module.cc index effa43ca57..0e0a76bdda 100644 --- a/Filters/src/FilterG4Out_module.cc +++ b/Filters/src/FilterG4Out_module.cc @@ -34,7 +34,8 @@ #include // art includes. -#include "fhiclcpp/ParameterSet.h" +#include "fhiclcpp/types/OptionalSequence.h" + #include "art/Framework/Core/EDFilter.h" #include "art/Framework/Principal/Event.h" #include "art/Framework/Principal/SelectorBase.h" @@ -109,19 +110,100 @@ namespace mu2e { } } - //---------------------------------------------------------------- - // input product => output instance name - struct ProductMapEntry : public std::pair { - ProductMapEntry(const fhicl::ParameterSet& pset) - : std::pair(pset.get("in"), pset.get("out")) - {} - }; - } // anonymous namespace //================================================================ class FilterG4Out : public art::EDFilter { + public: + + struct IOMapEntry { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom in { + Name("in"), + Comment("The input collection") + }; + + fhicl::Atom out { + Name("out"), + Comment("Map the input to this instance name on the output") + }; + }; + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Sequence mainHitInputs { + Name("mainHitInputs"), + Comment("Particles and StepPointMCs mentioned in thise collections will be preserved.") + }; + + fhicl::Sequence mainSPPtrInputs { + Name("mainSPPtrInputs"), + Comment("A list of SimParticlePtrCollections. The pointed to SimParticles will be preserved."), + std::vector() + }; + + fhicl::Sequence extraHitInputs { + Name("extraHitInputs"), + Comment("If a hit in one of these collection is produced by a preserved SimParticle, the hit will be kept."), + std::vector() + }; + + fhicl::Sequence mcTrajectoryInputs { + Name("mcTrajectoryInputs"), + Comment("Trajectories to preserve if the corresponding SimParticle is preserved."), + std::vector() + }; + + fhicl::Sequence vetoDaughters { + Name("vetoDaughters"), + Comment("SimParticlePtrCollections; the daughters and further descendants of the pointed-to particles will be dropped."), + std::vector() + }; + + fhicl::Sequence vetoParticles { + Name("vetoParticles"), + Comment("SimParticlePtrCollections; the particles and all their descendants will be dropped.."), + std::vector() + }; + + fhicl::OptionalSequence > simParticleIOMap { + Name("simParticleIOMap"), + Comment("Specify an output instance name for each SimParticleCollection referenced by the inputs.\n" + "This should only be used when inputs depend on multiple SimParticle collections (e.g. in mixed events)." + ) + }; + + + + // It looks like the GenParticle compression code can write out multiple copies + // of the same particle. The setting is not used by any fcl files in the + // current master branch of Offline. Comment it out untile the issue is + // verified and resolved. + + //FIXME:fhicl::Atom compressGenParticles { + //FIXME: Name("compressGenParticles"), + //FIXME: Comment("By default GenParticles are not touched, and the output SimParticles will point\n" + //FIXME: "to the original GenParticleCollection. If GenParticle compression is requested,\n" + //FIXME: "a new GenParticleCollection will be produced, and output SimParticles will point to it." + //FIXME: ), + //FIXME: false + //FIXME: }; + + + + }; + + using Parameters = art::EDFilter::Table; + explicit FilterG4Out(const Parameters& conf); + + virtual bool filter(art::Event& event) override; + virtual void endJob() override; + private: typedef std::vector InputTags; InputTags mainHitInputs_; // These hits, and SimParticles referenced here, will be kept InputTags mainSPPtrInputs_; // SimParticles referenced here, will be kept @@ -140,7 +222,7 @@ namespace mu2e { OutputNames mainOutputNames_; OutputNames extraOutputNames_; - typedef std::vector VPM; + typedef std::vector VPM; VPM simParticleIOVec_; OutputNames simPartOutNames; @@ -157,26 +239,18 @@ namespace mu2e { unsigned numVetoedParticles_; unsigned numVetoedHits_; - - public: - explicit FilterG4Out(const fhicl::ParameterSet& pset); - virtual bool filter(art::Event& event) override; - virtual void endJob() override; }; //================================================================ - FilterG4Out::FilterG4Out(const fhicl::ParameterSet& pset) - : art::EDFilter{pset} - , compressGenParticles_(pset.get("compressGenParticles", false)) + FilterG4Out::FilterG4Out(const Parameters& conf) + : art::EDFilter{conf} + , compressGenParticles_(false /*FIXME: compressGenParticles_(conf().compressGenParticles() */) , numInputEvents_(), numPassedEvents_() , numMainHits_(), numInputExtraHits_(), numPassedExtraHits_() , numInputParticles_(), numPassedParticles_() , numVetoedParticles_(), numVetoedHits_() { - typedef std::vector VS; - - const VS mainStrings(pset.get("mainHitInputs")); - for(const auto& i : mainStrings) { + for(const auto& i : conf().mainHitInputs()) { mainHitInputs_.emplace_back(i); // Coalesce same instance names from multiple input modules/processes. mainOutputNames_.insert(mainHitInputs_.back().instance()); @@ -185,13 +259,11 @@ namespace mu2e { produces(i); } - const VS ptrStrings(pset.get("mainSPPtrInputs", VS())); - for(const auto& i : ptrStrings) { + for(const auto& i : conf().mainSPPtrInputs()) { mainSPPtrInputs_.emplace_back(i); } - const VS extraStrings(pset.get("extraHitInputs", VS())); - for(const auto& i : extraStrings) { + for(const auto& i : conf().extraHitInputs()) { extraHitInputs_.emplace_back(i); // Coalesce same instance names from multiple input modules/processes. extraOutputNames_.insert(extraHitInputs_.back().instance()); @@ -200,57 +272,50 @@ namespace mu2e { produces(i); } - const VS trajectoryStrings(pset.get("mcTrajectoryInputs", VS())); - for(const auto& i : trajectoryStrings) { + for(const auto& i : conf().mcTrajectoryInputs()) { trajectoryInputs_.emplace_back(i); } if(!trajectoryInputs_.empty()) { produces(); } - const VS vdStrings(pset.get("vetoDaughters", VS())); - for(const auto& i : vdStrings) { + for(const auto& i : conf().vetoDaughters()) { vetoDaughtersInputs_.emplace_back(i); } - const VS vpStrings(pset.get("vetoParticles", VS())); - for(const auto& i : vpStrings) { + for(const auto& i : conf().vetoParticles()) { vetoParticlesInputs_.emplace_back(i); } // We can't merge different SimParticle collections (unlike the hits) // Need to have a separate output collection for every input one. - typedef std::vector SPIOPS; - SPIOPS simParticleIOPS(pset.get("simParticleIOMap", SPIOPS())); - for(const auto& i: simParticleIOPS) { - simParticleIOVec_.emplace_back(i); - } + conf().simParticleIOMap(simParticleIOVec_); if(!simParticleIOVec_.empty()) { - // The validity and uniquiness of the input half will is checked - // inside the event loop, where ProductID-s can be resolved. + + // FIXME: the check for duplicate InputTags + // needs https://cdcvs.fnal.gov/redmine/issues/23320 + // + //redmine#23320:std::set inset; + for(const auto & i : simParticleIOVec_) { - simPartOutNames.insert(i.second); - produces(i.second); + //redmine#23320:if(!inset.insert(i.in()).second) { + //redmine#23320: throw cet::exception("BADCONFIG") + //redmine#23320: <<"FilterG4Out: duplicate input tag in simParticleIOMap: in: "<(i.out()); } } else { - const unsigned numSimPartOuts(pset.get("numSimParticleCollections")); - if((numSimPartOuts == 1) && pset.get("noInstanceName", true)) { - const std::string defaultInstance; - simPartOutNames.insert(defaultInstance); - produces(defaultInstance); - } - else { - // Assign arbitrary unique instance names to the output collections. - // We need to know how many outputs will be needed. - for(unsigned i = 0; i < numSimPartOuts; ++i) { - std::ostringstream os; - os<<"s"<(os.str()); - } - } + const std::string defaultInstance; + simPartOutNames.insert(defaultInstance); + produces(defaultInstance); } produces(); @@ -335,11 +400,11 @@ namespace mu2e { if(!simParticleIOVec_.empty()) { for(const auto& i : simParticleIOVec_) { - auto ih = event.getValidHandle(i.first); - if(!spim.insert(std::make_pair(ih.id(), i.second)).second) { + auto ih = event.getValidHandle(i.in()); + if(!spim.insert(std::make_pair(ih.id(), i.out())).second) { throw cet::exception("BADCONFIG") <<"FilterG4Out: Different entries of simParticleIOMap resolved to the same product!\n" - <<"The current one: { in : "< // art includes. -#include "fhiclcpp/ParameterSet.h" #include "art/Framework/Core/EDFilter.h" #include "art/Framework/Principal/Event.h" #include "art/Framework/Principal/Run.h" @@ -26,16 +25,38 @@ namespace mu2e { typedef std::map StatMap; StatMap stats_; public: - explicit FilterStatusG4(const fhicl::ParameterSet& pset); + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom input { + Name("input"), + Comment("The StatusG4 object to use.") + }; + + fhicl::Atom maxAcceptedStatus { + Name("maxAcceptedStatus"), + Comment("The filter passes events with StatusG4 <= maxAcceptedStatus.\n" + "See MCDataProducts/inc/StatusG4.hh for the meaning of different status values.\n" + "By default maxAcceptedStatus=0 and only perfect events are passed." + ), + 0 + }; + }; + + using Parameters = art::EDFilter::Table; + explicit FilterStatusG4(const Parameters& conf); + virtual bool filter(art::Event& event) override; virtual void endJob() override; }; //================================================================ - FilterStatusG4::FilterStatusG4(const fhicl::ParameterSet& pset) - : art::EDFilter{pset} - , token_{consumes(pset.get("input"))} - , maxAcceptedStatus_(pset.get("maxAcceptedStatus", 0)) + FilterStatusG4::FilterStatusG4(const Parameters& conf) + : art::EDFilter{conf} + , token_{consumes(conf().input())} + , maxAcceptedStatus_(conf().maxAcceptedStatus()) {} //================================================================ diff --git a/Filters/src/StepPointMCCollectionUpdater_module.cc b/Filters/src/StepPointMCCollectionUpdater_module.cc index 85d7925d0e..4297dc5711 100644 --- a/Filters/src/StepPointMCCollectionUpdater_module.cc +++ b/Filters/src/StepPointMCCollectionUpdater_module.cc @@ -21,29 +21,52 @@ namespace mu2e { class StepPointMCCollectionUpdater : public art::EDProducer { public: - explicit StepPointMCCollectionUpdater(fhicl::ParameterSet const& pset); + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom remapping { + Name("remapping"), + Comment("The SimParticleRemapping object to use.") + }; + + fhicl::Sequence inputs { + Name("inputs"), + Comment("A list of StepPointMCCollections to rewrite.") + }; + + fhicl::Atom outInstanceName { + Name("outInstanceName"), + Comment( + "We create a single data product, so the normal Mu2e policy is\n" + "to not use instance name for it. However when our output is\n" + "fed to FilterG4Out, the latter ignores module labels but keeps\n" + "instance names of its \"extraHitInputs\" collections. If a job runs\n" + "several StepPointMCCollectionUpdater modules and their outputs\n" + "are passed to FilterG4Out, a way to preserve information is to\n" + "use instance names for StepPointMCCollectionUpdater outputs.\n" + ) + }; + }; + + using Parameters = art::EDProducer::Table; + explicit StepPointMCCollectionUpdater(const Parameters& conf); + void produce(art::Event& evt) override; private: typedef std::vector InputTags; art::InputTag remapping_; InputTags inputs_; - - // We create a single data product, so the normal Mu2e policy is - // to not use instance name for it. However when our output is - // fed to FilterG4Out, the latter ignores module labels but keeps - // instance names of "extraHitInputs" collections. If a job runs - // several StepPointMCCollectionUpdater modules and their outputs - // are passed to FilterG4Out, a way to preserve information is to - // use instance names for StepPointMCCollectionUpdater outputs. std::string outInstanceName_; }; //================================================================ - StepPointMCCollectionUpdater::StepPointMCCollectionUpdater(const fhicl::ParameterSet& pset) - : art::EDProducer{pset} - , remapping_(pset.get("remapping")) - , inputs_(pset.get >("inputs")) - , outInstanceName_(pset.get("outInstanceName")) + StepPointMCCollectionUpdater::StepPointMCCollectionUpdater(const Parameters& conf) + : art::EDProducer{conf} + , remapping_(conf().remapping()) + , inputs_(conf().inputs()) + , outInstanceName_(conf().outInstanceName()) { produces(outInstanceName_); } diff --git a/JobConfig/beam/DS-flash.fcl b/JobConfig/beam/DS-flash.fcl index 5cdc969dbb..93a3399912 100644 --- a/JobConfig/beam/DS-flash.fcl +++ b/JobConfig/beam/DS-flash.fcl @@ -91,10 +91,8 @@ physics.producers.outOfTargetMuonDaughters: { physics.filters.flashPrefilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [ "g4run:tracker", "g4run:calorimeter", "g4run:calorimeterRO" ] extraHitInputs: [ "g4run:virtualdetector", "g4run:protonabsorber" ] - numSimParticleCollections: 1 vetoParticles: [ "stoppedMuonDaughters", "outOfTargetMuonDaughters" ] } @@ -113,8 +111,6 @@ physics.producers.CaloShowerStepFromStepPt.module_type: CaloShowerStepFromStepPt // The final filter physics.filters.detectorFilter: { module_type: "FilterG4Out" - noInstanceName: true - numSimParticleCollections: 1 mainHitInputs: [ "flashPrefilter:tracker" ] diff --git a/JobConfig/beam/DS.fcl b/JobConfig/beam/DS.fcl index 406fb3f530..9eae75ddfc 100644 --- a/JobConfig/beam/DS.fcl +++ b/JobConfig/beam/DS.fcl @@ -141,38 +141,30 @@ physics : { filters: { mothersFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [ "g4run:DetectorMother" ] extraHitInputs: [ "g4run:virtualdetector" ] - numSimParticleCollections: 1 vetoParticles: [ "stoppedMuonDaughters", "outOfTargetMuonDaughters" ] } crvFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [ "g4run:CRV" ] extraHitInputs: [ "g4run:virtualdetector" ] - numSimParticleCollections: 1 vetoParticles: [ "stoppedMuonDaughters", "outOfTargetMuonDaughters" ] } tgtStopFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [] extraHitInputs: [ "g4run:virtualdetector" ] mainSPPtrInputs: [ "stoppedMuonFinder" ] - numSimParticleCollections: 1 } ootStopFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [] extraHitInputs: [ "g4run:virtualdetector" ] mainSPPtrInputs: [ "outOfTargetMuonFinder" ] - numSimParticleCollections: 1 } g4status: { diff --git a/JobConfig/beam/DS_pions.fcl b/JobConfig/beam/DS_pions.fcl index 0f747ebaae..0e4a21d0b9 100644 --- a/JobConfig/beam/DS_pions.fcl +++ b/JobConfig/beam/DS_pions.fcl @@ -117,11 +117,9 @@ physics : { filters : { stopFilter : { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [] extraHitInputs : [ "g4run:virtualdetector", "vacuuas1:vacuuas1"] mainSPPtrInputs : [ "stoppedPionFinder" ] - numSimParticleCollections : 1 vetoDaughters : [ "stoppedPionFinder" ] } } // filters diff --git a/JobConfig/beam/PS.fcl b/JobConfig/beam/PS.fcl index c6895c9379..121c3574dc 100644 --- a/JobConfig/beam/PS.fcl +++ b/JobConfig/beam/PS.fcl @@ -189,37 +189,29 @@ physics : { filters: { muonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:mubeam" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } dsRegionFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:dsregion" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } extmonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonbeam" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } extmonRegionFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonregion" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } diff --git a/JobConfig/beam/TS-CRV.fcl b/JobConfig/beam/TS-CRV.fcl index 7c98ebacee..27dda352b5 100644 --- a/JobConfig/beam/TS-CRV.fcl +++ b/JobConfig/beam/TS-CRV.fcl @@ -95,10 +95,8 @@ physics : { filters: { crvFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:CRV" ] extraHitInputs : [ ] - numSimParticleCollections : 1 vetoDaughters: [] } diff --git a/JobConfig/beam/TS.fcl b/JobConfig/beam/TS.fcl index 5cb52ceacb..409d788c83 100644 --- a/JobConfig/beam/TS.fcl +++ b/JobConfig/beam/TS.fcl @@ -99,19 +99,15 @@ physics : { filters: { muonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:DSVacuum" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } crvFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:CRV" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } diff --git a/JobConfig/beam/beam_defs_g4s1.fcl b/JobConfig/beam/beam_defs_g4s1.fcl index 4a45268574..0d59ed6af6 100644 --- a/JobConfig/beam/beam_defs_g4s1.fcl +++ b/JobConfig/beam/beam_defs_g4s1.fcl @@ -203,37 +203,29 @@ physics : { filters: { muonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:mubeam" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } dsRegionFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:dsregion" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } extmonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonbeam" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } extmonRegionFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonregion" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } diff --git a/JobConfig/beam/beam_g4rs3.fcl b/JobConfig/beam/beam_g4rs3.fcl index 4b767bcac9..b24b96bef7 100644 --- a/JobConfig/beam/beam_g4rs3.fcl +++ b/JobConfig/beam/beam_g4rs3.fcl @@ -19,7 +19,7 @@ services : { message : @local::default_message TFileService : { fileName : "nts.owner.beam-g4rs3.version.sequencer.root" } RandomNumberGenerator : { } - GeometryService : { inputFile : "JobConfig/common/geom_baseline.txt" } + GeometryService : { @table::Services.Core.GeometryService inputFile : "JobConfig/common/geom_baseline.txt" } ConditionsService : { conditionsfile : "Mu2eG4/test/conditions_01.txt" } GlobalConstantsService : { inputFile : "Mu2eG4/test/globalConstants_01.txt" } G4Helper : { } @@ -103,19 +103,15 @@ physics : { filters: { mothersFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [ "g4run:DetectorMother" ] extraHitInputs: [ "g4run:virtualdetector" ] - numSimParticleCollections: 1 vetoParticles: [] } crvFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [ "g4run:CRV" ] extraHitInputs: [ "g4run:virtualdetector" ] - numSimParticleCollections: 1 vetoParticles: [] } diff --git a/JobConfig/beam/beam_g4s1MT.fcl b/JobConfig/beam/beam_g4s1MT.fcl index e0eee1f408..c26f58fdea 100644 --- a/JobConfig/beam/beam_g4s1MT.fcl +++ b/JobConfig/beam/beam_g4s1MT.fcl @@ -210,37 +210,29 @@ physics : { filters: { muonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:mubeam" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } dsRegionFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:dsregion" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } extmonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonbeam" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } extmonRegionFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonregion" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } diff --git a/JobConfig/beam/prolog.fcl b/JobConfig/beam/prolog.fcl index dd9d1847c6..9bfde19851 100644 --- a/JobConfig/beam/prolog.fcl +++ b/JobConfig/beam/prolog.fcl @@ -154,20 +154,16 @@ mu2e.physics.g4s4CommonBase: { filters: { detectorFilter: { module_type: FilterG4Out - noInstanceName: true mainHitInputs: [ "g4run:tracker" ] mainSPPtrInputs: [ "CaloShowerStepFromStepPt" ] extraHitInputs: [ "g4run:virtualdetector", "g4run:protonabsorber" ] - numSimParticleCollections: 1 vetoDaughters: [] } crvFilter: { module_type: FilterG4Out - noInstanceName: true mainHitInputs: [ "g4run:CRV"] extraHitInputs: [ "g4run:virtualdetector" ] - numSimParticleCollections: 1 vetoDaughters: [] } diff --git a/JobConfig/cosmic/cosmic_s1_target5.fcl b/JobConfig/cosmic/cosmic_s1_target5.fcl index 3204b42ac4..97be0ad9cd 100644 --- a/JobConfig/cosmic/cosmic_s1_target5.fcl +++ b/JobConfig/cosmic/cosmic_s1_target5.fcl @@ -237,11 +237,9 @@ physics : cosmicFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:crvStage1" ] extraHitInputs : [] mcTrajectoryInputs : [ "g4run" ] - numSimParticleCollections : 1 vetoDaughters: [] } diff --git a/JobConfig/extmon/extmonbeam_g4s2.fcl b/JobConfig/extmon/extmonbeam_g4s2.fcl index 34fd1835d1..fc98b9ac07 100644 --- a/JobConfig/extmon/extmonbeam_g4s2.fcl +++ b/JobConfig/extmon/extmonbeam_g4s2.fcl @@ -119,10 +119,8 @@ physics : { filters: { extmonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonbeam" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters: [] } g4consistent: { diff --git a/JobConfig/pbar/resample_vertex_s1.fcl b/JobConfig/pbar/resample_vertex_s1.fcl index dc37314250..c0739aea17 100644 --- a/JobConfig/pbar/resample_vertex_s1.fcl +++ b/JobConfig/pbar/resample_vertex_s1.fcl @@ -151,10 +151,8 @@ physics : { filters : { g4filter : { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:VirtualDetectorPSPbarIn" ] extraHitInputs : [ "g4run:virtualdetector"] - numSimParticleCollections : 1 vetoDaughters : [] } diff --git a/JobConfig/pbar/resample_vertex_s2.fcl b/JobConfig/pbar/resample_vertex_s2.fcl index 2b235c04a0..8406fe2d6d 100644 --- a/JobConfig/pbar/resample_vertex_s2.fcl +++ b/JobConfig/pbar/resample_vertex_s2.fcl @@ -111,10 +111,8 @@ physics : { filters : { g4filter : { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:Coll31Out" ] extraHitInputs : [ "g4run:virtualdetector"] - numSimParticleCollections : 1 vetoDaughters : [] } mixread: { diff --git a/JobConfig/pbar/vertex_s0.fcl b/JobConfig/pbar/vertex_s0.fcl index 8338c33740..7d14d61aa8 100644 --- a/JobConfig/pbar/vertex_s0.fcl +++ b/JobConfig/pbar/vertex_s0.fcl @@ -105,9 +105,7 @@ physics : { filters: { g4filter: { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:pbars0" ] - numSimParticleCollections : 1 vetoDaughters : [] } } diff --git a/JobConfig/pbar/vertex_s1.fcl b/JobConfig/pbar/vertex_s1.fcl index 2a97d0e4de..fffd31c229 100644 --- a/JobConfig/pbar/vertex_s1.fcl +++ b/JobConfig/pbar/vertex_s1.fcl @@ -149,10 +149,8 @@ physics : { filters : { g4filter : { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:VirtualDetectorPSPbarIn" ] extraHitInputs : [ "g4run:virtualdetector"] - numSimParticleCollections : 1 vetoDaughters : [] } } // filters diff --git a/JobConfig/pions/pions_g4s1.fcl b/JobConfig/pions/pions_g4s1.fcl index 8230765a6c..a05600c72a 100644 --- a/JobConfig/pions/pions_g4s1.fcl +++ b/JobConfig/pions/pions_g4s1.fcl @@ -106,10 +106,8 @@ physics : { filters : { g4filter : { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:vacuuas1" ] extraHitInputs : [ "g4run:virtualdetector" ] - numSimParticleCollections : 1 vetoDaughters : [] } } // filters diff --git a/JobConfig/pions/pions_g4s2.fcl b/JobConfig/pions/pions_g4s2.fcl index 319eb19171..5c478d7dde 100644 --- a/JobConfig/pions/pions_g4s2.fcl +++ b/JobConfig/pions/pions_g4s2.fcl @@ -113,10 +113,8 @@ physics : { filters : { g4filter : { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:vacuuas2" ] extraHitInputs : [ "g4run:virtualdetector", "vacuuas1:vacuuas1" ] - numSimParticleCollections : 1 vetoDaughters : [] } } // filters diff --git a/JobConfig/pions/pions_g4s3.fcl b/JobConfig/pions/pions_g4s3.fcl index 8f9ca0c520..4742cd0836 100644 --- a/JobConfig/pions/pions_g4s3.fcl +++ b/JobConfig/pions/pions_g4s3.fcl @@ -117,11 +117,9 @@ physics : { filters : { stopFilter : { module_type : FilterG4Out - noInstanceName : true mainHitInputs : [] extraHitInputs : [ "g4run:virtualdetector", "vacuuas1:vacuuas1" , "vacuuas2:vacuuas2" ] mainSPPtrInputs : [ "stoppedPionFinder" ] - numSimParticleCollections : 1 vetoDaughters : [ "stoppedPionFinder" ] } } // filters diff --git a/JobConfig/validation/psEnclosureExtMonWindow.fcl b/JobConfig/validation/psEnclosureExtMonWindow.fcl index ad23566149..687d7ec859 100644 --- a/JobConfig/validation/psEnclosureExtMonWindow.fcl +++ b/JobConfig/validation/psEnclosureExtMonWindow.fcl @@ -98,10 +98,8 @@ physics : { filters: { extmonBeamFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:extmonbeam" ] extraHitInputs : [ "g4run:virtualdetector", "g4run:PSEnclosureEndPlate", "g4run:PSEnclosureWindow0", "g4run:PSEnclosureWindow1" ] - numSimParticleCollections : 1 vetoDaughters: [] } } diff --git a/JobConfig/validation/stoppedMuonsSingleStage.fcl b/JobConfig/validation/stoppedMuonsSingleStage.fcl index bd97985ae2..491f3f9ebe 100644 --- a/JobConfig/validation/stoppedMuonsSingleStage.fcl +++ b/JobConfig/validation/stoppedMuonsSingleStage.fcl @@ -112,11 +112,9 @@ physics : { filters: { tgtStopFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [] extraHitInputs: [ "g4run:virtualdetector" ] mainSPPtrInputs: [ "stoppedMuonFinder" ] - numSimParticleCollections: 1 } g4consistent: { diff --git a/Mu2eG4/fcl/gdmldump.fcl b/Mu2eG4/fcl/gdmldump.fcl index b4af3f4791..a5388013a3 100644 --- a/Mu2eG4/fcl/gdmldump.fcl +++ b/Mu2eG4/fcl/gdmldump.fcl @@ -14,7 +14,7 @@ physics : { producers: { generate: { module_type : ExtMonFNALGun - guns: [] + guns: [ { reference: "detector" } ] } g4run : @local::g4run diff --git a/Mu2eUtilities/inc/ProtonPulseRandPDF.hh b/Mu2eUtilities/inc/ProtonPulseRandPDF.hh index 4285299d7f..90af8e7214 100644 --- a/Mu2eUtilities/inc/ProtonPulseRandPDF.hh +++ b/Mu2eUtilities/inc/ProtonPulseRandPDF.hh @@ -1,7 +1,7 @@ #ifndef ProtonPulseRandPDF_hh #define ProtonPulseRandPDF_hh -// +// // Constructor of a PDF to extract random times to describe the proton pulse // // $Id: ProtonPulseRandPDF.hh,v 1.11 2014/04/25 17:26:42 knoepfel Exp $ @@ -22,6 +22,8 @@ #include "CLHEP/Random/RandomEngine.h" // Framework includes +#include "fhiclcpp/types/Atom.h" +#include "fhiclcpp/types/OptionalAtom.h" #include "fhiclcpp/ParameterSet.h" #include "art/Framework/Services/Optional/RandomNumberGenerator.h" @@ -35,12 +37,15 @@ namespace mu2e { class ProtonPulseEnumDetail { public: enum enum_type { unknown, DEFAULT, TOTAL, OOT, ALLFLAT }; + + // Required for EnumToStringSparse static std::string const& typeName() { static std::string type("PotSpectrumType"); return type; } + static std::map const& names() { static std::map nam; - + if ( nam.empty() ) { nam[unknown] = "unknown"; nam[DEFAULT] = "default"; @@ -48,18 +53,48 @@ namespace mu2e { nam[OOT] = "oot"; nam[ALLFLAT] = "allflat"; } - + return nam; } }; - + typedef EnumToStringSparse ProtonPulseEnum; - // ================================================================== + // ================================================================== // ProtonPulseRandPDF class declaration - // ================================================================== + // ================================================================== class ProtonPulseRandPDF : public ProtonPulseEnum { public: + + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Atom pulseType { + Name("pulseType"), + Comment("Allowed values are: default, total, oot, allflat."), + "default" + }; + + fhicl::OptionalAtom tmin { + Name("tmin"), + Comment("Override proton pulse start time. The default is determined from the ConditionsService based on the pulseType.") + }; + + fhicl::OptionalAtom tmax { + Name("tmax"), + Comment("Override proton pulse end time. The default is determined from the ConditionsService based on the pulseType.") + }; + + fhicl::Atom tres { + Name("tres"), + Comment("The time bin size, in ns."), + 1. + }; + }; + + ProtonPulseRandPDF(art::RandomNumberGenerator::base_engine_t& engine, const Config& conf); + ProtonPulseRandPDF(art::RandomNumberGenerator::base_engine_t& engine, const fhicl::ParameterSet pset ); ~ProtonPulseRandPDF(){} @@ -74,13 +109,13 @@ namespace mu2e { const AcceleratorParams* accPar_; const ProtonPulseEnum pulseEnum_; - - const double tmin_; - const double tmax_; - const double tres_; + + double tmin_; + double tmax_; + double tres_; const std::vector times_; - - const double extFactor_; + + const double extFactor_; const Table<2> pulseShape_; const Table<2> acdipole_; diff --git a/Mu2eUtilities/inc/RootTreeSampler.hh b/Mu2eUtilities/inc/RootTreeSampler.hh index a1adf3bd15..723574c7a5 100644 --- a/Mu2eUtilities/inc/RootTreeSampler.hh +++ b/Mu2eUtilities/inc/RootTreeSampler.hh @@ -35,6 +35,9 @@ #include +#include "fhiclcpp/types/Atom.h" +#include "fhiclcpp/types/OptionalAtom.h" +#include "fhiclcpp/types/TupleAs.h" #include "fhiclcpp/ParameterSet.h" #include "CLHEP/Random/RandomEngine.h" @@ -56,6 +59,51 @@ namespace mu2e { class RootTreeSampler { public: + struct Config { + using Name=fhicl::Name; + using Comment=fhicl::Comment; + + fhicl::Sequence inputFiles { + Name("inputFiles"), + Comment("List of input ntuple files") + }; + + fhicl::Atom treeName { + Name("treeName"), + Comment("Name of the ROOT tree object containing particle records") + }; + + fhicl::Atom branchName { + Name("branchName"), + Comment("Name of the ROOT tree branch containing particle records") + }; + + fhicl::Atom averageNumRecordsToUse { + Name("averageNumRecordsToUse"), + Comment("Zero means use all record. Use a non-zero value\n" + "to load only a random subset of the records to limit memory use."), + 0 + }; + + fhicl::Atom verbosityLevel { + Name("verbosityLevel"), + Comment("A positive value generates more printouts than the default."), + 0 + }; + + fhicl::Atom pieBranchName { + Name("pieBranchName"), + Comment("Only for generators resampling correlated particles from\n" + "multiple ntuple records:\n" + "Name of the ROOT tree branch that maps input records to events."), + [this](){ return !std::is_same::value; } + }; + }; + + RootTreeSampler(art::RandomNumberGenerator::base_engine_t& engine, + const Config& conf); + + // legacy interface with pset RootTreeSampler(art::RandomNumberGenerator::base_engine_t& engine, const fhicl::ParameterSet& pset); @@ -89,6 +137,20 @@ namespace mu2e { Long64_t currentEntry_ = 0; Long64_t numUsedNtupleEntries_ = 0; + SingleRecordGetter(RootTreeSampler *ts, + TTree *tr, + TBranch *mainRecordBranch, + const Config& conf, + double recordUseFraction) + : parent_(ts) + , nt_(tr) + , mrb_(mainRecordBranch) + , recordUseFraction_(recordUseFraction) + , numTreeEntries_(tr->GetEntries()) + { + mrb_->SetAddress(&ntr_); + } + SingleRecordGetter(RootTreeSampler *ts, TTree *tr, TBranch *mainRecordBranch, @@ -147,6 +209,37 @@ namespace mu2e { Long64_t numUsedNtupleEntries_; + MultiRecordGetter(RootTreeSampler *ts, + TTree *tr, + TBranch *mainRecordBranch, + const Config& conf, + double recordUseFraction) + : parent_(ts) + , nt_(tr) + , mrb_(mainRecordBranch) + + , pieb_(nullptr) + , particleInEvent_(-1) + + , recordUseFraction_(recordUseFraction) + , numTreeEntries_(tr->GetEntries()) + , currentEntry_(0) + , numUsedNtupleEntries_(0) + { + const std::string pbn = conf.pieBranchName(); + pieb_ = tr->GetBranch(pbn.c_str()); + + mrb_->SetAddress(&ntr_); + + if(!pieb_) { + throw cet::exception("BADINPUT") + <<"RootTreeSampler: Could not get branch \""<GetName() + <<"\"\n"; + } + pieb_->SetAddress(&particleInEvent_); + } + MultiRecordGetter(RootTreeSampler *ts, TTree *tr, TBranch *mainRecordBranch, @@ -156,7 +249,7 @@ namespace mu2e { , nt_(tr) , mrb_(mainRecordBranch) - , pieb_(tr->GetBranch(pset.get("pieBranchName").c_str())) + , pieb_(nullptr) , particleInEvent_(-1) , recordUseFraction_(recordUseFraction) @@ -164,6 +257,9 @@ namespace mu2e { , currentEntry_(0) , numUsedNtupleEntries_(0) { + const std::string pbn = pset.get("pieBranchName"); + pieb_ = tr->GetBranch(pbn.c_str()); + mrb_->SetAddress(&ntr_); if(!pieb_) { @@ -232,12 +328,120 @@ namespace mu2e { }; // MultiRecordGetter //---------------------------------------------------------------- - }; + }; // RootTreeSampler } //================================================================ namespace mu2e { + template + RootTreeSampler:: + RootTreeSampler(art::RandomNumberGenerator::base_engine_t& engine, + const Config& conf) + : randFlat_(engine) + { + const auto inputFiles(conf.inputFiles()); + const auto treeName(conf.treeName()); + const long averageNumRecordsToUse(conf.averageNumRecordsToUse()); + int verbosityLevel = conf.verbosityLevel(); + + if(inputFiles.empty()) { + throw cet::exception("BADCONFIG")<<"Error: no inputFiles"; + } + + art::ServiceHandle tfs; + + double recordUseFraction = 1.; + if(averageNumRecordsToUse > 0) { + const long totalRecords = countInputRecords(tfs, inputFiles, treeName); + if(averageNumRecordsToUse < totalRecords) { + recordUseFraction = averageNumRecordsToUse/double(totalRecords); + if(verbosityLevel > 0) { + std::cout<<"RootTreeSampler: recordUseFraction = "<(infile->Get(treeName.c_str())); + if(!nt) { + throw cet::exception("BADINPUT")<<"RootTreeSampler: Could not get tree \""<GetName() + <<"\"\n"; + } + + //---------------------------------------------------------------- + // A rudimentary check that the input ntuple is consistent with the data structure + + const auto branchName(conf.branchName()); + TBranch *bb = nt->GetBranch(branchName.c_str()); + if(!bb) { + throw cet::exception("BADINPUT")<<"RootTreeSampler: Could not get branch \""<GetName() + <<"\"\n"; + } + + if(unsigned(bb->GetNleaves()) != NtupleRecord::numBranchLeaves()) { + throw cet::exception("BADINPUT")<<"RootTreeSampler: wrong number of leaves: expect " + <GetName() + <<"\" has "<GetNleaves() + <<"\n"; + } + //---------------------------------------------------------------- + + const Long64_t nTreeEntries = nt->GetEntries(); + std::cout<<"RootTreeSampler: reading "<GetName() + <::value, + SingleRecordGetter, MultiRecordGetter>::type + egt(this, nt, bb, conf, recordUseFraction); + + while(egt.hasMoreRecords()) { + records_.push_back(egt.getRecord()); + } + + if(verbosityLevel > 0) { + std::cout<<"RootTreeSampler: stored "< RootTreeSampler:: RootTreeSampler(art::RandomNumberGenerator::base_engine_t& engine, @@ -314,9 +518,9 @@ namespace mu2e { const Long64_t nTreeEntries = nt->GetEntries(); std::cout<<"RootTreeSampler: reading "<GetName() - <GetName() + < diff --git a/Mu2eUtilities/src/ProtonPulseRandPDF.cc b/Mu2eUtilities/src/ProtonPulseRandPDF.cc index 0fc68223e8..dd3639826b 100644 --- a/Mu2eUtilities/src/ProtonPulseRandPDF.cc +++ b/Mu2eUtilities/src/ProtonPulseRandPDF.cc @@ -43,7 +43,7 @@ // table entries. // // =NB1= No wrapping functionality is available if a time range is -// specified that is larger than the nominal 1695-ns microbunch +// specified that is larger than the nominal 1695-ns microbunch // time cycle. // // =NB2= The proton pulse is always centered at 0 ns. @@ -55,9 +55,29 @@ // but is unlikely to result in any noticeable effect. namespace mu2e{ - + + ProtonPulseRandPDF::ProtonPulseRandPDF(art::RandomNumberGenerator::base_engine_t& engine, + const Config& conf) + : accPar_ ( &*ConditionsHandle( "ignored" ) ) + , pulseEnum_ ( conf.pulseType() ) + , tmin_ ( setTmin() ) + , tmax_ ( setTmax() ) + , tres_ ( conf.tres() ) + , times_ ( setTimes() ) + , extFactor_ ( determineIntrinsicExt( ConfigFileLookupPolicy()( accPar_->potPulse ) ) ) + , pulseShape_ ( setPotPulseShape( ConfigFileLookupPolicy()( accPar_->potPulse ) ) ) + , acdipole_ ( loadTable<2>( ConfigFileLookupPolicy()( accPar_->acDipole ) ) ) + , spectrum_ ( setSpectrum() ) + , randSpectrum_( engine, &spectrum_.front(), times_.size() ) + { + // Process optional FHICL parameters: modify the values set in the + // initialization list if job config supplies overrides. + conf.tmin(tmin_); + conf.tmax(tmax_); + } + ProtonPulseRandPDF::ProtonPulseRandPDF(art::RandomNumberGenerator::base_engine_t& engine, - const fhicl::ParameterSet pset ) + const fhicl::ParameterSet pset ) : accPar_ ( &*ConditionsHandle( "ignored" ) ) , pulseEnum_ ( pset.get("pulseType","default") ) , tmin_ ( pset.get("tmin", setTmin() ) ) @@ -69,8 +89,8 @@ namespace mu2e{ , acdipole_ ( loadTable<2>( ConfigFileLookupPolicy()( accPar_->acDipole ) ) ) , spectrum_ ( setSpectrum() ) , randSpectrum_( engine, &spectrum_.front(), times_.size() ) - {} - + {} + //============================================================================================================ double ProtonPulseRandPDF::fire() { @@ -84,7 +104,7 @@ namespace mu2e{ double min(0.); if ( pulseEnum_ == DEFAULT ) min = -accPar_->limitingHalfWidth; if ( pulseEnum_ == TOTAL ) min = -accPar_->limitingHalfWidth; - if ( pulseEnum_ == OOT ) min = accPar_->limitingHalfWidth; + if ( pulseEnum_ == OOT ) min = accPar_->limitingHalfWidth; if ( pulseEnum_ == ALLFLAT ) min = -accPar_->limitingHalfWidth; return min; } @@ -93,12 +113,12 @@ namespace mu2e{ double ProtonPulseRandPDF::setTmax() { double max(0.); if ( pulseEnum_ == DEFAULT ) max = accPar_->limitingHalfWidth; - if ( pulseEnum_ == TOTAL ) max = accPar_->deBuncherPeriod - accPar_->limitingHalfWidth; + if ( pulseEnum_ == TOTAL ) max = accPar_->deBuncherPeriod - accPar_->limitingHalfWidth; if ( pulseEnum_ == OOT ) max = accPar_->deBuncherPeriod - accPar_->limitingHalfWidth; if ( pulseEnum_ == ALLFLAT ) max = accPar_->deBuncherPeriod - accPar_->limitingHalfWidth; return max; } - + //============================================================================================================ std::vector ProtonPulseRandPDF::setTimes() { std::vector times; @@ -136,18 +156,18 @@ namespace mu2e{ //============================================================================================================ std::vector ProtonPulseRandPDF::setSpectrum() { - + std::vector spectrum; spectrum.reserve( times_.size() ); - + if ( pulseEnum_ == ALLFLAT ) { spectrum = std::vector( times_.size() , 1. ); } else { - + for ( const auto& t : times_ ) spectrum.push_back( pulseShape_.getValueAtKey(t).at(0)*acdipole_.getValueAtKey(t).at(0) ); - + } return spectrum; } @@ -158,13 +178,13 @@ namespace mu2e{ auto const& shapevec = potShape.getShape( potShape(0,0), potShape( potShape.getNrows()-1, 0 ), tres_ ); double num(0.), denom(0.); - std::for_each( shapevec.begin(), shapevec.end(), - [&](const TableRow<2>& pt ) + std::for_each( shapevec.begin(), shapevec.end(), + [&](const TableRow<2>& pt ) { if ( std::abs(pt.first) >= accPar_->limitingHalfWidth ) { num += pt.second.at(0);} else denom += pt.second.at(0); } ); - + return num/denom; } diff --git a/Projects/edmonds-ipa-and-beam-test-sims/fcl/beam_g4s3_modified.fcl b/Projects/edmonds-ipa-and-beam-test-sims/fcl/beam_g4s3_modified.fcl index 97b733b679..9fb5caec5b 100644 --- a/Projects/edmonds-ipa-and-beam-test-sims/fcl/beam_g4s3_modified.fcl +++ b/Projects/edmonds-ipa-and-beam-test-sims/fcl/beam_g4s3_modified.fcl @@ -142,38 +142,30 @@ physics : { filters: { mothersFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [ "g4run:DetectorMother" ] extraHitInputs: [ "g4run:virtualdetector" ] - numSimParticleCollections: 1 vetoParticles: [ "stoppedMuonDaughters", "outOfTargetMuonDaughters" ] } crvFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [ "g4run:CRV" ] extraHitInputs: [ "g4run:virtualdetector" ] - numSimParticleCollections: 1 vetoParticles: [ "stoppedMuonDaughters", "outOfTargetMuonDaughters" ] } tgtStopFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [] extraHitInputs: [ "g4run:virtualdetector" ] mainSPPtrInputs: [ "stoppedMuonFinder" ] - numSimParticleCollections: 1 } ootStopFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs: [] extraHitInputs: [ "g4run:virtualdetector" ] mainSPPtrInputs: [ "outOfTargetMuonFinder" ] - numSimParticleCollections: 1 } g4status: { diff --git a/Validation/fcl/prolog.fcl b/Validation/fcl/prolog.fcl index 3710c2c95e..2d4977132d 100644 --- a/Validation/fcl/prolog.fcl +++ b/Validation/fcl/prolog.fcl @@ -208,11 +208,9 @@ cosmicFilter: cosmicFilter: { module_type: FilterG4Out - noInstanceName : true mainHitInputs : [ "g4run:CRV" ] extraHitInputs : [] mcTrajectoryInputs : [ ] - numSimParticleCollections : 1 vetoDaughters: [] } }