diff --git a/Generators/FaserCosmicGenerator/CMakeLists.txt b/Generators/FaserCosmicGenerator/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5bea0687466c0e7a4d51398e3fc9ed718215a6c6 --- /dev/null +++ b/Generators/FaserCosmicGenerator/CMakeLists.txt @@ -0,0 +1,10 @@ +################################################################################ +# Package: FaserCosmicGenerator +################################################################################ + +# Declare the package name: +atlas_subdir( FaserCosmicGenerator ) + +# Install files from the package: +atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} ) + diff --git a/Generators/FaserCosmicGenerator/README.md b/Generators/FaserCosmicGenerator/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4a1e19c73dbd391e77de2b05907fa5778b006165 --- /dev/null +++ b/Generators/FaserCosmicGenerator/README.md @@ -0,0 +1,3 @@ +Faser cosmic-ray generator + +Documentation goes here... \ No newline at end of file diff --git a/Generators/FaserCosmicGenerator/python/__init__.py b/Generators/FaserCosmicGenerator/python/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..42ea59fd7bebf56ad3497e2c7352f475aaba0950 --- /dev/null +++ b/Generators/FaserCosmicGenerator/python/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2021 CERN for the benefit of the FASER collaboration + +from FaserCosmicGenerator.cosmicSampler import CosmicSampler + diff --git a/Generators/FaserCosmicGenerator/python/cosmicSampler.py b/Generators/FaserCosmicGenerator/python/cosmicSampler.py new file mode 100644 index 0000000000000000000000000000000000000000..4dca1fed08bdd7321d9bba772677af9af7b5bfa2 --- /dev/null +++ b/Generators/FaserCosmicGenerator/python/cosmicSampler.py @@ -0,0 +1,47 @@ +# Copyright (C) 2021 CERN for the benefit of the FASER collaboration + +import ROOT,math,random + +PI = math.pi +TWOPI = 2*math.pi + +from ParticleGun.samplers import Sampler, SampledParticle + +class CosmicSampler(Sampler): + "Cosmic ray sampler" + + def __init__(self, maxMuonEnergyGeV = 10000, targetDepthMeters = 85, targetRadiusMm = 3000, thetaMinDegree = 0, thetaMaxDegree = 80): + if thetaMinDegree > thetaMaxDegree : + return RuntimeError("thetaMin must be less than or equal to thetaMax") + + self.maxEnergy = maxMuonEnergyGeV + self.depth = targetDepthMeters + self.radiusMm = targetRadiusMm # used for generating start position + self.radiusCm = self.radiusMm/10 # used for calculating rates + self.cosThMax = math.cos(thetaMinDegree*PI/180) + self.cosThMin = math.cos(thetaMaxDegree*PI/180) + # read range data + # compute rate + + def shoot(self): + # generate one event here + self.genPosition = ROOT.TLorentzVector() + self.genMomentum = ROOT.TLorentzVector() + + # placeholders to test class structure - should create a vertically down 1 TeV mu- starting above the detector + self.genPosition.SetY(self.radiusMm) + self.genMomentum.SetPxPyPzE(0,-math.sqrt((1.0e6)**2-(105.71)**2),0,1.0e6) + self.pdgCode = 13 + # end placeholders + + particles = [] + p = SampledParticle(self.pdgCode) + p.mom = self.genMomentum + p.pos = self.genPosition + particles.append(p) + return particles + + def __call__(self): + return self.shoot() + + diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py b/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py new file mode 100644 index 0000000000000000000000000000000000000000..ad04571192f49a3500e5de4eca60b3a2e12019f5 --- /dev/null +++ b/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +if __name__ == "__main__": + import os + import sys + import GaudiPython + import ParticleGun as PG + from FaserCosmicGenerator import CosmicSampler + from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator + from AthenaConfiguration.ComponentFactory import CompFactory + from AthenaCommon.AppMgr import * + from AthenaCommon.Logging import log, logging + from AthenaCommon.SystemOfUnits import TeV + from AthenaCommon.PhysicalConstants import pi + from AthenaCommon.Constants import VERBOSE, INFO + from AthenaCommon.Configurable import Configurable + from CalypsoConfiguration.AllConfigFlags import ConfigFlags + from CalypsoConfiguration.MainServicesConfig import MainServicesCfg + from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg + from McEventSelector.McEventSelectorConfig import McEventSelectorCfg + from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg + from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg + from G4FaserAlg.G4FaserAlgConfigNew import G4FaserAlgCfg + from G4FaserServices.G4FaserServicesConfigNew import G4GeometryNotifierSvcCfg +# +# Set up logging and new style config +# + log.setLevel(VERBOSE) + Configurable.configurableRun3Behavior = True +# +# Input settings (Generator file) +# +# from AthenaConfiguration.TestDefaults import defaultTestFiles +# ConfigFlags.Input.Files = defaultTestFiles.EVNT +# +# Alternatively, these must ALL be explicitly set to run without an input file +# (if missing, it will try to read metadata from a non-existent file and crash) +# + ConfigFlags.Input.Files = [""] + ConfigFlags.Input.isMC = True + ConfigFlags.Input.RunNumber = 12345 + ConfigFlags.Input.Collections = [""] + ConfigFlags.Input.ProjectName = "mc19" + ConfigFlags.Common.isOnline = False + ConfigFlags.Beam.Type = "collisions" + ConfigFlags.Beam.Energy = 7*TeV # Informational, does not affect simulation + ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Always needed + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Always needed; only the OFLCOND part matters +# Workaround for bug/missing flag; unimportant otherwise + ConfigFlags.addFlag("Input.InitialTimeStamp", 0) +# Workaround to avoid problematic ISF code + ConfigFlags.GeoModel.Layout = "Development" +# +# Output settings +# + ConfigFlags.Output.HITSFileName = "cosmics.HITS.pool.root" + ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light +# +# Geometry-related settings +# Do not change! +# + ConfigFlags.Detector.SimulateVeto = True + ConfigFlags.Detector.GeometryVeto = True + ConfigFlags.Detector.SimulateTrigger= True + ConfigFlags.Detector.GeometryTrigger= True + ConfigFlags.Detector.SimulatePreshower = True + ConfigFlags.Detector.GeometryPreshower = True + ConfigFlags.Detector.SimulateFaserSCT = True + ConfigFlags.Detector.GeometryFaserSCT = True + ConfigFlags.Detector.SimulateUpstreamDipole = True + ConfigFlags.Detector.SimulateCentralDipole = True + ConfigFlags.Detector.SimulateDownstreamDipole = True + ConfigFlags.Detector.GeometryUpstreamDipole = True + ConfigFlags.Detector.GeometryCentralDipole = True + ConfigFlags.Detector.GeometryDownstreamDipole = True + ConfigFlags.GeoModel.Align.Dynamic = False + ConfigFlags.Sim.ReleaseGeoModel = False +# +# All flags should be set before calling lock +# + ConfigFlags.lock() +# +# Construct ComponentAccumulator +# + acc = MainServicesCfg(ConfigFlags) +# +# Particle Gun generator (comment out to read generator file) +# Raw energies (without units given) are interpreted as MeV +# + pg = PG.ParticleGun() + pg.McEventKey = "GEN_EVENT" + pg.randomSeed = 123456 + + pg.sampler = CosmicSampler() + acc.addEventAlgo(pg, "AthBeginSeq") # to run *before* G4 +# +# Only one of these two should be used in a given job +# (MCEventSelectorCfg for generating events with no input file, +# PoolReadCfg when reading generator data from an input file) +# + acc.merge(McEventSelectorCfg(ConfigFlags)) + # acc.merge(PoolReadCfg(ConfigFlags)) +# +# Output stream configuration +# + acc.merge(OutputStreamCfg(ConfigFlags, + "HITS", + ["EventInfo#*", + "McEventCollection#TruthEvent", + "McEventCollection#GEN_EVENT", + "ScintHitCollection#*", + "FaserSiHitCollection#*" + ], disableEventTag=True)) + acc.getEventAlgo("OutputStreamHITS").AcceptAlgs = ["G4FaserAlg"] # optional + acc.getEventAlgo("OutputStreamHITS").WritingTool.ProcessingTag = "StreamHITS" # required +# +# Here is the configuration of the Geant4 pieces +# + acc.merge(FaserGeometryCfg(ConfigFlags)) + acc.merge(G4FaserAlgCfg(ConfigFlags)) + acc.addService(G4GeometryNotifierSvcCfg(ConfigFlags, ActivateLVNotifier=True)) +# +# Verbosity +# +# ConfigFlags.dump() +# logging.getLogger('forcomps').setLevel(VERBOSE) +# acc.foreach_component("*").OutputLevel = VERBOSE +# acc.foreach_component("*ClassID*").OutputLevel = INFO +# acc.getService("StoreGateSvc").Dump=True +# acc.getService("ConditionStore").Dump=True +# acc.printConfig() + f=open('FaserG4AppCfg_EVNT.pkl','wb') + acc.store(f) + f.close() +# +# Execute and finish +# + sys.exit(int(acc.run(maxEvents=500).isFailure()))