diff --git a/Simulation/G4Atlas/G4AtlasTools/CMakeLists.txt b/Simulation/G4Atlas/G4AtlasTools/CMakeLists.txt index d73deb18aa3cbb9dc47d43a42b583b60ddaee4e8..5f64c270991dd9b5386fbdbe1707bc8a09d77ddf 100644 --- a/Simulation/G4Atlas/G4AtlasTools/CMakeLists.txt +++ b/Simulation/G4Atlas/G4AtlasTools/CMakeLists.txt @@ -37,6 +37,11 @@ atlas_add_component( G4AtlasTools INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${TBB_INCLUDE_DIRS} LINK_LIBRARIES ${Boost_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} ${TBB_LIBRARIES} AthenaBaseComps G4AtlasInterfaces GaudiKernel G4PhysicsLists G4AtlasToolsLib ) +atlas_add_test( G4GeometryToolConfig_test + SCRIPT test/G4GeometryToolConfig_test.py + PROPERTIES TIMEOUT 300 ) + + # Install files from the package: atlas_install_python_modules( python/*.py ) diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py b/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..3a845687a31a783ee6fff6cb5e61ed564e02439b --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py @@ -0,0 +1,310 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AtlasGeoModel.GeoModelConfig import GeoModelCfg + +from Geo2G4.Geo2G4Conf import GeoDetectorTool +from BeamPipeGeoModel.BeamPipeGMConfig import BeamPipeGeometryCfg +from G4AtlasTools.G4AtlasToolsConf import CylindricalEnvelope + +from AthenaCommon.SystemOfUnits import mm, cm, m + +#tool cfg or just cfg? +def BeamPipeGeoDetectorToolCfg(ConfigFlags, name='BeamPipe', **kwargs): + #set up geometry + result=BeamPipeGeometryCfg(ConfigFlags) + kwargs.setdefault("DetectorName", "BeamPipe") + return result, GeoDetectorTool(name, **kwargs) + +def PixelGeoDetectorToolCfg(ConfigFlags, name='Pixel', **kwargs): + #set up geometry + result=BeamPipeGeometryCfg(ConfigFlags) + kwargs.setdefault("DetectorName", "Pixel") + return result, GeoDetectorTool(name, **kwargs) + +def SCTGeoDetectorToolCfg(ConfigFlags, name='SCT', **kwargs): + #set up geometry + result=BeamPipeGeometryCfg(ConfigFlags) + kwargs.setdefault("DetectorName", "SCT") + return result, GeoDetectorTool(name, **kwargs) + +def TRTGeoDetectorToolCfg(ConfigFlags, name='TRT', **kwargs): + #set up geometry + result=BeamPipeGeometryCfg(ConfigFlags) + kwargs.setdefault("DetectorName", "TRT") + return result, GeoDetectorTool(name, **kwargs) + +def IDetServicesMatGeoDetectorToolCfg(ConfigFlags, name='IDetServicesMat', **kwargs): + #set up geometry + result=BeamPipeGeometryCfg(ConfigFlags) + kwargs.setdefault("DetectorName", "InDetServMat") + return result, GeoDetectorTool(name, **kwargs) + +def getLArMgrGeoDetectorTool(name='LArMgr', **kwargs): + kwargs.setdefault("DetectorName", "LArMgr") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getTileGeoDetectorTool(name='Tile', **kwargs): + kwargs.setdefault("DetectorName", "Tile") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getLucidGeoDetectorTool(name='Lucid', **kwargs): + kwargs.setdefault("DetectorName", "LUCID") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getALFAGeoDetectorTool(name='ALFA', **kwargs): + kwargs.setdefault("DetectorName", "ALFA") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getZDCGeoDetectorTool(name='ZDC', **kwargs): + kwargs.setdefault("DetectorName", "ZDC") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getAFPGeoDetectorTool(name='AFP', **kwargs): + kwargs.setdefault("DetectorName", "AFP") + kwargs.setdefault("GeoDetectorName", "AFP_GeoModel") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getFwdRegionGeoDetectorTool(name='FwdRegion', **kwargs): + kwargs.setdefault("DetectorName", "FwdRegion") + kwargs.setdefault("GeoDetectorName", "ForwardRegionGeoModel") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getMuonGeoDetectorTool(name='Muon', **kwargs): + kwargs.setdefault("DetectorName", "Muon") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def getCavernInfraGeoDetectorTool(name='CavernInfra', **kwargs): + kwargs.setdefault("DetectorName", "CavernInfra") + return CfgMgr.GeoDetectorTool(name, **kwargs) + +def IDETEnvelopeCfg(ConfigFlags, name="IDET", **kwargs): + result = ComponentAccumulator() + + isUpgrade = ConfigFlags.GeoModel.Run =="RUN4" + isRUN2 = ConfigFlags.GeoModel.Run in ["RUN2", "RUN3"] + isRUN1 = not (isRUN2 or isUpgrade) + + kwargs.setdefault("DetectorName", "IDET") + innerRadius = 37.*mm # RUN1 default + if isRUN2: + innerRadius = 28.9*mm #29.15*mm + if isUpgrade: + innerRadius = 32.15*mm + kwargs.setdefault("InnerRadius", innerRadius) + kwargs.setdefault("OuterRadius", 1.148*m) + kwargs.setdefault("dZ", 347.5*cm) + + SubDetectorList=[] + if ConfigFlags.Detector.GeometryPixel: + accPixel, toolPixel = PixelGeoDetectorToolCfg(ConfigFlags) + SubDetectorList += [toolPixel] + result.merge(accPixel) + if ConfigFlags.Detector.GeometrySCT: + accSCT, toolSCT = SCTGeoDetectorToolCfg(ConfigFlags) + SubDetectorList += [toolSCT] + result.merge(accSCT) + if ConfigFlags.Detector.GeometryTRT and not isUpgrade: + accTRT, toolTRT = TRTGeoDetectorToolCfg(ConfigFlags) + SubDetectorList += [toolTRT] + result.merge(accTRT) + + accIDetServices, toolIDetServices = IDetServicesMatGeoDetectorToolCfg(ConfigFlags) + SubDetectorList += [toolIDetServices] + result.merge(accIDetServices) + kwargs.setdefault("SubDetectors", SubDetectorList) + return result, CylindricalEnvelope(name, **kwargs) + +def getCALOEnvelope(name="CALO", **kwargs): + kwargs.setdefault("DetectorName", "CALO") + kwargs.setdefault("NSurfaces", 18) + kwargs.setdefault("InnerRadii", [41.,41.,41.,41.,41.,41.,120.,120.,1148.,1148.,120.,120.,41.,41.,41.,41.,41.,41.]) #FIXME Units? + kwargs.setdefault("OuterRadii", [415.,415,3795.,3795.,4251.,4251.,4251.,4251.,4251.,4251.,4251.,4251.,4251.,4251.,3795.,3795.,415.,415.]) #FIXME Units? + kwargs.setdefault("ZSurfaces", [-6781.,-6735.,-6735.,-6530.,-6530.,-4587.,-4587.,-3475.,-3475.,3475.,3475.,4587.,4587.,6530.,6530.,6735.,6735.,6781.]) #FIXME Units? + SubDetectorList=[] + from AthenaCommon.DetFlags import DetFlags + if DetFlags.geometry.LAr_on(): + SubDetectorList += ['LArMgr'] + if DetFlags.geometry.Tile_on(): + SubDetectorList += ['Tile'] + kwargs.setdefault("SubDetectors", SubDetectorList) + return CfgMgr.PolyconicalEnvelope(name, **kwargs) + +def getForwardRegionEnvelope(name='ForwardRegion', **kwargs): + kwargs.setdefault("DetectorName", "ForDetEnvelope") + SubDetectorList=[] + from AthenaCommon.DetFlags import DetFlags + if DetFlags.geometry.FwdRegion_on(): + SubDetectorList += ['FwdRegion'] + # FIXME Temporary solution - looking for a better place to add this one. + from AthenaCommon.CfgGetter import getPublicTool + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += getPublicTool("ForwardRegionProperties") + if DetFlags.geometry.ZDC_on(): + SubDetectorList += ['ZDC'] + if DetFlags.geometry.ALFA_on(): + SubDetectorList += ['ALFA'] + if DetFlags.geometry.AFP_on(): + SubDetectorList += ['AFP'] + kwargs.setdefault("SubDetectors", SubDetectorList) + return CfgMgr.GeoDetectorTool(name, **kwargs) ##FIXME Should this really be a GeoDetectorTool??? + +def getMUONEnvelope(name="MUONQ02", **kwargs): #FIXME rename to MUON when safe + kwargs.setdefault("DetectorName", "MUONQ02") #FIXME rename to MUON when safe + kwargs.setdefault("NSurfaces", 34) + kwargs.setdefault("InnerRadii", [1050.,1050.,1050.,1050.,436.7,436.7,279.,279.,70.,70.,420.,420.,3800.,3800.,4255.,4255.,4255.,4255.,4255.,4255.,3800.,3800.,420.,420.,70.,70.,279.,279.,436.7,436.7,1050.,1050.,1050.,1050.]) #FIXME Units? + kwargs.setdefault("OuterRadii", [1500.,1500.,2750.,2750.,12650.,12650.,13400.,13400.,14200.,14200.,14200.,14200.,14200.,14200.,14200.,14200.,13000.,13000.,14200.,14200.,14200.,14200.,14200.,14200.,14200.,14200.,13400.,13400.,12650.,12650.,2750.,2750.,1500.,1500.]) #FIXME Units? + kwargs.setdefault("ZSurfaces", [-26046.,-23001.,-23001.,-22030.,-22030.,-18650.,-18650.,-12900.,-12900.,-6783.,-6783.,-6736.,-6736.,-6550.,-6550.,-4000.,-4000.,4000.,4000.,6550.,6550.,6736.,6736.,6783.,6783.,12900.,12900.,18650.,18650.,22030.,22030.,23001.,23001.,26046.]) #FIXME Units? + SubDetectorList=[] + from AthenaCommon.DetFlags import DetFlags + if DetFlags.geometry.Muon_on(): + SubDetectorList += ['Muon'] + kwargs.setdefault("SubDetectors", SubDetectorList) + return CfgMgr.PolyconicalEnvelope(name, **kwargs) + +def getCosmicShortCut(name="CosmicShortCut", **kwargs): + kwargs.setdefault("DetectorName", "TTR_BARREL") + kwargs.setdefault("NSurfaces", 14) + kwargs.setdefault("InnerRadii", [70.,70.,12500.,12500.,12500.,12500.,13000.,13000.,12500.,12500.,12500.,12500.,70.,70.]) #FIXME Units? + kwargs.setdefault("OuterRadii", [12501.,12501.,12501.,12501.,13001.,13001.,13001.,13001.,13001.,13001.,12501.,12501.,12501.,12501.]) #FIXME Units? + kwargs.setdefault("ZSurfaces", [-22031.,-22030.,-22030.,-12901.,-12901.,-12900.,-12900., 12900.,12900.,12901.,12901.,22030.,22030.,22031.]) #FIXME Units? + SubDetectorList=[] + kwargs.setdefault("SubDetectors", SubDetectorList) + return CfgMgr.PolyconicalEnvelope(name, **kwargs) + +def generateSubDetectorList(): + SubDetectorList=[] + from G4AtlasApps.SimFlags import simFlags + from AthenaCommon.BeamFlags import jobproperties + if jobproperties.Beam.beamType() == 'cosmics' or \ + (simFlags.CavernBG.statusOn and not 'Signal' in simFlags.CavernBG.get_Value() ): + if jobproperties.Beam.beamType() == 'cosmics' and hasattr(simFlags, "ReadTR"): + SubDetectorList += ['CosmicShortCut'] + from AthenaCommon.DetFlags import DetFlags + if DetFlags.Muon_on(): + SubDetectorList += ['MUONQ02'] #FIXME rename to MUON when safe + if DetFlags.ID_on(): + SubDetectorList += ['IDET'] + if DetFlags.Calo_on(): + SubDetectorList += ['CALO'] + if DetFlags.ID_on(): #HACK + if DetFlags.bpipe_on(): #HACK + SubDetectorList += ['BeamPipe'] #HACK + if DetFlags.geometry.Lucid_on(): + SubDetectorList += ['Lucid'] + if simFlags.ForwardDetectors.statusOn: + SubDetectorList += ['ForwardRegion'] + #if DetFlags.Muon_on(): #HACK + # SubDetectorList += ['MUONQ02'] #FIXME rename to MUON when safe #HACK + #SubDetectorList += generateFwdSubDetectorList() #FIXME Fwd Detectors not supported yet. + return SubDetectorList + +def getATLAS(name="Atlas", **kwargs): + kwargs.setdefault("DetectorName", "Atlas") + kwargs.setdefault("NSurfaces", 18) + from G4AtlasApps.SimFlags import simFlags + from AthenaCommon.BeamFlags import jobproperties + from AthenaCommon.DetFlags import DetFlags + ## InnerRadii + innerRadii = [0.0] * 18 + kwargs.setdefault("InnerRadii", innerRadii) + + ## Shrink the global ATLAS envelope to the activated detectors, + ## except when running on special setups. + + ## OuterRadii + AtlasForwardOuterR = 2751. + AtlasOuterR1 = 14201. + AtlasOuterR2 = 14201. + AtlasOuterR3 = 1501. + if jobproperties.Beam.beamType() != 'cosmics' and not DetFlags.Muon_on() and not \ + (simFlags.CavernBG.statusOn and not 'Signal' in simFlags.CavernBG.get_Value() ): + AtlasOuterR1 = 4251. + AtlasOuterR2 = 4251. + if not DetFlags.Calo_on(): + AtlasOuterR1 = 1150. + AtlasOuterR2 = 1150. + + outerRadii = [0.0] * 18 + for i in (0, 1, 16, 17): + outerRadii[i] = 1501. + for i in (2, 3, 14, 15): + outerRadii[i] = AtlasForwardOuterR + for i in (4, 5, 12, 13): + outerRadii[i] = AtlasOuterR2 + for i in xrange(6, 12): + outerRadii[i] = AtlasOuterR1 + + ## World R range + if simFlags.WorldRRange.statusOn: + if simFlags.WorldRRange.get_Value() > max(AtlasOuterR1, AtlasOuterR2): + routValue = simFlags.WorldRRange.get_Value() + for i in xrange(4, 14): + outerRadii[i] = routValue + else: + raise RuntimeError('getATLASEnvelope: ERROR simFlags.WorldRRange must be > %f. Current value %f' % max(AtlasOuterR1, AtlasOuterR2), routValue) + kwargs.setdefault("OuterRadii", outerRadii) + + ## ZSurfaces + zSurfaces = [-26046., -23001., -23001., -22031., -22031., -12899., -12899., -6741., -6741., 6741., 6741., 12899., 12899., 22031., 22031., 23001., 23001., 26046.] # FIXME units mm?? + + if simFlags.ForwardDetectors.statusOn: + zSurfaces[0] = -400000. + zSurfaces[17] = 400000. + + if simFlags.WorldZRange.statusOn: + if simFlags.WorldZRange.get_Value() < 26046.: + AtlasG4Eng.G4Eng.log.error('') + raise RuntimeError('getATLASEnvelope: ERROR simFlags.WorldZRange must be > 26046. Current value: %f' % simFlags.WorldZRange.get_Value()) + zSurfaces[17] = simFlags.WorldZRange.get_Value() + 100. + zSurfaces[16] = simFlags.WorldZRange.get_Value() + 50. + zSurfaces[15] = simFlags.WorldZRange.get_Value() + 50. + zSurfaces[14] = simFlags.WorldZRange.get_Value() + zSurfaces[13] = simFlags.WorldZRange.get_Value() + zSurfaces[0] = -simFlags.WorldZRange.get_Value() - 100. + zSurfaces[1] = -simFlags.WorldZRange.get_Value() - 50. + zSurfaces[2] = -simFlags.WorldZRange.get_Value() - 50. + zSurfaces[3] = -simFlags.WorldZRange.get_Value() + zSurfaces[4] = -simFlags.WorldZRange.get_Value() + kwargs.setdefault("ZSurfaces", zSurfaces) + kwargs.setdefault("SubDetectors", generateSubDetectorList()) + return CfgMgr.PolyconicalEnvelope(name, **kwargs) + +def getCavernWorld(name="Cavern", **kwargs): + kwargs.setdefault("DetectorName", "World") + bedrockDX = 302700 + bedrockDZ = 301000 + from G4AtlasApps.SimFlags import simFlags + if not (hasattr(simFlags,'CavernBG') and simFlags.CavernBG.statusOn ): + ## Be ready to resize bedrock if the cosmic generator needs more space + if simFlags.ISFRun: + # for ISF cosmics simulation, set world volume to biggest possible case + bedrockDX = 1000.*3000 # 3 km + bedrockDZ = 1000.*3000 # 3 km + else: + from CosmicGenerator.CosmicGeneratorConfig import CavernPropertyCalculator + theCavernProperties = CavernPropertyCalculator() + if theCavernProperties.BedrockDX() > bedrockDX: + bedrockDX = theCavernProperties.BedrockDX() + if theCavernProperties.BedrockDZ() > bedrockDZ: + bedrockDZ = theCavernProperties.BedrockDZ() + kwargs.setdefault("dX", bedrockDX) #FIXME Units? + kwargs.setdefault("dY", 57300 + 41000 + 1000) # 1 extra metre to help voxelization... #FIXME Units? + kwargs.setdefault("dZ", bedrockDZ) #FIXME Units? + # Subtraction Solid - has to be a better way to do this!! + kwargs.setdefault("NumberOfHoles", 1) + kwargs.setdefault("HoleNames", ['BelowCavern']) + kwargs.setdefault("Hole_dX", [bedrockDX]); + kwargs.setdefault("Hole_dY", [41000]); + kwargs.setdefault("Hole_dZ", [bedrockDZ]); + kwargs.setdefault("HolePosX", [0]); + kwargs.setdefault("HolePosY", [-58300]); + kwargs.setdefault("HolePosZ", [0]); + kwargs.setdefault("SubDetectors", ['CavernInfra', 'Atlas']) + return CfgMgr.BoxEnvelope(name, **kwargs) + +def getG4AtlasDetectorConstructionTool(name="G4AtlasDetectorConstructionTool", **kwargs): + return CfgMgr.G4AtlasDetectorConstructionTool(name, **kwargs) + +def getMaterialDescriptionTool(name="MaterialDescriptionTool", **kwargs): + ## kwargs.setdefault("SomeProperty", aValue) + return CfgMgr.MaterialDescriptionTool(name, **kwargs) \ No newline at end of file diff --git a/Simulation/G4Atlas/G4AtlasTools/test/G4GeometryToolConfig_test.py b/Simulation/G4Atlas/G4AtlasTools/test/G4GeometryToolConfig_test.py new file mode 100755 index 0000000000000000000000000000000000000000..5fb7e6e9ec3addc5b0be6e8351c72e360f6e0d3c --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/test/G4GeometryToolConfig_test.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +"""Run tests on G4Geometry Tool configuration + +Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +""" +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator + + +if __name__ == '__main__': + from AthenaConfiguration.MainServicesConfig import MainServicesSerialCfg + import os + + # Set up logging and config behaviour + from AthenaCommon.Logging import log + from AthenaCommon.Constants import DEBUG + from AthenaCommon.Configurable import Configurable + log.setLevel(DEBUG) + Configurable.configurableRun3Behavior = 1 + + + #import config flags + from AthenaConfiguration.AllConfigFlags import ConfigFlags + + from AthenaConfiguration.TestDefaults import defaultTestFiles + inputDir = defaultTestFiles.d + ConfigFlags.Input.Files = defaultTestFiles.EVNT + + ConfigFlags.Detector.GeometryPixel = True + ConfigFlags.Detector.GeometrySCT = True + ConfigFlags.Detector.GeometryTRT = True + + # Finalize + ConfigFlags.lock() + + + from G4AtlasTools.G4GeometryToolConfig import BeamPipeGeoDetectorToolCfg + from G4AtlasTools.G4GeometryToolConfig import PixelGeoDetectorToolCfg + from G4AtlasTools.G4GeometryToolConfig import SCTGeoDetectorToolCfg + from G4AtlasTools.G4GeometryToolConfig import TRTGeoDetectorToolCfg + from G4AtlasTools.G4GeometryToolConfig import IDETEnvelopeCfg + + ## Initialize a new component accumulator + cfg = ComponentAccumulator() + + acc, tool = BeamPipeGeoDetectorToolCfg(ConfigFlags) + cfg.merge(acc) + cfg.addPublicTool(tool) + + acc1, tool1 = PixelGeoDetectorToolCfg(ConfigFlags) + cfg.merge(acc1) + cfg.addPublicTool(tool1) + + acc2, tool2 = SCTGeoDetectorToolCfg(ConfigFlags) + cfg.merge(acc2) + cfg.addPublicTool(tool2) + + acc3, tool3 = TRTGeoDetectorToolCfg(ConfigFlags) + cfg.merge(acc3) + cfg.addPublicTool(tool3) + + acc4, tool4 = IDETEnvelopeCfg(ConfigFlags) + cfg.merge(acc4) + cfg.addPublicTool(tool4) + + cfg.printConfig(withDetails=True, summariseProps = True) + ConfigFlags.dump() + + f=open("test.pkl","w") + cfg.store(f) + f.close() + + + + print cfg._publicTools + print "-----------------finished----------------------"