From 13c1123e525cf7093734b511997e3fd5fd1688d0 Mon Sep 17 00:00:00 2001 From: John Derek Chapman <chapman@hep.phy.cam.ac.uk> Date: Tue, 29 Nov 2016 22:15:46 +0100 Subject: [PATCH] src/DetectorGeometryBase.cxx (SetRotationAndOffset): ensure that additional translations are added to any existing ones rather than overwriting them. ATLASSIM-3001. Tagging: G4AtlasTools-00-02-23-02 (G4AtlasTools-00-02-23-02) 2016-11-29 John Chapman <John.Chapman@cern.ch> * Tagging: G4AtlasTools-00-02-23-02 * Branch for Muon Envelope updates in 20.3.X-VAL. * Tagging: G4AtlasTools-00-02-23-01 2016-06-17 John Chapman <John.Chapman@cern.ch> add hook for HGTDSensorSD. ATLASSIM-2789. * Tagging: G4AtlasTools-00-02-23 2016-06-16 Zach Marshall <ZLMarshall@lbl.gov> * Adding more overrides to fix a bunch more clang warnings * Tagging: G4AtlasTools-00-02-22 2016-06-08 Zach Marshall <ZLMarshall@lbl.gov> * TightMuonSteppingFieldManager: Had min and max upside down * Tagging: G4AtlasTools-00-02-21 2016-06-04 Zach Marshall <ZLMarshall@lbl.gov> ... (Long ChangeLog diff - truncated) --- .../G4AtlasTools/DetectorFieldManagerTool.h | 3 + .../G4AtlasTools/G4AtlasTools/EnvelopeTool.h | 2 +- .../G4AtlasTools/FastSimulationBase.h | 2 +- .../G4AtlasTools/GlobalFieldManagerTool.h | 7 +++ .../G4AtlasTools/SensitiveDetectorBase.h | 2 +- .../G4AtlasTools/UserActionBase.h | 4 +- .../G4AtlasTools/python/G4AtlasToolsConfig.py | 5 +- .../python/G4AtlasToolsConfigDb.py | 2 + .../G4AtlasTools/python/G4FieldConfig.py | 23 +++++++- .../src/DetectorFieldManagerTool.cxx | 12 +++- .../G4AtlasTools/src/DetectorGeometryBase.cxx | 4 +- .../src/FastSimulationMasterTool.h | 2 +- .../src/GlobalFieldManagerTool.cxx | 28 ++++++++- .../src/SensitiveDetectorMasterTool.h | 2 +- .../src/TightMuonElseNoFieldManager.cxx | 38 ++++++++++++ .../src/TightMuonElseNoFieldManager.h | 44 ++++++++++++++ .../src/TightMuonSteppingFieldManager.cxx | 59 +++++++++++++++++++ .../src/TightMuonSteppingFieldManager.h | 48 +++++++++++++++ 18 files changed, 274 insertions(+), 13 deletions(-) create mode 100644 Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.cxx create mode 100644 Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.h create mode 100644 Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.cxx create mode 100644 Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.h diff --git a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/DetectorFieldManagerTool.h b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/DetectorFieldManagerTool.h index b3cc044d959..8fe96097edd 100644 --- a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/DetectorFieldManagerTool.h +++ b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/DetectorFieldManagerTool.h @@ -39,6 +39,9 @@ class DetectorFieldManagerTool : public G4FieldManagerToolBase /// List of volumes to assign this field configuration to std::vector<std::string> m_volumeList; + /// Option for muons feeling the B-field only + bool m_muonOnlyField; + /// My field manager thread_utils::ThreadLocalOwner<G4FieldManager> m_fieldMgrHolder; diff --git a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/EnvelopeTool.h b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/EnvelopeTool.h index 3a7d39bebbe..6af348c0c96 100644 --- a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/EnvelopeTool.h +++ b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/EnvelopeTool.h @@ -27,7 +27,7 @@ public: /** virtual methods being implemented here */ - virtual void BuildGeometry(); + virtual void BuildGeometry() override; private: ServiceHandle<IEnvelopeDefSvc> m_envelopeDefSvc; diff --git a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/FastSimulationBase.h b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/FastSimulationBase.h index 8f995eae457..9e038bcc22a 100644 --- a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/FastSimulationBase.h +++ b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/FastSimulationBase.h @@ -36,7 +36,7 @@ class FastSimulationBase : virtual public IFastSimulation, public AthAlgTool { virtual StatusCode EndOfAthenaEvent() override { return StatusCode::SUCCESS; } /** Query interface method to make athena happy */ - virtual StatusCode queryInterface(const InterfaceID&, void**); + virtual StatusCode queryInterface(const InterfaceID&, void**) override; protected: /// Retrieve the current Fast Simulation Model. In hive, this means the diff --git a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/GlobalFieldManagerTool.h b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/GlobalFieldManagerTool.h index 7e79134ae07..c9b35c66a7f 100644 --- a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/GlobalFieldManagerTool.h +++ b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/GlobalFieldManagerTool.h @@ -7,6 +7,7 @@ // Local includes #include "G4AtlasTools/G4FieldManagerToolBase.h" +#include "G4AtlasTools/ThreadLocalHolder.h" /** @class GlobalFieldManagerTool GlobalFieldManagerTool.h "G4AtlasTools/GlobalFieldManagerTool.h" @@ -33,6 +34,12 @@ class GlobalFieldManagerTool : public G4FieldManagerToolBase protected: + /// Tight muon stepping parameters via the field manager's configure for track + bool m_useTightMuonStepping; + + /// My field manager -- populated only in the case that we use tight muon stepping + thread_utils::ThreadLocalOwner<G4FieldManager> m_fieldMgrHolder; + }; #endif // G4ATLASTOOLS_GlobalFieldManagerTool_H diff --git a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/SensitiveDetectorBase.h b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/SensitiveDetectorBase.h index 8078ad466b8..6d5502f9c87 100644 --- a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/SensitiveDetectorBase.h +++ b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/SensitiveDetectorBase.h @@ -66,7 +66,7 @@ class SensitiveDetectorBase : virtual public ISensitiveDetector, public AthAlgTo virtual StatusCode Gather() override { return StatusCode::SUCCESS; } /** Query interface method to make athena happy */ - virtual StatusCode queryInterface(const InterfaceID&, void**); + virtual StatusCode queryInterface(const InterfaceID&, void**) override; protected: diff --git a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/UserActionBase.h b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/UserActionBase.h index 3a2ba5d35b3..20effbe2735 100644 --- a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/UserActionBase.h +++ b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/UserActionBase.h @@ -47,9 +47,9 @@ class UserActionBase : virtual public IUserAction , public AthAlgTool { virtual std::vector<std::string > GetRegions() override final {return m_regions;}; - virtual StatusCode queryInterface(const InterfaceID&, void**); + virtual StatusCode queryInterface(const InterfaceID&, void**) override; - virtual void setManagers(G4EventManager* em, G4TrackingManager* tm, G4StackManager* stam, G4SteppingManager* stem){ + virtual void setManagers(G4EventManager* em, G4TrackingManager* tm, G4StackManager* stam, G4SteppingManager* stem) override final { m_fpEventManager=em; m_stackManager=stam; m_fpSteppingManager=stem; diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py index 48873fecc93..90053594f8d 100644 --- a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py +++ b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py @@ -98,7 +98,8 @@ def generateCaloSensitiveDetectorList(): 'LArHECSensitiveDetector','LArMiniFCALSensitiveDetector'] if hasattr(DetFlags.simulate, 'HGTD_on') and DetFlags.simulate.HGTD_on(): SensitiveDetectorList += [ 'HGTDSensorSD' ] - SensitiveDetectorList += [ 'MinBiasScintillatorSD' ] + else: + SensitiveDetectorList += [ 'MinBiasScintillatorSD' ] from G4AtlasApps.SimFlags import simFlags if simFlags.CalibrationRun.get_Value() in ['LAr', 'LAr+Tile']: SensitiveDetectorList += [ 'LArDeadSensitiveDetector','LArInactiveSensitiveDetector','LArActiveSensitiveDetector' ] @@ -204,6 +205,8 @@ def getEmptySensitiveDetectorMasterTool(name="EmptySensitiveDetectorMasterTool", def getPhysicsListToolBase(name="PhysicsListToolBase", **kwargs): PhysOptionList = ["G4StepLimitationTool"] + from G4AtlasApps.SimFlags import simFlags + PhysOptionList += simFlags.PhysicsOptions.get_Value() PhysDecaysList = [] from AthenaCommon.DetFlags import DetFlags if DetFlags.simulate.TRT_on(): diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigDb.py b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigDb.py index 5f15cb0097b..211a22477f3 100644 --- a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigDb.py +++ b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfigDb.py @@ -63,9 +63,11 @@ addTool("G4AtlasTools.G4PhysicsRegionConfig.getCavernShaftsConcretePhysicsRegion addTool("G4AtlasTools.G4PhysicsRegionConfig.getSCTSiliconPhysicsRegionTool", 'SCTSiliconPhysicsRegionTool') addTool("G4AtlasTools.G4FieldConfig.getATLASFieldManagerTool", 'ATLASFieldManager') +addTool("G4AtlasTools.G4FieldConfig.getTightMuonsATLASFieldManagerTool", 'TightMuonsATLASFieldManager') addTool("G4AtlasTools.G4FieldConfig.getClassicFieldManagerTool", 'ClassicFieldManager') addTool("G4AtlasTools.G4FieldConfig.getBeamPipeFieldManagerTool", 'BeamPipeFieldManager') addTool("G4AtlasTools.G4FieldConfig.getInDetFieldManagerTool", 'InDetFieldManager') +addTool("G4AtlasTools.G4FieldConfig.getMuonsOnlyInCaloFieldManagerTool", 'MuonsOnlyInCaloFieldManager') addTool("G4AtlasTools.G4FieldConfig.getMuonFieldManagerTool", 'MuonFieldManager') addTool("G4AtlasTools.G4FieldConfig.getQ1FwdFieldMangerTool", 'Q1FwdFieldManager') addTool("G4AtlasTools.G4FieldConfig.getQ2FwdFieldMangerTool", 'Q2FwdFieldManager') diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4FieldConfig.py b/Simulation/G4Atlas/G4AtlasTools/python/G4FieldConfig.py index 0a3f48cf284..f532d1f40e1 100644 --- a/Simulation/G4Atlas/G4AtlasTools/python/G4FieldConfig.py +++ b/Simulation/G4Atlas/G4AtlasTools/python/G4FieldConfig.py @@ -7,6 +7,16 @@ def getATLASFieldManagerTool(name='ATLASFieldManager', **kwargs): from G4AtlasApps.SimFlags import simFlags kwargs.setdefault("IntegratorStepper", simFlags.G4Stepper.get_Value()) kwargs.setdefault("FieldSvc", "StandardField") + kwargs.setdefault("UseTightMuonStepping", False) + if simFlags.EquationOfMotion.statusOn: + kwargs.setdefault("EquationOfMotion", simFlags.EquationOfMotion.get_Value() ) + return CfgMgr.GlobalFieldManagerTool(name, **kwargs) + +def getTightMuonsATLASFieldManagerTool(name='TightMuonsATLASFieldManager', **kwargs): + from G4AtlasApps.SimFlags import simFlags + kwargs.setdefault("IntegratorStepper", simFlags.G4Stepper.get_Value()) + kwargs.setdefault("FieldSvc", "StandardField") + kwargs.setdefault("UseTightMuonStepping",True) if simFlags.EquationOfMotion.statusOn: kwargs.setdefault("EquationOfMotion", simFlags.EquationOfMotion.get_Value() ) return CfgMgr.GlobalFieldManagerTool(name, **kwargs) @@ -18,7 +28,8 @@ def getClassicFieldManagerTool(name='ClassicFieldManager', **kwargs): def getBasicDetectorFieldManagerTool(name='BasicDetectorFieldManager', **kwargs): from G4AtlasApps.SimFlags import simFlags kwargs.setdefault("IntegratorStepper", simFlags.G4Stepper.get_Value()) - kwargs.setdefault("FieldSvc", "StandardField") + kwargs.setdefault("FieldSvc", "StandardField") + kwargs.setdefault('MuonOnlyField', False) if simFlags.EquationOfMotion.statusOn: kwargs.setdefault("EquationOfMotion", simFlags.EquationOfMotion.get_Value() ) return CfgMgr.DetectorFieldManagerTool(name, **kwargs) @@ -41,6 +52,16 @@ def getInDetFieldManagerTool(name='InDetFieldManager', **kwargs): kwargs.setdefault('MinimumEpsilonStep', 0.00001) return getBasicDetectorFieldManagerTool(name, **kwargs) +def getMuonsOnlyInCaloFieldManagerTool(name='MuonsOnlyInCaloFieldManager', **kwargs): + kwargs.setdefault("LogicalVolumes", ['CALO::CALO']) + #kwargs.setdefault('DeltaChord', 0.00000002) + kwargs.setdefault('DeltaIntersection', 0.00000002) + kwargs.setdefault('DeltaOneStep', 0.000001) + kwargs.setdefault('MaximumEpsilonStep', 0.0000009) + kwargs.setdefault('MinimumEpsilonStep', 0.000001) + kwargs.setdefault('MuonOnlyField', True) + return getBasicDetectorFieldManagerTool(name, **kwargs) + def getMuonFieldManagerTool(name='MuonFieldManager', **kwargs): kwargs.setdefault("LogicalVolumes", ['MUONQ02::MUONQ02']) #kwargs.setdefault('DeltaChord', 0.00000002) diff --git a/Simulation/G4Atlas/G4AtlasTools/src/DetectorFieldManagerTool.cxx b/Simulation/G4Atlas/G4AtlasTools/src/DetectorFieldManagerTool.cxx index b63a3b4abfa..5ef53756134 100644 --- a/Simulation/G4Atlas/G4AtlasTools/src/DetectorFieldManagerTool.cxx +++ b/Simulation/G4Atlas/G4AtlasTools/src/DetectorFieldManagerTool.cxx @@ -5,6 +5,9 @@ // Main header #include "G4AtlasTools/DetectorFieldManagerTool.h" +// From this package +#include "TightMuonElseNoFieldManager.h" + // Geant4 includes #include "G4MagneticField.hh" #include "G4FieldManager.hh" @@ -22,6 +25,8 @@ DetectorFieldManagerTool::DetectorFieldManagerTool(const std::string& type, { declareProperty("LogicalVolumes", m_volumeList, "List of volumes to which the field will be applied"); + declareProperty("MuonOnlyField", m_muonOnlyField, + "Only muons experience the magnetic field"); } //----------------------------------------------------------------------------- @@ -42,7 +47,12 @@ StatusCode DetectorFieldManagerTool::initializeField() } // Create a new field manager - auto fieldMgr = new G4FieldManager(); + G4FieldManager * fieldMgr = nullptr; + if (m_muonOnlyField){ + fieldMgr = new TightMuonElseNoFieldManager(); + } else { + fieldMgr = new G4FieldManager(); + } // Save it in the TL holder m_fieldMgrHolder.set(fieldMgr); diff --git a/Simulation/G4Atlas/G4AtlasTools/src/DetectorGeometryBase.cxx b/Simulation/G4Atlas/G4AtlasTools/src/DetectorGeometryBase.cxx index dde15794cd0..bdfa8fad096 100644 --- a/Simulation/G4Atlas/G4AtlasTools/src/DetectorGeometryBase.cxx +++ b/Simulation/G4Atlas/G4AtlasTools/src/DetectorGeometryBase.cxx @@ -97,8 +97,8 @@ void DetectorGeometryBase::SetRotationAndOffset() //FIXME probably a neater way to do this part. m_envelope.theRotation=new G4RotationMatrix; m_envelope.theRotation->rotateX(m_rotateX); - m_envelope.theRotation->rotateX(m_rotateY); - m_envelope.theRotation->rotateX(m_rotateZ); + m_envelope.theRotation->rotateY(m_rotateY); + m_envelope.theRotation->rotateZ(m_rotateZ); if (m_envelope.thePositionedVolume) m_envelope.thePositionedVolume->SetRotation(m_envelope.theRotation); } diff --git a/Simulation/G4Atlas/G4AtlasTools/src/FastSimulationMasterTool.h b/Simulation/G4Atlas/G4AtlasTools/src/FastSimulationMasterTool.h index 6afe83fc048..f8e72aa726c 100644 --- a/Simulation/G4Atlas/G4AtlasTools/src/FastSimulationMasterTool.h +++ b/Simulation/G4Atlas/G4AtlasTools/src/FastSimulationMasterTool.h @@ -20,7 +20,7 @@ class FastSimulationMasterTool : public AthAlgTool , public virtual IFastSimulat virtual ~FastSimulationMasterTool() {} // Gaudi methods - virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface ); + virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface ) override; static const InterfaceID& interfaceID() { return IFastSimulationMasterTool::interfaceID(); } // Base class methods diff --git a/Simulation/G4Atlas/G4AtlasTools/src/GlobalFieldManagerTool.cxx b/Simulation/G4Atlas/G4AtlasTools/src/GlobalFieldManagerTool.cxx index 30cc295d150..b8ba6f02cae 100644 --- a/Simulation/G4Atlas/G4AtlasTools/src/GlobalFieldManagerTool.cxx +++ b/Simulation/G4Atlas/G4AtlasTools/src/GlobalFieldManagerTool.cxx @@ -5,6 +5,9 @@ // Main header #include "G4AtlasTools/GlobalFieldManagerTool.h" +// Local package include +#include "TightMuonSteppingFieldManager.h" + // Geant4 includes #include "G4TransportationManager.hh" #include "G4VUserPrimaryGeneratorAction.hh" @@ -23,6 +26,8 @@ GlobalFieldManagerTool::GlobalFieldManagerTool(const std::string& type, const IInterface* parent) : G4FieldManagerToolBase(type, name, parent) { + declareProperty("UseTightMuonStepping", m_useTightMuonStepping=false, + "Use tight muon stepping parameters by default"); } //----------------------------------------------------------------------------- @@ -39,7 +44,28 @@ StatusCode GlobalFieldManagerTool::initializeField() // Retrieve the global field manager auto transpManager = G4TransportationManager::GetTransportationManager(); - auto fieldMgr = transpManager->GetFieldManager(); + G4FieldManager* fieldMgr(nullptr); + if (m_useTightMuonStepping){ + // In the case of tight stepping we need to make our own global field manager + // If field manager already exists for current thread, error. + // There is no foreseen use-case for this situation. + if(m_fieldMgrHolder.get()) { + ATH_MSG_ERROR("GlobalFieldManagerTool::initializeField() - " << + "Field manager already exists!"); + return StatusCode::FAILURE; + } + // Create a new field manager + fieldMgr = new TightMuonSteppingFieldManager(); + + // Save it in the TL holder + m_fieldMgrHolder.set(fieldMgr); + + // Assign it to the global field manager + transpManager->SetFieldManager(fieldMgr); + } else { + // Otherwise get the default from the transportation manager + fieldMgr = transpManager->GetFieldManager(); + } // Configure the field manager fieldMgr->SetDetectorField(field); diff --git a/Simulation/G4Atlas/G4AtlasTools/src/SensitiveDetectorMasterTool.h b/Simulation/G4Atlas/G4AtlasTools/src/SensitiveDetectorMasterTool.h index d772e4d8b86..4b782b7ebcd 100644 --- a/Simulation/G4Atlas/G4AtlasTools/src/SensitiveDetectorMasterTool.h +++ b/Simulation/G4Atlas/G4AtlasTools/src/SensitiveDetectorMasterTool.h @@ -33,7 +33,7 @@ class SensitiveDetectorMasterTool : public AthAlgTool, virtual ~SensitiveDetectorMasterTool() {} /// Gaudi boiler plate methods - virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface ); + virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface ) override; static const InterfaceID& interfaceID() { return ISensitiveDetectorMasterTool::interfaceID(); } diff --git a/Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.cxx b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.cxx new file mode 100644 index 00000000000..2838d13fe21 --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.cxx @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TightMuonElseNoFieldManager.h" +#include "G4Track.hh" +#include "G4MuonPlus.hh" +#include "G4MuonMinus.hh" + +/// Normal constructor +TightMuonElseNoFieldManager::TightMuonElseNoFieldManager(G4Field *detectorField, G4ChordFinder *pChordFinder, G4bool b) + : G4FieldManager(detectorField,pChordFinder,b) + , m_globalField(nullptr) +{} + +/// Simple constructor +TightMuonElseNoFieldManager::TightMuonElseNoFieldManager(G4MagneticField *detectorMagneticField) + : G4FieldManager(detectorMagneticField) + , m_globalField(nullptr) +{} + +/// The one interesting method +void TightMuonElseNoFieldManager::ConfigureForTrack(const G4Track * track) +{ + // If they have not been set yet, get the settings for the global field manager + if (nullptr==m_globalField){ + m_globalField = const_cast<G4Field*>(GetDetectorField()); + } + + // If this is a muon, move it in the magnetic field; otherwise turn off the stepping + if (track->GetDefinition()==G4MuonPlus::Definition() || + track->GetDefinition()==G4MuonMinus::Definition() ){ + SetDetectorField(m_globalField); + } else { + SetDetectorField(nullptr); + } + +} diff --git a/Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.h b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.h new file mode 100644 index 00000000000..c3e1ba42531 --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonElseNoFieldManager.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TightMuonElseNoFieldManager_H +#define TightMuonElseNoFieldManager_H + +/** @class TightMuonElseNoFieldManager TightMuonElseNoFieldManager.h + * + * @brief G4FieldManager that sets tight stepping for muons; disables + * magnetic field for other particles + * + * @author Zach Marshall + * @date 2016-06-01 + */ + +#include "G4FieldManager.hh" +class G4Track; +class G4Field; +class G4ChordFinder; +class G4MagneticField; + +class TightMuonElseNoFieldManager : public G4FieldManager +{ + public: + /// Constructor + TightMuonElseNoFieldManager(G4Field *detectorField=0, G4ChordFinder *pChordFinder=0, G4bool b=true); + + /// Simple constructor + TightMuonElseNoFieldManager(G4MagneticField *detectorMagneticField); + + /// Simple destructor + virtual ~TightMuonElseNoFieldManager() {} + + /// The one interesting method + virtual void ConfigureForTrack(const G4Track *) override final; + + private: + /** Parameters of the stepper. This is to cache the global ones; the muon ones will be hard-coded */ + G4Field * m_globalField; + +}; + +#endif \ No newline at end of file diff --git a/Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.cxx b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.cxx new file mode 100644 index 00000000000..9d5962cff4a --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.cxx @@ -0,0 +1,59 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TightMuonSteppingFieldManager.h" +#include "G4Track.hh" +#include "G4ChordFinder.hh" +#include "G4MuonPlus.hh" +#include "G4MuonMinus.hh" + +/// Normal constructor +TightMuonSteppingFieldManager::TightMuonSteppingFieldManager(G4Field *detectorField, G4ChordFinder *pChordFinder, G4bool b) + : G4FieldManager(detectorField,pChordFinder,b) + , m_globalDeltaChord(-1.) + , m_globalDeltaOneStep(-1.) + , m_globalDeltaIntersection(-1.) + , m_globalMinEps(-1.) + , m_globalMaxEps(-1.) +{} + +/// Simple constructor +TightMuonSteppingFieldManager::TightMuonSteppingFieldManager(G4MagneticField *detectorMagneticField) + : G4FieldManager(detectorMagneticField) + , m_globalDeltaChord(-1.) + , m_globalDeltaOneStep(-1.) + , m_globalDeltaIntersection(-1.) + , m_globalMinEps(-1.) + , m_globalMaxEps(-1.) +{} + +/// The one interesting method +void TightMuonSteppingFieldManager::ConfigureForTrack(const G4Track * track) +{ + // If they have not been set yet, get the settings for the global field manager + if (m_globalDeltaChord<0){ + m_globalDeltaChord = GetChordFinder()->GetDeltaChord(); + m_globalDeltaOneStep = GetDeltaOneStep(); + m_globalDeltaIntersection = GetDeltaIntersection(); + m_globalMinEps = GetMinimumEpsilonStep(); + m_globalMaxEps = GetMaximumEpsilonStep(); + } + + // If this is a muon, set tight parameters; otherwise go back to the defaults + if (track->GetDefinition()==G4MuonPlus::Definition() || + track->GetDefinition()==G4MuonMinus::Definition() ){ + GetChordFinder()->SetDeltaChord(0.00000002); + SetDeltaOneStep(0.000001); + SetDeltaIntersection(0.00000002); + SetMinimumEpsilonStep(0.0000009); + SetMaximumEpsilonStep(0.000001); + } else { + GetChordFinder()->SetDeltaChord(m_globalDeltaChord); + SetDeltaOneStep(m_globalDeltaOneStep); + SetDeltaIntersection(m_globalDeltaIntersection); + SetMinimumEpsilonStep(m_globalMinEps); + SetMaximumEpsilonStep(m_globalMaxEps); + } + +} diff --git a/Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.h b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.h new file mode 100644 index 00000000000..577815ab548 --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/src/TightMuonSteppingFieldManager.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TightMuonSteppingFieldManager_H +#define TightMuonSteppingFieldManager_H + +/** @class TightMuonSteppingFieldManager TightMuonSteppingFieldManager.h + * + * @brief G4FieldManager that sets tight stepping for muons; caches global + * values for other particles + * + * @author Zach Marshall + * @date 2016-06-01 + */ + +#include "G4FieldManager.hh" +class G4Track; +class G4Field; +class G4ChordFinder; +class G4MagneticField; + +class TightMuonSteppingFieldManager : public G4FieldManager +{ + public: + /// Constructor + TightMuonSteppingFieldManager(G4Field *detectorField=0, G4ChordFinder *pChordFinder=0, G4bool b=true); + + /// Simple constructor + TightMuonSteppingFieldManager(G4MagneticField *detectorMagneticField); + + /// Simple destructor + virtual ~TightMuonSteppingFieldManager() {} + + /// The one interesting method + virtual void ConfigureForTrack(const G4Track *) override final; + + private: + /** Parameters of the stepper. This is to cache the global ones; the muon ones will be hard-coded */ + double m_globalDeltaChord; + double m_globalDeltaOneStep; + double m_globalDeltaIntersection; + double m_globalMinEps; + double m_globalMaxEps; + +}; + +#endif \ No newline at end of file -- GitLab