diff --git a/sbndcode/Filters/SimEnergyDepFakeTriggerFilter_module.cc b/sbndcode/Filters/SimEnergyDepFakeTriggerFilter_module.cc new file mode 100644 index 000000000..dddb2eec3 --- /dev/null +++ b/sbndcode/Filters/SimEnergyDepFakeTriggerFilter_module.cc @@ -0,0 +1,54 @@ +#include "art/Framework/Core/EDFilter.h" +#include "art/Framework/Core/ModuleMacros.h" +#include "art/Framework/Principal/Event.h" + +#include "lardataobj/Simulation/SimEnergyDeposit.h" + +namespace filt { + +class SimEnergyDepFakeTriggerFilter : public art::EDFilter { + public: + explicit SimEnergyDepFakeTriggerFilter(fhicl::ParameterSet const& pset); + virtual bool filter(art::Event& e) override; + + private: + const double fBeamTimeMin; // Minimum time of beam window [us] + const double fBeamTimeMax; // Maximum time of beam window [us] + const double fEnergyDeposit; // Minimum energy deposit in TPC for trigger [MeV] + + const std::string fSimEnergyDepModuleName; +}; + +SimEnergyDepFakeTriggerFilter::SimEnergyDepFakeTriggerFilter(fhicl::ParameterSet const& pset) + : EDFilter(pset) + , fBeamTimeMin(pset.get("BeamTimeMin")) + , fBeamTimeMax(pset.get("BeamTimeMax")) + , fEnergyDeposit(pset.get("EnergyDeposit")) + , fSimEnergyDepModuleName(pset.get("SimEnergyDepModuleName")) +{ +} + +bool SimEnergyDepFakeTriggerFilter::filter(art::Event& e) +{ + const art::ValidHandle>& + energyDeps(e.getValidHandle>(fSimEnergyDepModuleName)); + + double energy(0); + + for (const sim::SimEnergyDeposit& energyDep : *energyDeps) { + // Check particle time is within the beam time + const double time(energyDep.Time() * 1e-3); // [ns] -> [us] + if (time < fBeamTimeMin || time > fBeamTimeMax) + continue; + + // Add up the energy deposit inside the TPC + energy += energyDep.Energy(); // [MeV] + } + + // If the energy deposit within the beam time is greater than some limit then trigger the event + return energy > fEnergyDeposit; +} + +DEFINE_ART_MODULE(SimEnergyDepFakeTriggerFilter) + +} diff --git a/sbndcode/Filters/fcls/gennufilter.fcl b/sbndcode/Filters/fcls/gennufilter.fcl index 6cd9c9c8f..4ed9ff207 100644 --- a/sbndcode/Filters/fcls/gennufilter.fcl +++ b/sbndcode/Filters/fcls/gennufilter.fcl @@ -9,4 +9,7 @@ sbnd_gennufilter: NC: true } +sbnd_tpc_gennufilter: @local::sbnd_gennufilter +sbnd_tpc_gennufilter.VtxInTPC: true + END_PROLOG diff --git a/sbndcode/Filters/fcls/simenergydepfaketriggerfilter.fcl b/sbndcode/Filters/fcls/simenergydepfaketriggerfilter.fcl new file mode 100644 index 000000000..2188b686e --- /dev/null +++ b/sbndcode/Filters/fcls/simenergydepfaketriggerfilter.fcl @@ -0,0 +1,16 @@ +BEGIN_PROLOG + +sbnd_simenergydepfaketriggerfilter: +{ + module_type: "SimEnergyDepFakeTriggerFilter" + + # Select the beam spill time to match that in sbnd_filtergenintime + BeamTimeMin: -0.2 # Minimum time of beam window [us] + BeamTimeMax: 1.9 # Maximum time of beam window [us] + EnergyDeposit: 100 # Minimum energy deposit in TPC for trigger [MeV] + + # By default, take only the energy deposits within the TPC active volume + SimEnergyDepModuleName: "largeant:LArG4DetectorServicevolTPCActive" # Name of SimEnergyDeposit producer module +} + +END_PROLOG diff --git a/sbndcode/JobConfigurations/base/prodgenie_rockbox_sbnd.fcl b/sbndcode/JobConfigurations/base/prodgenie_rockbox_sbnd.fcl new file mode 100644 index 000000000..0743aa0ae --- /dev/null +++ b/sbndcode/JobConfigurations/base/prodgenie_rockbox_sbnd.fcl @@ -0,0 +1,117 @@ +# +# File: prodgenie_rockbox sbnd.fcl +# Purpose: Produce GENIE events in the SBND detector and surrounding dirt with spill structure +# using rockbox functionality in GENIEHelper +# Version: 1.0 +# +# This configuration runs event generation and largenat +# +# Input: no input file required +# +# Dependencies: +# - uses the bundle of SBND simulation services +# +# + +# +# services +# + +#include "simulationservices_sbnd.fcl" +#include "messages_sbnd.fcl" + +# +# filters +# + +#include "gennufilter.fcl" +#include "simenergydepfaketriggerfilter.fcl" + +# +# modules +# + +#include "genie_sbnd.fcl" +#include "larg4_sbnd.fcl" + + +process_name: GenieGen + +services: +{ + # Load the service that manages root files for histograms. + TFileService: { fileName: "hists_prodgenie_sbnd_%p-%tc.root" } + IFDH: {} # required by GENIEGen + @table::sbnd_simulation_services # load simulation services in bulk + @table::sbnd_g4_services +} + +# Start each new event with an empty event. +source: +{ + module_type: EmptyEvent + timestampPlugin: { plugin_type: "GeneratedEventTimestamp" } + maxEvents: 10 # Number of events to create + firstRun: 1 # Run number to use for this file + firstEvent: 1 # number of first event in the file +} + +# Define and configure some modules to do work on each event. +# First modules are defined; they are scheduled later. +# Modules are grouped by type. +physics: +{ + + filters: + { + # Filter events that have an interaction in the TPC + tpcfilter: @local::sbnd_tpc_gennufilter + + # Filter events where a particle deposits >100MeV in the TPC (AKA Dirt) + dirtfilter: @local::sbnd_simenergydepfaketriggerfilter + } + + + producers: + { + rns: { module_type: "RandomNumberSaver" } + + # Run GENIE in rockbox mode + generator: @local::sbnd_genie_simple_rockbox + + # A dummy module that forces the G4 physics list to be loaded + loader: { module_type: "PhysListLoader" } + + # The geant4 step + largeant: @local::sbnd_larg4 + } + + #define the producer and filter modules for this path, order matters, + simulatetpc: [ rns, generator, loader, largeant, tpcfilter ] + simulatedirt: [ rns, generator, loader, largeant, "!tpcfilter", dirtfilter ] + + #define the output stream, there could be more than one if using filters + # One can run any combination of outAll, outTPC and outDirt + # Each of which will produce an output with the specifeied interactions + + # By deault Keep everything in one file: + stream1: [ outAll ] + + #ie analyzers and output streams. these all run simultaneously + end_paths: [stream1] +} + +# block to define where the output goes. if you defined a filter in the physics +# block and put it in the trigger_paths then you need to put a SelectEvents: {SelectEvents: [XXX]} +# entry in the output stream you want those to go to, where XXX is the label of the filter module(s) +outputs: +{ + # Keep all events with either TPC neutrinos or dirt interactions in one output + outAll: + { + module_type: RootOutput + fileName: "prodgenie_sbnd_%p-%tc.root" # default file name, can override from command line with -o or --output + dataTier: "generated" + SelectEvents: [ simulatetpc, simulatedirt ] + } +} diff --git a/sbndcode/JobConfigurations/base/prodgenie_sbnd.fcl b/sbndcode/JobConfigurations/base/prodgenie_sbnd.fcl index 6276dc511..06a3c87de 100644 --- a/sbndcode/JobConfigurations/base/prodgenie_sbnd.fcl +++ b/sbndcode/JobConfigurations/base/prodgenie_sbnd.fcl @@ -2,11 +2,11 @@ # File: prodgenie_sbnd.fcl # Purpose: Produce GENIE events in the SBND detector with spill structure # Version: 1.1 -# +# # This configuration runs event generation only -# +# # Input: no input file required -# +# # Dependencies: # - uses the bundle of SBND simulation services # @@ -65,14 +65,14 @@ physics: generator: @local::sbnd_genie_simple } - #define the producer and filter modules for this path, order matters, - simulate: [ rns, generator ] + #define the producer and filter modules for this path, order matters, + simulate: [ rns, generator ] - #define the output stream, there could be more than one if using filters + #define the output stream, there could be more than one if using filters stream1: [ out1 ] #ie analyzers and output streams. these all run simultaneously - end_paths: [stream1] + end_paths: [stream1] } # block to define where the output goes. if you defined a filter in the physics diff --git a/sbndcode/JobConfigurations/base/split_tpc_nu.fcl b/sbndcode/JobConfigurations/base/split_tpc_nu.fcl new file mode 100644 index 000000000..43bea105d --- /dev/null +++ b/sbndcode/JobConfigurations/base/split_tpc_nu.fcl @@ -0,0 +1,88 @@ +# +# File: split_tpc_nu.fcl +# Purpose: Take in pregenerated GENIE events that contain both TPC and dirt events and split +# them into two output streams based on whether they had a TPC interaction or not +# Version: 1.0 +# +# Input: File with GENIE run as generator and largeant to track energy depositions +# +# Dependencies: +# - uses the bundle of SBND simulation services +# +# + +# +# services +# + +#include "simulationservices_sbnd.fcl" +#include "messages_sbnd.fcl" + +# +# filters +# + +#include "gennufilter.fcl" + +process_name: GenieDirtOutputs + +services: +{ + TFileService: { fileName: "hists_split_tpc_nu_sbnd_%p-%tc.root" } + @table::sbnd_simulation_services # load simulation services in bulk +} + +#source is now a root file +source: +{ + module_type: RootInput + maxEvents: -1 # Number of events to create +} + +# Define and configure some modules to do work on each event. +# First modules are defined; they are scheduled later. +# Modules are grouped by type. +physics: +{ + + filters: + { + # Filter events that have an interaction in the TPC + tpcfilter: @local::sbnd_tpc_gennufilter + } + + # Note we assume that every event has already been filtered to require a tpc interaction + # or a dirt interaction previously. Therefore, anything without a tpc interaction is + # assumed to be dirt + filtertpc: [ tpcfilter ] + filterdirt: [ "!tpcfilter" ] + + # Split the outputs into those with/without TPC interactions + stream1: [ outTPC, outDirt ] + + #ie analyzers and output streams. these all run simultaneously + end_paths: [stream1] +} + +outputs: + { + # Keep only the events with a TPC neutrino + # N.B. These events will still have some random coincidence of dirt interactions + outTPC: + { + module_type: RootOutput + fileName: "tpc_%ifb_%p-%tc.root" + dataTier: "generated" + SelectEvents: [ filtertpc ] + } + + # Keep only the events that have a no TPC neutrino but a dirt interaction + outDirt: + { + module_type: RootOutput + fileName: "dirt_%ifb_%p-%tc.root" + dataTier: "generated" + SelectEvents: [ filterdirt ] + } +} + diff --git a/sbndcode/JobConfigurations/standard/g4/g4_dirt_filter.fcl b/sbndcode/JobConfigurations/standard/g4/g4_dirt_filter.fcl new file mode 100644 index 000000000..830bfd79c --- /dev/null +++ b/sbndcode/JobConfigurations/standard/g4/g4_dirt_filter.fcl @@ -0,0 +1,5 @@ +# Runs standard g4 fcl without largeant designed for use with gen stage fcls that run a largeant dirt filter + +#include "standard_g4_sbnd.fcl" + +physics.simulate: [ rns , ionandscint , ionandscintout , pdfastsim , pdfastsimout , simdrift , mcreco ] diff --git a/sbndcode/JobConfigurations/standard/g4/g4_dirt_overlay_filter.fcl b/sbndcode/JobConfigurations/standard/g4/g4_dirt_overlay_filter.fcl new file mode 100644 index 000000000..49c2badb0 --- /dev/null +++ b/sbndcode/JobConfigurations/standard/g4/g4_dirt_overlay_filter.fcl @@ -0,0 +1,29 @@ +# Runs G4 on CORSIKA and merges with the G4 instance already run on GENIE +# The remainder of standard g4 fcl is then run with minor modifications to the input labels +# The output produced drops the GENIE and CORSIKA specific G4 instances and keeps only the merged output + +#include "mergesimsources_sbnd.fcl" +#include "g4_dirt_filter.fcl" + +# Create a new instance of largeant to just look at CORSIKA +physics.producers.largeantcosmic: @local::sbnd_larg4 +physics.producers.largeantcosmic.inputCollections: [ "corsika" ] + +# Merge together the largeant instances +physics.producers.largeant: @local::sbnd_merge_overlay_sim_sources + +# We need to explicitly tell ionandscint to look at largeant otherwise it will take everything in the event and double count +physics.producers.ionandscint.InputModuleLabels: ["largeant"] +physics.producers.ionandscintout.InputModuleLabels: ["largeant"] + +physics.simulate: [ rns , loader, largeantcosmic , largeant , ionandscint , ionandscintout , pdfastsim , pdfastsimout , simdrift , mcreco ] + +outputs.out1.outputCommands: [ "keep *_*_*_*" + # Drop the SimEnergyDeposits made by LArG4 + , "drop sim::SimEnergyDeposits_largeant_*_*" + # Drop the IonAndScint w/ SCE offsets applied + , "drop *_ionandscint__*" + # Drop the GENIE and CORSIKA specific largeant instances + , "drop *_largeantnu_*_*" + , "drop *_largeantcosmic_*_*" + ] diff --git a/sbndcode/JobConfigurations/standard/g4/g4_sce_dirt_filter.fcl b/sbndcode/JobConfigurations/standard/g4/g4_sce_dirt_filter.fcl new file mode 100644 index 000000000..91b6934af --- /dev/null +++ b/sbndcode/JobConfigurations/standard/g4/g4_sce_dirt_filter.fcl @@ -0,0 +1,4 @@ +# Runs standard g4 fcl without largeant designed for use with gen stage fcls that run a largeant dirt filter with sce +#include "g4_dirt_filter.fcl" + +#include "enable_spacecharge_services_sbnd.fcl" diff --git a/sbndcode/JobConfigurations/standard/g4/g4_sce_dirt_overlay_filter.fcl b/sbndcode/JobConfigurations/standard/g4/g4_sce_dirt_overlay_filter.fcl new file mode 100644 index 000000000..4bd680d95 --- /dev/null +++ b/sbndcode/JobConfigurations/standard/g4/g4_sce_dirt_overlay_filter.fcl @@ -0,0 +1,6 @@ +# Runs G4 on CORSIKA and merges with the G4 instance already run on GENIE with sce +# The remainder of standard g4 fcl is then run with minor modifications to the input labels +# The output produced drops the GENIE and CORSIKA specific G4 instances and keeps only the merged output +#include "g4_dirt_overlay_filter.fcl" + +#include "enable_spacecharge_services_sbnd.fcl" diff --git a/sbndcode/JobConfigurations/standard/gen/genie/prodgenie_nu_spill_world_sbnd.fcl b/sbndcode/JobConfigurations/standard/gen/genie/prodgenie_nu_spill_world_sbnd.fcl index fb458bcfa..3aac3f38c 100644 --- a/sbndcode/JobConfigurations/standard/gen/genie/prodgenie_nu_spill_world_sbnd.fcl +++ b/sbndcode/JobConfigurations/standard/gen/genie/prodgenie_nu_spill_world_sbnd.fcl @@ -1,14 +1,8 @@ -# Simulates GENIE neutrino interactions from the BNB beam +# Simulates GENIE neutrino interactions from the BNB beam # with the beam spill structure, in the full world wolume. # Usually used for studyin dirt events. Uses flux files # with a larger window. #include "prodgenie_sbnd.fcl" -physics.producers.generator: { - @table::physics.producers.generator - @table::sbnd_genie_simple_dirt - EventsPerSpill: 0 - TopVolume: "volWorld" - FluxUpstreamZ: -18 #Start the flux rays at 18m upstream of the TPC frontface. Chosen as this is the distance a muon of 8 GeV (max flux sim. energy) can travel -} +physics.producers.generator: @local::sbnd_genie_simple_dirt diff --git a/sbndcode/JobConfigurations/standard/gen/genie/prodgenie_rockbox_intrnue_sbnd.fcl b/sbndcode/JobConfigurations/standard/gen/genie/prodgenie_rockbox_intrnue_sbnd.fcl new file mode 100644 index 000000000..6af7dbbc1 --- /dev/null +++ b/sbndcode/JobConfigurations/standard/gen/genie/prodgenie_rockbox_intrnue_sbnd.fcl @@ -0,0 +1,7 @@ +# Simulates GENIE nue and anue neutrino interactions from the BNB beam +# using the rockbox confiuration + +#include "prodgenie_rockbox_sbnd.fcl" + +#include "set_genie_nue.fcl" + diff --git a/sbndcode/JobConfigurations/standard/gen/overlay/prodoverlay_corsika_cosmics_proton_genie_rockbox_intrnue_sbnd.fcl b/sbndcode/JobConfigurations/standard/gen/overlay/prodoverlay_corsika_cosmics_proton_genie_rockbox_intrnue_sbnd.fcl new file mode 100644 index 000000000..26de0e687 --- /dev/null +++ b/sbndcode/JobConfigurations/standard/gen/overlay/prodoverlay_corsika_cosmics_proton_genie_rockbox_intrnue_sbnd.fcl @@ -0,0 +1,5 @@ +# Produce GENIE nue and anue rockbox interactions and overlay CORSIKA cosmics +# Note: To run G4 over CORSIKA and merge collections together you will need g4_dirt_overlay_filter.fcl +#include "overlay/prodoverlay_corsika_cosmics_proton_genie_rockbox_sbnd.fcl" + +#include "set_genie_nue.fcl" diff --git a/sbndcode/JobConfigurations/standard/gen/overlay/prodoverlay_corsika_cosmics_proton_genie_rockbox_sbnd.fcl b/sbndcode/JobConfigurations/standard/gen/overlay/prodoverlay_corsika_cosmics_proton_genie_rockbox_sbnd.fcl new file mode 100644 index 000000000..a5d82107f --- /dev/null +++ b/sbndcode/JobConfigurations/standard/gen/overlay/prodoverlay_corsika_cosmics_proton_genie_rockbox_sbnd.fcl @@ -0,0 +1,23 @@ +# Produce GENIE rockbox interactions and overlay CORSIKA cosmics +# Note: To run G4 over CORSIKA and merge collections together you will need g4_dirt_overlay_filter.fcl + +#include "mergesimsources_sbnd.fcl" +#include "corsika_sbnd.fcl" +#include "prodgenie_rockbox_sbnd.fcl" + +# Now we are generating overlays we need to add CORSIKA to GENIE +physics.producers.corsika: @local::sbnd_corsika_p + +# Remove largeant, this name is now reserved for the merged output +physics.producers.largeant: @erase + +# Create a new instance of largeant to just look at GENIE +physics.producers.largeantnu: @local::sbnd_larg4 +physics.producers.largeantnu.inputCollections: [ "generator" ] + +# Tell the dirt filter to use the new largeant for neutrinos only +physics.filters.dirtfilter.SimEnergyDepModuleName: "largeantnu:LArG4DetectorServicevolTPCActive" + +# Rename largeant and add CORSIKA to the workflows +physics.simulatetpc: [ rns, generator, loader, largeantnu, tpcfilter, corsika ] +physics.simulatedirt: [ rns, generator, loader, largeantnu, "!tpcfilter", dirtfilter, corsika ] diff --git a/sbndcode/LArG4/mergesimsources_sbnd.fcl b/sbndcode/LArG4/mergesimsources_sbnd.fcl index f9a425bf6..99f8fec5a 100644 --- a/sbndcode/LArG4/mergesimsources_sbnd.fcl +++ b/sbndcode/LArG4/mergesimsources_sbnd.fcl @@ -14,4 +14,23 @@ sbnd_merge_sim_sources : { EnergyDepositInstanceLabels: [ "priorSCE" ] } +# Save the list of volumes (instance names) in which largeant creates SimEnergyDeposits +largeant_volumes: [ "LArG4DetectorServicevolFieldCage" + , "LArG4DetectorServicevolPMT" + , "LArG4DetectorServicevolXArapuca" + , "LArG4DetectorServicevolPDSstructure" + , "LArG4DetectorServicevolTPCPlaneVert" + , "LArG4DetectorServicevolCryostat" + , "LArG4DetectorServicevolTPCActive" + ] + +# Merge seperate instances of largeant for GENIE and CORSIKA +sbnd_merge_overlay_sim_sources : { + @table::sbnd_merge_sim_sources + FillMCParticles: true + FillSimEnergyDeposits: true + InputSourcesLabels: [ "largeantnu", "largeantcosmic"] + EnergyDepositInstanceLabels: @local::largeant_volumes +} + END_PROLOG diff --git a/sbndcode/LArSoftConfigurations/gen/genie_sbnd.fcl b/sbndcode/LArSoftConfigurations/gen/genie_sbnd.fcl index 23838781e..788d4ac74 100644 --- a/sbndcode/LArSoftConfigurations/gen/genie_sbnd.fcl +++ b/sbndcode/LArSoftConfigurations/gen/genie_sbnd.fcl @@ -306,8 +306,27 @@ sbnd_genie_simple_dirt: { EventsPerSpill: 0 POTPerSpill: 5e12 MaxFluxFileMB: 100 + TopVolume: "volWorld" + #Start the flux rays at 18m upstream of the TPC frontface. Chosen as this is the distance a muon of 8 GeV (max flux sim. energy) can travel + FluxUpstreamZ: -18 } +sbnd_genie_simple_rockbox: { + @table::sbnd_genie_simple_dirt + # Use GENIE Rockbox to more efficiently simulate dirt: https://cdcvs.fnal.gov/redmine/projects/nutools/wiki/GENIEHelper_Geometry#Special-case-RockBox-FiducialCut-strings + # Define FV: -210 < x < 210, -210 < y < 210, -10 < x < 510 + # Include interactions in the FV + # Apply a 500cm buffer around the FV + # Estimate dE/dx loss in rock: 2.5*1.7e-3 (Default Value) + # Apply a fudge factor to account for the fact the detector is not up against the rock, i.e. we have gaps of lower density + FiducialCut: "rockbox:(-210,-210,-10)(210,210,510),0,500,0.00425,1.3" + # As we are changing the FV we need to recalculate the maximum path lengths + # This file was generated by running with: + # GeomScan: "flux: 10000 1.1 1" + GeomScan: "file: GENIE/sbnd_rock_maxpathlength_fluxI_gdmlv02_00.xml" +} + + sbnd_genie_simple_numi: { @table::standard_genie