From 3523de4373bc53cda8f61eddefa34fd447f3fbb4 Mon Sep 17 00:00:00 2001 From: Dave Casper <dcasper@uci.edu> Date: Thu, 29 Apr 2021 08:44:01 +0000 Subject: [PATCH] Incorporate FaserNu --- .../EcalGeoModel/test/EcalGMConfig_test.py | 2 +- Control/CalypsoCommon/python/GlobalFlags.py | 2 +- .../python/DetectorConfigFlags.py | 16 +- .../python/GenEventReadExampleConfig.py | 2 +- .../GeoModelTest/python/GeoModelTestConfig.py | 2 +- .../python/RDOReadExampleConfig.py | 2 +- .../SimHitExample/CMakeLists.txt | 2 +- .../SimHitExample/src/SimHitAlg.cxx | 25 +- .../SimHitExample/src/SimHitAlg.h | 15 +- .../python/TrackerDataAccessExampleConfig.py | 2 +- .../python/TriggerDataAccessExampleConfig.py | 2 +- .../python/WaveformDataAccessExampleConfig.py | 2 +- ...CMakeLists.txt.disabled => CMakeLists.txt} | 8 +- .../python/WriteAlignmentConfig.py | 26 +- .../WriteAlignment/scripts/CopyAlignFolder.sh | 2 +- .../WriteAlignment/src/WriteAlignmentAlg.cxx | 64 +- .../DetDescrCnvSvc/src/DetDescrCnvSvc.cxx | 2 + .../FaserDetDescr/FaserDetectorID.h | 58 + .../FaserDetDescr/src/FaserDetectorID.cxx | 184 ++- .../src/FaserDetectorIDHelper.cxx | 36 +- .../FaserDetDescr/src/FaserDetectorIDHelper.h | 4 + .../GeoModel/FaserGeoAdaptors/CMakeLists.txt | 5 +- .../FaserGeoAdaptors/GeoNeutrinoHit.h | 53 + .../FaserGeoAdaptors/GeoNeutrinoHit.icc | 48 + .../GeoModel/FaserGeoAdaptors/src/statics.cxx | 3 + .../GeoModel/FaserGeoModel/data/geomDB.sql | 429 ++++++- .../python/FaserGeoModelConfig.py | 3 + .../FaserGeoModel/python/GeoModelInit.py | 8 + .../FaserGeoModel/python/ScintGMConfig.py | 2 +- .../test/FaserGeometryConfig_EVNT_test.py | 2 +- .../EmulsionGeoModel/CMakeLists.txt | 28 + .../EmulsionGeoModel/EmulsionDetectorTool.h | 61 + .../EmulsionGeoModelAthenaComps.h | 29 + .../python/EmulsionGeoModelConfig.py | 21 + .../EmulsionGeoModel/src/EmulsionBase.cxx | 117 ++ .../EmulsionGeoModel/src/EmulsionBase.h | 60 + .../src/EmulsionBaseboard.cxx | 58 + .../EmulsionGeoModel/src/EmulsionBaseboard.h | 43 + .../src/EmulsionComponentFactory.cxx | 40 + .../src/EmulsionComponentFactory.h | 89 ++ .../EmulsionGeoModel/src/EmulsionDataBase.cxx | 108 ++ .../EmulsionGeoModel/src/EmulsionDataBase.h | 61 + .../src/EmulsionDetectorFactory.cxx | 229 ++++ .../src/EmulsionDetectorFactory.h | 50 + .../src/EmulsionDetectorTool.cxx | 249 ++++ .../EmulsionGeoModel/src/EmulsionFilm.cxx | 98 ++ .../EmulsionGeoModel/src/EmulsionFilm.h | 48 + .../src/EmulsionFilmParameters.cxx | 66 + .../src/EmulsionFilmParameters.h | 35 + .../src/EmulsionGeneralParameters.cxx | 110 ++ .../src/EmulsionGeneralParameters.h | 44 + .../src/EmulsionGeoModelAthenaComps.cxx | 23 + .../src/EmulsionGeometryManager.cxx | 112 ++ .../src/EmulsionGeometryManager.h | 66 + .../src/EmulsionIdentifier.cxx | 23 + .../EmulsionGeoModel/src/EmulsionIdentifier.h | 48 + .../src/EmulsionMaterialManager.cxx | 83 ++ .../src/EmulsionMaterialManager.h | 48 + .../EmulsionGeoModel/src/EmulsionOptions.cxx | 47 + .../EmulsionGeoModel/src/EmulsionOptions.h | 35 + .../EmulsionGeoModel/src/EmulsionPlates.cxx | 112 ++ .../EmulsionGeoModel/src/EmulsionPlates.h | 52 + .../src/EmulsionPlatesParameters.cxx | 61 + .../src/EmulsionPlatesParameters.h | 35 + .../components/EmulsionGeoModel_entries.cxx | 3 + .../test/EmulsionGMConfig_test.py | 22 + .../NeutrinoGeoModelUtils/CMakeLists.txt | 22 + .../DetectorFactoryBase.h | 51 + .../DistortedMaterialManager.h | 28 + .../NeutrinoGeoModelUtils/ExtraMaterial.h | 37 + .../NeutrinoGeoModelUtils/GenericTubeMaker.h | 55 + .../NeutrinoDDAthenaComps.h | 76 ++ .../NeutrinoMaterialManager.h | 244 ++++ .../TopLevelPlacements.h | 47 + .../NeutrinoGeoModelUtils/TubeVolData.h | 59 + .../src/DistortedMaterialManager.cxx | 46 + .../src/ExtraMaterial.cxx | 74 ++ .../src/GenericTubeMaker.cxx | 164 +++ .../src/NeutrinoDDAthenaComps.cxx | 35 + .../src/NeutrinoMaterialManager.cxx | 1042 ++++++++++++++++ .../src/TopLevelPlacements.cxx | 145 +++ .../NeutrinoGeoModelUtils/src/TubeVolData.cxx | 101 ++ .../data/IdDictNeutrino.xml | 7 +- .../NeutrinoIdentifier/CMakeLists.txt | 24 + .../NeutrinoIdentifier/EmulsionID.h | 573 +++++++++ .../NeutrinoIdentifierDict.h | 17 + .../NeutrinoIdentifier/selection.xml | 3 + .../NeutrinoIdentifier/src/EmulsionID.cxx | 1068 +++++++++++++++++ .../NeutrinoReadoutGeometry/CMakeLists.txt | 21 + .../EmulsionDetectorManager.h | 163 +++ .../ExtendedAlignableTransform.h | 57 + .../NeutrinoCommonItems.h | 92 ++ .../NeutrinoReadoutGeometry/NeutrinoDD_Defs.h | 22 + .../NeutrinoDetectorDesign.h | 171 +++ .../NeutrinoDetectorElement.h | 687 +++++++++++ .../NeutrinoDetectorElementCollection.h | 44 + .../NeutrinoDetectorManager.h | 147 +++ .../NeutrinoDetectorManagerBase.h | 204 ++++ .../NeutrinoIntersect.h | 94 ++ .../NeutrinoLocalPosition.h | 173 +++ .../NeutrinoNumerology.h | 68 ++ .../NeutrinoNumerology.icc | 33 + .../NeutrinoReadoutGeometry/Version.h | 91 ++ .../src/EmulsionDetectorManager.cxx | 350 ++++++ .../src/NeutrinoCommonItems.cxx | 22 + .../src/NeutrinoDetectorDesign.cxx | 99 ++ .../src/NeutrinoDetectorElement.cxx | 930 ++++++++++++++ .../src/NeutrinoDetectorElementCollection.cxx | 19 + .../src/NeutrinoDetectorManager.cxx | 144 +++ .../src/NeutrinoDetectorManagerBase.cxx | 424 +++++++ .../src/NeutrinoLocalPosition.cxx | 100 ++ .../src/NeutrinoNumerology.cxx | 31 + .../NeutrinoReadoutGeometry/src/Version.cxx | 121 ++ .../NeutrinoIdCnv/CMakeLists.txt | 15 + .../share/NeutrinoIdCnv_jobOptions.py | 6 + .../src/EmulsionIDDetDescrCnv.cxx | 239 ++++ .../NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.h | 71 ++ .../src/NeutrinoIdCnv_entries.cxx | 3 + .../NeutrinoSimEventAthenaPool/CMakeLists.txt | 27 + .../NeutrinoSimDataCollection_p1.h | 4 + .../NeutrinoSimData_p1.h | 4 + .../NeutrinoSimEventAthenaPoolCnvDict.h | 9 + .../NeutrinoSimEventAthenaPool/selection.xml | 2 + .../src/NeutrinoHitCollectionCnv.cxx | 33 + .../src/NeutrinoHitCollectionCnv.h | 29 + .../NeutrinoSimEventTPCnv/CMakeLists.txt | 26 + .../NeutrinoHits/NeutrinoHitCnv_p1.h | 34 + .../NeutrinoHitCollectionCnv_p1.h | 41 + .../NeutrinoHits/NeutrinoHitCollection_p1.h | 57 + .../NeutrinoHits/NeutrinoHit_p1.h | 19 + .../NeutrinoSimEventTPCnvDict.h | 20 + .../NeutrinoSimEventTPCnv/selection.xml | 7 + .../src/NeutrinoHits/NeutrinoHitCnv_p1.cxx | 54 + .../NeutrinoHitCollectionCnv_p1.cxx | 312 +++++ .../NeutrinoG4/EmulsionG4_SD/CMakeLists.txt | 22 + .../python/EmulsionG4_SDToolConfig.py | 21 + .../EmulsionG4_SD/src/EmulsionSensorSD.cxx | 119 ++ .../EmulsionG4_SD/src/EmulsionSensorSD.h | 57 + .../src/EmulsionSensorSDTool.cxx | 35 + .../EmulsionG4_SD/src/EmulsionSensorSDTool.h | 40 + .../src/components/EmulsionG4_SD_entries.cxx | 3 + Neutrino/NeutrinoSimEvent/CMakeLists.txt | 28 + .../NeutrinoSimEvent/NeutrinoHit.h | 183 +++ .../NeutrinoSimEvent/NeutrinoHitCollection.h | 20 + .../NeutrinoSimEvent/NeutrinoHitIdHelper.h | 57 + .../NeutrinoSimEvent/NeutrinoSimEventDict.h | 10 + .../NeutrinoSimEvent/selection.xml | 5 + Neutrino/NeutrinoSimEvent/src/NeutrinoHit.cxx | 159 +++ .../src/NeutrinoHitIdHelper.cxx | 85 ++ README.md | 19 +- .../test/PreshowerGMConfig_test.py | 2 +- .../test/TriggerGMConfig_test.py | 2 +- .../VetoGeoModel/test/VetoGMConfig_test.py | 2 +- Simulation/G4Faser/G4FaserAlg/test/runEcal.py | 2 +- Simulation/G4Faser/G4FaserAlg/test/runG4.py | 2 +- .../G4Faser/G4FaserAlg/test/runG4Cosmics.py | 2 +- .../G4FaserAlg/test/runG4DecayInFlight.py | 2 +- .../G4Faser/G4FaserAlg/test/runG4FaserNu.py | 132 ++ .../G4FaserAlg/test/runGeantinoScan.py | 2 +- Simulation/G4Faser/G4FaserAlg/test/runGen.py | 2 +- .../python/G4FaserServicesConfigNew.py | 11 +- .../python/G4FaserToolsConfigNew.py | 17 + .../G4FaserTools/python/G4FieldConfigNew.py | 10 + .../python/G4GeometryToolConfig.py | 13 +- .../python/G4PhysicsRegionConfigNew.py | 10 + .../python/FaserISF_HepMC_ToolsConfigNew.py | 23 +- Simulation/README.md | 5 + .../src/TrackerAlignDBTool.cxx | 12 +- .../src/TrackerAlignDBTool.h | 1 + .../data/SCT_Conditions.py | 223 +++- .../test/DipoleGMConfig_test.py | 2 +- .../test/FaserSCT_GMConfig_test.py | 2 +- ...cker_Interface.xml => IdDictInterface.xml} | 0 .../test/FaserSCT_DigitizationDbg.py | 3 +- .../test/SCT_DigitizationConfigNew_test.py | 2 +- .../python/FaserSpacePointsCosmics.py | 2 +- .../test/TrackerClusterFitDbg.py | 2 +- .../test/FaserSCT_ClusterizationDbg.py | 2 +- .../test/FaserSCT_ClusterizationDbgCosmics.py | 2 +- .../test/StatisticsDbg.py | 2 +- .../test/TrackerSpacePointFormationDbg.py | 2 +- .../TrackerSpacePointFormationDbgCosmics.py | 2 +- .../test/TruthSeededTrackFinderDbg.py | 2 +- .../src/FaserSiHitIdHelper.cxx | 4 +- .../FaserActsMaterialMapping_jobOptions.py | 2 +- .../test/FaserActsExtrapolationAlg.py | 2 +- .../test/FaserActsWriteTrackingGeometry.py | 2 +- .../test/FaserActsKalmanFilterAlg.py | 2 +- .../ATLAS_CHECK_THREAD_SAFETY | 1 - graphics/VTI12/README.md | 8 +- graphics/VTI12/VTI12Algs/share/vti12.py | 6 +- .../VTI12GeometrySystems/VP1GeoFlags.h | 13 +- .../src/GeoSysController.cxx | 3 + .../src/VP1GeometrySystem.cxx | 7 + .../src/VisAttributes.cxx | 28 +- .../src/VolumeTreeModel.cxx | 5 +- .../src/geometrysystemcontroller.ui | 48 + .../VTI12SimHitSystems/CMakeLists.txt | 2 +- .../src/VP1SimHitSystem.cxx | 25 +- .../src/simhitcontrollerform.ui | 47 +- .../VTI12TrackSystems/CMakeLists.txt | 1 + .../SimHitHandle_NeutrinoHit.h | 50 + .../src/SimHitHandle_NeutrinoHit.cxx | 157 +++ .../src/TrackCollHandle_TruthTracks.cxx | 14 +- graphics/VTI12/VTI12Utils/CMakeLists.txt | 1 + .../VTI12/VTI12Utils/VTI12Utils/VP1DetInfo.h | 7 + .../VTI12Utils/VTI12Utils/VP1JobConfigInfo.h | 2 + graphics/VTI12/VTI12Utils/src/VP1DetInfo.cxx | 22 + .../VTI12/VTI12Utils/src/VP1JobConfigInfo.cxx | 6 + 209 files changed, 14260 insertions(+), 230 deletions(-) rename Control/CalypsoExample/WriteAlignment/{CMakeLists.txt.disabled => CMakeLists.txt} (79%) create mode 100644 DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.h create mode 100644 DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.icc create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/CMakeLists.txt create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionDetectorTool.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionGeoModelAthenaComps.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/python/EmulsionGeoModelConfig.py create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeoModelAthenaComps.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.h create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/components/EmulsionGeoModel_entries.cxx create mode 100644 Neutrino/NeutrinoDetDescr/EmulsionGeoModel/test/EmulsionGMConfig_test.py create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/CMakeLists.txt create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DetectorFactoryBase.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DistortedMaterialManager.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/ExtraMaterial.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/GenericTubeMaker.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoMaterialManager.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TopLevelPlacements.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TubeVolData.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/DistortedMaterialManager.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/ExtraMaterial.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/GenericTubeMaker.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoDDAthenaComps.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoMaterialManager.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TopLevelPlacements.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TubeVolData.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/CMakeLists.txt create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/EmulsionID.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/NeutrinoIdentifierDict.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/selection.xml create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/src/EmulsionID.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/CMakeLists.txt create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/EmulsionDetectorManager.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/ExtendedAlignableTransform.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoCommonItems.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDD_Defs.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManager.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManagerBase.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoIntersect.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoLocalPosition.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.icc create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/Version.h create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/EmulsionDetectorManager.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoCommonItems.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorDesign.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElement.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElementCollection.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManager.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManagerBase.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoLocalPosition.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoNumerology.cxx create mode 100644 Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/Version.cxx create mode 100644 Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/CMakeLists.txt create mode 100644 Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/share/NeutrinoIdCnv_jobOptions.py create mode 100644 Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.cxx create mode 100644 Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.h create mode 100644 Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/NeutrinoIdCnv_entries.cxx create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/CMakeLists.txt create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimDataCollection_p1.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimData_p1.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPoolCnvDict.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/selection.xml create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.cxx create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/CMakeLists.txt create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCnv_p1.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollection_p1.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHit_p1.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnvDict.h create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/selection.xml create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCnv_p1.cxx create mode 100644 Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCollectionCnv_p1.cxx create mode 100644 Neutrino/NeutrinoG4/EmulsionG4_SD/CMakeLists.txt create mode 100644 Neutrino/NeutrinoG4/EmulsionG4_SD/python/EmulsionG4_SDToolConfig.py create mode 100644 Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.cxx create mode 100644 Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.h create mode 100644 Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.cxx create mode 100644 Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.h create mode 100644 Neutrino/NeutrinoG4/EmulsionG4_SD/src/components/EmulsionG4_SD_entries.cxx create mode 100644 Neutrino/NeutrinoSimEvent/CMakeLists.txt create mode 100644 Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHit.h create mode 100644 Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitCollection.h create mode 100644 Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitIdHelper.h create mode 100644 Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoSimEventDict.h create mode 100644 Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/selection.xml create mode 100644 Neutrino/NeutrinoSimEvent/src/NeutrinoHit.cxx create mode 100644 Neutrino/NeutrinoSimEvent/src/NeutrinoHitIdHelper.cxx create mode 100644 Simulation/G4Faser/G4FaserAlg/test/runG4FaserNu.py rename Tracker/TrackerDetDescr/TrackerIdDictFiles/data/{IdDictTracker_Interface.xml => IdDictInterface.xml} (100%) create mode 100644 graphics/VTI12/VTI12Systems/VTI12TrackSystems/VTI12TrackSystems/SimHitHandle_NeutrinoHit.h create mode 100644 graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_NeutrinoHit.cxx diff --git a/Calorimeter/CaloDetDescr/EcalGeoModel/test/EcalGMConfig_test.py b/Calorimeter/CaloDetDescr/EcalGeoModel/test/EcalGMConfig_test.py index 9df7d390..18ac17cf 100644 --- a/Calorimeter/CaloDetDescr/EcalGeoModel/test/EcalGMConfig_test.py +++ b/Calorimeter/CaloDetDescr/EcalGeoModel/test/EcalGMConfig_test.py @@ -10,7 +10,7 @@ if __name__ == "__main__": from AthenaConfiguration.TestDefaults import defaultTestFiles ConfigFlags.Input.Files = defaultTestFiles.HITS - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.Detector.EnableEcal = True ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() diff --git a/Control/CalypsoCommon/python/GlobalFlags.py b/Control/CalypsoCommon/python/GlobalFlags.py index d620bd8b..0fe1ac4e 100644 --- a/Control/CalypsoCommon/python/GlobalFlags.py +++ b/Control/CalypsoCommon/python/GlobalFlags.py @@ -67,7 +67,7 @@ class ConditionsTag(JobProperty): """ statusOn=True allowedTypes=['str'] - StoredValue='OFLCOND-XXXX-XXX-XX' + StoredValue='OFLCOND-FASER-01' # class DatabaseInstance(JobProperty): diff --git a/Control/CalypsoConfiguration/python/DetectorConfigFlags.py b/Control/CalypsoConfiguration/python/DetectorConfigFlags.py index fb0c315a..5588000a 100644 --- a/Control/CalypsoConfiguration/python/DetectorConfigFlags.py +++ b/Control/CalypsoConfiguration/python/DetectorConfigFlags.py @@ -7,10 +7,11 @@ from CalypsoConfiguration.AutoConfigFlags import DetDescrInfo, getDefaultDetecto allDetectors = [ - 'Veto', 'Trigger', 'Preshower', 'FaserSCT', 'Ecal', 'Dipole', + 'Emulsion', 'Veto', 'Trigger', 'Preshower', 'FaserSCT', 'Ecal', 'Dipole', ] allGroups = { + 'Neutrino' : [ 'Emulsion' ], 'Tracker' : ['SCT'], 'Scintillator' : ['Veto', 'Trigger', 'Preshower'], 'FaserCalo' : ['Ecal'], @@ -21,6 +22,10 @@ def createDetectorConfigFlags(): dcf=AthConfigFlags() #Detector.Geometry - merger of the old geometry and detdescr tasks + + dcf.addFlag('Detector.GeometryEmulsion', False) + dcf.addFlag('Detector.GeometryNeutrino', lambda prevFlags : (prevFlags.Detector.GeometryEmulsion)) + dcf.addFlag('Detector.GeometryDipole', False) dcf.addFlag('Detector.GeometryMagnet', lambda prevFlags : (prevFlags.Detector.GeometryDipole )) @@ -54,6 +59,10 @@ def createDetectorConfigFlags(): # prevFlags.Detector.EnableCentralDipole or # prevFlags.Detector.EnableDownstreamDipole)) # dcf.addFlag('Detector.EnableDecayVolume', False) + + dcf.addFlag('Detector.EnableEmulsion', lambda prevFlags : 'Emulsion' in getDefaultDetectors(prevFlags.GeoModel.FaserVersion)) + dcf.addFlag('Detector.EnableNeutrino', lambda prevFlags : (prevFlags.Detector.EnableEmulsion)) + dcf.addFlag('Detector.EnableVeto', lambda prevFlags : 'Veto' in getDefaultDetectors(prevFlags.GeoModel.FaserVersion)) dcf.addFlag('Detector.EnableTrigger', lambda prevFlags : 'Trigger' in getDefaultDetectors(prevFlags.GeoModel.FaserVersion)) dcf.addFlag('Detector.EnablePreshower', lambda prevFlags : 'Preshower' in getDefaultDetectors(prevFlags.GeoModel.FaserVersion)) @@ -70,6 +79,9 @@ def createDetectorConfigFlags(): # prevFlags.Detector.EnableFaserCalo)) # Reco flags + dcf.addFlag('Detector.RecoEmulsion', False) + dcf.addFlag('Detector.RecoNeutrino', lambda prevFlags : (prevFlags.Detector.RecoEmulsion)) + dcf.addFlag('Detector.RecoVeto', False) dcf.addFlag('Detector.RecoTrigger', False) dcf.addFlag('Detector.RecoPreshower', False) @@ -77,7 +89,7 @@ def createDetectorConfigFlags(): dcf.addFlag('Detector.RecoWaveform', lambda prevFlags : (prevFlags.Detector.RecoVeto or prevFlags.Detector.RecoTrigger or prevFlags.Detector.RecoPreshower or prevFlags.Detector.RecoEcal)) dcf.addFlag('Detector.RecoFaserSCT', False) - dcf.addFlag('Detector.RecoTracker', lambda prevFlags : (prevFlags.Detector.RecoSCT)) + dcf.addFlag('Detector.RecoTracker', lambda prevFlags : (prevFlags.Detector.RecoFaserSCT)) return dcf diff --git a/Control/CalypsoExample/GenEventExample/python/GenEventReadExampleConfig.py b/Control/CalypsoExample/GenEventExample/python/GenEventReadExampleConfig.py index 28073eb6..1b84f616 100644 --- a/Control/CalypsoExample/GenEventExample/python/GenEventReadExampleConfig.py +++ b/Control/CalypsoExample/GenEventExample/python/GenEventReadExampleConfig.py @@ -26,7 +26,7 @@ if __name__ == "__main__": # Flags for this job ConfigFlags.Input.isMC = True # Needed to bypass autoconfig - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Default FASER geometry ConfigFlags.Detector.EnableFaserSCT = True ConfigFlags.Input.Files = ["my.cosmics.pool.root"] diff --git a/Control/CalypsoExample/GeoModelTest/python/GeoModelTestConfig.py b/Control/CalypsoExample/GeoModelTest/python/GeoModelTestConfig.py index e7f6feb7..ad33f2cf 100644 --- a/Control/CalypsoExample/GeoModelTest/python/GeoModelTestConfig.py +++ b/Control/CalypsoExample/GeoModelTest/python/GeoModelTestConfig.py @@ -30,7 +30,7 @@ if __name__ == "__main__": # Flags for this job ConfigFlags.Input.isMC = True # Needed to bypass autoconfig - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Default FASER geometry ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Writes out a GeoModel file with the full geometry tree (optional, comment out to skip) # ConfigFlags.Detector.EnableVeto = True diff --git a/Control/CalypsoExample/RDOReadExample/python/RDOReadExampleConfig.py b/Control/CalypsoExample/RDOReadExample/python/RDOReadExampleConfig.py index fcaea799..7bffba5e 100644 --- a/Control/CalypsoExample/RDOReadExample/python/RDOReadExampleConfig.py +++ b/Control/CalypsoExample/RDOReadExample/python/RDOReadExampleConfig.py @@ -26,7 +26,7 @@ if __name__ == "__main__": # Flags for this job ConfigFlags.Input.isMC = True # Needed to bypass autoconfig - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Default FASER geometry ConfigFlags.Detector.GeometryFaserSCT = True ConfigFlags.Input.Files = ["my.RDO.pool.root"] diff --git a/Control/CalypsoExample/SimHitExample/CMakeLists.txt b/Control/CalypsoExample/SimHitExample/CMakeLists.txt index 77084ea3..19aa729b 100644 --- a/Control/CalypsoExample/SimHitExample/CMakeLists.txt +++ b/Control/CalypsoExample/SimHitExample/CMakeLists.txt @@ -3,7 +3,7 @@ atlas_subdir( SimHitExample ) atlas_add_component( SimHitExample src/*.cxx src/components/SimHitExample_entries.cxx - LINK_LIBRARIES AthenaBaseComps GeneratorObjects TrackerSimEvent ScintSimEvent FaserCaloSimEvent + LINK_LIBRARIES AthenaBaseComps GeneratorObjects TrackerSimEvent ScintSimEvent FaserCaloSimEvent NeutrinoSimEvent ) atlas_install_joboptions( share/*.py ) \ No newline at end of file diff --git a/Control/CalypsoExample/SimHitExample/src/SimHitAlg.cxx b/Control/CalypsoExample/SimHitExample/src/SimHitAlg.cxx index 86a1ecf5..100b0eea 100644 --- a/Control/CalypsoExample/SimHitExample/src/SimHitAlg.cxx +++ b/Control/CalypsoExample/SimHitExample/src/SimHitAlg.cxx @@ -32,6 +32,8 @@ StatusCode SimHitAlg::initialize() ATH_CHECK( m_mcEventKey.initialize() ); ATH_CHECK( m_faserSiHitKey.initialize() ); + ATH_CHECK( m_emulsionHitKey.initialize() ); + ATH_CHECK( m_preshowerHitKey.initialize() ); ATH_CHECK( m_triggerHitKey.initialize() ); ATH_CHECK( m_vetoHitKey.initialize() ); @@ -41,9 +43,11 @@ StatusCode SimHitAlg::initialize() ATH_MSG_INFO( "Using GenEvent collection with key " << m_mcEventKey.key()); ATH_MSG_INFO( "Using Faser SiHit collection with key " << m_faserSiHitKey.key()); - ATH_MSG_INFO( "Using ScintHit collection with key " << m_preshowerHitKey.key()); - ATH_MSG_INFO( "Using ScintHit collection with key " << m_triggerHitKey.key()); - ATH_MSG_INFO( "Using ScintHit collection with key " << m_vetoHitKey.key()); + ATH_MSG_INFO( "Using Emulsion NeutrinoHit collection with key " << m_emulsionHitKey.key() ); + + ATH_MSG_INFO( "Using Preshower ScintHit collection with key " << m_preshowerHitKey.key()); + ATH_MSG_INFO( "Using Trigger ScintHit collection with key " << m_triggerHitKey.key()); + ATH_MSG_INFO( "Using Veto ScintHit collection with key " << m_vetoHitKey.key()); ATH_MSG_INFO( "Using CaloHit collection with key " << m_ecalHitKey.key()); return StatusCode::SUCCESS; @@ -61,6 +65,12 @@ StatusCode SimHitAlg::execute() SG::ReadHandle<FaserSiHitCollection> h_siHits(m_faserSiHitKey); ATH_MSG_INFO("Read FaserSiHitCollection with " << h_siHits->size() << " hits"); + SG::ReadHandle<NeutrinoHitCollection> h_emulsionHits(m_emulsionHitKey); + if (h_emulsionHits.isValid()) + { + ATH_MSG_INFO("Read NeutrinoHitCollection with " << h_emulsionHits->size() << " hits"); + } + SG::ReadHandle<ScintHitCollection> h_preshowerHits(m_preshowerHitKey); ATH_MSG_INFO("Read ScintHitCollection/Preshower with " << h_preshowerHits->size() << " hits"); SG::ReadHandle<ScintHitCollection> h_triggerHits(m_triggerHitKey); @@ -86,6 +96,15 @@ StatusCode SimHitAlg::execute() ePrimary = (*p)->momentum().e(); } + if (h_emulsionHits.isValid() && h_emulsionHits->size()!=0) + { + //Loop over all hits; print + for (const NeutrinoHit& hit : *h_emulsionHits) + { + hit.print(); + } + } + // The hit container might be empty because particles missed the wafers //if (h_siHits->size() == 0) return StatusCode::SUCCESS; diff --git a/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h b/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h index 3cf0fde8..d7747bbf 100644 --- a/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h +++ b/Control/CalypsoExample/SimHitExample/src/SimHitAlg.h @@ -1,6 +1,7 @@ #include "AthenaBaseComps/AthHistogramAlgorithm.h" #include "GeneratorObjects/McEventCollection.h" #include "TrackerSimEvent/FaserSiHitCollection.h" +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" #include "ScintSimEvent/ScintHitCollection.h" #include "FaserCaloSimEvent/CaloHitCollection.h" #include <TH1.h> @@ -36,14 +37,20 @@ class SimHitAlg : public AthHistogramAlgorithm // Read handle keys for data containers // Any other event data can be accessed identically // Note the key names ("GEN_EVENT" or "SCT_Hits") are Gaudi properties and can be configured at run-time + + // Truth information SG::ReadHandleKey<McEventCollection> m_mcEventKey { this, "McEventCollection", "GEN_EVENT" }; + + // Tracker hits SG::ReadHandleKey<FaserSiHitCollection> m_faserSiHitKey { this, "FaserSiHitCollection", "SCT_Hits" }; + // Emulsion hits + SG::ReadHandleKey<NeutrinoHitCollection> m_emulsionHitKey { this, "NeutrinoHitCollection", "EmulsionHits" }; + //PreshowerHits, TriggerHits, VetoHits Sav new stuff - SG::ReadHandleKey<ScintHitCollection> m_scintHitKey { this, "ScintHitCollection", "Scint_Hits" }; //template. remove later - SG::ReadHandleKey<ScintHitCollection> m_preshowerHitKey { this, "ScintHitCollection", "PreshowerHits" }; - SG::ReadHandleKey<ScintHitCollection> m_triggerHitKey { this, "ScintHitCollection", "TriggerHits" }; - SG::ReadHandleKey<ScintHitCollection> m_vetoHitKey { this, "ScintHitCollection", "VetoHits" }; + SG::ReadHandleKey<ScintHitCollection> m_preshowerHitKey { this, "PreshowerHitCollection", "PreshowerHits" }; + SG::ReadHandleKey<ScintHitCollection> m_triggerHitKey { this, "TriggerHitCollection", "TriggerHits" }; + SG::ReadHandleKey<ScintHitCollection> m_vetoHitKey { this, "VetoHitCollection", "VetoHits" }; //EcalHits SG::ReadHandleKey<CaloHitCollection> m_ecalHitKey { this, "CaloHitCollection", "EcalHits" }; diff --git a/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py b/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py index d420ec08..e4dcd1c1 100644 --- a/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py +++ b/Control/CalypsoExample/TrackerDataAccessExample/python/TrackerDataAccessExampleConfig.py @@ -31,7 +31,7 @@ if __name__ == "__main__": # Flags for this job ConfigFlags.Input.isMC = False # Needed to bypass autoconfig - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.GeoModel.FaserVersion = "FASER-01" # FASER geometry ConfigFlags.Input.ProjectName = "data20" # Needed to bypass autoconfig diff --git a/Control/CalypsoExample/TriggerDataAccessExample/python/TriggerDataAccessExampleConfig.py b/Control/CalypsoExample/TriggerDataAccessExample/python/TriggerDataAccessExampleConfig.py index 54ceea6a..ffab4e9f 100644 --- a/Control/CalypsoExample/TriggerDataAccessExample/python/TriggerDataAccessExampleConfig.py +++ b/Control/CalypsoExample/TriggerDataAccessExample/python/TriggerDataAccessExampleConfig.py @@ -31,7 +31,7 @@ if __name__ == "__main__": # Flags for this job ConfigFlags.Input.isMC = False # Needed to bypass autoconfig - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Default FASER geometry ConfigFlags.Input.ProjectName = "data20" diff --git a/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py b/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py index 096aacdd..d46ef749 100644 --- a/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py +++ b/Control/CalypsoExample/WaveformDataAccessExample/python/WaveformDataAccessExampleConfig.py @@ -31,7 +31,7 @@ if __name__ == "__main__": # Flags for this job ConfigFlags.Input.isMC = False # Needed to bypass autoconfig - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Default FASER geometry ConfigFlags.Input.ProjectName = "data20" diff --git a/Control/CalypsoExample/WriteAlignment/CMakeLists.txt.disabled b/Control/CalypsoExample/WriteAlignment/CMakeLists.txt similarity index 79% rename from Control/CalypsoExample/WriteAlignment/CMakeLists.txt.disabled rename to Control/CalypsoExample/WriteAlignment/CMakeLists.txt index 751e8c0e..0c167609 100644 --- a/Control/CalypsoExample/WriteAlignment/CMakeLists.txt.disabled +++ b/Control/CalypsoExample/WriteAlignment/CMakeLists.txt @@ -15,10 +15,10 @@ atlas_add_component( WriteAlignment INCLUDE_DIRS ${GEOMODELCORE_INCLUDE_DIRS} LINK_LIBRARIES ${GEOMODELCORE_LIBRARIES} AthenaBaseComps GeoModelUtilities ScintReadoutGeometry TrackerReadoutGeometry TrackerAlignGenToolsLib ) -atlas_add_test( WriteAlignmentCheck - SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/python/WriteAlignmentConfig.py - PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - PROPERTIES TIMEOUT 300 ) +# atlas_add_test( WriteAlignmentCheck +# SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/python/WriteAlignmentConfig.py +# PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +# PROPERTIES TIMEOUT 300 ) # Install files from the package: #atlas_install_headers( WriteAlignment ) diff --git a/Control/CalypsoExample/WriteAlignment/python/WriteAlignmentConfig.py b/Control/CalypsoExample/WriteAlignment/python/WriteAlignmentConfig.py index 41fb9c93..de5a92ac 100644 --- a/Control/CalypsoExample/WriteAlignment/python/WriteAlignmentConfig.py +++ b/Control/CalypsoExample/WriteAlignment/python/WriteAlignmentConfig.py @@ -2,7 +2,7 @@ #!/usr/bin/env python import sys -from AthenaCommon.Constants import VERBOSE +from AthenaCommon.Constants import VERBOSE, INFO from AthenaConfiguration.ComponentFactory import CompFactory def WriteAlignmentCfg(flags, name="WriteAlignmentAlg", **kwargs): @@ -12,11 +12,11 @@ def WriteAlignmentCfg(flags, name="WriteAlignmentAlg", **kwargs): a = FaserGeometryCfg(flags) # This section is to allow alignment to be written to a conditions DB file - from IOVDbSvc.IOVDbSvcConfig import IOVDbSvcCfg - result = IOVDbSvcCfg(flags) - iovDbSvc = result.getPrimary() - iovDbSvc.dbConnection="sqlite://;schema=ALLP200.db;dbname=OFLP200" - a.merge(result) + # from IOVDbSvc.IOVDbSvcConfig import IOVDbSvcCfg + # result = IOVDbSvcCfg(flags) + # iovDbSvc = result.getPrimary() + # iovDbSvc.dbConnection="sqlite://;schema=ALLP200.db;dbname=OFLP200" + # a.merge(result) AthenaPoolCnvSvc=CompFactory.AthenaPoolCnvSvc apcs=AthenaPoolCnvSvc() @@ -28,8 +28,11 @@ def WriteAlignmentCfg(flags, name="WriteAlignmentAlg", **kwargs): # Configure the algorithm itself WriteAlignmentAlg = CompFactory.WriteAlignmentAlg - outputTool = CompFactory.AthenaOutputStreamTool("DbStreamTool", OutputFile = "FaserSCT_AlignDb.pool.root") - kwargs.setdefault("AlignDbTool", CompFactory.TrackerAlignDBTool("AlignDbTool", OutputTool = outputTool)) + outputTool = CompFactory.AthenaOutputStreamTool("DbStreamTool", OutputFile = "FaserSCT_AlignDb.pool.root", + PoolContainerPrefix="ConditionsContainer", + TopLevelContainerName = "<type>", + SubLevelBranchName= "<key>" ) + kwargs.setdefault("AlignDbTool", CompFactory.TrackerAlignDBTool("AlignDbTool", OutputTool = outputTool, OutputLevel=VERBOSE)) a.addEventAlgo(WriteAlignmentAlg(name, **kwargs)) return a @@ -45,9 +48,10 @@ if __name__ == "__main__": # Flags for this job ConfigFlags.Input.isMC = True # Needed to bypass autoconfig - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Default FASER geometry ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Writes out a GeoModel file with the full geometry tree (optional, comment out to skip) + ConfigFlags.IOVDb.DBConnection = "sqlite://;schema=ALLP200.db;dbname=OFLP200" ConfigFlags.lock() # Configure components @@ -60,8 +64,8 @@ if __name__ == "__main__": # Configure verbosity # ConfigFlags.dump() # logging.getLogger('forcomps').setLevel(VERBOSE) - # acc.foreach_component("*").OutputLevel = VERBOSE - # acc.foreach_component("*ClassID*").OutputLevel = INFO + acc.foreach_component("*").OutputLevel = VERBOSE + acc.foreach_component("*ClassID*").OutputLevel = INFO # log.setLevel(VERBOSE) # Execute and finish diff --git a/Control/CalypsoExample/WriteAlignment/scripts/CopyAlignFolder.sh b/Control/CalypsoExample/WriteAlignment/scripts/CopyAlignFolder.sh index 3e95b231..ce694ce4 100644 --- a/Control/CalypsoExample/WriteAlignment/scripts/CopyAlignFolder.sh +++ b/Control/CalypsoExample/WriteAlignment/scripts/CopyAlignFolder.sh @@ -1,5 +1,5 @@ #!/bin/sh -AtlCoolCopy "sqlite://;schema=./ALLP200.db;dbname=OFLP200" "sqlite://;schema=data/ALLP200.db;dbname=OFLP200" -a -fnp -ot "OFLCOND-XXXX-XXX-XX" +AtlCoolCopy "sqlite://;schema=./ALLP200.db;dbname=OFLP200" "sqlite://;schema=data/ALLP200.db;dbname=OFLP200" -a -fnp -ot "TRACKER-ALIGN-01" cp -n PoolFileCatalog.xml data/ cp -n FaserSCT_AlignDb.pool.root data/ \ No newline at end of file diff --git a/Control/CalypsoExample/WriteAlignment/src/WriteAlignmentAlg.cxx b/Control/CalypsoExample/WriteAlignment/src/WriteAlignmentAlg.cxx index ed67d81a..6efcb9b4 100644 --- a/Control/CalypsoExample/WriteAlignment/src/WriteAlignmentAlg.cxx +++ b/Control/CalypsoExample/WriteAlignment/src/WriteAlignmentAlg.cxx @@ -33,42 +33,42 @@ StatusCode WriteAlignmentAlg::initialize() StatusCode WriteAlignmentAlg::execute(const EventContext&) const { - GeoModelExperiment* theExpt = nullptr; - std::vector<std::string> listOfManagers; - ATH_CHECK(detStore()->retrieve(theExpt, "FASER")); - if (theExpt != nullptr) - { - ATH_MSG_ALWAYS("Retrieved top-level FASER experiment geometry from DetStore."); - listOfManagers = theExpt->getListOfManagers(); - ATH_MSG_ALWAYS("Experiment has defined " << listOfManagers.size() << " detector managers:"); - for (auto mgr : listOfManagers) - { - const GeoVDetectorManager* pMgr = nullptr; - pMgr = theExpt->getManager(mgr); - if (pMgr != nullptr) - { - ATH_MSG_ALWAYS("Retrieved (generic) manager " << mgr << " from top-level experiment."); - } - else - { - ATH_MSG_FATAL("Failed to retrieve manager " << mgr); - return StatusCode::FAILURE; - } - } - } - else - { - ATH_MSG_FATAL("Failed to retrieve top-level FASER experiment geometry from DetStore."); - return StatusCode::FAILURE; - } + // GeoModelExperiment* theExpt = nullptr; + // std::vector<std::string> listOfManagers; + // ATH_CHECK(detStore()->retrieve(theExpt, "FASER")); + // if (theExpt != nullptr) + // { + // ATH_MSG_ALWAYS("Retrieved top-level FASER experiment geometry from DetStore."); + // listOfManagers = theExpt->getListOfManagers(); + // ATH_MSG_ALWAYS("Experiment has defined " << listOfManagers.size() << " detector managers:"); + // for (auto mgr : listOfManagers) + // { + // const GeoVDetectorManager* pMgr = nullptr; + // pMgr = theExpt->getManager(mgr); + // if (pMgr != nullptr) + // { + // ATH_MSG_ALWAYS("Retrieved (generic) manager " << mgr << " from top-level experiment."); + // } + // else + // { + // ATH_MSG_FATAL("Failed to retrieve manager " << mgr); + // return StatusCode::FAILURE; + // } + // } + // } + // else + // { + // ATH_MSG_FATAL("Failed to retrieve top-level FASER experiment geometry from DetStore."); + // return StatusCode::FAILURE; + // } - ATH_CHECK(testVeto()); + // ATH_CHECK(testVeto()); - ATH_CHECK(testTrigger()); + // ATH_CHECK(testTrigger()); - ATH_CHECK(testPreshower()); + // ATH_CHECK(testPreshower()); - ATH_CHECK(testSCT()); + // ATH_CHECK(testSCT()); ATH_CHECK(m_alignTool->createDB()); ATH_CHECK(m_alignTool->sortTrans()); diff --git a/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx b/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx index 44569943..50884e72 100644 --- a/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx +++ b/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx @@ -117,6 +117,8 @@ DetDescrCnvSvc::initialize() { // IdHelpers status = addToDetStore(125694213, "FaserID"); if (status != StatusCode::SUCCESS) return status; + status = addToDetStore(89852815, "EmulsionID"); + if (status != StatusCode::SUCCESS) return status; status = addToDetStore(131395045, "VetoID"); if (status != StatusCode::SUCCESS) return status; status = addToDetStore(58382802, "TriggerID"); diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h index b17d61f7..3de4b642 100644 --- a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h +++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h @@ -67,11 +67,18 @@ public: /// @name Detector system ids //@{ /// Detector systems: + Identifier neutrino (void) const; Identifier scint (void) const; Identifier tracker (void) const; Identifier calo (void) const; //@} + /// @name Neutrino subsystem ids + //@{ + Identifier emulsion (void) const; + //@} + + /// @name Scintillator subsystem ids //@{ Identifier veto (void) const; @@ -144,9 +151,11 @@ public: /// @name Test of an Identifier to see if it belongs to a particular detector (sub)system: //@{ + bool is_neutrino (Identifier id) const; bool is_scint (Identifier id) const; bool is_tracker (Identifier id) const; bool is_calo (Identifier id) const; + bool is_emulsion (Identifier id) const; bool is_veto (Identifier id) const; bool is_trigger (Identifier id) const; bool is_preshower (Identifier id) const; @@ -157,9 +166,11 @@ public: /// @name Test of an Identifier to see if it belongs to a particular detector (sub)system (using expanded ids): //@{ + bool is_neutrino (const ExpandedIdentifier& id) const; bool is_scint (const ExpandedIdentifier& id) const; bool is_tracker (const ExpandedIdentifier& id) const; bool is_calo (const ExpandedIdentifier& id) const; + bool is_emulsion (const ExpandedIdentifier& id) const; bool is_veto (const ExpandedIdentifier& id) const; bool is_trigger (const ExpandedIdentifier& id) const; bool is_preshower (const ExpandedIdentifier& id) const; @@ -209,10 +220,14 @@ protected: std::string fix_barrel_ec (const std::string& barrel_ec) const; /// Detector systems: + ExpandedIdentifier neutrino_exp (void) const; ExpandedIdentifier scint_exp (void) const; ExpandedIdentifier tracker_exp (void) const; ExpandedIdentifier calo_exp (void) const; + /// Neutrino: + ExpandedIdentifier emulsion_exp (void) const; + /// Scintillator: ExpandedIdentifier veto_exp (void) const; ExpandedIdentifier trigger_exp (void) const; @@ -226,9 +241,11 @@ protected: /// Provide efficient access to individual field values, for /// subclass idhelpers + int neutrino_field_value () const; int scint_field_value () const; int tracker_field_value () const; int calo_field_value () const; + int emulsion_field_value () const; int veto_field_value () const; int trigger_field_value () const; int preshower_field_value () const; @@ -283,9 +300,11 @@ private: bool m_is_initialized_from_dict; size_type m_DET_INDEX; size_type m_SUBDET_INDEX; + int m_NEUTRINO_ID; int m_SCINT_ID; int m_TRACKER_ID; int m_CALO_ID; + int m_EMULSION_ID; int m_VETO_ID; int m_TRIGGER_ID; int m_PRESHOWER_ID; @@ -296,11 +315,13 @@ private: bool m_isSLHC; IdDictDictionary* m_faser_dict; + IdDictDictionary* m_neutrino_dict; IdDictDictionary* m_scint_dict; IdDictDictionary* m_tracker_dict; IdDictDictionary* m_calo_dict; FaserDetectorIDHelper* m_helper; IdDictFieldImplementation m_det_impl; + IdDictFieldImplementation m_neutrino_part_impl; IdDictFieldImplementation m_scint_part_impl; IdDictFieldImplementation m_tracker_part_impl; IdDictFieldImplementation m_calo_part_impl; @@ -318,6 +339,14 @@ CLASS_DEF(FaserDetectorID, 125694213 , 1) //<<<<<< INLINE MEMBER FUNCTIONS >>>>>> ///////////////////////////////////////////////////////////////////////////// +inline ExpandedIdentifier +FaserDetectorID::neutrino_exp (void) const +{ + ExpandedIdentifier result; + return (result << m_NEUTRINO_ID); +} + + inline ExpandedIdentifier FaserDetectorID::scint_exp (void) const { @@ -339,6 +368,13 @@ FaserDetectorID::calo_exp(void) const return (result << m_CALO_ID); } +inline ExpandedIdentifier +FaserDetectorID::emulsion_exp (void) const +{ + ExpandedIdentifier result(neutrino_exp()); + return (result << m_EMULSION_ID); +} + inline ExpandedIdentifier FaserDetectorID::veto_exp (void) const { @@ -374,6 +410,9 @@ FaserDetectorID::ecal_exp (void) const return (result << m_ECAL_ID); } +inline int +FaserDetectorID::neutrino_field_value () const {return (m_NEUTRINO_ID);} + inline int FaserDetectorID::scint_field_value () const {return (m_SCINT_ID);} @@ -383,6 +422,9 @@ FaserDetectorID::tracker_field_value () const {return (m_TRACKER_ID);} inline int FaserDetectorID::calo_field_value () const {return (m_CALO_ID);} +inline int +FaserDetectorID::emulsion_field_value () const {return (m_EMULSION_ID);} + inline int FaserDetectorID::veto_field_value () const {return (m_VETO_ID);} @@ -398,6 +440,12 @@ FaserDetectorID::sct_field_value () const {return (m_SCT_ID);} inline int FaserDetectorID::ecal_field_value () const {return (m_ECAL_ID);} +inline bool +FaserDetectorID::is_neutrino (Identifier id) const +{ + return (m_det_impl.unpack(id) == m_NEUTRINO_ID); +} + inline bool FaserDetectorID::is_scint (Identifier id) const { @@ -416,6 +464,16 @@ FaserDetectorID::is_calo (Identifier id) const return (m_det_impl.unpack(id) == m_CALO_ID); } +inline bool +FaserDetectorID::is_emulsion (Identifier id) const +{ + bool result = false; + if(is_neutrino(id)) { + result = (m_neutrino_part_impl.unpack(id) == m_EMULSION_ID); + } + return result; +} + inline bool FaserDetectorID::is_veto (Identifier id) const { diff --git a/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx b/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx index 21f01037..9e8dfbb0 100644 --- a/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx +++ b/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx @@ -36,9 +36,11 @@ FaserDetectorID::FaserDetectorID() m_is_initialized_from_dict(false), m_DET_INDEX(999), m_SUBDET_INDEX(999), + m_NEUTRINO_ID(1), m_SCINT_ID(2), m_TRACKER_ID(3), m_CALO_ID(4), + m_EMULSION_ID(1), m_VETO_ID(1), m_TRIGGER_ID(2), m_PRESHOWER_ID(3), @@ -46,6 +48,7 @@ FaserDetectorID::FaserDetectorID() m_ECAL_ID(1), m_isSLHC(false), m_faser_dict(0), + m_neutrino_dict(0), m_scint_dict(0), m_tracker_dict(0), m_calo_dict(0), @@ -68,9 +71,11 @@ FaserDetectorID::FaserDetectorID(const FaserDetectorID& other) m_is_initialized_from_dict(other.m_is_initialized_from_dict), m_DET_INDEX (other.m_DET_INDEX), m_SUBDET_INDEX (other.m_SUBDET_INDEX), + m_NEUTRINO_ID (other.m_NEUTRINO_ID), m_SCINT_ID (other.m_SCINT_ID), m_TRACKER_ID (other.m_TRACKER_ID), m_CALO_ID (other.m_CALO_ID), + m_EMULSION_ID (other.m_EMULSION_ID), m_VETO_ID (other.m_VETO_ID), m_TRIGGER_ID (other.m_TRIGGER_ID), m_PRESHOWER_ID (other.m_PRESHOWER_ID), @@ -78,11 +83,13 @@ FaserDetectorID::FaserDetectorID(const FaserDetectorID& other) m_ECAL_ID (other.m_ECAL_ID), m_isSLHC (other.m_isSLHC), m_faser_dict (other.m_faser_dict), + m_neutrino_dict (other.m_neutrino_dict), m_scint_dict (other.m_scint_dict), m_tracker_dict (other.m_tracker_dict), m_calo_dict (other.m_calo_dict), m_helper (0), m_det_impl (other.m_det_impl), + m_neutrino_part_impl (other.m_neutrino_part_impl), m_scint_part_impl (other.m_scint_part_impl), m_tracker_part_impl (other.m_tracker_part_impl), m_calo_part_impl (other.m_calo_part_impl) @@ -107,19 +114,23 @@ FaserDetectorID::operator= (const FaserDetectorID& other) m_is_initialized_from_dict = other.m_is_initialized_from_dict; m_DET_INDEX = other.m_DET_INDEX; m_SUBDET_INDEX = other.m_SUBDET_INDEX; + m_NEUTRINO_ID = other.m_NEUTRINO_ID; m_SCINT_ID = other.m_SCINT_ID; m_TRACKER_ID = other.m_TRACKER_ID; m_CALO_ID = other.m_CALO_ID; + m_EMULSION_ID = other.m_EMULSION_ID; m_VETO_ID = other.m_VETO_ID; m_TRIGGER_ID = other.m_TRIGGER_ID; m_PRESHOWER_ID = other.m_PRESHOWER_ID; m_SCT_ID = other.m_SCT_ID; m_ECAL_ID = other.m_ECAL_ID; m_faser_dict = other.m_faser_dict; + m_neutrino_dict = other.m_neutrino_dict; m_scint_dict = other.m_scint_dict; m_tracker_dict = other.m_tracker_dict; m_calo_dict = other.m_calo_dict; m_det_impl = other.m_det_impl; + m_neutrino_part_impl = other.m_neutrino_part_impl; m_scint_part_impl = other.m_scint_part_impl; m_tracker_part_impl = other.m_tracker_part_impl; m_calo_part_impl = other.m_calo_part_impl; @@ -135,6 +146,15 @@ FaserDetectorID::operator= (const FaserDetectorID& other) return (*this); } +Identifier +FaserDetectorID::neutrino (void) const +{ + + Identifier result((Identifier::value_type)0); + // Pack field + m_det_impl.pack (neutrino_field_value(), result); + return (result); +} Identifier FaserDetectorID::scint (void) const @@ -164,6 +184,15 @@ FaserDetectorID::calo(void) const return (result); } +Identifier +FaserDetectorID::emulsion (void) const +{ + Identifier result((Identifier::value_type)0); + // Pack field + m_det_impl.pack (neutrino_field_value(), result); + m_neutrino_part_impl.pack(m_EMULSION_ID, result); + return (result); +} Identifier FaserDetectorID::veto (void) const @@ -355,6 +384,16 @@ FaserDetectorID::dictionaryVersion (void) const return (m_dict_version); } +bool +FaserDetectorID::is_neutrino (const ExpandedIdentifier& id) const +{ + bool result = false; + if ( id.fields() > 0 ){ + if ( id[0] == m_NEUTRINO_ID) result = true; + } + return result; +} + bool FaserDetectorID::is_scint (const ExpandedIdentifier& id) const { @@ -385,6 +424,16 @@ FaserDetectorID::is_calo (const ExpandedIdentifier& id) const return result; } +bool +FaserDetectorID::is_emulsion (const ExpandedIdentifier& id) const +{ + bool result = false; + if ( is_neutrino(id) && id.fields() > 1 ){ + if ( id[1] == m_EMULSION_ID ) result = true; + } + return result; +} + bool FaserDetectorID::is_veto (const ExpandedIdentifier& id) const { @@ -469,7 +518,11 @@ FaserDetectorID::show_to_string (Identifier id, ExpandedIdentifier prefix; // default is null prefix Identifier compact = id; - if (is_scint(id)) { + if (is_neutrino(id)) + { + dict = m_neutrino_dict; + } + else if (is_scint(id)) { dict = m_scint_dict; } else if (is_tracker(id)) { @@ -541,7 +594,11 @@ FaserDetectorID::print_to_string (Identifier id, ExpandedIdentifier prefix; // default is null prefix Identifier compact = id; - if (is_scint(id)) { + if (is_neutrino(id)) + { + dict = m_neutrino_dict; + } + else if (is_scint(id)) { dict = m_scint_dict; } else if (is_tracker(id)) { @@ -664,9 +721,11 @@ FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr) // levels and id values m_DET_INDEX = 999; m_SUBDET_INDEX = 999; + m_NEUTRINO_ID = -1; m_SCINT_ID = -1; m_TRACKER_ID = -1; m_CALO_ID = -1; + m_EMULSION_ID = -1; m_VETO_ID = -1; m_TRIGGER_ID = -1; m_PRESHOWER_ID = -1; @@ -678,7 +737,76 @@ FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr) // Get det ids - // Initialize ids for InDet subdet + // Initialize ids for Neutrino subdet + + m_neutrino_dict = dict_mgr.find_dictionary ("Neutrino"); + if(!m_neutrino_dict) { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorID" ); + log << MSG::WARNING << "initLevelsFromDict - cannot access Neutrino dictionary" << endmsg; + } + else { + std::cout << " FaserDetectorID::initLevelsFromDict - Warning cannot access Neutrino dictionary " + << std::endl; + } + } + else { + + // Found Neutrino dict + + top_dict = m_neutrino_dict; // save as top_dict + + // Check if this is SLHC layout + // m_isSLHC = (m_scint_dict->m_version=="SLHC"); + + // Get Neutrino subdets + + field = m_neutrino_dict->find_field("part"); + if (!field) { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorID" ); + log << MSG::ERROR << "initLevelsFromDict - unable to find 'part' field for Neutrino dictionary" << endmsg; + } + else { + std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'part' field for Neutrino dictionary" + << std::endl; + } + return (1); + } + + label = field->find_label("Emulsion"); + if (label) { + if (label->m_valued) { + m_EMULSION_ID = label->m_value; + } + else { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorID" ); + log << MSG::ERROR << "initLevelsFromDict - label Emulsion does NOT have a value " + << endmsg; + } + else { + std::cout << "FaserDetectorID::initLevelsFromDict - label Emulsion does NOT have a value " + << std::endl; + } + return (1); + } + } + else { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorID" ); + log << MSG::ERROR << "initLevelsFromDict - unable to find 'Emulsion' label " + << endmsg; + } + else { + std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Emulsion' label " + << std::endl; + } + return (1); + } + } + + // Initialize ids for Scint subdet m_scint_dict = dict_mgr.find_dictionary ("Scintillator"); if(!m_scint_dict) { if(m_msgSvc) { @@ -956,6 +1084,38 @@ FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr) return (1); } + // Get neutrino id + label = field->find_label("Neutrino"); + if (label) { + if (label->m_valued) { + m_NEUTRINO_ID = label->m_value; + } + else { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorID" ); + log << MSG::ERROR << "initLevelsFromDict - label Neutrino does NOT have a value " + << endmsg; + } + else { + std::cout << "FaserDetectorID::initLevelsFromDict - label Neutrino does NOT have a value " + << std::endl; + } + return (1); + } + } + else { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorID" ); + log << MSG::ERROR << "initLevelsFromDict - unable to find 'Neutrino' label " + << endmsg; + } + else { + std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'Neutrino' label " + << std::endl; + } + return (1); + } + // Get scint id label = field->find_label("Scintillator"); if (label) { @@ -1054,7 +1214,11 @@ FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr) // Get name of next level std::string name; - if (top_dict->m_name == "Scintillator") { + if (top_dict->m_name == "Neutrino") + { + name = "part"; + } + else if (top_dict->m_name == "Scintillator") { name = "part"; } else if (top_dict->m_name == "Calorimeter") { @@ -1104,7 +1268,17 @@ FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr) // Set the field implementations const IdDictRegion* region = 0; - size_type region_index = m_helper->veto_region_index(); + + size_type region_index = m_helper->emulsion_region_index(); + if (m_neutrino_dict && FaserDetectorIDHelper::UNDEFINED != region_index) { + region = m_neutrino_dict->m_regions[region_index]; + // Detector + m_det_impl = region->m_implementation[m_DET_INDEX]; + // InDet part + m_neutrino_part_impl = region->m_implementation[m_SUBDET_INDEX]; + } + + region_index = m_helper->veto_region_index(); if (m_scint_dict && FaserDetectorIDHelper::UNDEFINED != region_index) { region = m_scint_dict->m_regions[region_index]; // Detector diff --git a/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx index 0a877bb9..f192dcaf 100644 --- a/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx +++ b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.cxx @@ -28,6 +28,7 @@ FaserDetectorIDHelper::FaserDetectorIDHelper(void) : m_isSLHC(false), + m_emulsion_region_index(UNDEFINED), m_veto_region_index(UNDEFINED), m_trigger_region_index(UNDEFINED), m_preshower_region_index(UNDEFINED), @@ -51,7 +52,40 @@ FaserDetectorIDHelper::initialize_from_dictionary(const IdDictMgr& dict_mgr) FaserDetectorID faser_id; ExpandedIdentifier id; - const IdDictDictionary* dict = dict_mgr.find_dictionary ("Scintillator"); + const IdDictDictionary* dict = dict_mgr.find_dictionary ("Neutrino"); + if(!dict) { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorIDHelper" ); + log << MSG::WARNING << "initialize_from_dictionary - cannot access Neutrino dictionary " + << endmsg; + } + else { + std::cout << " FaserDetectorIDHelper::initialize_from_dictionary - Warning: cannot access Neutrino dictionary " + << std::endl; + } + } + else { + // Check if this is SLHC layout + // m_isSLHC = (dict->m_version=="SLHC"); + + // Save index to a VETO region for unpacking + id = faser_id.emulsion_exp(); + if (dict->find_region(id, m_emulsion_region_index)) { + if(m_msgSvc) { + MsgStream log(m_msgSvc, "FaserDetectorIDHelper" ); + log << MSG::WARNING << "initialize_from_dictionary - unable to find emulsion region index: id, reg " + << (std::string)id << " " << m_emulsion_region_index + << endmsg; + } + else { + std::cout << "FaserDetectorIDHelper::initialize_from_dictionary - Warning: unable to find emulsion region index: id, reg " + << (std::string)id << " " << m_emulsion_region_index + << std::endl; + } + } + } + + dict = dict_mgr.find_dictionary ("Scintillator"); if(!dict) { if(m_msgSvc) { MsgStream log(m_msgSvc, "FaserDetectorIDHelper" ); diff --git a/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h index 9836bb95..ead07e48 100644 --- a/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h +++ b/DetectorDescription/FaserDetDescr/src/FaserDetectorIDHelper.h @@ -45,6 +45,7 @@ public: ~FaserDetectorIDHelper(void); + size_type emulsion_region_index(); size_type veto_region_index(); size_type trigger_region_index(); size_type preshower_region_index(); @@ -59,6 +60,7 @@ private: /// Flag for slhc layout: bool m_isSLHC; + size_type m_emulsion_region_index; size_type m_veto_region_index; size_type m_trigger_region_index; size_type m_preshower_region_index; @@ -74,6 +76,8 @@ private: //<<<<<< INLINE PUBLIC FUNCTIONS >>>>>> //<<<<<< INLINE MEMBER FUNCTIONS >>>>>> +inline FaserDetectorIDHelper::size_type FaserDetectorIDHelper::emulsion_region_index() +{return (m_emulsion_region_index);} inline FaserDetectorIDHelper::size_type FaserDetectorIDHelper::veto_region_index() {return (m_veto_region_index);} diff --git a/DetectorDescription/GeoModel/FaserGeoAdaptors/CMakeLists.txt b/DetectorDescription/GeoModel/FaserGeoAdaptors/CMakeLists.txt index 5a09b1fe..649f3042 100644 --- a/DetectorDescription/GeoModel/FaserGeoAdaptors/CMakeLists.txt +++ b/DetectorDescription/GeoModel/FaserGeoAdaptors/CMakeLists.txt @@ -14,5 +14,8 @@ atlas_add_library( FaserGeoAdaptors PUBLIC_HEADERS FaserGeoAdaptors INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} DEFINITIONS ${CLHEP_DEFINITIONS} - LINK_LIBRARIES ${CLHEP_LIBRARIES} Identifier FaserCaloIdentifier CaloReadoutGeometry FaserCaloSimEvent ScintIdentifier ScintReadoutGeometry ScintSimEvent TrackerIdentifier TrackerReadoutGeometry TrackerSimEvent StoreGateLib SGtests ) + LINK_LIBRARIES ${CLHEP_LIBRARIES} Identifier NeutrinoIdentifier NeutrinoReadoutGeometry NeutrinoSimEvent + FaserCaloIdentifier CaloReadoutGeometry FaserCaloSimEvent + ScintIdentifier ScintReadoutGeometry ScintSimEvent + TrackerIdentifier TrackerReadoutGeometry TrackerSimEvent StoreGateLib SGtests ) diff --git a/DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.h b/DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.h new file mode 100644 index 00000000..e8ab78a4 --- /dev/null +++ b/DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEOADAPTORS_GEONEUTRINOHIT_h +#define GEOADAPTORS_GEONEUTRINOHIT_h +//----------------------------------------------------------// +// // +// An adaptor for NeutrinoHits. // +// // +// Joe Boudreau Feb 04. // +// // +// This adaptor class allows NeutrinoHits to behave // +// as if they knew which detector they were in. // +// // +// // +//----------------------------------------------------------// +#include "CLHEP/Geometry/Point3D.h" +class NeutrinoHit; +class EmulsionID; +namespace NeutrinoDD { + class EmulsionDetectorManager; +} + +class GeoNeutrinoHit { + + public: + + // Constructor: + GeoNeutrinoHit(const NeutrinoHit & h); + + // Get the absolute global position: + HepGeom::Point3D<double> getGlobalPosition() const; + + // Underlying hit. + const NeutrinoHit &data() const { return *m_hit;} + + // Is this hit ok? + + operator bool () const { return s_emulsion; } + + private: + + static void init(); + + const NeutrinoHit *m_hit; + static const NeutrinoDD::EmulsionDetectorManager *s_emulsion; + static const EmulsionID *s_nID; +}; + +#include "FaserGeoAdaptors/GeoNeutrinoHit.icc" + +#endif diff --git a/DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.icc b/DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.icc new file mode 100644 index 00000000..83df3315 --- /dev/null +++ b/DetectorDescription/GeoModel/FaserGeoAdaptors/FaserGeoAdaptors/GeoNeutrinoHit.icc @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoSimEvent/NeutrinoHit.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "StoreGate/StoreGateSvc.h" +#include "NeutrinoIdentifier/EmulsionID.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +inline void GeoNeutrinoHit::init() { + + ServiceHandle<StoreGateSvc> detStore ("DetectorStore", "GeoNeutrinoHit"); + if (detStore.retrieve().isSuccess()) { + if(detStore->retrieve(s_emulsion,"Emulsion").isFailure()) + s_emulsion = 0; + if(detStore->retrieve(s_nID,"EmulsionID").isFailure()) + s_nID = 0; + } +} + +inline GeoNeutrinoHit::GeoNeutrinoHit (const NeutrinoHit & h) { + m_hit = &h; + if (!s_emulsion) init(); +} + +inline HepGeom::Point3D<double> GeoNeutrinoHit::getGlobalPosition() const { + + Identifier id; + const NeutrinoDD::NeutrinoDetectorElement *geoelement=NULL; + id = s_nID->film_id(m_hit->getModule(), m_hit->getBase(), m_hit->getFilm()); + geoelement = s_emulsion->getDetectorElement(id); + + if (geoelement) { + + const HepGeom::Point3D<double> globalStartPos = Amg::EigenTransformToCLHEP(geoelement->transformHit()) * HepGeom::Point3D<double>(m_hit->localStartPosition()); + const HepGeom::Point3D<double> globalEndPos = Amg::EigenTransformToCLHEP(geoelement->transformHit()) * HepGeom::Point3D<double>(m_hit->localEndPosition()); + + double x=(globalStartPos.x() + globalEndPos.x())/2; + double y=(globalStartPos.y() + globalEndPos.y())/2; + double z=(globalStartPos.z() + globalEndPos.z())/2; + + return HepGeom::Point3D<double>(x,y,z); + } + + return HepGeom::Point3D<double>(0.0,0.0,0.0); +} diff --git a/DetectorDescription/GeoModel/FaserGeoAdaptors/src/statics.cxx b/DetectorDescription/GeoModel/FaserGeoAdaptors/src/statics.cxx index 7c72a510..ca6dd213 100644 --- a/DetectorDescription/GeoModel/FaserGeoAdaptors/src/statics.cxx +++ b/DetectorDescription/GeoModel/FaserGeoAdaptors/src/statics.cxx @@ -5,12 +5,15 @@ #include "FaserGeoAdaptors/GeoScintHit.h" #include "FaserGeoAdaptors/GeoFaserSiHit.h" #include "FaserGeoAdaptors/GeoFaserCaloHit.h" +#include "FaserGeoAdaptors/GeoNeutrinoHit.h" +const NeutrinoDD::EmulsionDetectorManager *GeoNeutrinoHit::s_emulsion = 0; const ScintDD::VetoDetectorManager *GeoScintHit::s_veto = 0; const ScintDD::TriggerDetectorManager *GeoScintHit::s_trigger = 0; const ScintDD::PreshowerDetectorManager *GeoScintHit::s_preshower = 0; const TrackerDD::SCT_DetectorManager *GeoFaserSiHit::s_sct; const CaloDD::EcalDetectorManager *GeoFaserCaloHit::s_ecal = 0; +const EmulsionID *GeoNeutrinoHit::s_nID = 0; const VetoID *GeoScintHit::s_vID = 0; const TriggerID *GeoScintHit::s_tID = 0; const PreshowerID *GeoScintHit::s_pID = 0; diff --git a/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql b/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql index a18d47bc..edd02d7b 100644 --- a/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql +++ b/DetectorDescription/GeoModel/FaserGeoModel/data/geomDB.sql @@ -129,6 +129,58 @@ CREATE TABLE IF NOT EXISTS "EMULSIONTOPLEVEL_DATA2TAG" ( "EMULSIONTOPLEVEL_DATA_ID" SLONGLONG ); -- +DROP TABLE IF EXISTS "EMULSIONGENERAL_DATA"; +CREATE TABLE IF NOT EXISTS "EMULSIONGENERAL_DATA" ( + "EMULSIONGENERAL_DATA_ID" SLONGLONG UNIQUE, + "NMODULES" INT, + "NBASEPERMOD" INT, + "FIRSTBASEZ" DOUBLE, + "LASTBASEZ" DOUBLE +); +-- +DROP TABLE IF EXISTS "EMULSIONGENERAL_DATA2TAG"; +CREATE TABLE IF NOT EXISTS "EMULSIONGENERAL_DATA2TAG" ( + "EMULSIONGENERAL_TAG_ID" SLONGLONG, + "EMULSIONGENERAL_DATA_ID" SLONGLONG +); +-- +DROP TABLE IF EXISTS "EMULSIONFILM_DATA"; +CREATE TABLE IF NOT EXISTS "EMULSIONFILM_DATA" ( + "EMULSIONFILM_DATA_ID" SLONGLONG UNIQUE, + "BASEDX" DOUBLE, + "BASEDY" DOUBLE, + "BASEDZ" DOUBLE, + "BASEMAT" TEXT, + "FILMDX" DOUBLE, + "FILMDY" DOUBLE, + "FILMDZ" DOUBLE, + "FILMMAT" TEXT +); +-- +DROP TABLE IF EXISTS "EMULSIONFILM_DATA2TAG"; +CREATE TABLE IF NOT EXISTS "EMULSIONFILM_DATA2TAG" ( + "EMULSIONFILM_TAG_ID" SLONGLONG, + "EMULSIONFILM_DATA_ID" SLONGLONG +); +-- +DROP TABLE IF EXISTS "EMULSIONPLATES_DATA"; +CREATE TABLE IF NOT EXISTS "EMULSIONPLATES_DATA" ( + "EMULSIONPLATES_DATA_ID" SLONGLONG UNIQUE, + "DX" DOUBLE, + "DY" DOUBLE, + "DZ" DOUBLE, + "POSX" DOUBLE, + "POSY" DOUBLE, + "POSZ" DOUBLE, + "MATERIAL" TEXT +); +-- +DROP TABLE IF EXISTS "EMULSIONPLATES_DATA2TAG"; +CREATE TABLE IF NOT EXISTS "EMULSIONPLATES_DATA2TAG" ( + "EMULSIONPLATES_TAG_ID" SLONGLONG, + "EMULSIONPLATES_DATA_ID" SLONGLONG +); +-- -- Tables for describing Veto scintillator plates (and passive radiators) -- DROP TABLE IF EXISTS "VETOTOPLEVEL_DATA"; @@ -166,6 +218,7 @@ CREATE TABLE IF NOT EXISTS "VETOSTATIONGENERAL_DATA2TAG" ( "VETOSTATIONGENERAL_TAG_ID" SLONGLONG, "VETOSTATIONGENERAL_DATA_ID" SLONGLONG ); +-- DROP TABLE IF EXISTS "VETOPLATEGENERAL_DATA"; CREATE TABLE IF NOT EXISTS "VETOPLATEGENERAL_DATA" ( "VETOPLATEGENERAL_DATA_ID" SLONGLONG UNIQUE, @@ -596,6 +649,9 @@ INSERT INTO "HVS_NODE" VALUES (1004, "NeutrinoMatComponents", 1, 0, NULL); INSERT INTO "HVS_NODE" VALUES (1005, "NeutrinoIdentifier", 1, 0, NULL); INSERT INTO "HVS_NODE" VALUES (11, "Emulsion", 1, 1, NULL); INSERT INTO "HVS_NODE" VALUES (110, "EmulsionTopLevel", 11, 0, NULL); +INSERT INTO "HVS_NODE" VALUES (111, "EmulsionGeneral", 11, 0, NULL); +INSERT INTO "HVS_NODE" VALUES (112, "EmulsionFilm", 11, 0, NULL); +INSERT INTO "HVS_NODE" VALUES (113, "EmulsionPlates", 11, 0, NULL); INSERT INTO "HVS_NODE" VALUES (114, "EmulsionSwitches", 11, 0, NULL); INSERT INTO "HVS_NODE" VALUES (2, "Scintillator", 0, 1, NULL); INSERT INTO "HVS_NODE" VALUES (2003, "ScintMaterials", 2, 0, NULL); @@ -650,6 +706,8 @@ INSERT INTO "HVS_NODE" VALUES (4005, "CaloIdentifier", 4, 0, NULL); INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-00", 100000, NULL, 0, 0, 1549238400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-01", 100039, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-CR", 107784, NULL, 0, 0, 1598400000000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASER-02", 107788, NULL, 0, 0, 1619222400000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (0, "FASERNU-02", 107804, NULL, 0, 0, 1619308800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (90, "FaserCommon-00", 100013, NULL, 0, 0, 1549324800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (9000, "Materials-00", 100005, NULL, 0, 0, 1549238400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (9001, "StdMaterials-00", 100006, NULL, 0, 0, 1549238400000000000, NULL, 22); @@ -658,20 +716,28 @@ INSERT INTO "HVS_TAG2NODE" VALUES (9003, "Elements-00", 100008, NULL, 0, 0, 1549 INSERT INTO "HVS_TAG2NODE" VALUES (1, "Neutrino-00", 100031, NULL, 0, 0, 1582416000000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (11,"Emulsion-00", 100034, NULL, 0, 0, 1582416000000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (110, "EmulsionTopLevel-00", 100035, NULL, 0, 0, 1582416000000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (111, "EmulsionGeneral-00", 107805, NULL, 0, 0, 1619308800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (112, "EmulsionFilm-00", 107806, NULL, 0, 0, 1619308800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (113, "EmulsionPlates-00", 107807, NULL, 0, 0, 1619308800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (114, "EmulsionSwitches-00", 100036, NULL, 0, 0, 1582416000000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (2, "Scintillator-00", 100001, NULL, 0, 0, 1549238400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (2, "Scintillator-01", 100042, NULL, 0, 0, 1590796800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (2, "Scintillator-02", 107789, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-00", 100002, NULL, 0, 0, 1549238400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-01", 100038, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-CR", 107783, NULL, 0, 0, 1598400000000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (3, "Tracker-02", 107790, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-00", 100026, NULL, 0, 0, 1567987200000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-01", 100037, NULL, 0, 0, 1159079680000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-CR", 107781, NULL, 0, 0, 1598400000000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (31, "SCT-02", 107791, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (32, "Dipole-00", 100027, NULL, 0, 0, 1568678400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (32, "Dipole-01", 100041, NULL, 0, 0, 1590796800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (32, "Dipole-02", 107792, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-00", 106788, NULL, 0, 0, 1567987200000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-01", 106790, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-CR", 107786, NULL, 0, 0, 1598400000000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (310, "SctTopLevel-02", 107793, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (311, "SctBarrelModule-00", 107003, NULL, 0, 0, 1567987200000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (312, "SctBarrelSensor-00", 106730, NULL, 0, 0, 1567987200000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (313, "SctFaserGeneral-00", 106789, NULL, 0, 0, 1567987200000000000, NULL, 22); @@ -686,26 +752,33 @@ INSERT INTO "HVS_TAG2NODE" VALUES (3181,"SctFrameGeneral-00", 100054, NULL, 0, 0 INSERT INTO "HVS_TAG2NODE" VALUES (3182,"SctFrameShape-00", 100055, NULL, 0, 0, 1591574400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (320, "DipoleTopLevel-00", 100029, NULL, 0, 0, 1568678400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (320, "DipoleTopLevel-01", 100040, NULL, 0, 0, 1590796800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (320, "DipoleTopLevel-02", 107794, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (321, "DipoleGeneral-00", 100004, NULL, 0, 0, 1568678400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (324, "DipoleSwitches-00", 100028, NULL, 0, 0, 1568678400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (4, "Calorimeter-00", 100003, NULL, 0, 0, 1549238400000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (4, "Calorimeter-02", 107795, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (41, "Ecal-00", 100056, NULL, 0, 0, 1593907200000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (41, "Ecal-02", 107796, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (410, "EcalTopLevel-00", 100058, NULL, 0, 0, 1599350400000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (410, "EcalTopLevel-02", 107797, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (411, "EcalRowGeneral-00", 100059, NULL, 0, 0, 1599350400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (414, "EcalSwitches-00", 100057, NULL, 0, 0, 1593907200000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (210, "VetoTopLevel-00", 100009, NULL, 0, 0, 1567123200000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (210, "VetoTopLevel-01", 100046, NULL, 0, 0, 1590796800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (210, "VetoTopLevel-02", 107798, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (211, "VetoStationGeneral-00", 100010, NULL, 0, 0, 1567123200000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (212, "VetoPlateGeneral-00", 100025, NULL, 0, 0, 1567209600000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (211, "VetoStationGeneral-01", 100049, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (212, "VetoPlateGeneral-01", 100050, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (220, "TriggerTopLevel-00", 110009, NULL, 0, 0, 1581292800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (220, "TriggerTopLevel-01", 100047, NULL, 0, 0, 1590796800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (220, "TriggerTopLevel-02", 107799, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (221, "TriggerStationGeneral-00", 110010, NULL, 0, 0, 1581292800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (221, "TriggerStationGeneral-01", 100051, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (222, "TriggerPlateGeneral-00", 110025, NULL, 0, 0, 1581292800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (230, "PreshowerTopLevel-00", 120009, NULL, 0, 0, 1581292800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (230, "PreshowerTopLevel-01", 100048, NULL, 0, 0, 1590796800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (230, "PreshowerTopLevel-02", 107800, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (231, "PreshowerStationGeneral-00", 120010, NULL, 0, 0, 1581292800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (231, "PreshowerStationGeneral-01", 100052, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (232, "PreshowerPlateGeneral-00", 120025, NULL, 0, 0, 1581292800000000000, NULL, 22); @@ -726,119 +799,173 @@ INSERT INTO "HVS_TAG2NODE" VALUES (23, "Preshower-00", 100020, NULL, 0, 0, 15504 INSERT INTO "HVS_TAG2NODE" VALUES (21, "Veto-01", 100043, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (22, "Trigger-01", 100044, NULL, 0, 0, 1590796800000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (23, "Preshower-01", 100045, NULL, 0, 0, 1590796800000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (21, "Veto-02", 107801, NULL, 0, 0, 1619222400000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (22, "Trigger-02", 107802, NULL, 0, 0, 1619222400000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (23, "Preshower-02", 107803, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (1005, "NeutrinoIdentifier-00", 100030, NULL, 0, 0, 1582416000000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (2005, "ScintIdentifier-00", 100016, NULL, 0, 0, 1550448000000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (3005, "TrackerIdentifier-00", 100017, NULL, 0, 0, 1550448000000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (3005, "TrackerIdentifier-CR", 107785, NULL, 0, 0, 1598400000000000000, NULL, 22); +INSERT INTO "HVS_TAG2NODE" VALUES (3005, "TrackerIdentifier-02", 107787, NULL, 0, 0, 1619222400000000000, NULL, 22); INSERT INTO "HVS_TAG2NODE" VALUES (4005, "CaloIdentifier-00", 100018, NULL, 0, 0, 1550448000000000000, NULL, 22); -- Data for the HVS_LTAG2LTAG table +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107804, 1, 100031); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 2, 100001); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100039, 2, 100042); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107784, 2, 100042); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107788, 2, 107789); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 3, 100002); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100039, 3, 100038); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107784, 3, 107783); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107788, 3, 107790); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 4, 100003); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100039, 4, 100003); INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107784, 4, 100003); -INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 9000, 100005); -INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100039, 9000, 100005); -INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107784, 9000, 100005); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107788, 4, 107795); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 90, 100013); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100039, 90, 100013); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107788, 90, 100013); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 9000, 100005); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100039, 9000, 100005); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107784, 9000, 100005); +INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 107788, 9000, 100005); INSERT INTO "HVS_LTAG2LTAG" VALUES (9000, 100005, 9001, 100006); INSERT INTO "HVS_LTAG2LTAG" VALUES (9000, 100005, 9002, 100007); INSERT INTO "HVS_LTAG2LTAG" VALUES (9000, 100005, 9003, 100008); INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100031, 11, 100034); INSERT INTO "HVS_LTAG2LTAG" VALUES (11, 100034, 110, 100035); +INSERT INTO "HVS_LTAG2LTAG" VALUES (11, 100034, 111, 107805); +INSERT INTO "HVS_LTAG2LTAG" VALUES (11, 100034, 112, 107806); +INSERT INTO "HVS_LTAG2LTAG" VALUES (11, 100034, 113, 107807); INSERT INTO "HVS_LTAG2LTAG" VALUES (11, 100034, 114, 100036); INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100031, 1003, 100032); INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100031, 1004, 100033); +INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100031, 1005, 100030); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 21, 100015); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 22, 100019); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 23, 100020); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 21, 100043); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 22, 100044); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 23, 100045); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 107789, 21, 107801); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 107789, 22, 107802); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 107789, 23, 107803); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 2003, 100011); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 2004, 100012); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 2005, 100016); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 2003, 100011); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 2004, 100012); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 2005, 100016); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 107789, 2003, 100011); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 107789, 2004, 100012); +INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 107789, 2005, 100016); INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100015, 210, 100009); INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100043, 210, 100046); +INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 107801, 210, 100046); INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100015, 211, 100010); -INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100015, 212, 100025); INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100043, 211, 100049); +INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 107801, 211, 100049); +INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100015, 212, 100025); INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100043, 212, 100050); +INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 107801, 212, 100050); +INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100015, 214, 100014); +INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100043, 214, 100014); +INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 107801, 214, 100014); INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100019, 220, 110009); INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100044, 220, 100047); +INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 107802, 220, 100047); INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100019, 221, 110010); INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100044, 221, 100051); +INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 107802, 221, 100051); INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100019, 222, 110025); -INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100044, 221, 110010); INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100044, 222, 110025); +INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 107802, 222, 110025); +INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100019, 224, 110014); +INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100044, 224, 110014); +INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 107802, 224, 110014); INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100020, 230, 120009); INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100045, 230, 120048); +INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 107803, 230, 120048); INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100020, 231, 120010); INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100045, 231, 100052); +INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 107803, 231, 100052); INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100020, 232, 120025); INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100045, 232, 120025); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 2003, 100011); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 2004, 100012); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 2003, 100011); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 2004, 100012); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 3003, 100021); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 3004, 100022); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 3003, 100021); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 3004, 100022); +INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 107803, 232, 120025); +INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100020, 234, 120014); +INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100045, 234, 120014); +INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 107803, 234, 120014); INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 31, 100026); INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 31, 100037); INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107783, 31, 107781); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107790, 31, 107791); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 32, 100027); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 32, 100041); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107790, 32, 107792); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 3003, 100021); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 3003, 100021); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107790, 3003, 100021); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 3004, 100022); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 3004, 100022); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107790, 3004, 100022); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 3005, 100017); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 3005, 100017); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107781, 3005, 107785); +INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107790, 3005, 107787); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 310, 106788); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 310, 106790); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100081, 310, 107786); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 310, 106790); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 311, 107003); -INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 312, 106730); -INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 313, 106789); -INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 314, 107782); -INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 315, 107777); -INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 316, 107778); -INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 317, 107779); -INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 318, 100053); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 311, 107003); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 311, 107003); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 312, 106730); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 312, 106730); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 312, 106730); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 313, 106789); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 313, 106791); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107781, 313, 107780); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 313, 106791); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 314, 107782); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 314, 107782); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 314, 107782); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 315, 107777); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 315, 107777); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 315, 107777); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 316, 107778); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 316, 107778); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 316, 107778); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 317, 107779); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 317, 107779); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 317, 107779); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100026, 318, 100053); INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 100037, 318, 100053); +INSERT INTO "HVS_LTAG2LTAG" VALUES (31, 107791, 318, 100053); INSERT INTO "HVS_LTAG2LTAG" VALUES (318, 100053, 3181, 100054); INSERT INTO "HVS_LTAG2LTAG" VALUES (318, 100053, 3182, 100055); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 32, 100027); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 32, 100041); INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100027, 320, 100029); -INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100027, 321, 100004); -INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100027, 324, 100028); INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100041, 320, 100040); +INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 107792, 320, 107794); +INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100027, 321, 100004); INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100041, 321, 100004); +INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 107792, 321, 100004); +INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100027, 324, 100028); INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 100041, 324, 100028); +INSERT INTO "HVS_LTAG2LTAG" VALUES (32, 107792, 324, 100028); INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 100003, 41, 100056); -INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 100056, 410, 100058); -INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 100056, 411, 100059); -INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 100056, 414, 100057); +INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 107795, 41, 107796); INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 100003, 4003, 100023); INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 100003, 4004, 100024); -INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100000, 90, 100013); -INSERT INTO "HVS_LTAG2LTAG" VALUES (0, 100039, 90, 100013); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 21, 100015); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 22, 100019); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 23, 100020); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 21, 100043); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 22, 100044); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 23, 100045); -INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100015, 214, 100014); -INSERT INTO "HVS_LTAG2LTAG" VALUES (21, 100043, 214, 100014); -INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100019, 224, 110014); -INSERT INTO "HVS_LTAG2LTAG" VALUES (22, 100044, 224, 110014); -INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100020, 234, 120014); -INSERT INTO "HVS_LTAG2LTAG" VALUES (23, 100045, 234, 120014); -INSERT INTO "HVS_LTAG2LTAG" VALUES (1, 100031, 1005, 100030); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100001, 2005, 100016); -INSERT INTO "HVS_LTAG2LTAG" VALUES (2, 100042, 2005, 100016); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100002, 3005, 100017); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 100038, 3005, 100017); -INSERT INTO "HVS_LTAG2LTAG" VALUES (3, 107781, 3005, 107785); INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 100003, 4005, 100018); +INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 107795, 4003, 100023); +INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 107795, 4004, 100024); +INSERT INTO "HVS_LTAG2LTAG" VALUES (4, 107795, 4005, 100018); +INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 100056, 410, 100058); +INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 107796, 410, 107797); +INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 100056, 411, 100059); +INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 100056, 414, 100057); +INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 107796, 411, 100059); +INSERT INTO "HVS_LTAG2LTAG" VALUES (41, 107796, 414, 100057); -- Data for the HVS_TAGCACHE table INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "FASER", "FASER-00", 100000); INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-00", "FaserCommon", "FaserCommon-00", 100013); @@ -1020,6 +1147,128 @@ INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "NeutrinoIdentifier", "NeutrinoId INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "ScintIdentifier", "ScintIdentifier-00", 100016); INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "TrackerIdentifier", "TrackerIdentifier-CR", 107785); INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-CR", "CaloIdentifier", "CaloIdentifier-00", 100018); + +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "FASER", "FASER-02", 107788); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "FaserCommon", "FaserCommon-00", 100013); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Materials", "Materials-00", 100005); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "StdMaterials", "StdMaterials-00", 100006); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "StdMatComponents", "StdMatComponents-00", 100007); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Elements", "Elements-00", 100008); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Scintillator", "Scintillator-02", 107789); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Tracker", "Tracker-02", 107790); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SCT", "SCT-02", 107791); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctTopLevel", "SCTTopLevel-02", 107793); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctBrlModule", "SCTBrlModule-00", 107003); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctBrlSensor", "SCTBrlSensor-00", 106730); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctFaserGeneral", "SCTFaserGeneral-01", 106791); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctSwitches", "SCTSwitches-00", 107782); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SCTMaterials", "SCTMaterials-00", 107777); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SCTMatComponents", "SCTMatComponents-00", 107778); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctConditions", "SctConditions-00", 107779); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctFrame", "SctFrame-00", 100053); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctFrameGeneral", "SctFrameGeneral-00", 100054); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "SctFrameShape", "SctFrameShape-00", 100055); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Dipole", "Dipole-02", 107792); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "DipoleTopLevel", "DipoleTopLevel-02", 107794); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "DipoleGeneral", "DipoleGeneral-00", 100004); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "DipoleSwitches", "DipoleSwitches-00", 100028); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Calorimeter", "Calorimeter-02", 107795); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Ecal", "Ecal-02", 107796); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "EcalTopLevel", "EcalTopLevel-02", 107797); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "EcalRowGeneral", "EcalRowGeneral-00", 100059); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "EcalSwitches", "EcalSwitches-00", 100057); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoTopLevel", "VetoTopLevel-02", 107798); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoStationGeneral", "VetoStationGeneral-01", 100049); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoPlateGeneral", "VetoPlateGeneral-01", 100050); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TriggerTopLevel", "TriggerTopLevel-02", 107799); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TriggerStationGeneral", "TriggerStationGeneral-01", 100051); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TriggerPlateGeneral", "TriggerPlateGeneral-00", 110025); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerTopLevel", "PreshowerTopLevel-02", 107800); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerStationGeneral", "PreshowerStationGeneral-01", 100052); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerPlateGeneral", "PreshowerPlateGeneral-00", 120025); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "NeutrinoMaterials", "NeutrinoMaterials-00", 100032); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "NeutrinoMatComponents", "NeutrinoMatComponents-00", 100033); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "ScintMaterials", "ScintMaterials-00", 100011); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "ScintMatComponents", "ScintMatComponents-00", 100012); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TrackerMaterials", "TrackerMaterials-00", 100021); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TrackerMatComponents", "TrackerMatComponents-00", 100022); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "CaloMaterials", "CaloMaterials-00", 100023); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "CaloMatComponents", "CaloMatComponents-00", 100024); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "VetoSwitches", "VetoSwitches-00", 100014); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TriggerSwitches", "TriggerSwitches-00", 110014); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "PreshowerSwitches", "PreshowerSwitches-00", 120014); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Veto", "Veto-02", 107801); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Trigger", "Trigger-02", 107802); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "Preshower", "Preshower-02", 107803); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "NeutrinoIdentifier", "NeutrinoIdentifier-00", 100030); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "ScintIdentifier", "ScintIdentifier-00", 100016); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "TrackerIdentifier", "TrackerIdentifier-02", 107787); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASER-02", "CaloIdentifier", "CaloIdentifier-00", 100018); + +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "FASER", "FASERNU-02", 107804); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "FaserCommon", "FaserCommon-00", 100013); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Materials", "Materials-00", 100005); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "StdMaterials", "StdMaterials-00", 100006); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "StdMatComponents", "StdMatComponents-00", 100007); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Elements", "Elements-00", 100008); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Neutrino", "Neutrino-00", 100031); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Emulsion", "Emulsion-00", 100034); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EmulsionTopLevel", "EmulsionTopLevel-00", 100035); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EmulsionGeneral", "EmulsionGeneral-00", 107805); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EmulsionFilm", "EmulsionFilm-00", 107806); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EmulsionPlates", "EmulsionPlates-00", 107807); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EmulsionSwitches", "EmulsionSwitches-00", 100036); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Scintillator", "Scintillator-02", 107789); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Tracker", "Tracker-02", 107790); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SCT", "SCT-02", 107791); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctTopLevel", "SCTTopLevel-02", 107793); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctBrlModule", "SCTBrlModule-00", 107003); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctBrlSensor", "SCTBrlSensor-00", 106730); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctFaserGeneral", "SCTFaserGeneral-01", 106791); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctSwitches", "SCTSwitches-00", 107782); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SCTMaterials", "SCTMaterials-00", 107777); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SCTMatComponents", "SCTMatComponents-00", 107778); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctConditions", "SctConditions-00", 107779); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctFrame", "SctFrame-00", 100053); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctFrameGeneral", "SctFrameGeneral-00", 100054); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "SctFrameShape", "SctFrameShape-00", 100055); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Dipole", "Dipole-02", 107792); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "DipoleTopLevel", "DipoleTopLevel-02", 107794); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "DipoleGeneral", "DipoleGeneral-00", 100004); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "DipoleSwitches", "DipoleSwitches-00", 100028); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Calorimeter", "Calorimeter-02", 107795); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Ecal", "Ecal-02", 107796); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EcalTopLevel", "EcalTopLevel-02", 107797); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EcalRowGeneral", "EcalRowGeneral-00", 100059); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "EcalSwitches", "EcalSwitches-00", 100057); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoTopLevel", "VetoTopLevel-02", 107798); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoStationGeneral", "VetoStationGeneral-01", 100049); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoPlateGeneral", "VetoPlateGeneral-01", 100050); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TriggerTopLevel", "TriggerTopLevel-02", 107799); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TriggerStationGeneral", "TriggerStationGeneral-01", 100051); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TriggerPlateGeneral", "TriggerPlateGeneral-00", 110025); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerTopLevel", "PreshowerTopLevel-02", 107800); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerStationGeneral", "PreshowerStationGeneral-01", 100052); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerPlateGeneral", "PreshowerPlateGeneral-00", 120025); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "NeutrinoMaterials", "NeutrinoMaterials-00", 100032); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "NeutrinoMatComponents", "NeutrinoMatComponents-00", 100033); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "ScintMaterials", "ScintMaterials-00", 100011); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "ScintMatComponents", "ScintMatComponents-00", 100012); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TrackerMaterials", "TrackerMaterials-00", 100021); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TrackerMatComponents", "TrackerMatComponents-00", 100022); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "CaloMaterials", "CaloMaterials-00", 100023); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "CaloMatComponents", "CaloMatComponents-00", 100024); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "VetoSwitches", "VetoSwitches-00", 100014); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TriggerSwitches", "TriggerSwitches-00", 110014); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "PreshowerSwitches", "PreshowerSwitches-00", 120014); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Veto", "Veto-02", 107801); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Trigger", "Trigger-02", 107802); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "Preshower", "Preshower-02", 107803); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "NeutrinoIdentifier", "NeutrinoIdentifier-00", 100030); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "ScintIdentifier", "ScintIdentifier-00", 100016); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "TrackerIdentifier", "TrackerIdentifier-02", 107787); +INSERT INTO "HVS_TAGCACHE" VALUES ("FASERNU-02", "CaloIdentifier", "CaloIdentifier-00", 100018); + -- -- -- Part 2b: Content (Leaf node) data @@ -1562,18 +1811,72 @@ INSERT INTO "ELEMENTS_DATA2TAG" VALUES (100008, 90); INSERT INTO "ELEMENTS_DATA2TAG" VALUES (100008, 91); -- -- +INSERT INTO "EMULSIONTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, -2475.72, 0.0, 0.0, 0.0, 321, "Emulsion"); +INSERT INTO "EMULSIONTOPLEVEL_DATA" VALUES (1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 321, "StationA"); +INSERT INTO "EMULSIONTOPLEVEL_DATA2TAG" VALUES (100035, 0); +INSERT INTO "EMULSIONTOPLEVEL_DATA2TAG" VALUES (100035, 1); +-- +-- +INSERT INTO "EMULSIONGENERAL_DATA" VALUES (0, 35, 22, -524.275, 525.275); +INSERT INTO "EMULSIONGENERAL_DATA2TAG" VALUES (107805, 0); +-- +-- +INSERT INTO "EMULSIONFILM_DATA" VALUES (0, 250.0, 300.0, 0.210, "neutrino::Polystyrene", 250.0, 300.0, 0.070, "neutrino::Emulsion"); +INSERT INTO "EMULSIONFILM_DATA2TAG" VALUES (107806, 0); +-- +-- +INSERT INTO "EMULSIONPLATES_DATA" VALUES (0, 250.0, 300.0, 1050.9, 0.0, 0.0, 0.0, "std::Wolfram"); +INSERT INTO "EMULSIONPLATES_DATA2TAG" VALUES (107807, 0); +-- +-- +INSERT INTO "NEUTRINOMATERIALS_DATA" VALUES (0, "Polystyrene", 1.06); +INSERT INTO "NEUTRINOMATERIALS_DATA" VALUES (1, "Emulsion", 3.58); +INSERT INTO "NEUTRINOMATERIALS_DATA2TAG" VALUES (100032, 0); +INSERT INTO "NEUTRINOMATERIALS_DATA2TAG" VALUES (100032, 1); +-- +-- +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(0, 0, "Hydrogen", 8.0); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(1, 0, "Carbon", 8.0); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(2, 1, "Hydrogen", 0.388171); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(3, 1, "Carbon", 0.184594); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(4, 1, "Nitrogen", 0.052763); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(5, 1, "Oxygen", 0.119373); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(6, 1, "Sodium", 0.002647); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(7, 1, "Sulfur", 0.001708); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(8, 1, "Bromine", 0.123103); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(9, 1, "Silver", 0.125381); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA" VALUES(10,1, "Iodine", 0.002261); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 0); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 1); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 2); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 3); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 4); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 5); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 6); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 7); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 8); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 9); +INSERT INTO "NEUTRINOMATCOMPONENTS_DATA2TAG" VALUES (100033, 10); +-- +-- INSERT INTO "VETOTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, -1725.0, 0.0, 0.0, 0.0, 321, "Veto"); INSERT INTO "VETOTOPLEVEL_DATA" VALUES (1, 0.0, 0.0, -160.0, 0.0, 0.0, 0.0, 321, "StationA"); INSERT INTO "VETOTOPLEVEL_DATA" VALUES (2, 0.0, 0.0, 160.0, 0.0, 0.0, 0.0, 321, "StationB"); INSERT INTO "VETOTOPLEVEL_DATA" VALUES (3, 0.0, 0.0, -1709.0, 0.0, 0.0, 0.0, 321, "Veto"); INSERT INTO "VETOTOPLEVEL_DATA" VALUES (4, 0.0, 0.0, -100.0, 0.0, 0.0, 0.0, 321, "StationA"); INSERT INTO "VETOTOPLEVEL_DATA" VALUES (5, 0.0, 0.0, 100.0, 0.0, 0.0, 0.0, 321, "StationB"); +INSERT INTO "VETOTOPLEVEL_DATA" VALUES (6, 0.0, 0.0, -1694.65, 0.0, 0.0, 0.0, 321, "Veto"); +INSERT INTO "VETOTOPLEVEL_DATA" VALUES (7, 0.0, 0.0, -85.0, 0.0, 0.0, 2.6, 321, "StationA"); +INSERT INTO "VETOTOPLEVEL_DATA" VALUES (8, 0.0, 0.0, 85.0, 0.0, 0.0,-2.6, 321, "StationB"); INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100009, 0); INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100009, 1); INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100009, 2); INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100046, 3); INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100046, 4); INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (100046, 5); +INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107798, 6); +INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107798, 7); +INSERT INTO "VETOTOPLEVEL_DATA2TAG" VALUES (107798, 8); -- -- INSERT INTO "VETOSTATIONGENERAL_DATA" VALUES (0, 2, 100.0); @@ -1590,10 +1893,13 @@ INSERT INTO "VETOPLATEGENERAL_DATA2TAG" VALUES (100050, 1); INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, 187.0, 0.0, 0.0, 0.0, 321, "Trigger"); INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 321, "StationA"); INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (2, 0.0, -5.0, -28.9, 0.0, 0.0, 0.0, 321, "Trigger"); +INSERT INTO "TRIGGERTOPLEVEL_DATA" VALUES (3, 0.0, -5.0, -29.2, 0.0, 0.0, 0.0, 321, "Trigger"); INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (110009, 0); INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (110009, 1); INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (100047, 1); INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (100047, 2); +INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (107799, 3); +INSERT INTO "TRIGGERTOPLEVEL_DATA2TAG" VALUES (107799, 1); -- -- INSERT INTO "TRIGGERSTATIONGENERAL_DATA" VALUES (0, 2, 195.0, 11.0); @@ -1608,10 +1914,13 @@ INSERT INTO "TRIGGERPLATEGENERAL_DATA2TAG" VALUES (110025, 0); INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, 2626.0, 0.0, 0.0, 0.0, 321, "Preshower"); INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 321, "StationA"); INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (2, 0.0, 0.0, 2662.7, 0.0, 0.0, 0.0, 321, "Preshower"); +INSERT INTO "PRESHOWERTOPLEVEL_DATA" VALUES (3, 0.0, 0.0, 2662.35, 0.0, 0.0, 0.0, 321, "Preshower"); INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (120009, 0); INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (120009, 1); INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (100048, 1); INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (100048, 2); +INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (107800, 1); +INSERT INTO "PRESHOWERTOPLEVEL_DATA2TAG" VALUES (107800, 3); -- -- INSERT INTO "PRESHOWERSTATIONGENERAL_DATA" VALUES (0, 2, 80.0); @@ -1626,9 +1935,13 @@ INSERT INTO "PRESHOWERPLATEGENERAL_DATA2TAG" VALUES (120025, 0); INSERT INTO "ECALTOPLEVEL_DATA" VALUES (0, 0.0, 0.0, 3099.2, 0.0, 0.0, 0.0, 321, "Ecal"); INSERT INTO "ECALTOPLEVEL_DATA" VALUES (1, 0.0, -71.6, 0.0, 0.0, 2.8, 0.0, 321, "BottomRow"); INSERT INTO "ECALTOPLEVEL_DATA" VALUES (2, 0.0, 49.6, 0.0, 0.0, 2.8, 0.0, 321, "TopRow"); +INSERT INTO "ECALTOPLEVEL_DATA" VALUES (3, 0.0, 0.0, 3098.9, 0.0, 0.0, 0.0, 321, "Ecal"); INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (100058, 0); INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (100058, 1); INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (100058, 2); +INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107797, 1); +INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107797, 2); +INSERT INTO "ECALTOPLEVEL_DATA2TAG" VALUES (107797, 3); -- -- INSERT INTO "ECALROWGENERAL_DATA" VALUES (0, 2, 0.0, 2.8); @@ -1649,6 +1962,10 @@ INSERT INTO "FASERCOMMON_DATA" VALUES (0, "RUN3", "TRACKER", "NONE"); INSERT INTO "FASERCOMMON_DATA2TAG" VALUES (100013, 0); -- -- +INSERT INTO "EMULSIONSWITCHES_DATA" VALUES (0, "Emulsion", 1, 0, "GEO", "Development", "Baseline geometry"); +INSERT INTO "EMULSIONSWITCHES_DATA2TAG" VALUES (100036, 0); +-- +-- INSERT INTO "VETOSWITCHES_DATA" VALUES (0, "Veto", 1, 0, "GEO", "Development", "Baseline geometry"); INSERT INTO "VETOSWITCHES_DATA2TAG" VALUES (100014, 0); -- @@ -1675,8 +1992,10 @@ INSERT INTO "SCINTIDENTIFIER_DATA2TAG" VALUES (100016, 0); -- INSERT INTO "TRACKERIDENTIFIER_DATA" VALUES (0, "Tracker", "TrackerIdDictFiles/IdDictTracker.xml", "Baseline layout"); INSERT INTO "TRACKERIDENTIFIER_DATA" VALUES (1, "Tracker", "TrackerIdDictFiles/IdDictCosmic.xml", "Cosmic ray test stand"); +INSERT INTO "TRACKERIDENTIFIER_DATA" VALUES (2, "Tracker", "TrackerIdDictFiles/IdDictInterface.xml", "Tracker with interface detector"); INSERT INTO "TRACKERIDENTIFIER_DATA2TAG" VALUES (100017, 0); INSERT INTO "TRACKERIDENTIFIER_DATA2TAG" VALUES (107785, 1); +INSERT INTO "TRACKERIDENTIFIER_DATA2TAG" VALUES (107787, 2); -- -- INSERT INTO "CALOIDENTIFIER_DATA" VALUES (0, "Calorimeter", "CaloIdDictFiles/IdDictCalorimeter.xml", "Baseline layout"); @@ -1713,6 +2032,9 @@ INSERT INTO "SCTTOPLEVEL_DATA" VALUES(4,0.0,0.0,-1190.0,0.0,0.0,0.0,312,'Station INSERT INTO "SCTTOPLEVEL_DATA" VALUES(5,0.0,0.0, 0.0,0.0,0.0,0.0,312,'StationB'); INSERT INTO "SCTTOPLEVEL_DATA" VALUES(6,0.0,0.0, 1190.0,0.0,0.0,0.0,312,'StationC'); INSERT INTO "SCTTOPLEVEL_DATA" VALUES(7,0.0,0.0, 1237.7075,0.0,0.0,0.0,312,'SCT'); +INSERT INTO "SCTTOPLEVEL_DATA" VALUES(8,0.0,0.0, 1237.4 ,0.0,0.0,0.0,312,'SCT'); +INSERT INTO "SCTTOPLEVEL_DATA" VALUES(9,0.0,0.0,-3097.55 ,0.0,0.0,0.0,312,'Interface'); + DROP TABLE IF EXISTS "SCTTOPLEVEL_DATA2TAG"; CREATE TABLE "SCTTOPLEVEL_DATA2TAG" ( "SCTTOPLEVEL_TAG_ID" SLONGLONG ,"SCTTOPLEVEL_DATA_ID" SLONGLONG ); @@ -1726,6 +2048,11 @@ INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(106790,6); INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(106790,7); INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107786,5); INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107786,7); +INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,4); +INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,5); +INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,6); +INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,8); +INSERT INTO "SCTTOPLEVEL_DATA2TAG" VALUES(107793,9); -- -- DROP TABLE IF EXISTS "SCTFASERGENERAL_DATA"; @@ -1844,6 +2171,10 @@ INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(3,0.0,0.0, 0.0,0.0,0.0,0.0,312,'Dipole' INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(4,0.0,0.0,-812.32,0.0,0.0,0.0,312,'UpstreamDipole'); INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(5,0.0,0.0, 637.726,0.0,0.0,0.0,312,'CentralDipole'); INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(6,0.0,0.0,1837.726,0.0,0.0,0.0,312,'DownstreamDipole'); +INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(7,0.0,0.0,-812.60,0.0,0.0,0.0,312,'UpstreamDipole'); +INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(8,0.0,0.0, 637.40,0.0,0.0,0.0,312,'CentralDipole'); +INSERT INTO "DIPOLETOPLEVEL_DATA" VALUES(9,0.0,0.0,1837.40,0.0,0.0,0.0,312,'DownstreamDipole'); + DROP TABLE IF EXISTS "DIPOLETOPLEVEL_DATA2TAG"; CREATE TABLE "DIPOLETOPLEVEL_DATA2TAG" ( "DIPOLETOPLEVEL_TAG_ID" SLONGLONG ,"DIPOLETOPLEVEL_DATA_ID" SLONGLONG ); @@ -1855,6 +2186,10 @@ INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(100040,3); INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(100040,4); INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(100040,5); INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(100040,6); +INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,3); +INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,7); +INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,8); +INSERT INTO "DIPOLETOPLEVEL_DATA2TAG" VALUES(107794,9); -- -- DROP TABLE IF EXISTS "DIPOLEGENERAL_DATA"; diff --git a/DetectorDescription/GeoModel/FaserGeoModel/python/FaserGeoModelConfig.py b/DetectorDescription/GeoModel/FaserGeoModel/python/FaserGeoModelConfig.py index c75cbdbc..72e1d79a 100644 --- a/DetectorDescription/GeoModel/FaserGeoModel/python/FaserGeoModelConfig.py +++ b/DetectorDescription/GeoModel/FaserGeoModel/python/FaserGeoModelConfig.py @@ -8,6 +8,9 @@ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator def FaserGeometryCfg (flags): acc = ComponentAccumulator() + from EmulsionGeoModel.EmulsionGeoModelConfig import EmulsionGeometryCfg + acc.merge(EmulsionGeometryCfg(flags)) + from FaserGeoModel.ScintGMConfig import ScintGeometryCfg acc.merge(ScintGeometryCfg(flags)) diff --git a/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py b/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py index 7d9c16d9..e645c94b 100644 --- a/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py +++ b/DetectorDescription/GeoModel/FaserGeoModel/python/GeoModelInit.py @@ -22,6 +22,10 @@ def _setupGeoModel(): # Set up detector tools here + if not hasattr(svcMgr,'NeutrinoGeometryDBSvc'): + from GeometryDBSvc.GeometryDBSvcConf import GeometryDBSvc + svcMgr+=GeometryDBSvc("NeutrinoGeometryDBSvc") + if not hasattr(svcMgr,'ScintGeometryDBSvc'): from GeometryDBSvc.GeometryDBSvcConf import GeometryDBSvc svcMgr+=GeometryDBSvc("ScintGeometryDBSvc") @@ -35,6 +39,10 @@ def _setupGeoModel(): svcMgr+=GeometryDBSvc("CaloGeometryDBSvc") # from AthenaCommon import CfgGetter + from EmulsionGeoModel.EmulsionGeoModelConf import EmulsionDetectorTool + emulsionDetectorTool = EmulsionDetectorTool(DetectorName = "Emulsion", Alignable = True, RDBAccessSvc = "RDBAccessSvc", GeometryDBSvc = "NeutrinoGeometryDBSvc", GeoDbTagSvc = "GeoDbTagSvc") + geoModelSvc.DetectorTools += [ emulsionDetectorTool ] + from VetoGeoModel.VetoGeoModelConf import VetoDetectorTool vetoDetectorTool = VetoDetectorTool( DetectorName = "Veto", Alignable = True, diff --git a/DetectorDescription/GeoModel/FaserGeoModel/python/ScintGMConfig.py b/DetectorDescription/GeoModel/FaserGeoModel/python/ScintGMConfig.py index 1c94db58..93c42c05 100644 --- a/DetectorDescription/GeoModel/FaserGeoModel/python/ScintGMConfig.py +++ b/DetectorDescription/GeoModel/FaserGeoModel/python/ScintGMConfig.py @@ -35,7 +35,7 @@ if __name__ == "__main__": # from AthenaConfiguration.TestDefaults import defaultTestFiles # Provide MC input # ConfigFlags.Input.Files = defaultTestFiles.HITS - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.Detector.GeometryVeto = True ConfigFlags.Detector.GeometryTrigger= True ConfigFlags.Detector.GeometryPreshower= True diff --git a/DetectorDescription/GeoModel/FaserGeoModel/test/FaserGeometryConfig_EVNT_test.py b/DetectorDescription/GeoModel/FaserGeoModel/test/FaserGeometryConfig_EVNT_test.py index eb0ced94..d96261d5 100644 --- a/DetectorDescription/GeoModel/FaserGeoModel/test/FaserGeometryConfig_EVNT_test.py +++ b/DetectorDescription/GeoModel/FaserGeoModel/test/FaserGeometryConfig_EVNT_test.py @@ -23,7 +23,7 @@ if __name__ == "__main__": ConfigFlags.Common.ProductionStep = ProductionStep.Simulation ConfigFlags.Input.Files = defaultTestFiles.EVNT ConfigFlags.GeoModel.FaserVersion = "FASER-01" - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/CMakeLists.txt b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/CMakeLists.txt new file mode 100644 index 00000000..71d3ffbd --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/CMakeLists.txt @@ -0,0 +1,28 @@ +################################################################################ +# Package: EmulsionGeoModel +################################################################################ + +# Declare the package name: +atlas_subdir( EmulsionGeoModel ) + +# External dependencies: +find_package( Boost COMPONENTS filesystem thread system ) +find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess ) +find_package( Eigen ) +find_package( GeoModel ) + +# Component(s) in the package: +atlas_add_component( EmulsionGeoModel + src/*.cxx + src/components/*.cxx + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} ${GEOMODEL_LIBRARIES} AthenaKernel GeoModelFaserUtilities GaudiKernel SGTools StoreGateLib SGtests AthenaPoolUtilities DetDescrConditions FaserDetDescr NeutrinoGeoModelUtils NeutrinoReadoutGeometry NeutrinoIdentifier Identifier ) + +atlas_add_test( EmulsionGMConfig_test + SCRIPT python ${CMAKE_CURRENT_SOURCE_DIR}/test/EmulsionGMConfig_test.py + PROPERTIES WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + PROPERTIES TIMEOUT 300 ) + +# Install files from the package: +atlas_install_python_modules( python/*.py ) +atlas_install_scripts( test/*.py ) diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionDetectorTool.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionDetectorTool.h new file mode 100644 index 00000000..f7eab489 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionDetectorTool.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONGEOMODEL_EMULSIONDETECTORTOOL_H +#define EMULSIONGEOMODEL_EMULSIONDETECTORTOOL_H + +#include "GeoModelFaserUtilities/GeoModelTool.h" +#include "EmulsionGeoModel/EmulsionGeoModelAthenaComps.h" + +#include "GeometryDBSvc/IGeometryDBSvc.h" +#include "GeoModelInterfaces/IGeoDbTagSvc.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" + +#include "GaudiKernel/ServiceHandle.h" + +#include <string> + +namespace NeutrinoDD { + class EmulsionDetectorManager; +} + +class EmulsionID; +// class FaserDetectorID; + +class EmulsionDetectorTool : public GeoModelTool { + +public: + // Standard Constructor + EmulsionDetectorTool(const std::string& type, const std::string& name, const IInterface* parent); + + virtual StatusCode create() override final; + virtual StatusCode clear() override final; + + // Register callback function on ConDB object + virtual StatusCode registerCallback ATLAS_NOT_THREAD_SAFE () override final; + + // Callback function itself + virtual StatusCode align(IOVSVC_CALLBACK_ARGS) override; + +private: + StringProperty m_detectorName{this, "DetectorName", "Emulsion"}; + BooleanProperty m_alignable{this, "Alignable", true}; + BooleanProperty m_useDynamicAlignFolders{this, "useDynamicAlignFolders", false}; + bool m_cosmic; + + const NeutrinoDD::EmulsionDetectorManager* m_manager; + + EmulsionGeoModelAthenaComps m_athenaComps; + + ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc; + ServiceHandle< IRDBAccessSvc > m_rdbAccessSvc; + ServiceHandle< IGeometryDBSvc > m_geometryDBSvc; + + StringProperty m_run1Folder{this, "Run1Folder", "/Neutrino/Align"}; + StringProperty m_run2L1Folder{this, "Run2L1Folder", "/Neutrino/AlignL1/ID"}; + StringProperty m_run2L2Folder{this, "Run2L2Folder", "/Neutrino/AlignL2/SCT"}; + StringProperty m_run2L3Folder{this, "Run2L3Folder", "/Neutrino/AlignL3"}; +}; + +#endif // EMULSIONGEOMODEL_EMULSIONDETECTORTOOL_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionGeoModelAthenaComps.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionGeoModelAthenaComps.h new file mode 100644 index 00000000..977e6d61 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/EmulsionGeoModel/EmulsionGeoModelAthenaComps.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EmulsionGeoModel_EmulsionGeoModelAthenaComps_H +#define EmulsionGeoModel_EmulsionGeoModelAthenaComps_H 1 + +#include "NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h" + +class EmulsionID; + +/// Class to hold various Athena components +// template <class ID_HELPER> +class EmulsionGeoModelAthenaComps : public NeutrinoDD::AthenaComps { + +public: + + EmulsionGeoModelAthenaComps(); + + void setIdHelper(const EmulsionID* idHelper); + + const EmulsionID* getIdHelper() const; + +private: + const EmulsionID* m_idHelper; + +}; + +#endif // EmulsionGeoModel_EmulsionGeoModelAthenaComps_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/python/EmulsionGeoModelConfig.py b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/python/EmulsionGeoModelConfig.py new file mode 100644 index 00000000..d1465d18 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/python/EmulsionGeoModelConfig.py @@ -0,0 +1,21 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + +from AthenaConfiguration.ComponentFactory import CompFactory +# from IOVDbSvc.IOVDbSvcConfig import addFoldersSplitOnline + +def EmulsionGeometryCfg( flags ): + from FaserGeoModel.GeoModelConfig import GeoModelCfg + acc = GeoModelCfg( flags ) + geoModelSvc = acc.getPrimary() + + if flags.Detector.GeometryEmulsion: + GeometryDBSvc = CompFactory.GeometryDBSvc + acc.addService(GeometryDBSvc("NeutrinoGeometryDBSvc")) + + EmulsionDetectorTool = CompFactory.EmulsionDetectorTool + emulsionDetectorTool = EmulsionDetectorTool() + + emulsionDetectorTool.useDynamicAlignFolders = flags.GeoModel.Align.Dynamic + geoModelSvc.DetectorTools += [ emulsionDetectorTool ] + + return acc diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.cxx new file mode 100644 index 00000000..5f841889 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.cxx @@ -0,0 +1,117 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionBase.h" + +#include "EmulsionGeometryManager.h" +#include "EmulsionMaterialManager.h" + +#include "EmulsionFilmParameters.h" + +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoVPhysVol.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoAlignableTransform.h" + +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" + +#include "GaudiKernel/SystemOfUnits.h" + +using namespace NeutrinoDD; + +EmulsionBase::EmulsionBase(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials) + : EmulsionUniqueComponentFactory(name, detectorManager, geometryManager, materials) +{ + getParameters(); + m_logVolume = preBuild(); +} + + +void +EmulsionBase::getParameters() +{ + const EmulsionFilmParameters * parameters = m_geometryManager->filmParameters(); + m_baseThickness = parameters->baseThickness(); + m_baseHeight = parameters->baseHeight(); + m_baseWidth = parameters->baseWidth(); + m_filmThickness = parameters->filmThickness(); + m_filmHeight = parameters->filmHeight(); + m_filmWidth = parameters->filmWidth(); + m_detectorManager->numerology().setNumFilmsPerBase(2); +} + +const GeoLogVol * +EmulsionBase::preBuild() +{ + // Create child elements + m_baseboard = new EmulsionBaseboard("Baseboard", m_detectorManager, m_geometryManager, m_materials); + m_front = new EmulsionFilm("FrontFilm", m_detectorManager, m_geometryManager, m_materials); + m_back = new EmulsionFilm("BackFilm", m_detectorManager, m_geometryManager, m_materials); + + // Build a box to hold the base and two films + m_width = std::max(m_baseWidth, m_filmWidth); + m_height = std::max(m_baseHeight, m_filmHeight); + m_thickness = m_baseThickness + 2 * m_filmThickness; + const GeoBox* baseShape = new GeoBox(0.5*m_width, 0.5*m_height, 0.5*m_thickness); + + GeoLogVol * baseLog = new GeoLogVol(getName(), baseShape, m_materials->gasMaterial()); + + m_baseboardPos = new GeoTrf::Translate3D(0.0, 0.0, 0.0); + m_frontPos = new GeoTrf::Translate3D(0.0, 0.0, -(m_baseThickness + m_filmThickness)/2); + m_backPos = new GeoTrf::Translate3D(0.0, 0.0, (m_baseThickness + m_filmThickness)/2); + + return baseLog; +} + +GeoVPhysVol * +EmulsionBase::build(EmulsionIdentifier id) +{ + GeoFullPhysVol * base = new GeoFullPhysVol(m_logVolume); + + // Add Baseboard + GeoTransform * baseboardTransform = new GeoTransform(*m_baseboardPos); + base->add(baseboardTransform); + base->add(m_baseboard->getVolume()); + + // Add front side + GeoAlignableTransform * frontTransform = new GeoAlignableTransform(*m_frontPos); + base->add(frontTransform); + int frontNumber = 0; + base->add(new GeoNameTag("Film#"+intToString(frontNumber))); // Identifier side=0 + base->add(new GeoIdentifierTag(frontNumber)); + id.setFilm(frontNumber); + Identifier frontId = id.getFilmId(); + GeoVPhysVol * frontSide = m_front->build(id); + base->add(frontSide); + // Store alignable transform + m_detectorManager->addAlignableTransform(0, frontId, frontTransform, frontSide); + + // Add back side + GeoAlignableTransform * backTransform = new GeoAlignableTransform(*m_backPos); + base->add(backTransform); + int backNumber = 1; + base->add(new GeoNameTag("Film#"+intToString(backNumber))); // Identifier side=1 + base->add(new GeoIdentifierTag(backNumber)); + id.setFilm(backNumber); + Identifier backId = id.getFilmId(); + GeoVPhysVol * backSide = m_back->build(id); + base->add(backSide); + // Store alignable transform + m_detectorManager->addAlignableTransform(0, backId, backTransform, backSide); + + return base; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.h new file mode 100644 index 00000000..a0df5dec --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBase.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONGEOMODEL_EMULSIONBASE_H +#define EMULSIONGEOMODEL_EMULSIONBASE_H + +#include "EmulsionComponentFactory.h" +#include "EmulsionFilm.h" +#include "EmulsionBaseboard.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/GeoDefinitions.h" + +#include <atomic> +#include <string> + +class GeoMaterial; +class GeoVPhysVol; + +class EmulsionBase: public EmulsionUniqueComponentFactory +{ +public: + EmulsionBase(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials); + +public: + double thickness() const {return m_thickness;} + double width() const {return m_width;} + double height() const {return m_height;} + + virtual GeoVPhysVol * build(EmulsionIdentifier id); + +private: + void getParameters(); + virtual const GeoLogVol * preBuild(); + + double m_thickness; + double m_width; + double m_height; + + double m_baseThickness; + double m_baseHeight; + double m_baseWidth; + double m_filmThickness; + double m_filmHeight; + double m_filmWidth; + + EmulsionBaseboard* m_baseboard; + EmulsionFilm* m_front; + EmulsionFilm* m_back; + + GeoTrf::Transform3D * m_frontPos; + GeoTrf::Transform3D * m_backPos; + GeoTrf::Translate3D * m_baseboardPos; + +}; + +#endif // EMULSIONGEOMODEL_EMULSIONBASE_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.cxx new file mode 100644 index 00000000..5cad5bd1 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.cxx @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionBaseboard.h" + +#include "EmulsionGeometryManager.h" +#include "EmulsionMaterialManager.h" + +#include "EmulsionFilmParameters.h" + +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoMaterial.h" + +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" + +#include "GaudiKernel/SystemOfUnits.h" + +using namespace NeutrinoDD; + +EmulsionBaseboard::EmulsionBaseboard(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials) + : EmulsionSharedComponentFactory(name, detectorManager, geometryManager, materials) +{ + getParameters(); + m_physVolume = build(); +} + + +void +EmulsionBaseboard::getParameters() +{ + const EmulsionFilmParameters * parameters = m_geometryManager->filmParameters(); + m_material = m_materials->getMaterial(parameters->baseMaterial()); + m_thickness = parameters->baseThickness(); + m_height = parameters->baseHeight(); + m_width = parameters->baseWidth(); +} + +GeoVPhysVol * +EmulsionBaseboard::build() +{ + const GeoBox* baseboardShape = new GeoBox(0.5*m_width, 0.5*m_height, 0.5*m_thickness); + + GeoLogVol * baseboardLog = new GeoLogVol(getName(), baseboardShape, m_material); + + GeoPhysVol * baseboard = new GeoPhysVol(baseboardLog); + + return baseboard; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.h new file mode 100644 index 00000000..57123c8f --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionBaseboard.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONGEOMODEL_EMULSIONBASEBOARD_H +#define EMULSIONGEOMODEL_EMULSIONBASEBOARD_H + +#include "EmulsionComponentFactory.h" + +#include <atomic> +#include <string> + +class GeoMaterial; +class GeoVPhysVol; +namespace NeutrinoDD{class NeutrinoDetectorDesign;} + +class EmulsionBaseboard: public EmulsionSharedComponentFactory +{ +public: + EmulsionBaseboard(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials); + +public: + const GeoMaterial * material() const {return m_material;} + double thickness() const {return m_thickness;} + double width() const {return m_width;} + double height() const {return m_height;} + + virtual GeoVPhysVol * build(); + +private: + void getParameters(); + + const GeoMaterial * m_material; + double m_thickness; + double m_width; + double m_height; + +}; + +#endif // EMULSIONGEOMODEL_EMULSIONBASEBOARD_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.cxx new file mode 100644 index 00000000..f919d78e --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.cxx @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionComponentFactory.h" +#include "GaudiKernel/SystemOfUnits.h" + +#include <sstream> +#include <string> + +using NeutrinoDD::EmulsionDetectorManager; + +const double EmulsionComponentFactory::s_epsilon = 1.0e-6 * Gaudi::Units::mm; + +EmulsionComponentFactory::EmulsionComponentFactory(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials) + : m_detectorManager(detectorManager), + m_geometryManager(geometryManager), + m_materials(materials), + m_name(name) +{} + +EmulsionComponentFactory::~EmulsionComponentFactory() +{} + +std::string +EmulsionComponentFactory::intToString(int i) const +{ + std::ostringstream str; + str << i; + return str.str(); +} + +double +EmulsionComponentFactory::epsilon() const +{ + return s_epsilon; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.h new file mode 100644 index 00000000..2606dbb9 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionComponentFactory.h @@ -0,0 +1,89 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONGEOMODEL_EMULSIONCOMPONENTFACTORY_H +#define EMULSIONGEOMODEL_EMULSIONCOMPONENTFACTORY_H + +#include "EmulsionIdentifier.h" +#include <string> + +namespace NeutrinoDD{class EmulsionDetectorManager;} +class EmulsionGeometryManager; +class EmulsionMaterialManager; + +class GeoLogVol; +class GeoVPhysVol; + + +class EmulsionComponentFactory +{ + +public: + EmulsionComponentFactory(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials); + + const std::string & getName() const {return m_name;} + + // utility function to covert int to string + std::string intToString(int i) const; + +protected: + NeutrinoDD::EmulsionDetectorManager* m_detectorManager; + const EmulsionGeometryManager* m_geometryManager; + EmulsionMaterialManager* m_materials; + + double epsilon() const; + virtual ~EmulsionComponentFactory(); + +private: + std::string m_name; + static const double s_epsilon; + +}; + + +class EmulsionSharedComponentFactory : public EmulsionComponentFactory +{ + +public: + EmulsionSharedComponentFactory(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials=nullptr) : + EmulsionComponentFactory(name, detectorManager, geometryManager, materials), + m_physVolume(nullptr) + {}; + + GeoVPhysVol * getVolume() {return m_physVolume;} + +protected: + GeoVPhysVol * m_physVolume; + virtual GeoVPhysVol * build() = 0; + +}; + +class EmulsionUniqueComponentFactory : public EmulsionComponentFactory +{ + +public: + EmulsionUniqueComponentFactory(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials=nullptr) : + EmulsionComponentFactory(name, detectorManager, geometryManager, materials), + m_logVolume{nullptr} + {}; + + virtual GeoVPhysVol * build(EmulsionIdentifier id) = 0; + +protected: + const GeoLogVol * m_logVolume; + + virtual const GeoLogVol * preBuild() = 0; + +}; + +#endif // EMULSIONGEOMODEL_EMULSIONCOMPONENTFACTORY_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.cxx new file mode 100644 index 00000000..eae5fd1e --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.cxx @@ -0,0 +1,108 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionDataBase.h" + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" + +#include "GeoModelInterfaces/IGeoDbTagSvc.h" +#include "GeoModelFaserUtilities/DecodeFaserVersionKey.h" + +#include "EmulsionGeoModel/EmulsionGeoModelAthenaComps.h" + +#include <iostream> + +EmulsionDataBase::EmulsionDataBase(const EmulsionGeoModelAthenaComps * athenaComps) +{ + m_athenaComps = athenaComps; + + IGeoDbTagSvc * geoDbTag = m_athenaComps->geoDbTagSvc(); + + // Get version tag and node for Emulsion + DecodeFaserVersionKey versionKey(geoDbTag,"Emulsion"); + std::string versionTag = versionKey.tag(); + std::string versionNode = versionKey.node(); + + // Get version tag and node for Neutrino. + DecodeFaserVersionKey neutrinoVersionKey(geoDbTag,"Neutrino"); + + // Access the RDB + IRDBAccessSvc* rdbSvc = m_athenaComps->rdbAccessSvc(); + + // Emulsion version tag + m_emulsionVersionTag = rdbSvc->getChildTag("Emulsion", versionKey.tag(), versionKey.node(), "FASERDD"); + + +///////////////////////////////////////////////////////// +// +// Gets the structures +// +///////////////////////////////////////////////////////// + + msg(MSG::INFO) << "Retrieving Record Sets from database ..." << endmsg; + msg(MSG::DEBUG) << " Using version tag: " << versionTag << endmsg; + msg(MSG::DEBUG) << " at node: " << versionNode << endmsg; + msg(MSG::DEBUG) << " Emulsion Version: " << m_emulsionVersionTag << endmsg; + + // ATLS - not sure I use it. + // General atlas parameters + + // + // Emulsion General + // + + // Emulsion TopLevel + m_topLevel = rdbSvc->getRecordsetPtr("EmulsionTopLevel", versionTag, versionNode, "FASERDD"); + msg(MSG::DEBUG) << "Table EmulsionTopLevel Fetched" << endmsg; + + // Weight Table + m_weightTable = rdbSvc->getRecordsetPtr("EmulsionWeights", versionTag, versionNode, "FASERDD"); + msg(MSG::DEBUG) << "Table EmulsionWeights Fetched" << endmsg; + + // Extra Scaling Table. This is used for extra material studies. For nominal material the table should be empty. + // NB this is at InnerDetector level node. + m_scalingTable = rdbSvc->getRecordsetPtr("EmulsionMatScaling", neutrinoVersionKey.tag(), neutrinoVersionKey.node(), "FASERDD"); + msg(MSG::DEBUG) << "Table EmulsionMatScaling Fetched" << endmsg; + +// // Default conditions +// m_conditions = rdbSvc->getRecordsetPtr("EmulsionConditions", versionTag, versionNode, "FASERDD"); +// msg(MSG::DEBUG) << "Table EmulsionConditions Fetched" << endmsg; + + m_emulsionGeneral = rdbSvc->getRecordsetPtr("EmulsionGeneral", versionTag, versionNode, "FASERDD"); + msg(MSG::DEBUG) << "Table EmulsionGeneral Fetched" << endmsg; + + m_emulsionFilm = rdbSvc->getRecordsetPtr("EmulsionFilm", versionTag, versionNode, "FASERDD"); + msg(MSG::DEBUG) << "Table EmulsionFilm Fetched" << endmsg; + + m_emulsionPlates = rdbSvc->getRecordsetPtr("EmulsionPlates", versionTag, versionNode, "FASERDD"); + msg(MSG::DEBUG) << "Table EmulsionPlates Fetched" << endmsg; + +} + +const EmulsionGeoModelAthenaComps* EmulsionDataBase::athenaComps() const { return m_athenaComps; } + +IRDBRecordset_ptr EmulsionDataBase::weightTable() const {return m_weightTable;} + +IRDBRecordset_ptr EmulsionDataBase::scalingTable() const {return m_scalingTable;} + +// //const IRDBRecord* EmulsionDataBase::atls() const {return *m_atls)[0];} +IRDBRecordset_ptr EmulsionDataBase::topLevelTable() const {return m_topLevel;} + +// IRDBRecordset_ptr EmulsionDataBase::conditionsTable() const {return m_conditions;} +// const IRDBRecord* EmulsionDataBase::conditions() const {return (*m_conditions)[0];} + +const IRDBRecord* EmulsionDataBase::emulsionGeneral() const {return (*m_emulsionGeneral)[0];} +const IRDBRecord* EmulsionDataBase::emulsionFilm() const {return (*m_emulsionFilm)[0];} +const IRDBRecord* EmulsionDataBase::emulsionPlates() const {return (*m_emulsionPlates)[0];} + +const std::string & EmulsionDataBase::versionTag() const { + return m_emulsionVersionTag; +} + +MsgStream& EmulsionDataBase::msg (MSG::Level lvl) const +{ + return m_athenaComps->msg(lvl); +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.h new file mode 100644 index 00000000..35bf120c --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDataBase.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EmulsionGeoModel_EmulsionDataBase_H +#define EmulsionGeoModel_EmulsionDataBase_H + +#include "EmulsionGeoModel/EmulsionGeoModelAthenaComps.h" +#include <string> + +#include "RDBAccessSvc/IRDBAccessSvc.h" +class IRDBRecord; + + +class EmulsionDataBase +{ + + +public: + + EmulsionDataBase(const EmulsionGeoModelAthenaComps* athenaComps); + + const EmulsionGeoModelAthenaComps* athenaComps() const; + + IRDBRecordset_ptr weightTable() const; + IRDBRecordset_ptr scalingTable() const; + IRDBRecordset_ptr topLevelTable() const; + + const IRDBRecord* emulsionGeneral() const; + const IRDBRecord* emulsionFilm() const; + const IRDBRecord* emulsionPlates() const; + + // Return the Emulsion version tag. + const std::string & versionTag() const; + + MsgStream& msg (MSG::Level lvl) const; + +private: + + EmulsionDataBase(const EmulsionDataBase &); + EmulsionDataBase& operator= (const EmulsionDataBase &); + +private: + + const EmulsionGeoModelAthenaComps* m_athenaComps; + + std::string m_emulsionVersionTag; + + IRDBRecordset_ptr m_weightTable; + IRDBRecordset_ptr m_scalingTable; + IRDBRecordset_ptr m_topLevel; + IRDBRecordset_ptr m_conditions; + + IRDBRecordset_ptr m_emulsionGeneral; + IRDBRecordset_ptr m_emulsionFilm; + IRDBRecordset_ptr m_emulsionPlates; + + +}; + +#endif //EmulsionGeoModel_EmulsionDataBase_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.cxx new file mode 100644 index 00000000..25fc8912 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.cxx @@ -0,0 +1,229 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +// +// EmulsionDetectorFactory: This is the top level node +// + + +#include "EmulsionDetectorFactory.h" + +#include "EmulsionDataBase.h" +#include "EmulsionIdentifier.h" +#include "EmulsionGeometryManager.h" +#include "EmulsionMaterialManager.h" +#include "EmulsionGeneralParameters.h" +#include "NeutrinoReadoutGeometry/Version.h" +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" + +#include "EmulsionBase.h" +#include "EmulsionPlates.h" +#include "EmulsionDataBase.h" +#include "EmulsionGeoModel/EmulsionGeoModelAthenaComps.h" + +// +// GeoModel include files: +// +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoVPhysVol.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoShape.h" +#include "GeoModelKernel/GeoShapeUnion.h" +#include "GeoModelKernel/GeoShapeShift.h" +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelInterfaces/IGeoDbTagSvc.h" +#include "GeoModelFaserUtilities/DecodeFaserVersionKey.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "DetDescrConditions/AlignableTransformContainer.h" +# +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/ISvcLocator.h" + +#include "GeoModelKernel/GeoDefinitions.h" +#include "GaudiKernel/SystemOfUnits.h" + + + +#include <iostream> +#include <iomanip> +#include <string> + +using NeutrinoDD::EmulsionDetectorManager; +using NeutrinoDD::NeutrinoCommonItems; + +EmulsionDetectorFactory::EmulsionDetectorFactory(const EmulsionGeoModelAthenaComps * athenaComps, + const EmulsionOptions & options) + : NeutrinoDD::DetectorFactoryBase(athenaComps), + m_useDynamicAlignFolders(false) +{ + + // Create the detector manager + m_detectorManager = new EmulsionDetectorManager(detStore()); + msg(MSG::DEBUG) << "Created EmulsionDetectorManager" << endmsg; + + // Create the database + m_db = new EmulsionDataBase{athenaComps}; + msg(MSG::DEBUG) << "Created EmulsionDataBase" << endmsg; + + // Create the material manager + m_materials = new EmulsionMaterialManager{m_db}; + msg(MSG::DEBUG) << "Created EmulsionMaterialManager" << endmsg; + + // Create the geometry manager. + m_geometryManager = new EmulsionGeometryManager{m_db}; + msg(MSG::DEBUG) << "Created EmulsionGeometryManager" << endmsg; + m_geometryManager->setOptions(options); + msg(MSG::DEBUG) << "Set options on EmulsionGeometryManager" << endmsg; + + m_useDynamicAlignFolders = options.dynamicAlignFolders(); + + // Set Version information + // Get the geometry tag + DecodeFaserVersionKey versionKey(geoDbTagSvc(),"Emulsion"); + IRDBRecordset_ptr switchSet + = rdbAccessSvc()->getRecordsetPtr("EmulsionSwitches", versionKey.tag(), versionKey.node(),"FASERDD"); + const IRDBRecord *switches = (*switchSet)[0]; + msg(MSG::DEBUG) << "Retrieved EmulsionSwitches" << endmsg; + + std::string layout = "Final"; + std::string description; + if (!switches->isFieldNull("LAYOUT")) { + layout = switches->getString("LAYOUT"); + } + if (!switches->isFieldNull("DESCRIPTION")) { + description = switches->getString("DESCRIPTION"); + } + + std::string versionTag = rdbAccessSvc()->getChildTag("Emulsion", versionKey.tag(), versionKey.node(),"FASERDD"); + std::string versionName = switches->getString("VERSIONNAME"); + int versionMajorNumber = 1; + int versionMinorNumber = 0; + int versionPatchNumber = 0; + NeutrinoDD::Version version(versionTag, + versionName, + layout, + description, + versionMajorNumber, + versionMinorNumber, + versionPatchNumber); + m_detectorManager->setVersion(version); +} + + +EmulsionDetectorFactory::~EmulsionDetectorFactory() +{ + // NB the detector manager (m_detectorManager)is stored in the detector store by the + // Tool and so we don't delete it. + delete m_db; + delete m_materials; + delete m_geometryManager; +} + +void EmulsionDetectorFactory::create(GeoPhysVol *world) +{ + + msg(MSG::INFO) << "Building Emulsion Detector." << endmsg; + msg(MSG::INFO) << " " << m_detectorManager->getVersion().fullDescription() << endmsg; + + // Change precision. + int oldPrecision = std::cout.precision(6); + + // The tree tops get added to world. We name it "neutrino" though. + GeoPhysVol *neutrino = world; + + const EmulsionGeneralParameters * emulsionGeneral = m_geometryManager->generalParameters(); + + GeoTrf::Transform3D emulsionTransform = emulsionGeneral->partTransform("Emulsion"); + + std::string stationA_Label = "StationA"; + + bool stationA_Present = emulsionGeneral->partPresent(stationA_Label); + + // + // Plate is the same for all stations + // + // EmulsionBase base("Base", m_detectorManager, m_geometryManager, m_materials); + // msg(MSG::DEBUG) << "Created Emulsion base with dimensions (" << base.width() << "," << base.height() << "," << base.thickness() << ")" << endmsg; + // + // Station A + // + if (stationA_Present) + { + msg(MSG::DEBUG) << "Building the Emulsion Station A." << endmsg; + + // // Create the station + EmulsionPlates stationA("EmulsionStationA", m_detectorManager, m_geometryManager, m_materials); + EmulsionIdentifier id{m_geometryManager->athenaComps()->getIdHelper()}; + + GeoVPhysVol* stationA_PV = stationA.build(id); + GeoAlignableTransform* stationA_Transform = new GeoAlignableTransform(emulsionTransform * emulsionGeneral->partTransform(stationA_Label)); + + GeoNameTag* topLevelNameTag = new GeoNameTag("Emulsion"); + neutrino->add(topLevelNameTag); + neutrino->add(new GeoIdentifierTag(0)); + neutrino->add(stationA_Transform); + neutrino->add(stationA_PV); + m_detectorManager->addTreeTop(stationA_PV); + + // // Store alignable transform for station (level = 1) + m_detectorManager->addAlignableTransform(2, id.getFilmId(), stationA_Transform, stationA_PV); + } + + // Set the neighbours + m_detectorManager->initNeighbours(); + + // Set number of pmts in numerology. + // const NeutrinoDD::NeutrinoDetectorDesign* design = m_detectorManager->getEmulsionDesign(); + // if (design != nullptr) + // { + // m_detectorManager->numerology().setNumFilmsPerBase(m_detectorManager->getEmulsionDesign()->cells()); + // } + // else + // { + // m_detectorManager->numerology().setNumPmtsPerPlate(0); + // } + + + // Register the keys and the level corresponding to the key + // and whether it expects a global or local shift. + // level 0: sensor, level 1: module, level 2, layer/disc, level 3: whole barrel/enccap + + + if (!m_useDynamicAlignFolders){ + + m_detectorManager->addAlignFolderType(NeutrinoDD::static_run1); + // m_detectorManager->addFolder("/Neutrino/Align"); + } + else { + m_detectorManager->addAlignFolderType(NeutrinoDD::timedependent_run2); + // m_detectorManager->addGlobalFolder("/Neutrino/AlignL1/Neutrino"); + // m_detectorManager->addGlobalFolder("/Neutrino/AlignL2/Emulsion"); + // m_detectorManager->addChannel("/Neutrino/AlignL1/Neutrino",3,NeutrinoDD::global); + // m_detectorManager->addChannel("/Neutrino/AlignL2/Emulsion",2,NeutrinoDD::global); + // m_detectorManager->addFolder("/Neutrino/AlignL3"); + } + + // Return precision to its original value + std::cout.precision(oldPrecision); + +} + + +const EmulsionDetectorManager * EmulsionDetectorFactory::getDetectorManager() const +{ + return m_detectorManager; +} + + diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.h new file mode 100644 index 00000000..1b53eadd --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorFactory.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOGEOMODEL_NEUTRINODETECTORFACTORY_H +#define NEUTRINOGEOMODEL_NEUTRINODETECTORFACTORY_H + +#include "NeutrinoGeoModelUtils/DetectorFactoryBase.h" +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" + +class GeoPhysVol; +class EmulsionDataBase; +class EmulsionGeometryManager; +class EmulsionGeoModelAthenaComps; +class EmulsionMaterialManager; +class EmulsionOptions; + +class EmulsionDetectorFactory : public NeutrinoDD::DetectorFactoryBase +{ + + public: + // Constructor + EmulsionDetectorFactory(const EmulsionGeoModelAthenaComps * athenaComps, + const EmulsionOptions & options); + + // Destructor + virtual ~EmulsionDetectorFactory(); + + // Creation of geometry: + virtual void create(GeoPhysVol *world); + + // Access to the results: + virtual const NeutrinoDD::EmulsionDetectorManager * getDetectorManager() const; + + private: + // Copy and assignments operations illegal and so are made private + EmulsionDetectorFactory(const EmulsionDetectorFactory &right); + const EmulsionDetectorFactory & operator=(const EmulsionDetectorFactory &right); + + NeutrinoDD::EmulsionDetectorManager *m_detectorManager; + EmulsionGeometryManager *m_geometryManager; + EmulsionDataBase* m_db; + EmulsionMaterialManager* m_materials; + bool m_useDynamicAlignFolders; + +}; + +#endif + diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx new file mode 100644 index 00000000..ed7015b1 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionDetectorTool.cxx @@ -0,0 +1,249 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionGeoModel/EmulsionDetectorTool.h" + +#include "EmulsionDetectorFactory.h" +#include "EmulsionDataBase.h" +// #include "EmulsionMaterialManager.h" +#include "EmulsionOptions.h" + +// temporary +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "NeutrinoIdentifier/EmulsionID.h" +#include "DetDescrConditions/AlignableTransformContainer.h" + +#include "GeoModelFaserUtilities/GeoModelExperiment.h" +#include "GeoModelFaserUtilities/DecodeFaserVersionKey.h" +#include "StoreGate/DataHandle.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" + +#include "AthenaKernel/ClassID_traits.h" +#include "SGTools/DataProxy.h" + +using NeutrinoDD::EmulsionDetectorManager; +using NeutrinoDD::NeutrinoDetectorManager; + +// +// Constructor +// +EmulsionDetectorTool::EmulsionDetectorTool(const std::string& type, + const std::string& name, + const IInterface* parent) + : GeoModelTool(type, name, parent), + m_cosmic{false}, + m_manager{nullptr}, + m_athenaComps{ }, + m_geoDbTagSvc{"GeoDbTagSvc", name}, + m_rdbAccessSvc{"RDBAccessSvc", name}, + m_geometryDBSvc{"NeutrinoGeometryDBSvc", name} +{ + // Get parameter values from jobOptions file + declareProperty("GeoDbTagSvc", m_geoDbTagSvc); + declareProperty("RDBAccessSvc", m_rdbAccessSvc); + declareProperty("GeometryDBSvc", m_geometryDBSvc); +} + +// +// Create the Geometry via the factory corresponding to this tool +// + +StatusCode +EmulsionDetectorTool::create() +{ + // Get the detector configuration. + ATH_CHECK(m_geoDbTagSvc.retrieve()); + + DecodeFaserVersionKey versionKey{&*m_geoDbTagSvc, "Emulsion"}; + // Issue error if AUTO. + if (versionKey.tag() == "AUTO") { + ATH_MSG_ERROR("AUTO Faser version. Please select a version."); + } + ATH_MSG_INFO("Building Emulsion with Version Tag: " << versionKey.tag() << " at Node: " << versionKey.node()); + + ATH_CHECK(m_rdbAccessSvc.retrieve()); + // Print the Emulsion version tag: + std::string emulsionVersionTag{m_rdbAccessSvc->getChildTag("Emulsion", versionKey.tag(), versionKey.node(), "FASERDD")}; + ATH_MSG_INFO("Emulsion Version: " << emulsionVersionTag << " Package Version: " << PACKAGE_VERSION); + // Check if version is empty. If so, then the Emulsion cannot be built. This may or may not be intentional. We + // just issue an INFO message. + if (emulsionVersionTag.empty()) { + ATH_MSG_INFO("No Emulsion Version. Emulsion will not be built."); + } else { + std::string versionName; + if (versionKey.custom()) { + ATH_MSG_WARNING("EmulsionDetectorTool: Detector Information coming from a custom configuration!!"); + } else { + ATH_MSG_DEBUG("EmulsionDetectorTool: Detector Information coming from the database and job options IGNORED."); + ATH_MSG_DEBUG("Keys for Emulsion Switches are " << versionKey.tag() << " " << versionKey.node()); + + IRDBRecordset_ptr switchSet{m_rdbAccessSvc->getRecordsetPtr("EmulsionSwitches", versionKey.tag(), versionKey.node(), "FASERDD")}; + const IRDBRecord* switches{(*switchSet)[0]}; + m_detectorName.setValue(switches->getString("DETECTORNAME")); + + if (not switches->isFieldNull("COSMICLAYOUT")) + { + m_cosmic = switches->getInt("COSMICLAYOUT"); + } + if (not switches->isFieldNull("VERSIONNAME")) + { + versionName = switches->getString("VERSIONNAME"); + } + } + + ATH_MSG_DEBUG("Creating the Emulsion"); + ATH_MSG_DEBUG("Emulsion Geometry Options: "); + ATH_MSG_DEBUG(" Alignable: " << (m_alignable.value() ? "true" : "false")); + ATH_MSG_DEBUG(" CosmicLayout: " << (m_cosmic ? "true" : "false")); + ATH_MSG_DEBUG(" VersionName: " << versionName); + + EmulsionOptions options; + options.setAlignable(m_alignable.value()); + options.setDynamicAlignFolders(m_useDynamicAlignFolders.value()); + m_manager = nullptr; + + // + // Locate the top level experiment node + // + GeoModelExperiment* theExpt{nullptr}; + ATH_CHECK(detStore()->retrieve(theExpt, "FASER")); + + // Retrieve the Geometry DB Interface + ATH_CHECK(m_geometryDBSvc.retrieve()); + + // Pass athena services to factory, etc + m_athenaComps.setDetStore(detStore().operator->()); + m_athenaComps.setGeoDbTagSvc(&*m_geoDbTagSvc); + m_athenaComps.setGeometryDBSvc(&*m_geometryDBSvc); + m_athenaComps.setRDBAccessSvc(&*m_rdbAccessSvc); + const EmulsionID* idHelper{nullptr}; + ATH_CHECK(detStore()->retrieve(idHelper, "EmulsionID")); + m_athenaComps.setIdHelper(idHelper); + idHelper->test_base_packing(); + // + // This strange way of casting is to avoid an + // utterly brain damaged compiler warning. + // + GeoPhysVol* world{&*theExpt->getPhysVol()}; + if (world != nullptr) ATH_MSG_INFO("Retrieved World PhysVol"); + + EmulsionDetectorFactory theEmulsion{&m_athenaComps, options}; + ATH_MSG_INFO("Created instance of detector factory"); + theEmulsion.create(world); + ATH_MSG_INFO("Called create method on factory"); + m_manager = theEmulsion.getDetectorManager(); + ATH_MSG_INFO("Attempted to retrieve detector manager"); + + if (m_manager==nullptr) { + ATH_MSG_FATAL("EmulsionDetectorManager not created"); + return StatusCode::FAILURE; + } + + // Get the manager from the factory and store it in the detector store. + // m_detector is non constant so I can not set it to a const pointer. + // m_detector = theSCT.getDetectorManager(); + + ATH_MSG_DEBUG("Registering EmulsionDetectorManager. "); + ATH_CHECK(detStore()->record(m_manager, m_manager->getName())); + theExpt->addManager(m_manager); + + // Create a symLink to the NeutrinoDetectorManager base class + const NeutrinoDetectorManager* neutrinoDetManager{m_manager}; + ATH_CHECK(detStore()->symLink(m_manager, neutrinoDetManager)); + } + + return StatusCode::SUCCESS; +} + +StatusCode +EmulsionDetectorTool::clear() +{ + ATH_MSG_WARNING("Called untested EmulsionDetectorTool::clear()"); + SG::DataProxy* proxy{detStore()->proxy(ClassID_traits<EmulsionDetectorManager>::ID(), m_manager->getName())}; + if (proxy) { + proxy->reset(); + m_manager = nullptr; + } + return StatusCode::SUCCESS; +} + +StatusCode +EmulsionDetectorTool::registerCallback() +{ + StatusCode sc{StatusCode::FAILURE, true}; + if (m_alignable.value()) { + ATH_MSG_WARNING("Called untested EmulsionDetectorTool::registerCallback()"); + if (m_useDynamicAlignFolders.value()) { + + if (detStore()->contains<CondAttrListCollection>(m_run2L1Folder.value())) { + ATH_MSG_DEBUG("Registering callback on global Container with folder " << m_run2L1Folder.value()); + const DataHandle<CondAttrListCollection> calc; + ATH_CHECK(detStore()->regFcn(&IGeoModelTool::align, dynamic_cast<IGeoModelTool*>(this), calc, m_run2L1Folder.value())); + sc = StatusCode::SUCCESS; + } else { + ATH_MSG_WARNING("Unable to register callback on global Container with folder " << m_run2L1Folder.value()); + return StatusCode::FAILURE; + } + + if (detStore()->contains<CondAttrListCollection>(m_run2L2Folder.value())) { + ATH_MSG_DEBUG("Registering callback on global Container with folder " << m_run2L2Folder.value()); + const DataHandle<CondAttrListCollection> calc; + ATH_CHECK(detStore()->regFcn(&IGeoModelTool::align, dynamic_cast<IGeoModelTool*>(this), calc, m_run2L2Folder.value())); + sc = StatusCode::SUCCESS; + } else { + ATH_MSG_WARNING("Unable to register callback on global Container with folder " << m_run2L2Folder.value()); + return StatusCode::FAILURE; + } + + if (detStore()->contains<AlignableTransformContainer>(m_run2L3Folder.value())) { + ATH_MSG_DEBUG("Registering callback on AlignableTransformContainer with folder " << m_run2L3Folder.value()); + const DataHandle<AlignableTransformContainer> atc; + ATH_CHECK(detStore()->regFcn(&IGeoModelTool::align, dynamic_cast<IGeoModelTool*>(this), atc, m_run2L3Folder.value())); + sc = StatusCode::SUCCESS; + } else { + ATH_MSG_WARNING("Unable to register callback on AlignableTransformContainer with folder " << m_run2L3Folder.value()); + return StatusCode::FAILURE; + } + + } else { + + if (detStore()->contains<AlignableTransformContainer>(m_run1Folder.value())) { + ATH_MSG_DEBUG("Registering callback on AlignableTransformContainer with folder " << m_run1Folder.value()); + const DataHandle<AlignableTransformContainer> atc; + ATH_CHECK(detStore()->regFcn(&IGeoModelTool::align, dynamic_cast<IGeoModelTool*>(this), atc, m_run1Folder.value())); + sc = StatusCode::SUCCESS; + } else { + ATH_MSG_WARNING("Unable to register callback on AlignableTransformContainer with folder " + << m_run1Folder.value() << ", Alignment disabled (only if no Run2 scheme is loaded)!"); + return StatusCode::FAILURE; + } + } + } else { + ATH_MSG_INFO("Alignment disabled. No callback registered"); + // We return failure otherwise it will try and register + // a GeoModelSvc callback associated with this callback. + return StatusCode::FAILURE; + } + return sc; +} + +StatusCode +EmulsionDetectorTool::align(IOVSVC_CALLBACK_ARGS_P(I, keys)) +{ + ATH_MSG_WARNING("Called untested EmulsionDetectorTool::align()"); + void* i = &I; + void* k = &keys; + if (i == nullptr && k == nullptr) return StatusCode::SUCCESS; // suppress stupid warning + if (m_manager==nullptr) { + ATH_MSG_FATAL("Manager does not exist"); + return StatusCode::FAILURE; + } + if (m_alignable.value()) { + return m_manager->align(I, keys); + } else { + ATH_MSG_DEBUG("Alignment disabled. No alignments applied"); + return StatusCode::SUCCESS; + } +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.cxx new file mode 100644 index 00000000..e6c24e2b --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.cxx @@ -0,0 +1,98 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionFilm.h" + +#include "EmulsionGeometryManager.h" +#include "EmulsionMaterialManager.h" + +#include "EmulsionFilmParameters.h" + +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoMaterial.h" + +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" + +#include "GaudiKernel/SystemOfUnits.h" + +using namespace NeutrinoDD; + +EmulsionFilm::EmulsionFilm(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials) + : EmulsionUniqueComponentFactory(name, detectorManager, geometryManager, materials), + m_noElementWarning{true} +{ + getParameters(); + m_logVolume = preBuild(); +} + + +void +EmulsionFilm::getParameters() +{ + const EmulsionFilmParameters * parameters = m_geometryManager->filmParameters(); + m_material = m_materials->getMaterial(parameters->filmMaterial()); + m_thickness = parameters->filmThickness(); + m_height = parameters->filmHeight(); + m_width = parameters->filmWidth(); +} + +const GeoLogVol * +EmulsionFilm::preBuild() +{ + // Simple box + const GeoBox* filmShape = new GeoBox(0.5*m_width, 0.5*m_height, 0.5*m_thickness); + + GeoLogVol * filmLog = new GeoLogVol(getName(), filmShape, m_material); + makeDesign(); + return filmLog; +} + +void +EmulsionFilm::makeDesign() +{ + m_design = new NeutrinoDetectorDesign( m_width, m_height, m_thickness ); +} + + + +GeoVPhysVol * +EmulsionFilm::build(EmulsionIdentifier id) +{ + GeoFullPhysVol * film = new GeoFullPhysVol(m_logVolume); + + // Make detector element and add to collection + // Only do so if we have a valid id helper. + + //id.print(); // for debugging only + + const NeutrinoCommonItems* commonItems = m_geometryManager->commonItems(); + + if (commonItems->getIdHelper()) { + + NeutrinoDetectorElement * detElement; + + detElement = new NeutrinoDetectorElement(id.getFilmId(), + m_design, + film, + commonItems); + // Add the detector element. + m_detectorManager->addDetectorElement(detElement); + + } else { + if (m_noElementWarning) { + std::cout << "WARNING!!!!: No Emulsion id helper and so no elements being produced." << std::endl; + m_noElementWarning = false; + } + } + return film; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.h new file mode 100644 index 00000000..b3f25ccd --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilm.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONGEOMODEL_EMULSIONFILM_H +#define EMULSIONGEOMODEL_EMULSIONFILM_H + +#include "EmulsionComponentFactory.h" + +#include <atomic> +#include <string> + +class GeoMaterial; +class GeoVPhysVol; +namespace NeutrinoDD{class NeutrinoDetectorDesign;} + +class EmulsionFilm: public EmulsionUniqueComponentFactory +{ +public: + EmulsionFilm(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials); + +public: + const GeoMaterial * material() const {return m_material;} + double thickness() const {return m_thickness;} + double width() const {return m_width;} + double height() const {return m_height;} + + virtual GeoVPhysVol * build(EmulsionIdentifier id); + +private: + void getParameters(); + virtual const GeoLogVol * preBuild(); + void makeDesign(); + + const GeoMaterial * m_material; + double m_thickness; + double m_width; + double m_height; + + NeutrinoDD::NeutrinoDetectorDesign* m_design; + + mutable std::atomic_bool m_noElementWarning; +}; + +#endif // EMULSIONGEOMODEL_EMULSIONFILM_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.cxx new file mode 100644 index 00000000..0a1eef8f --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.cxx @@ -0,0 +1,66 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionFilmParameters.h" +#include "EmulsionGeometryManager.h" + +#include "EmulsionDataBase.h" + +#include "RDBAccessSvc/IRDBRecord.h" +#include "GaudiKernel/SystemOfUnits.h" + +#include <cmath> + + +EmulsionFilmParameters::EmulsionFilmParameters(EmulsionDataBase* rdb) +{ + m_rdb = rdb; +} + +double +EmulsionFilmParameters::baseWidth() const +{ + return m_rdb->emulsionFilm()->getDouble("BASEDX") * Gaudi::Units::mm; +} + +double +EmulsionFilmParameters::baseHeight() const +{ + return m_rdb->emulsionFilm()->getDouble("BASEDY") * Gaudi::Units::mm; +} + +double +EmulsionFilmParameters::baseThickness() const +{ + return m_rdb->emulsionFilm()->getDouble("BASEDZ") * Gaudi::Units::mm; +} + +std::string EmulsionFilmParameters::baseMaterial() const +{ + return m_rdb->emulsionFilm()->getString("BASEMAT"); +} + +double +EmulsionFilmParameters::filmWidth() const +{ + return m_rdb->emulsionFilm()->getDouble("FILMDX") * Gaudi::Units::mm; +} + +double +EmulsionFilmParameters::filmHeight() const +{ + return m_rdb->emulsionFilm()->getDouble("FILMDY") * Gaudi::Units::mm; +} + +double +EmulsionFilmParameters::filmThickness() const +{ + return m_rdb->emulsionFilm()->getDouble("FILMDZ") * Gaudi::Units::mm; +} + +std::string EmulsionFilmParameters::filmMaterial() const +{ + return m_rdb->emulsionFilm()->getString("FILMMAT"); +} + diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.h new file mode 100644 index 00000000..a85ec246 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionFilmParameters.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EmulsionGeoModel_EmulsionFilmParameters_H +#define EmulsionGeoModel_EmulsionFilmParameters_H + +#include <string> + +class EmulsionDataBase; + +class EmulsionFilmParameters { + +public: + + // Constructor + EmulsionFilmParameters(EmulsionDataBase* rdb); + + double baseThickness() const; + double baseWidth() const; + double baseHeight() const; + double filmThickness() const; + double filmWidth() const; + double filmHeight() const; + + std::string baseMaterial() const; + std::string filmMaterial() const; + + private: + EmulsionDataBase * m_rdb; + +}; + + +#endif // EmulsionGeoModel_EmulsionFilmParameters_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.cxx new file mode 100644 index 00000000..d9637953 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.cxx @@ -0,0 +1,110 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionGeneralParameters.h" +#include "EmulsionDataBase.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "GeoModelKernel/GeoDefinitions.h" +#include "NeutrinoGeoModelUtils/TopLevelPlacements.h" + +const double EmulsionSAFETY = 0.01 * Gaudi::Units::mm; // Used in some places to make envelopes slightly larger to ensure + // no overlaps due to rounding errors. + + +EmulsionGeneralParameters::EmulsionGeneralParameters(EmulsionDataBase* rdb) +{ + m_rdb = rdb; + m_placements = new TopLevelPlacements(m_rdb->topLevelTable()); +} + + +EmulsionGeneralParameters::~EmulsionGeneralParameters() +{ + delete m_placements; +} + + +const GeoTrf::Transform3D & +EmulsionGeneralParameters::partTransform(const std::string & partName) const +{ + return m_placements->transform(partName); +} + + +bool +EmulsionGeneralParameters::partPresent(const std::string & partName) const +{ + return m_placements->present(partName); +} + +// +// General +// +double +EmulsionGeneralParameters::safety() const +{ + return EmulsionSAFETY; +} + +int +EmulsionGeneralParameters::nModules() const +{ + return m_rdb->emulsionGeneral()->getInt("NMODULES"); +} + +int +EmulsionGeneralParameters::nBasesPerModule() const +{ + return m_rdb->emulsionGeneral()->getInt("NBASEPERMOD"); +} + +double +EmulsionGeneralParameters::firstBaseZ() const +{ + return m_rdb->emulsionGeneral()->getDouble("FIRSTBASEZ") * Gaudi::Units::mm; +} + +double +EmulsionGeneralParameters::lastBaseZ() const +{ + return m_rdb->emulsionGeneral()->getDouble("LASTBASEZ") * Gaudi::Units::mm; +} + +// Default Conditions. Values should be come form conditions data base. These values provide +// default vlaues if nothing from the conditions database is provided. + + +// double +// EmulsionGeneralParameters::temperature() const +// { +// if (m_rdb->conditionsTable()->size() == 0) { +// return 266.15 * Gaudi::Units::kelvin; // -7 C +// } +// return (m_rdb->conditions()->getDouble("TEMPERATURE") + 273.15) * Gaudi::Units::kelvin; +// } + + +// double +// SCT_GeneralParameters::biasVoltage() const +// { +// if (m_rdb->conditionsTable()->size() == 0) { +// return 100 * Gaudi::Units::volt; +// } +// return m_rdb->conditions()->getDouble("BIASVOLT") * Gaudi::Units::volt; +// } + +// double +// SCT_GeneralParameters::depletionVoltage() const +// { +// if (m_rdb->conditionsTable()->size() == 0) { +// return 20 * Gaudi::Units::volt; +// } +// return m_rdb->conditions()->getDouble("DEPLETIONVOLT") * Gaudi::Units::volt; +// } + + + + diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.h new file mode 100644 index 00000000..65d618ce --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeneralParameters.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EmulsionGeoModel_EmulsionGeneralParameters_H +#define EmulsionGeoModel_EmulsionGeneralParameters_H + +#include "GeoModelKernel/GeoDefinitions.h" + +#include <map> +#include <string> + +class EmulsionDataBase; +class TopLevelPlacements; + +class EmulsionGeneralParameters { + +public: + + EmulsionGeneralParameters(EmulsionDataBase* rdb); + ~EmulsionGeneralParameters(); + //Explicitly disallow copy, assignment to appease coverity + EmulsionGeneralParameters(const EmulsionGeneralParameters &) = delete; + EmulsionGeneralParameters & operator=(const EmulsionGeneralParameters &) = delete; + + // General + double safety() const; + + const GeoTrf::Transform3D & partTransform(const std::string & partName) const; + bool partPresent(const std::string & partName) const; + + int nModules() const; + int nBasesPerModule() const; + double firstBaseZ() const; + double lastBaseZ() const; + +private: + + EmulsionDataBase * m_rdb; + TopLevelPlacements * m_placements; +}; + + +#endif // EmulsionGeoModel_EmulsionGeneralParameters_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeoModelAthenaComps.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeoModelAthenaComps.cxx new file mode 100644 index 00000000..f6bf50fd --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeoModelAthenaComps.cxx @@ -0,0 +1,23 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionGeoModel/EmulsionGeoModelAthenaComps.h" + +EmulsionGeoModelAthenaComps::EmulsionGeoModelAthenaComps() + : NeutrinoDD::AthenaComps("EmulsionGeoModel"), + m_idHelper(0) +{} + +void +EmulsionGeoModelAthenaComps::setIdHelper(const EmulsionID* idHelper) +{ + m_idHelper = idHelper; +} + +const EmulsionID* +EmulsionGeoModelAthenaComps::getIdHelper() const +{ + return m_idHelper; +} + diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.cxx new file mode 100644 index 00000000..679678fb --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.cxx @@ -0,0 +1,112 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionGeometryManager.h" + +#include "NeutrinoGeoModelUtils/DistortedMaterialManager.h" +#include "NeutrinoIdentifier/EmulsionID.h" +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" +#include "EmulsionFilmParameters.h" +#include "EmulsionPlatesParameters.h" +#include "EmulsionDataBase.h" +#include "EmulsionGeneralParameters.h" +#include "EmulsionGeoModel/EmulsionGeoModelAthenaComps.h" + +EmulsionGeometryManager::EmulsionGeometryManager(EmulsionDataBase* rdb) + : m_athenaComps{rdb->athenaComps()}, + m_rdb{rdb} +{ + // This class uses reference counting. Should not be delete'd in destructor. + m_commonItems = new NeutrinoDD::NeutrinoCommonItems(m_athenaComps->getIdHelper()); + + m_filmParameters = std::make_unique<EmulsionFilmParameters>(m_rdb); + m_platesParameters = std::make_unique<EmulsionPlatesParameters>(m_rdb); + m_generalParameters = std::make_unique<EmulsionGeneralParameters>(m_rdb); + m_distortedMatManager = std::make_unique<NeutrinoDD::DistortedMaterialManager>(); +} + +EmulsionGeometryManager::~EmulsionGeometryManager() +{ +} + +// +// Access to run time options. +// +const EmulsionOptions & +EmulsionGeometryManager::options() const +{ + return m_options; +} + +void +EmulsionGeometryManager::setOptions(const EmulsionOptions & options) +{ + m_options = options; +} + +const EmulsionGeoModelAthenaComps * +EmulsionGeometryManager::athenaComps() const +{ + return m_athenaComps; +} + +// +// NeutrinoCommonItems which are passed to NeutrinoDetectorElements. +// + +const NeutrinoDD::NeutrinoCommonItems * +EmulsionGeometryManager::commonItems() const +{ + return m_commonItems; +} + +const EmulsionFilmParameters * +EmulsionGeometryManager::filmParameters() const +{ + return m_filmParameters.get(); +} + +const EmulsionPlatesParameters * +EmulsionGeometryManager::platesParameters() const +{ + return m_platesParameters.get(); +} + +const EmulsionGeneralParameters * +EmulsionGeometryManager::generalParameters() const +{ + return m_generalParameters.get(); +} + +const NeutrinoDD::DistortedMaterialManager * +EmulsionGeometryManager::distortedMatManager() const +{ + return m_distortedMatManager.get(); +} + +EmulsionGeometryManager& +EmulsionGeometryManager::operator=(const EmulsionGeometryManager& right) { + if (this != &right) { + m_options = right.m_options; + m_athenaComps = right.m_athenaComps; + m_commonItems = right.m_commonItems; + m_rdb = right.m_rdb; + m_filmParameters.reset(new EmulsionFilmParameters(m_rdb)); + m_platesParameters.reset(new EmulsionPlatesParameters(m_rdb)); + m_generalParameters.reset(new EmulsionGeneralParameters(m_rdb)); + m_distortedMatManager.reset(new NeutrinoDD::DistortedMaterialManager()); + } + return *this; +} + +EmulsionGeometryManager::EmulsionGeometryManager(const EmulsionGeometryManager& right) { + m_options = right.m_options; + m_athenaComps = right.m_athenaComps; + m_commonItems = right.m_commonItems; + m_rdb = right.m_rdb; + m_filmParameters.reset(new EmulsionFilmParameters(m_rdb)); + m_platesParameters.reset(new EmulsionPlatesParameters(m_rdb)); + m_generalParameters.reset(new EmulsionGeneralParameters(m_rdb)); + m_distortedMatManager.reset(new NeutrinoDD::DistortedMaterialManager()); +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.h new file mode 100644 index 00000000..a068602e --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionGeometryManager.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EmulsionGeoModel_EmulsionGeometryManager_H +#define EmulsionGeoModel_EmulsionGeometryManager_H + +#include "EmulsionOptions.h" + +#include <memory> + +namespace NeutrinoDD { + class NeutrinoCommonItems; + class DistortedMaterialManager; +} + +class EmulsionFilmParameters; +class EmulsionPlatesParameters; +class EmulsionDataBase; +class EmulsionGeneralParameters; +class EmulsionGeoModelAthenaComps; + +class EmulsionGeometryManager { + +public: + + // Constructor + EmulsionGeometryManager(EmulsionDataBase* rdb); + + // Destructor + ~EmulsionGeometryManager(); + + // Access to run time options + const EmulsionOptions & options() const; + void setOptions(const EmulsionOptions & options); + + // Access to athena components + const EmulsionGeoModelAthenaComps * athenaComps() const; + + // To be passed to detector element. + const NeutrinoDD::NeutrinoCommonItems * commonItems() const; + + const EmulsionFilmParameters* filmParameters() const; + const EmulsionPlatesParameters* platesParameters() const; + const EmulsionGeneralParameters* generalParameters() const; + const NeutrinoDD::DistortedMaterialManager* distortedMatManager() const; + + EmulsionGeometryManager& operator=(const EmulsionGeometryManager& right); + EmulsionGeometryManager(const EmulsionGeometryManager& right); + +private: + + EmulsionOptions m_options; + const EmulsionGeoModelAthenaComps * m_athenaComps; + NeutrinoDD::NeutrinoCommonItems * m_commonItems; + EmulsionDataBase* m_rdb; + + std::unique_ptr<EmulsionFilmParameters> m_filmParameters; + std::unique_ptr<EmulsionPlatesParameters> m_platesParameters; + std::unique_ptr<EmulsionGeneralParameters> m_generalParameters; + std::unique_ptr<NeutrinoDD::DistortedMaterialManager> m_distortedMatManager; + +}; + + +#endif // EmulsionGeoModel_EmulsionGeometryManager_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.cxx new file mode 100644 index 00000000..52bdf151 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.cxx @@ -0,0 +1,23 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionIdentifier.h" +#include "NeutrinoIdentifier/EmulsionID.h" +#include "Identifier/Identifier.h" + +#include <cassert> +#include <iostream> + +Identifier +EmulsionIdentifier::getFilmId() +{ + assert (m_idHelper); + return m_idHelper->film_id(m_module, m_base, m_film); +} + +void EmulsionIdentifier::print() +{ + std::cout << "1/1/" << m_module << "/" + << m_base << "/" << m_film << std::endl; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.h new file mode 100644 index 00000000..f82ba9c1 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionIdentifier.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONGEOMODEL_EMULSIONIDENTIFIER_H +#define EMULSIONGEOMODEL_EMULSIONIDENTIFIER_H + +class Identifier; +class EmulsionID; + +class EmulsionIdentifier +{ +public: + + EmulsionIdentifier( const EmulsionID* idHelper, + int module = 0, + int base = 0, + int film = 0 ) + : m_idHelper{idHelper}, + m_module{module}, + m_base{base}, + m_film{film} + {}; + + + void setModule(int i) {m_module = i;} + int getModule() const {return m_module;} + + void setBase(int i) {m_base = i;} + int getBase() const {return m_base;} + + void setFilm(int i) {m_film = i;} + int getFilm() const {return m_film;} + + + Identifier getFilmId(); + + // For debugging purposes. + void print(); + +private: + const EmulsionID* m_idHelper; + int m_module; + int m_base; + int m_film; +}; + +#endif // EMULSIONGEOMODEL_EMULSIONIDENTIFIER_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.cxx new file mode 100644 index 00000000..b7007072 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.cxx @@ -0,0 +1,83 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionMaterialManager.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoElement.h" +#include "EmulsionDataBase.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/Bootstrap.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/SystemOfUnits.h" + +#include <iostream> + +// Constructor +EmulsionMaterialManager::EmulsionMaterialManager(EmulsionDataBase* db) +{ + // Get my material manager. + ISvcLocator* svcLocator = Gaudi::svcLocator(); // from Bootstrap + StoreGateSvc* detStore; + StatusCode sc = svcLocator->service("DetectorStore", detStore ); + if (sc.isFailure()) { + std::cout << "Could not locate DetectorStore" << std::endl; + return; + } + + m_materialManager = std::make_unique<NeutrinoMaterialManager>("EmulsionMaterialManager", db->athenaComps()); + m_materialManager->addWeightTable(db->weightTable(), "preshower"); + m_materialManager->addScalingTable(db->scalingTable()); + + loadMaterials(); + + m_gasMaterial = m_materialManager->getMaterial("std::Air"); +} + +// Add materials not yet in the database +void +EmulsionMaterialManager::loadMaterials() +{ +} + +const GeoElement* +EmulsionMaterialManager::getElement(const std::string & elementName) const +{ + return m_materialManager->getElement(elementName); +} + +const GeoMaterial* +EmulsionMaterialManager::getMaterial(const std::string & materialName) const +{ + return m_materialManager->getMaterial(materialName); +} + +void +EmulsionMaterialManager::addMaterial(GeoMaterial* material) +{ + return m_materialManager->addMaterial(material); +} + +const GeoMaterial* +EmulsionMaterialManager::getMaterial(const std::string & originalMaterial, + double density, + const std::string & newName) +{ + + return m_materialManager->getMaterial(originalMaterial, density, newName); +} + +const GeoMaterial * +EmulsionMaterialManager::getMaterialForVolume(const std::string & materialName, double volume) +{ + return m_materialManager->getMaterialForVolume(materialName, volume); +} + + + +const GeoMaterial* +EmulsionMaterialManager::gasMaterial() const +{ + return m_gasMaterial; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.h new file mode 100644 index 00000000..900d63ec --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionMaterialManager.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONMATERIALMANAGER_H +#define EMULSIONMATERIALMANAGER_H + +// EmulsionMaterialManager. This provides an interface to the NeutrinoMaterialManager which in turn +// is an interface to GeoModel Material Manager with some additional functionality. +#include "NeutrinoGeoModelUtils/NeutrinoMaterialManager.h" + +#include <memory> +#include <string> + +class GeoMaterial; +class GeoElement; +class NeutrinoMaterialManager; +class EmulsionDataBase; + +class EmulsionMaterialManager +{ + +public: + + EmulsionMaterialManager(EmulsionDataBase* db); + + const GeoMaterial* getMaterial(const std::string & materialName) const; + const GeoElement* getElement(const std::string & elementName) const; + + const GeoMaterial* getMaterial(const std::string & originalMaterial, + double density, + const std::string & newName = ""); + const GeoMaterial *getMaterialForVolume(const std::string & materialName, double volume); + + // Default gas material + const GeoMaterial* gasMaterial() const; + +private: + void loadMaterials(); + void addMaterial(GeoMaterial* material); + + std::unique_ptr<NeutrinoMaterialManager> m_materialManager; + const GeoMaterial* m_gasMaterial; + +}; + + +#endif // EMULSIONMATERIALMANAGER_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.cxx new file mode 100644 index 00000000..d8d6c893 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.cxx @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionOptions.h" + +EmulsionOptions::EmulsionOptions() + : m_alignable(true) +// , m_alignModule(true) + , m_dynAlignFolders(false) +{} + +void +EmulsionOptions::setAlignable(bool flag) +{ + m_alignable = flag; +} + +bool +EmulsionOptions::alignable() const +{ + return m_alignable; +} + +// following may eventually become useful +// +// void +// SCT_Options::setAlignAtModuleLevel(bool flag) +// { +// m_alignModule = flag; +// } + +// bool +// SCT_Options::alignAtModuleLevel() const +// { +// return m_alignModule; +// } + +void EmulsionOptions::setDynamicAlignFolders(const bool flag) +{ + m_dynAlignFolders = flag; +} + +bool EmulsionOptions::dynamicAlignFolders() const +{ + return m_dynAlignFolders; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.h new file mode 100644 index 00000000..9854273f --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionOptions.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EmulsionGeoModel_EmulsionOptions_H +#define EmulsionGeoModel_EmulsionOptions_H + +// Class for any run time options. + + +class EmulsionOptions +{ + +public: + EmulsionOptions(); + bool alignable() const; +// bool alignAtModuleLevel() const; + + void setAlignable(bool flag = true); +// void setAlignAtModuleLevel(bool flag = true); + + //dynamic alignment folders + void setDynamicAlignFolders(const bool flag = true); + bool dynamicAlignFolders() const; + +private: + + bool m_alignable; +// bool m_alignModule; + bool m_dynAlignFolders; //controls which set of alignment folders is used + +}; + + +#endif // EmulsionGeoModel_EmulsionOptions_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.cxx new file mode 100644 index 00000000..7424987e --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.cxx @@ -0,0 +1,112 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionPlates.h" + +#include "EmulsionGeometryManager.h" +#include "EmulsionMaterialManager.h" +#include "EmulsionGeneralParameters.h" +#include "EmulsionPlatesParameters.h" + +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoVPhysVol.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoIdentifierTag.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoAlignableTransform.h" + +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" + +#include "GaudiKernel/SystemOfUnits.h" + +using namespace NeutrinoDD; + +EmulsionPlates::EmulsionPlates(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials) + : EmulsionUniqueComponentFactory(name, detectorManager, geometryManager, materials) +{ + getParameters(); + m_logVolume = preBuild(); +} + + +void +EmulsionPlates::getParameters() +{ + const EmulsionGeneralParameters * generalParameters = m_geometryManager->generalParameters(); + const EmulsionPlatesParameters * platesParameters = m_geometryManager->platesParameters(); + + m_width = platesParameters->platesWidth(); + m_height = platesParameters->platesHeight(); + m_thickness = platesParameters->platesThickness(); + m_material = m_materials->getMaterial(platesParameters->platesMaterial()); + + m_nBasesPerModule = generalParameters->nBasesPerModule(); + m_nModules = generalParameters->nModules(); + m_firstBaseZ = generalParameters->firstBaseZ(); + m_lastBaseZ = generalParameters->lastBaseZ(); + + m_detectorManager->numerology().setNumBasesPerModule(m_nBasesPerModule); +} + +const GeoLogVol * +EmulsionPlates::preBuild() +{ + // create child element + m_base = new EmulsionBase("Base", m_detectorManager, m_geometryManager, m_materials); + + + // Build a box to hold everything + const GeoBox* platesShape = new GeoBox(0.5*m_width, 0.5*m_height, 0.5*m_thickness); + + // GeoLogVol * platesLog = new GeoLogVol(getName(), platesShape, m_materials->gasMaterial()); + GeoLogVol * platesLog = new GeoLogVol(getName(), platesShape, m_material); + + // m_baseboardPos = new GeoTrf::Translate3D(0.0, 0.0, 0.0); + // m_frontPos = new GeoTrf::Translate3D(0.0, 0.0, -(m_baseThickness + m_filmThickness)/2); + // m_backPos = new GeoTrf::Translate3D(0.0, 0.0, (m_baseThickness + m_filmThickness)/2); + + return platesLog; +} + +GeoVPhysVol * +EmulsionPlates::build(EmulsionIdentifier id) +{ + GeoFullPhysVol * plates = new GeoFullPhysVol(m_logVolume); + + int nBases = 0; + int nBasesTotal = m_nModules * m_nBasesPerModule; + // Loop over modules + for (int module = 0; module < m_nModules; module++) + { + id.setModule(module); + // plates->add(new GeoNameTag("Module#"+intToString(module))); + // plates->add(new GeoIdentifierTag(module)); + // Loop over bases in a module + for (int base = 0; base < m_nBasesPerModule; base++) + { + id.setBase(base); + GeoAlignableTransform* theTransform = new GeoAlignableTransform( GeoTrf::Translate3D {0.0, 0.0, m_firstBaseZ + ((m_lastBaseZ - m_firstBaseZ)/(nBasesTotal-1))*nBases++} ); + plates->add(theTransform); + plates->add(new GeoNameTag("Base#"+intToString(module*100 + base))); + plates->add(new GeoIdentifierTag(module*100 + base)); + GeoVPhysVol* physBase = m_base->build(id); + plates->add(physBase); + m_detectorManager->addAlignableTransform(1, id.getFilmId(), theTransform, physBase); + } + m_detectorManager->numerology().useModule(module); + } + + return plates; +} diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.h new file mode 100644 index 00000000..b827265b --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlates.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMULSIONGEOMODEL_EMULSIONPLATES_H +#define EMULSIONGEOMODEL_EMULSIONPLATES_H + +#include "EmulsionComponentFactory.h" +#include "EmulsionBase.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/GeoDefinitions.h" + +#include <atomic> +#include <string> + +class GeoMaterial; +class GeoVPhysVol; + +class EmulsionPlates: public EmulsionUniqueComponentFactory +{ +public: + EmulsionPlates(const std::string & name, + NeutrinoDD::EmulsionDetectorManager* detectorManager, + const EmulsionGeometryManager* geometryManager, + EmulsionMaterialManager* materials); + +public: + double thickness() const {return m_thickness;} + double width() const {return m_width;} + double height() const {return m_height;} + + virtual GeoVPhysVol * build(EmulsionIdentifier id); + +private: + void getParameters(); + virtual const GeoLogVol * preBuild(); + + double m_thickness; + double m_width; + double m_height; + const GeoMaterial * m_material; + + int m_nModules; + int m_nBasesPerModule; + double m_firstBaseZ; + double m_lastBaseZ; + + EmulsionBase* m_base; + +}; + +#endif // EMULSIONGEOMODEL_EMULSIONPLATES_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.cxx new file mode 100644 index 00000000..67af6b05 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.cxx @@ -0,0 +1,61 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EmulsionPlatesParameters.h" +#include "EmulsionGeometryManager.h" + +#include "EmulsionDataBase.h" + +#include "RDBAccessSvc/IRDBRecord.h" +#include "GaudiKernel/SystemOfUnits.h" + +#include <cmath> + + +EmulsionPlatesParameters::EmulsionPlatesParameters(EmulsionDataBase* rdb) +{ + m_rdb = rdb; +} + +double +EmulsionPlatesParameters::platesWidth() const +{ + return m_rdb->emulsionPlates()->getDouble("DX"); +} + +double +EmulsionPlatesParameters::platesHeight() const +{ + return m_rdb->emulsionPlates()->getDouble("DY"); +} + +double +EmulsionPlatesParameters::platesThickness() const +{ + return m_rdb->emulsionPlates()->getDouble("DZ"); +} + +double +EmulsionPlatesParameters::platesX() const +{ + return m_rdb->emulsionPlates()->getDouble("POSX"); +} + +double +EmulsionPlatesParameters::platesY() const +{ + return m_rdb->emulsionPlates()->getDouble("POSY"); +} + +double +EmulsionPlatesParameters::platesZ() const +{ + return m_rdb->emulsionPlates()->getDouble("POSZ"); +} + +std::string +EmulsionPlatesParameters::platesMaterial() const +{ + return m_rdb->emulsionPlates()->getString("MATERIAL"); +} \ No newline at end of file diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.h b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.h new file mode 100644 index 00000000..71962b66 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/EmulsionPlatesParameters.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EmulsionGeoModel_EmulsionPlatesParameters_H +#define EmulsionGeoModel_EmulsionPlatesParameters_H + +#include <string> + +class EmulsionDataBase; + +class EmulsionPlatesParameters { + +public: + + // Constructor + EmulsionPlatesParameters(EmulsionDataBase* rdb); + + + // General + double platesWidth() const; + double platesHeight() const; + double platesThickness() const; + double platesX() const; + double platesY() const; + double platesZ() const; + std::string platesMaterial() const; + + private: + EmulsionDataBase * m_rdb; + +}; + + +#endif // EmulsionGeoModel_EmulsionPlatesParameters_H diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/components/EmulsionGeoModel_entries.cxx b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/components/EmulsionGeoModel_entries.cxx new file mode 100644 index 00000000..908a4adf --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/src/components/EmulsionGeoModel_entries.cxx @@ -0,0 +1,3 @@ +#include "EmulsionGeoModel/EmulsionDetectorTool.h" + +DECLARE_COMPONENT( EmulsionDetectorTool ) \ No newline at end of file diff --git a/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/test/EmulsionGMConfig_test.py b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/test/EmulsionGMConfig_test.py new file mode 100644 index 00000000..f200fa84 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/EmulsionGeoModel/test/EmulsionGMConfig_test.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Run tests on EmulsionGeoModel configuration + +Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +""" +if __name__ == "__main__": + from AthenaCommon.Configurable import Configurable + Configurable.configurableRun3Behavior=1 + from CalypsoConfiguration.AllConfigFlags import ConfigFlags + from AthenaConfiguration.TestDefaults import defaultTestFiles + + ConfigFlags.Input.Files = defaultTestFiles.HITS + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion + ConfigFlags.GeoModel.Align.Dynamic = False + ConfigFlags.lock() + + from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator + from EmulsionGeoModel.EmulsionGeoModelConfig import EmulsionGeometryCfg + acc = EmulsionGeometryCfg(ConfigFlags) + f=open('EmulsionGeometryCfg.pkl','wb') + acc.store(f) + f.close() diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/CMakeLists.txt b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/CMakeLists.txt new file mode 100644 index 00000000..4b79c5b3 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/CMakeLists.txt @@ -0,0 +1,22 @@ +################################################################################ +# Package: NeutrinoGeoModelUtils +################################################################################ + +# Declare the package name: +atlas_subdir( NeutrinoGeoModelUtils ) + +# External dependencies: +find_package( Boost COMPONENTS filesystem thread system ) +find_package( CLHEP ) +find_package( CORAL COMPONENTS CoralBase CoralKernel RelationalAccess ) +find_package( GeoModel ) + +# Component(s) in the package: +atlas_add_library( NeutrinoGeoModelUtils + src/*.cxx + PUBLIC_HEADERS NeutrinoGeoModelUtils + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} + DEFINITIONS ${CLHEP_DEFINITIONS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${CORAL_LIBRARIES} ${CLHEP_LIBRARIES} ${GEOMODEL_LIBRARIES} AthenaKernel GaudiKernel StoreGateLib SGtests GeoPrimitives GeometryDBSvcLib + PRIVATE_LINK_LIBRARIES GeoModelFaserUtilities ) + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DetectorFactoryBase.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DetectorFactoryBase.h new file mode 100644 index 00000000..86f49a39 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DetectorFactoryBase.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NeutrinoGeoModelUtils_DetectorFactoryBase_H +#define NeutrinoGeoModelUtils_DetectorFactoryBase_H + +#include "AthenaKernel/MsgStreamMember.h" +#include "GeoModelKernel/GeoVDetectorFactory.h" +#include "NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h" + +class StoreGateSvc; +class IGeoDbTagSvc; +class IRDBAccessSvc; + +namespace NeutrinoDD { + +class DetectorFactoryBase : public GeoVDetectorFactory +{ + +public: + DetectorFactoryBase(const NeutrinoDD::AthenaComps * athenaComps) + : m_athenaComps(athenaComps) + {} + + StoreGateSvc * detStore() const {return m_athenaComps->detStore();} + + IGeoDbTagSvc * geoDbTagSvc() const {return m_athenaComps->geoDbTagSvc();} + + IRDBAccessSvc * rdbAccessSvc() const {return m_athenaComps->rdbAccessSvc();} + + IGeometryDBSvc * geomDB() const {return m_athenaComps->geomDB();} + + //Declaring the Message method for further use + MsgStream& msg (MSG::Level lvl) const { return m_athenaComps->msg(lvl); } + + //Declaring the Method providing Verbosity Level + bool msgLvl (MSG::Level lvl) const { return m_athenaComps->msgLvl(lvl); } + + const NeutrinoDD::AthenaComps * getAthenaComps() {return m_athenaComps;} + +private: + + const NeutrinoDD::AthenaComps * m_athenaComps; + +}; + +} // end namespace + +#endif // NeutrinoGeoModelUtils_DetectorFactoryBase_H + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DistortedMaterialManager.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DistortedMaterialManager.h new file mode 100644 index 00000000..4d9a4e52 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/DistortedMaterialManager.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NeutrinoGeoModelUtils_DistortedMaterialManager_h +#define NeutrinoGeoModelUtils_DistortedMaterialManager_h + +class AbsMaterialManager; +#include "RDBAccessSvc/IRDBAccessSvc.h" + +namespace NeutrinoDD { + +class DistortedMaterialManager +{ +public: + DistortedMaterialManager(); + IRDBRecordset_ptr extraMaterialTable() const {return m_xMatTable;} + const AbsMaterialManager * materialManager() const {return m_materialManager;} + +private: + const AbsMaterialManager * m_materialManager; + IRDBRecordset_ptr m_xMatTable; +}; + + +} // endnamespace + +#endif // NeutrinoGeoModelUtils_DistortedMaterialManager_h diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/ExtraMaterial.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/ExtraMaterial.h new file mode 100644 index 00000000..f0cefb05 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/ExtraMaterial.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NeutrinoGeoModelUtils_ExtraMaterial +#define NeutrinoGeoModelUtils_ExtraMaterial + +#include <cmath> +#include <string> +#include <sstream> +#include "RDBAccessSvc/IRDBAccessSvc.h" + +class GeoPhysVol; +class GeoFullPhysVol; +class AbsMaterialManager; + +namespace NeutrinoDD { + +class DistortedMaterialManager; + +class ExtraMaterial +{ +public: + ExtraMaterial(IRDBRecordset_ptr xMatTable, const AbsMaterialManager * matManager); + ExtraMaterial(const NeutrinoDD::DistortedMaterialManager * manager); + void add(GeoPhysVol * parent, const std::string & parentName, double zPos = 0); + void add(GeoFullPhysVol * parent, const std::string & parentName, double zPos = 0); + +private: + void add(GeoPhysVol * parent, GeoFullPhysVol * fullparent, const std::string & parentName, double zPos); + IRDBRecordset_ptr m_xMatTable; + const AbsMaterialManager * m_matManager; +}; + +} // end namespace + +#endif // NeutrinoGeoModelUtils_ExtraMaterial diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/GenericTubeMaker.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/GenericTubeMaker.h new file mode 100644 index 00000000..5fa74a1a --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/GenericTubeMaker.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NeutrinoGeoModelUtils_GenericTubeMaker_h +#define NeutrinoGeoModelUtils_GenericTubeMaker_h + +#include "NeutrinoGeoModelUtils/TubeVolData.h" +#include <string> + +class GeoVPhysVol; +class GeoPhysVol; +class GeoFullPhysVol; +class GeoShape; +class IRDBRecord; + +/// Helper class to make general tubes used mainly for services. +/// Takes as input a DB table which has the following columns +/// Handles numberouse cases +/// Simple tubes: Rmin2, Rmax2 <=0. +/// Cones: Uses Rmin2 and Rmax2. +/// Tube and cone sectors: Uses phi start and phi delta. +/// If RadialDiv > 0 then simulates the CLHEP::radial dependence of tubes/cables going outward CLHEP::radially. +/// + +namespace NeutrinoDD { + +class GenericTubeMaker +{ +public: + GenericTubeMaker(const IRDBRecord *); + const TubeVolData & volData() const {return m_volData;} + std::string name() const; + std::string materialName() const; + const GeoShape * buildShape(); + void placeVolume(GeoPhysVol * parent, GeoVPhysVol * child, double zParent = 0); + void placeVolume(GeoFullPhysVol * fullparent, GeoVPhysVol * child, double zParent = 0); + void placeVolTwoSide(GeoPhysVol * parentPos, GeoPhysVol * parentNeg, GeoVPhysVol * child, double zParent = 0); + void placeVolTwoSide(GeoFullPhysVol * fullparentPos, GeoFullPhysVol * fullparentNeg, GeoVPhysVol * child, double zParent = 0); + + +private: + + void placeVolume(GeoPhysVol * parent, GeoFullPhysVol * fullparent, GeoVPhysVol * child, double zParent); + void placeVolTwoSide(GeoPhysVol * parentPos, GeoPhysVol * parentNeg, + GeoFullPhysVol * fullparentPos, GeoFullPhysVol * fullparentNeg, + GeoVPhysVol * child, double zParent); + + const IRDBRecord * m_record; + TubeVolData m_volData; +}; + +} // end namespace + +#endif // NeutrinoGeoModelUtils_GenericTubeMaker_h diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h new file mode 100644 index 00000000..7d1aad8a --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NeutrinoGeoModelUtils_NeutrinoDDAthenaComps_H +#define NeutrinoGeoModelUtils_NeutrinoDDAthenaComps_H + +// Message Stream Member +#include "AthenaKernel/MsgStreamMember.h" +class StoreGateSvc; +class IGeoDbTagSvc; +class IRDBAccessSvc; +class IGeometryDBSvc; + +#include <string> +namespace NeutrinoDD { + +/// Class to hold various Athena components. +class AthenaComps { + +public: + + AthenaComps(const std::string & msgStreamName); + + //Declaring the Message method for further use + MsgStream& msg (MSG::Level lvl) const { return m_msg << lvl; } + + //Declaring the Method providing Verbosity Level + bool msgLvl (MSG::Level lvl) const { return m_msg.get().level() <= lvl; } + + void setDetStore(StoreGateSvc *); + void setGeoDbTagSvc(IGeoDbTagSvc *); + void setRDBAccessSvc(IRDBAccessSvc *); + void setGeometryDBSvc(IGeometryDBSvc *); + + StoreGateSvc * detStore() const; + IGeoDbTagSvc * geoDbTagSvc() const; + IRDBAccessSvc * rdbAccessSvc() const; + IGeometryDBSvc * geomDB() const; + +private: + //Declaring private message stream member. + mutable Athena::MsgStreamMember m_msg; + + StoreGateSvc * m_detStore; + IGeoDbTagSvc * m_geoDbTagSvc; + IRDBAccessSvc * m_rdbAccessSvc; + IGeometryDBSvc * m_geometryDBSvc; + +}; + +inline StoreGateSvc * AthenaComps::detStore() const +{ + return m_detStore; +} + +inline IGeoDbTagSvc * AthenaComps::geoDbTagSvc() const +{ + return m_geoDbTagSvc; +} + +inline IRDBAccessSvc * AthenaComps::rdbAccessSvc() const +{ + return m_rdbAccessSvc; +} + +inline IGeometryDBSvc * AthenaComps::geomDB() const +{ + return m_geometryDBSvc; +} + +} // endnamespace + +#endif // NeutrinoGeoModelUtils_NeutrinoDDAthenaComps_H + + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoMaterialManager.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoMaterialManager.h new file mode 100644 index 00000000..eb1c9774 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/NeutrinoMaterialManager.h @@ -0,0 +1,244 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef SCINTMATERIALMANAGER_H +#define SCINTMATERIALMANAGER_H + +// Message Stream Member +#include "AthenaKernel/MsgStreamMember.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" + +class GeoMaterial; +class GeoElement; +class AbsMaterialManager; +class StoreGateSvc; +class IGeometryDBSvc; + +namespace NeutrinoDD +{ + class AthenaComps; +} + +#include <string> +#include <map> + +/// NeutrinoMaterialManager. This provides an interface to the GeoModel Material Manager +/// as well as allowing additional materials to be defined or standard ones redefined. +/// It also allows creating new materials based on existing ones but with a different +/// density. It is also possible to specify a weight table and this is used to create +/// materials with a density such that the the total weight is correct. + + +class NeutrinoMaterialManager +{ + +public: + + NeutrinoMaterialManager(const std::string & managerName, StoreGateSvc* detStore); + NeutrinoMaterialManager(const std::string & managerName, StoreGateSvc* detStore, + IRDBRecordset_ptr weightTable, + const std::string & space = "", + bool extraFunctionality = false); + NeutrinoMaterialManager(const std::string & managerName, StoreGateSvc* detStore, + IRDBRecordset_ptr weightTable, + IRDBRecordset_ptr compositionTable, + const std::string & space = ""); + NeutrinoMaterialManager(const std::string & managerName, + const NeutrinoDD::AthenaComps *); + ~NeutrinoMaterialManager(); + + void addWeightTable(IRDBRecordset_ptr weightTable, const std::string & space = ""); + void addWeightMaterial(std::string materialName, std::string materialBase, double weight, int linearWeightFlag); + void addCompositionTable(IRDBRecordset_ptr compositionTable, const std::string & space = ""); + void addScalingTable(IRDBRecordset_ptr scalingTable); + + + bool hasMaterial(const std::string &materialName) const; + + /// Get material. First looks for locally defined material and if not found looks in GeoModel material manager. + const GeoMaterial* getMaterial(const std::string & materialName); + + /// Get element from GeoModel material manager + const GeoElement* getElement(const std::string & elementName) const; + + /// Create and get material with a specified density based on an existing material. + /// If a newName is supplied it creates the new material even if the orginal material + /// has the same density. It however first checks if the material with NewName exists. + /// If no newName is supplied then it checks the density of + /// the existing material. If it is consistent it returns the material. + /// If it is different it creates a material with the string "Modified" added to the + /// name. + const GeoMaterial* getMaterial(const std::string & origMaterialName, + double density, + const std::string & newName = ""); + + // Creates a new material based on origMaterialName but with denisty scaled + // by scaleFactor. If no newName then will add the string containing the scale + // factor. Eg if scale 12.345678 "Silicon" -> "Silicon12_3456" + // If the scale factor is 1 and there is no newName then it just returns the + // original material. + // scaleFactor must be between 0.001 and 1000. + const GeoMaterial* getMaterialScaled(const std::string & origMaterialName, + double scaleFactor, + const std::string & newName = ""); + + /// Create and get material with a density calculated to give weight in predefined weight table. + const GeoMaterial * getMaterialForVolume(const std::string & materialName, + double volume, + const std::string & newName = ""); + + // Similar to getMaterialForVolume but if weight table uses linear weight, then determine weight + // using length. First looks in special table of material compositions which can specify several + // components and their count. + const GeoMaterial * getMaterialForVolumeLength(const std::string & materialName, + double volume, + double length, + const std::string & newName = ""); + + // As above but rather than using the special table of material compositions, the compositions is specified + // in the arguments as a vector of materials and multiplictive factors. + const GeoMaterial * getMaterialForVolumeLength(const std::string & name, + const std::vector<std::string> & materialComponents, + const std::vector<double> factors, + double volume, + double length); + + // As above but only one material making up the composition. + const GeoMaterial * getMaterialForVolumeLength(const std::string & name, + const std::string & materialComponent, + double factor, + double volume, + double length); + + // Define composite material : function used to create dynamically a new composite material by adding + // a defined volume of glue/grease to an already existing material (IBL stave) + const GeoMaterial * getCompositeMaterialForVolume(const std::string & newMatName, + const double volumeTot, + const double volume1, const std::string & matName1, + const double volume2, const std::string & matName2 + ); + + // Define a new material composition. + const GeoMaterial * getMaterial(const std::string & name, + const std::vector<std::string> & materialComponents, + const std::vector<double> & fractWeights, + double density); + + + /// Add material + void addMaterial(GeoMaterial *material); + + //Declaring the Message method for further use + MsgStream& msg (MSG::Level lvl) const { return m_msg << lvl; } + + //Declaring the Method providing Verbosity Level + bool msgLvl (MSG::Level lvl){ return m_msg.get().level() <= lvl; } + + +private: + + class MaterialByWeight { + public: + MaterialByWeight() : weight(0), linearWeightFlag(false) {} + MaterialByWeight(const std::string & name_in, double weight_in, bool linearWeightFlag_in) + : name(name_in), weight(weight_in), linearWeightFlag(linearWeightFlag_in) {} + MaterialByWeight(double weight_in) + : weight(weight_in), linearWeightFlag(false) {} + std::string name; + double weight; + bool linearWeightFlag; + }; + + class MaterialComponent { + public: + MaterialComponent() : factor(1), actualLength(-1) {} + MaterialComponent(const std::string & name_in, double factor_in = 1, bool actualLength_in = -1) + : name(name_in), factor(factor_in), actualLength(actualLength_in) {} + std::string name; + double factor; + double actualLength; + }; + + /// Class to hold information need to create a material + class MaterialDef { + public: + MaterialDef(); + MaterialDef(const std::string & name, double density); + void addComponent(const std::string & compName, double fraction); + void setCreated() {m_created = true;} + unsigned int numComponents() const {return m_components.size();} + bool isCreated() const {return m_created;} + const std::string & name() const {return m_name;} + double density() const {return m_density;} + const std::string & compName(unsigned int i) const {return m_components[i];} + double fraction(unsigned int i) const {return m_fractions[i];} + double totalFraction() const; + + private: + std::string m_name; + double m_density; + std::vector<std::string> m_components; + std::vector<double> m_fractions; + bool m_created; + }; + + + const AbsMaterialManager * retrieveManager(StoreGateSvc* detStore); + const GeoMaterial* getAdditionalMaterial(const std::string & materialName) const; + bool compareDensity(double d1, double d2) const; + void addWeightTableOld(IRDBRecordset_ptr weightTable, const std::string & space); + + // Internal versions. The public versions allow materials to be have extra scaling. + const GeoMaterial* getMaterialInternal(const std::string & materialName) const; + const GeoMaterial* getMaterialInternal(const std::string & origMaterialName, + double density, + const std::string & newName = ""); + const GeoMaterial* getMaterialScaledInternal(const std::string & origMaterialName, + double scaleFactor, + const std::string & newName = ""); + const GeoMaterial * getMaterialInternal(const std::string & name, + const std::vector<std::string> & materialComponents, + const std::vector<double> & fractWeights, + double density); + + // Methods to return material with extra scaling. + const GeoMaterial * extraScaledMaterial(const std::string & materialName, + const std::string & newName, + const GeoMaterial * origMaterial); + + const GeoMaterial * extraScaledMaterial(const std::string & materialName, + const GeoMaterial * origMaterial); + + const IGeometryDBSvc * db(); + void addTextFileMaterials(); + void createMaterial(const MaterialDef & material); + double getExtraScaleFactor(const std::string & materialName); + + const AbsMaterialManager *m_materialManager; + std::string m_managerName; + + typedef std::map<std::string, const GeoMaterial *> MaterialStore; + MaterialStore m_store; + + typedef std::map<std::string, MaterialByWeight > MaterialWeightMap; + MaterialWeightMap m_weightMap; + + typedef std::map<std::string, MaterialComponent > MaterialCompositionMap; + MaterialCompositionMap m_matCompositionMap; + + typedef std::map<std::string, double > ExtraScaleFactorMap; + ExtraScaleFactorMap m_scalingMap; + + //Declaring private message stream member. + mutable Athena::MsgStreamMember m_msg; + + // Has linear weight flag. + bool m_extraFunctionality; + + const NeutrinoDD::AthenaComps * m_athenaComps; + +}; + + +#endif // SCINTMATERIALMANAGER_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TopLevelPlacements.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TopLevelPlacements.h new file mode 100644 index 00000000..53d45c5b --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TopLevelPlacements.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef SCINTGEOMODELUTILS_TOPLEVELPLACEMENTS_H +#define SCINTGEOMODELUTILS_TOPLEVELPLACEMENTS_H + +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/GeoDefinitions.h" + +#include <map> +#include <string> + +class IRDBRecord; + +class TopLevelPlacements +{ + +public: + + TopLevelPlacements(IRDBRecordset_ptr topLevelTable); + ~TopLevelPlacements(); + + bool present(const std::string & partName) const; + const GeoTrf::Transform3D & transform(const std::string & partName) const; + + +private: + + class Part { + public: + std::string label; + GeoTrf::Transform3D transform; + }; + + void fillPlacements(IRDBRecordset_ptr topLevelTable); + GeoTrf::Transform3D partTransform(const IRDBRecord* record) const; + Part * getPart(const std::string & partName) const; + + std::map<std::string, Part *> m_parts; + bool m_noTopLevelTable; + + static GeoTrf::Transform3D s_identityTransform; +}; + +#endif // SCINTGEOMODELUTILS_TOPLEVELPLACEMENTS_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TubeVolData.h b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TubeVolData.h new file mode 100644 index 00000000..0d1f613e --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/NeutrinoGeoModelUtils/TubeVolData.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NeutrinoGeoModelUtils_TubeVolData_h +#define NeutrinoGeoModelUtils_TubeVolData_h + +class IRDBRecord; +#include <string> + +namespace NeutrinoDD { + + +/// Helper class to read in generic TUBE, TUBS, CONS or PCON type volumes. + +class TubeVolData +{ + public: + enum VolShape {TUBE, TUBS, CONS, RADIAL}; + + TubeVolData(const IRDBRecord *); + double rmin() const {return m_rmin1;} + double rmax() const {return m_rmax1;} + double rmin2() const {return m_rmin2;} + double rmax2() const {return m_rmax2;} + double length() const {return m_length;} + double zMid() const {return m_zMid;} + double phiStart() const {return m_phiStart;} + double phiDelta() const {return m_phiDelta;} + double phiStep() const {return m_phiStep;} + int nRepeat() const {return m_nRepeat;} + int radialDivisions() const {return m_radialDiv;} + bool bothZ() const {return m_bothZ;} + + VolShape shape() const {return m_shape;} + std::string material() const; + + double maxRadius() const; + + private: + const IRDBRecord * m_record; + bool m_bothZ; + int m_nRepeat; + int m_radialDiv; + double m_phiStart; + double m_phiDelta; + double m_phiStep; + double m_rmin1; + double m_rmin2; + double m_rmax1; + double m_rmax2; + double m_length; + double m_zMid; + VolShape m_shape{CONS}; +}; + +} // end namespace + +#endif // NeutrinoGeoModelUtils_TubeVolData diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/DistortedMaterialManager.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/DistortedMaterialManager.cxx new file mode 100644 index 00000000..fbaae2a6 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/DistortedMaterialManager.cxx @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + + +#include "NeutrinoGeoModelUtils/DistortedMaterialManager.h" +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelFaserUtilities/DecodeFaserVersionKey.h" +#include "AthenaKernel/MsgStreamMember.h" +#include "StoreGate/StoreGateSvc.h" +#include "RDBAccessSvc/IRDBAccessSvc.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/Bootstrap.h" + +namespace NeutrinoDD { + DistortedMaterialManager::DistortedMaterialManager() { + ISvcLocator* svcLocator = Gaudi::svcLocator(); // from Bootstrap + + Athena::MsgStreamMember log("ExtraMaterialManager"); + log << MSG::DEBUG << "Initialized Neutrino Distorted Material Manager" << endmsg; + + StoreGateSvc* detStore; + StatusCode sc; + sc = svcLocator->service("DetectorStore", detStore); + if (sc.isFailure()) log << MSG::FATAL << "Could not locate DetectorStore" << endmsg; + + IRDBAccessSvc* rdbSvc; + sc = svcLocator->service("RDBAccessSvc", rdbSvc); + if (sc.isFailure()) log << MSG::FATAL << "Could not locate RDBAccessSvc" << endmsg; + + // Get version tag and node for InDet. + DecodeFaserVersionKey versionKey("Neutrino"); + std::string detectorKey = versionKey.tag(); + std::string detectorNode = versionKey.node(); + + log << MSG::DEBUG << "Retrieving Record Sets from database ..." << endmsg; + log << MSG::DEBUG << "Key = " << detectorKey << " Node = " << detectorNode << endmsg; + + m_xMatTable = rdbSvc->getRecordsetPtr("NeutrinoExtraMaterial", detectorKey, detectorNode, "FASERDD"); + + const StoredMaterialManager* theGeoMaterialManager = 0; + sc = detStore->retrieve(theGeoMaterialManager, "MATERIALS"); + if (sc.isFailure()) log << MSG::FATAL << "Could not locate GeoModel Material manager" << endmsg; + m_materialManager = theGeoMaterialManager; + } +} // end namespace diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/ExtraMaterial.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/ExtraMaterial.cxx new file mode 100644 index 00000000..315524c0 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/ExtraMaterial.cxx @@ -0,0 +1,74 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "NeutrinoGeoModelUtils/ExtraMaterial.h" +#include "NeutrinoGeoModelUtils/GenericTubeMaker.h" +#include "NeutrinoGeoModelUtils/TubeVolData.h" +#include "NeutrinoGeoModelUtils/DistortedMaterialManager.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoTubs.h" +#include "GeoModelKernel/GeoCons.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoMaterial.h" + +#include "GeoModelInterfaces/AbsMaterialManager.h" + +#include <string> +#include <sstream> +#include <iostream> + +namespace NeutrinoDD { + ExtraMaterial::ExtraMaterial(IRDBRecordset_ptr xMatTable, const AbsMaterialManager* matManager) + : m_xMatTable(xMatTable), + m_matManager(matManager) + {} + + ExtraMaterial::ExtraMaterial(const DistortedMaterialManager* manager) + : m_xMatTable(manager->extraMaterialTable()), + m_matManager(manager->materialManager()) + {} + + void + ExtraMaterial::add(GeoPhysVol* parent, const std::string& region, double zParent) { + add(parent, 0, region, zParent); + } + + void + ExtraMaterial::add(GeoFullPhysVol* parent, const std::string& region, double zParent) { + add(0, parent, region, zParent); + } + + void + ExtraMaterial::add(GeoPhysVol* parent, GeoFullPhysVol* fullparent, const std::string& region, double zParent) { + //std::cout << "Adding Extra material for region: " << region << ", zParent = " << zParent << std::endl; + + for (unsigned int i = 0; i < m_xMatTable->size(); i++) { + std::ostringstream volnamestr; + volnamestr << "ExtraMaterial" << i; + + //std::cout << "In Extra material " << i << std::endl; + + if ((*m_xMatTable)[i]->getString("REGION") == region) { + //std::cout << "Extra material Match " << i << std::endl; + + GenericTubeMaker tubeHelper((*m_xMatTable)[i]); + const GeoMaterial* material = m_matManager->getMaterial(tubeHelper.volData().material()); + const GeoShape* shape = tubeHelper.buildShape(); + GeoLogVol* logVol = new GeoLogVol(volnamestr.str(), shape, material); + GeoPhysVol* physVol = new GeoPhysVol(logVol); + + if (parent) { + tubeHelper.placeVolume(parent, physVol, zParent); + } else { + tubeHelper.placeVolume(fullparent, physVol, zParent); + } + } + } + } +} // end namespace diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/GenericTubeMaker.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/GenericTubeMaker.cxx new file mode 100644 index 00000000..5b7f5481 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/GenericTubeMaker.cxx @@ -0,0 +1,164 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "NeutrinoGeoModelUtils/GenericTubeMaker.h" +#include "NeutrinoGeoModelUtils/TubeVolData.h" + +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoTubs.h" +#include "GeoModelKernel/GeoCons.h" +#include "GeoModelKernel/GeoPcon.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoDefinitions.h" +#include "GaudiKernel/SystemOfUnits.h" + +#include "RDBAccessSvc/IRDBRecord.h" + +namespace NeutrinoDD { + GenericTubeMaker::GenericTubeMaker(const IRDBRecord* record) + : m_record(record), + m_volData(record) + {} + + std::string + GenericTubeMaker::materialName() const { + return m_record->getString("MATERIAL"); + } + + std::string + GenericTubeMaker::name() const { + return m_record->getString("NAME"); + } + + const GeoShape* + GenericTubeMaker::buildShape() { + const GeoShape* shape = 0; + + switch (m_volData.shape()) { + case TubeVolData::TUBE: + shape = new GeoTube(m_volData.rmin(), m_volData.rmax(), 0.5 * m_volData.length()); + break; + + case TubeVolData::TUBS: + shape = new GeoTubs(m_volData.rmin(), m_volData.rmax(), 0.5 * m_volData.length(), + m_volData.phiStart(), m_volData.phiDelta()); + break; + + case TubeVolData::CONS: + shape = new GeoCons(m_volData.rmin(), m_volData.rmin2(), m_volData.rmax(), m_volData.rmax2(), + 0.5 * m_volData.length(), m_volData.phiStart(), m_volData.phiDelta()); + break; + + case TubeVolData::RADIAL: + // This simulates the radial decrease in density. + double zstart = -0.5 * m_volData.length(); + GeoPcon* shapeTmp = new GeoPcon(m_volData.phiStart(), m_volData.phiDelta()); + shapeTmp->addPlane(zstart, m_volData.rmin(), m_volData.rmax()); + double radialDelta = (m_volData.rmax() - m_volData.rmin()) / m_volData.radialDivisions(); + for (int i = 0; i < m_volData.radialDivisions(); i++) { + double rIntermediate = m_volData.rmax() - i * radialDelta; + double reductionFactor = m_volData.rmin() / rIntermediate; + shapeTmp->addPlane(zstart + reductionFactor * m_volData.length(), m_volData.rmin(), rIntermediate); + } + shapeTmp->addPlane(zstart + m_volData.length(), m_volData.rmin(), m_volData.rmin()); + shape = shapeTmp; + break; + } + + return shape; + } + + void + GenericTubeMaker::placeVolume(GeoPhysVol* parent, GeoVPhysVol* child, double zParent) { + placeVolume(parent, 0, child, zParent); + } + + void + GenericTubeMaker::placeVolume(GeoFullPhysVol* fullparent, GeoVPhysVol* child, double zParent) { + placeVolume(0, fullparent, child, zParent); + } + + void + GenericTubeMaker::placeVolTwoSide(GeoPhysVol* parentPos, GeoPhysVol* parentNeg, GeoVPhysVol* child, double zParent) { + placeVolTwoSide(parentPos, parentNeg, 0, 0, child, zParent); + } + + void + GenericTubeMaker::placeVolTwoSide(GeoFullPhysVol* fullparentPos, GeoFullPhysVol* fullparentNeg, GeoVPhysVol* child, + double zParent) { + placeVolTwoSide(0, 0, fullparentPos, fullparentNeg, child, zParent); + } + + void + GenericTubeMaker::placeVolume(GeoPhysVol* parent, GeoFullPhysVol* fullparent, GeoVPhysVol* child, double zParent) { + for (int iRepeat = 0; iRepeat < m_volData.nRepeat(); iRepeat++) { + double phi = m_volData.phiStep() * iRepeat; + + GeoTransform* xform = 0; + double zOffset = m_volData.zMid() - zParent; + if (zOffset != 0 || iRepeat > 0) { + xform = new GeoTransform(GeoTrf::TranslateZ3D(zOffset) * GeoTrf::RotateZ3D(phi)); + } + + if (parent) { + if (xform) parent->add(xform); + parent->add(child); + } else { + if (xform) fullparent->add(xform); + fullparent->add(child); + } + + // Place in negative z as well. + if (m_volData.bothZ()) { + GeoTransform* xformNeg = new GeoTransform(GeoTrf::RotateY3D(180 * Gaudi::Units::deg) * GeoTrf::TranslateZ3D( + zOffset) * GeoTrf::RotateZ3D(phi)); + if (parent) { + parent->add(xformNeg); + parent->add(child); + } else { + fullparent->add(xformNeg); + fullparent->add(child); + } + } + } // iRepeat loop + } + + void + GenericTubeMaker::placeVolTwoSide(GeoPhysVol* parentPos, GeoPhysVol* parentNeg, + GeoFullPhysVol* fullparentPos, GeoFullPhysVol* fullparentNeg, + GeoVPhysVol* child, double zParent) { + for (int iRepeat = 0; iRepeat < m_volData.nRepeat(); iRepeat++) { + double phi = m_volData.phiStep() * iRepeat; + double zOffset = m_volData.zMid() - zParent; + const bool newXform((zOffset != 0)or(iRepeat > 0)); + + if (parentPos) { + if (newXform) { + parentPos->add(new GeoTransform(GeoTrf::TranslateZ3D(zOffset) * GeoTrf::RotateZ3D(phi))); + } + parentPos->add(child); + } else if (fullparentPos) { + if (newXform) { + fullparentPos->add(new GeoTransform(GeoTrf::TranslateZ3D(zOffset) * GeoTrf::RotateZ3D(phi))); + } + fullparentPos->add(child); + } + + // Place in negative z as well. + if (m_volData.bothZ()) { + GeoTransform* xformNeg = new GeoTransform(GeoTrf::RotateY3D(180 * Gaudi::Units::deg) * GeoTrf::TranslateZ3D( + zOffset) * GeoTrf::RotateZ3D(phi)); + if (parentNeg) { + parentNeg->add(xformNeg); + parentNeg->add(child); + } else { + fullparentNeg->add(xformNeg); + fullparentNeg->add(child); + } + } + } // iRepeat loop + } +}// end namespace diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoDDAthenaComps.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoDDAthenaComps.cxx new file mode 100644 index 00000000..40fdc37e --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoDDAthenaComps.cxx @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h" + +namespace NeutrinoDD { + AthenaComps::AthenaComps(const std::string& msgStreamName) + : m_msg(msgStreamName), + m_detStore(0), + m_geoDbTagSvc(0), + m_rdbAccessSvc(0), + m_geometryDBSvc(0) + {} + + void + AthenaComps::setDetStore(StoreGateSvc* detStore) { + m_detStore = detStore; + } + + void + AthenaComps::setGeoDbTagSvc(IGeoDbTagSvc* geoDbTagSvc) { + m_geoDbTagSvc = geoDbTagSvc; + } + + void + AthenaComps::setRDBAccessSvc(IRDBAccessSvc* rdbAccessSvc) { + m_rdbAccessSvc = rdbAccessSvc; + } + + void + AthenaComps::setGeometryDBSvc(IGeometryDBSvc* geometryDBSvc) { + m_geometryDBSvc = geometryDBSvc; + } +} diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoMaterialManager.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoMaterialManager.cxx new file mode 100644 index 00000000..475250a1 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/NeutrinoMaterialManager.cxx @@ -0,0 +1,1042 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "NeutrinoGeoModelUtils/NeutrinoMaterialManager.h" +#include "NeutrinoGeoModelUtils/NeutrinoDDAthenaComps.h" +#include "GeoModelInterfaces/AbsMaterialManager.h" +#include "GeoModelInterfaces/StoredMaterialManager.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/Units.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "GeometryDBSvc/IGeometryDBSvc.h" +#include "StoreGate/StoreGateSvc.h" + +#include <iostream> +#include <iomanip> +#include <cmath> +#include <stdexcept> + +// Constructor +NeutrinoMaterialManager::NeutrinoMaterialManager(const std::string& managerName, + StoreGateSvc* detStore) + : m_managerName(managerName), + m_msg(managerName), + m_extraFunctionality(false), + m_athenaComps(0) { + m_materialManager = retrieveManager(detStore); +} + +// Constructor +NeutrinoMaterialManager::NeutrinoMaterialManager(const std::string& managerName, + StoreGateSvc* detStore, + IRDBRecordset_ptr weightTable, + const std::string& space, + bool extraFunctionality) + : m_managerName(managerName), + m_msg(managerName), + m_extraFunctionality(extraFunctionality), + m_athenaComps(0) { + m_materialManager = retrieveManager(detStore); + + if (weightTable) addWeightTable(weightTable, space); + + // For testing we add a few materials. + //m_weightMap["veto::CoolingBlock"] = MaterialByWeight(2.418*CLHEP::gram); + //m_weightMap["veto::CoolingBlock"] = MaterialByWeight(2*CLHEP::gram); + //m_weightMap["veto::BrlHybrid"] = MaterialByWeight("veto::Hybrid", 8*CLHEP::gram); + //m_weightMap["veto::FwdHybrid"] = MaterialByWeight("std::Carbon", 7.662*CLHEP::gram); +} + +NeutrinoMaterialManager::NeutrinoMaterialManager(const std::string& managerName, StoreGateSvc* detStore, + IRDBRecordset_ptr weightTable, + IRDBRecordset_ptr compositionTable, + const std::string& space) + : m_managerName(managerName), + m_msg(managerName), + m_extraFunctionality(true), + m_athenaComps(0) { + m_materialManager = retrieveManager(detStore); + + if (weightTable) addWeightTable(weightTable, space); + if (compositionTable) addCompositionTable(compositionTable, space); +} + +NeutrinoMaterialManager::NeutrinoMaterialManager(const std::string& managerName, + const NeutrinoDD::AthenaComps* athenaComps) + : m_managerName(managerName), + m_msg(managerName), + m_extraFunctionality(true), + m_athenaComps(athenaComps) { + m_materialManager = retrieveManager(athenaComps->detStore()); + addTextFileMaterials(); +} + +NeutrinoMaterialManager::~NeutrinoMaterialManager() { + // Dereference the materials. + MaterialStore::const_iterator iter; + for (iter = m_store.begin(); iter != m_store.end(); ++iter) { + iter->second->unref(); + } +} + +const AbsMaterialManager* +NeutrinoMaterialManager::retrieveManager(StoreGateSvc* detStore) { + const StoredMaterialManager* theGeoMaterialManager = nullptr; + + if (StatusCode::SUCCESS != detStore->retrieve(theGeoMaterialManager, "MATERIALS")) { + msg(MSG::FATAL) << "Cannot locate Materials"; + } + + return theGeoMaterialManager; +} + +const GeoElement* +NeutrinoMaterialManager::getElement(const std::string& elementName) const { + return m_materialManager->getElement(elementName); +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterial(const std::string& materialName) { + return extraScaledMaterial(materialName, getMaterialInternal(materialName)); +} + +bool +NeutrinoMaterialManager::hasMaterial(const std::string& materialName) const { + return m_store.find(materialName) != m_store.end(); +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialInternal(const std::string& materialName) const { + // First check local store of materials. If not found then get it from the GeoModel + // manager. + const GeoMaterial* material = getAdditionalMaterial(materialName); + + if (!material) { + // This prints error message if not found. + material = m_materialManager->getMaterial(materialName); + } + return material; +} + +const GeoMaterial* +NeutrinoMaterialManager::getAdditionalMaterial(const std::string& materialName) const { + MaterialStore::const_iterator iter; + if ((iter = m_store.find(materialName)) != m_store.end()) { + return iter->second; + } else { + return 0; + } +} + +const GeoMaterial* +NeutrinoMaterialManager::getCompositeMaterialForVolume(const std::string& newMatName, + const double volumeTot, + const double volume1, const std::string& matName1, + const double volume2, const std::string& matName2 + ) { + std::vector<std::string> baseMaterials; + std::vector<double> fracWeight; + baseMaterials.reserve(2); + fracWeight.reserve(2); + + msg(MSG::DEBUG) << "Composite material : " << volumeTot / Gaudi::Units::cm3 << " = " << volume1 / Gaudi::Units::cm3 << " + " << + volume2 / Gaudi::Units::cm3 << endmsg; + msg(MSG::DEBUG) << "Composite material : " << matName1 << " " << matName2 << endmsg; + + double density1, density2; + + MaterialWeightMap::const_iterator iter; + if ((iter = m_weightMap.find(matName1)) != m_weightMap.end()) { + const GeoMaterial* mat1 = getMaterialForVolume(matName1, volume1); + density1 = mat1->getDensity(); + msg(MSG::DEBUG) << "Composite material 1 - weight : " << density1 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << endmsg; + } else { + const GeoMaterial* mat1 = getMaterial(matName1); + density1 = mat1->getDensity(); + msg(MSG::DEBUG) << "Composite material 1 - standard : " << density1 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << endmsg; + } + + if ((iter = m_weightMap.find(matName2)) != m_weightMap.end()) { + const GeoMaterial* mat2 = getMaterialForVolume(matName2, volume2); + density2 = mat2->getDensity(); + msg(MSG::DEBUG) << "Composite material 2 - weight : " << density2 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << endmsg; + } else { + const GeoMaterial* mat2 = getMaterial(matName2); + density2 = mat2->getDensity(); + msg(MSG::DEBUG) << "Composite material 2 - standard : " << density2 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << endmsg; + } + + double weight1 = density1 * volume1; + double weight2 = density2 * volume2; + double invWeightTot = 1.0 / (weight1 + weight2); + + double density = (weight1 + weight2) / volumeTot; + + double frac1 = weight1 / (weight1 + weight2); + double frac2 = weight2 / (weight1 + weight2); + double density_2 = 1.0 / (frac1 / density1 + frac2 / density2); + double density_3 = (weight1 + weight2) / (volume1 + volume2); + msg(MSG::DEBUG) << "-> weights : " << weight1 / (GeoModelKernelUnits::gram) << " " << weight2 / (GeoModelKernelUnits::gram) << endmsg; + msg(MSG::DEBUG) << "-> density : " << density / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << " " << density_2 / + (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << " " << density_3 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << endmsg; + + + baseMaterials.push_back(matName1); + baseMaterials.push_back(matName2); + fracWeight.push_back(weight1 * invWeightTot); + fracWeight.push_back(weight2 * invWeightTot); + + return getMaterial(newMatName, baseMaterials, fracWeight, density); +} + +// This creates a new material with specified density. + +// If a newName is supplied it creates the new material even if the orginal material +// has the same density. It however first checks if the material with NewName exists. + +// If no new name is supplied then it checks the density of +// the existing material. If it is consistent it returns the material. +// If it is different it creates a material with the string "Modified" added to the +// name. + + +const GeoMaterial* +NeutrinoMaterialManager::getMaterial(const std::string& origMaterialName, + double density, + const std::string& newName) { + return extraScaledMaterial(origMaterialName, newName, + getMaterialInternal(origMaterialName, density, newName)); +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialInternal(const std::string& origMaterialName, + double density, + const std::string& newName) { + std::string newName2 = newName; + bool newNameProvided = !newName2.empty(); + if (!newNameProvided) { + newName2 = origMaterialName + "Modified"; + } + + const GeoMaterial* newMaterial = 0; + + // First see if we already have the modified material + const GeoMaterial* material = getAdditionalMaterial(newName2); + if (material) { + if (!compareDensity(material->getDensity(), density)) { + msg(MSG::WARNING) << "Density is not consistent for material " << newName2 + << " " << material->getDensity() / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) + << " / " << density / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << endmsg; + } + newMaterial = material; + } else { + const GeoMaterial* origMaterial = getMaterialInternal(origMaterialName); + newMaterial = origMaterial; + if (origMaterial) { + // If no new name was provided we check if the density is compatible + // and if so we return the original material. + if (newNameProvided || !compareDensity(origMaterial->getDensity(), density)) { + // create new material + GeoMaterial* newMaterialTmp = new GeoMaterial(newName2, density); + newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), 1.); + addMaterial(newMaterialTmp); + newMaterial = newMaterialTmp; + } + } + } + return newMaterial; +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialScaled(const std::string& origMaterialName, + double scaleFactor, + const std::string& newName) { + return extraScaledMaterial(origMaterialName, newName, + getMaterialScaledInternal(origMaterialName, scaleFactor, newName)); +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialScaledInternal(const std::string& origMaterialName, + double scaleFactor, + const std::string& newName) { + // Don't allow large scale factors + if (scaleFactor > 1000 || scaleFactor < 0.001) { + msg(MSG::ERROR) << "Scale factor must be between 0.001 and 1000." << endmsg; + return 0; + } + + const GeoMaterial* origMaterial = getMaterialInternal(origMaterialName); + + // If scalefactor is 1 and no new name is requested + // then just return the orginal material + if (newName.empty() && scaleFactor == 1.) return origMaterial; + + const GeoMaterial* newMaterial = 0; + + if (origMaterial) { + double density = origMaterial->getDensity() * scaleFactor; + std::string newName2 = newName; + if (newName2.empty()) { + // Create name using the scale factor. + int scaleInt = static_cast<int>(scaleFactor * 10000); + int scale1 = scaleInt / 10000; + int scale2 = scaleInt % 10000; + + std::ostringstream os; + os << origMaterialName << scale1 << "_" << std::setw(4) << std::setfill('0') << scale2; + newName2 = os.str(); + } + + newMaterial = getMaterialInternal(origMaterialName, density, newName2); + } + + return newMaterial; +} + +void +NeutrinoMaterialManager::addMaterial(GeoMaterial* material) { + std::string name(material->getName()); + if (m_store.find(name) != m_store.end()) { + msg(MSG::WARNING) << "Ignoring attempt to redefine an existing material: " << name << endmsg; + // Delete the material if it is not already ref counted. + material->ref(); + material->unref(); + //std::cout << m_store[name] << std::endl; + } else { + material->lock(); + material->ref(); + m_store[name] = material; + + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Created new material: " << name << ", " << material->getDensity() / + (Gaudi::Units::g / Gaudi::Units::cm3) << " g/cm3" << endmsg; + } +} + +bool +NeutrinoMaterialManager::compareDensity(double d1, double d2) const { + return(std::abs(d1 / d2 - 1.) < 1e-5); +} + +void +NeutrinoMaterialManager::addWeightTable(IRDBRecordset_ptr weightTable, const std::string& space) { + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Reading in weight table: " << weightTable->nodeName() << endmsg; + // If not using geometryDBSvc revert to old version + if (!db()) { + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "GeometryDBSvc not available. Using old version." << endmsg; + addWeightTableOld(weightTable, space); + return; + } + for (unsigned int i = 0; i < db()->getTableSize(weightTable); i++) { + std::string materialName = db()->getString(weightTable, "MATERIAL", i); + if (!space.empty()) { + materialName = space + "::" + materialName; + } + std::string materialBase; + if (db()->testField(weightTable, "BASEMATERIAL", i)) { + materialBase = db()->getString(weightTable, "BASEMATERIAL", i); + } + double weight = db()->getDouble(weightTable, "WEIGHT", i) * GeoModelKernelUnits::gram; + //std::cout << materialName << " " << materialBase << " " << weight/CLHEP::g << std::endl; + + bool linearWeightFlag = false; + if (m_extraFunctionality && db()->testField(weightTable, "LINWEIGHTFLAG", i)) { + linearWeightFlag = db()->getInt(weightTable, "LINWEIGHTFLAG", i); + } + + if (m_weightMap.find(materialName) != m_weightMap.end()) { + msg(MSG::WARNING) << "Material: " << materialName << " already exists in weight table" << endmsg; + } else { + msg(MSG::DEBUG) << "Adding " << materialName + << " weight " << weight + << " linearWeightFlag " << linearWeightFlag + << " raw weight " << db()->getDouble(weightTable, "WEIGHT", i) + << " m_extraFunctionality " << m_extraFunctionality + << " to weight table" << endmsg; + m_weightMap[materialName] = MaterialByWeight(materialBase, weight, linearWeightFlag); + } + } +} + +void +NeutrinoMaterialManager::addWeightMaterial(std::string materialName, std::string materialBase, double weight, + int linearWeightFlag) { + // Weight in gr + weight = weight * GeoModelKernelUnits::gram; + + if (m_weightMap.find(materialName) != m_weightMap.end()) { + msg(MSG::WARNING) << "Material: " << materialName << " already exists in weight table" << endmsg; + } else { + msg(MSG::DEBUG) << "Adding " << materialName + << " weight " << weight + << " linearWeightFlag " << linearWeightFlag + << " to weight table" << endmsg; + m_weightMap[materialName] = MaterialByWeight(materialBase, weight, linearWeightFlag); + } +} + +void +NeutrinoMaterialManager::addWeightTableOld(IRDBRecordset_ptr weightTable, const std::string& space) { + for (unsigned int i = 0; i < weightTable->size(); i++) { + const IRDBRecord* record = (*weightTable)[i]; + std::string materialName = record->getString("MATERIAL"); + if (!space.empty()) { + materialName = space + "::" + materialName; + } + std::string materialBase; + if (!record->isFieldNull("BASEMATERIAL")) { + materialBase = record->getString("BASEMATERIAL"); + } + double weight = record->getDouble("WEIGHT") * GeoModelKernelUnits::gram; + //std::cout << materialName << " " << materialBase << " " << weight/CLHEP::g << std::endl; + + bool linearWeightFlag = false; + if (m_extraFunctionality) { + linearWeightFlag = record->getInt("LINWEIGHTFLAG"); + } + + if (m_weightMap.find(materialName) != m_weightMap.end()) { + msg(MSG::WARNING) << "Material: " << materialName << " already exists in weight table" << endmsg; + } else { + m_weightMap[materialName] = MaterialByWeight(materialBase, weight, linearWeightFlag); + } + } +} + +void +NeutrinoMaterialManager::addCompositionTable(IRDBRecordset_ptr compositionTable, const std::string& space) { + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Reading in composition table: " << compositionTable->nodeName() << endmsg; + + if (!db()) { + msg(MSG::ERROR) << "GeometryDBSvc not available. Unable to read in composition table." << endmsg; + } + for (unsigned int i = 0; i < db()->getTableSize(compositionTable); i++) { + std::string materialName = db()->getString(compositionTable, "MATERIAL", i); + if (!space.empty()) { + materialName = space + "::" + materialName; + } + + std::string componentName = db()->getString(compositionTable, "COMPONENT", i); + int count = db()->getInt(compositionTable, "COUNT", i); + double factor = db()->getDouble(compositionTable, "FACTOR", i); + double actualLength = db()->getDouble(compositionTable, "ACTUALLENGTH", i); + + m_matCompositionMap.insert(std::pair<std::string, MaterialComponent>(materialName, + MaterialComponent(componentName, + count * factor, + actualLength))); + } +} + +void +NeutrinoMaterialManager::addScalingTable(IRDBRecordset_ptr scalingTable) { + if (!scalingTable) return; + + if (db()->getTableSize(scalingTable) == 0) return; + + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Reading in extra material scaling table: " << scalingTable->nodeName() << + endmsg; + if (!db()) { + msg(MSG::ERROR) << "GeometryDBSvc not available. Unable to read in scaling table." << endmsg; + } + for (unsigned int i = 0; i < db()->getTableSize(scalingTable); i++) { + std::string materialName = db()->getString(scalingTable, "MATERIAL", i); + double scalingFactor = db()->getDouble(scalingTable, "FACTOR", i); + + if (msgLvl(MSG::DEBUG)) { + if (scalingFactor >= 0 || scalingFactor == 1) { + msg(MSG::DEBUG) << "Material " << materialName << " will be scaled by: " << scalingFactor << endmsg; + } else { + // -ve or scalefactor = 1 means will not be scaled. + msg(MSG::DEBUG) << "Material " << materialName << " will be NOT be scaled." << endmsg; + } + } + if (m_scalingMap.find(materialName) != m_scalingMap.end()) { + msg(MSG::WARNING) << "Overriding material: " << materialName << " which already exists in scaling table" << + endmsg; + } + m_scalingMap[materialName] = scalingFactor; + } +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialForVolume(const std::string& materialName, double volume, const std::string& newName) { + // Make sure we have a valid volume size. + if (volume <= 0) { + msg(MSG::ERROR) << "Invalid volume : " << volume << endmsg; + return 0; + } + + // Find if material is in the weight table. + // If so we use the information to create a material with the + // density calculated from the volume and weight. If a base material + // is specified in the weight table, then a new material is made + // which is the same as the base material but with the new + // density. If no base material is specified then there should be a + // material already existing with that name. If the existing material already has the + // correct density it is used, otherwise a new material is created + // with the string "Modified" added to the material name. + + MaterialWeightMap::const_iterator iter; + if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) { + const std::string& materialBase = iter->second.name; + double weight = iter->second.weight; + double density = weight / volume; + if (iter->second.linearWeightFlag) { + msg(MSG::ERROR) << "Material defined by linear weight cannot be created with getMaterialForVolume method: " << + materialName << endmsg; + } + + if (msgLvl(MSG::VERBOSE)) { + msg(MSG::VERBOSE) + << + "Found material in weight table - name, base, weight(g), volume(cm3), density(g/cm3): " + << materialName << ", " + << materialBase << ", " + << weight / GeoModelKernelUnits::gram << ", " + << volume / Gaudi::Units::cm3 << ", " + << density / (Gaudi::Units::g / Gaudi::Units::cm3) << endmsg; + } + + if (materialBase.empty()) { + return getMaterial(materialName, density, newName); + } else { + if (newName.empty()) { + return getMaterial(materialBase, density, materialName); + } else { + return getMaterial(materialBase, density, newName); + } + } + } else { + // If not in the weight table we just return the material. + // This is not an error. + if (msgLvl(MSG::VERBOSE)) + msg(MSG::VERBOSE) + << "Material not in weight table, using standard material: " + << materialName + << ", volume(cm3) = " << volume / Gaudi::Units::cm3 + << endmsg; + return getMaterial(materialName); + } +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialForVolumeLength(const std::string& materialName, double volume, double length, + const std::string& newName) { + // In the case there is no material composition table (MaterialCompositionMap) and no linear weights are used this + // will + // behave the same way as getMaterialForVolume. + // If the material is in the MaterialCompositionMap it will build a material using the components + // from that table. If any components are defined as a linear weight the length is used to calculate the + // weight (ie linear weight * length). + + + std::string name; + if (newName.empty()) { + name = materialName; + } else { + name = newName; + } + + // Make sure we have a valid volume size. + if (volume <= 0 || length <= 0) { + msg(MSG::ERROR) << "Invalid volume or length : " << volume << ", " << length << endmsg; + return 0; + } + + // First look in the predefinded collections + std::pair<MaterialCompositionMap::const_iterator, MaterialCompositionMap::const_iterator> iterRange; + iterRange = m_matCompositionMap.equal_range(materialName); + if (iterRange.first != m_matCompositionMap.end()) { + if (msgLvl(MSG::VERBOSE)) { + msg(MSG::VERBOSE) + << "Found material in material composition table:" << materialName << endmsg; + } + + std::vector<double> factors; + std::vector<std::string> components; + for (MaterialCompositionMap::const_iterator iter = iterRange.first; iter != iterRange.second; iter++) { + double factorTmp = iter->second.factor; + if (iter->second.actualLength > 0) factorTmp *= iter->second.actualLength / length; + factors.push_back(factorTmp); + components.push_back(iter->second.name); + } + return getMaterialForVolumeLength(name, components, factors, volume, length); + } + + // Next look in weight table + MaterialWeightMap::const_iterator iter; + if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) { + const std::string& materialBase = iter->second.name; + double weight = iter->second.weight; + double density = weight / volume; + if (iter->second.linearWeightFlag) weight *= length; + + if (materialBase.empty()) { + return getMaterial(materialName, density, newName); + } else { + return getMaterial(materialBase, density, name); + } + } else { + // Otherwise we just return the material. + // This is not an error. + if (msgLvl(MSG::VERBOSE)) + msg(MSG::VERBOSE) + << "Material not in weight table, using standard material: " + << materialName + << ", volume(cm3) = " << volume / Gaudi::Units::cm3 + << endmsg; + return getMaterial(materialName); + } +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialForVolumeLength(const std::string& name, + const std::string& materialComponent, + double factor, + double volume, + double length) { + std::vector<std::string> tmpMaterialComponents(1, materialComponent); + std::vector<double> tmpFactors(1, factor); + return getMaterialForVolumeLength(name, tmpMaterialComponents, tmpFactors, volume, length); +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialForVolumeLength(const std::string& name, + const std::vector<std::string>& materialComponents, + const std::vector<double> factors, + double volume, + double length) { + // Make sure we have a valid volume size. + if (volume <= 0 || length <= 0) { + msg(MSG::ERROR) << "Invalid volume or length : " << volume << ", " << length << endmsg; + return 0; + } + + if (!factors.empty() && factors.size() < materialComponents.size()) { + msg(MSG::WARNING) << "getMaterialForVolumeLength: factor vector size too small. Setting remaining factors to 1." << + endmsg; + } + + std::vector<std::string> baseMaterials; + std::vector<double> fracWeight; + baseMaterials.reserve(materialComponents.size()); + fracWeight.reserve(materialComponents.size()); + + double totWeight = 0; + for (unsigned int iComp = 0; iComp < materialComponents.size(); ++iComp) { + const std::string& materialName = materialComponents[iComp]; + + // First search in MaterialWeightMap + MaterialWeightMap::const_iterator iter; + if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) { + const std::string& materialBase = iter->second.name; + double weight = iter->second.weight; + + if (iComp < factors.size()) { + weight *= factors[iComp]; + } + msg(MSG::DEBUG) << "Material " << materialName + << " found in weight table, weight " << iter->second.weight / GeoModelKernelUnits::gram + << " factor " << factors[iComp] + << " w*fac*len " << weight * length / GeoModelKernelUnits::gram + << " basMat " << materialBase + << " linear? " << iter->second.linearWeightFlag << endmsg; + + if (iter->second.linearWeightFlag) weight *= length; + if (materialBase.empty()) { + // If no base material then name should refer to an already defined material + baseMaterials.push_back(materialName); + } else { + baseMaterials.push_back(materialBase); + } + fracWeight.push_back(weight); // Will be normalized later. + totWeight += weight; + } else { + // If not in the weight table we look for a regular material. + // I don't think this would normally be intentional so we give a warning message. + /* + if (msgLvl(MSG::WARNING)) + msg(MSG::WARNING) + << "Component material not in weight table, using standard material: " + << materialName << " with weight= " + << factors.at(iComp) * length + << endmsg; + const GeoMaterial * material = getMaterialInternal(materialName); + */ + + // In this case the factor should correspond to the linear weight + double weight = factors.at(iComp) * length * GeoModelKernelUnits::gram; + + // If material not found, will get error message when attempting to make the material. So carry on here. + baseMaterials.push_back(materialName); + fracWeight.push_back(weight); + totWeight += weight; + } + } + + if (msgLvl(MSG::VERBOSE)) { + msg(MSG::VERBOSE) << "Creating material from multiple components: " << name << endmsg; + for (unsigned int i = 0; i < materialComponents.size(); ++i) { + msg(MSG::VERBOSE) << " Component " << i << ": Name = " << baseMaterials[i] + << " Weight(g) = " << fracWeight[i] / Gaudi::Units::g << endmsg; + } + } + + for (unsigned int i = 0; i < fracWeight.size(); ++i) { + fracWeight[i] /= totWeight; + } + double density = totWeight / volume; + + return getMaterial(name, baseMaterials, fracWeight, density); +} + +// Add materials assuming they simply occupy the same volume. +/* + const GeoMaterial* + NeutrinoMaterialManager::getMaterial(const std::vector<const GeoMaterial *> & materialComponents, + const std::string & newName) + { + const GeoMaterial * newMaterial = 0; + std::vector<double> fracWeight; + fracWeight.reserve(materialComponents.size()); + + for (unsigned int i = 0; i < materialComponents.size(); i++) { + const GeoMaterial * origMaterial = materialComponents[i]; + double weight = origMaterial->getDensity(); + fracWeight.push_back(weight); + totWeight += weight; + } + for (unsigned int i = 0; i < fracWeight.size(); ++i) { + fracWeight[i] /= totWeight; + } + return getMaterial(materialComponents, fracWeight, totWeight, newName); + } + + const GeoMaterial* + NeutrinoMaterialManager::getMaterial(const std::vector<std::string> & materialComponents, + const std::string & newName) + { + const GeoMaterial * newMaterial = 0; + + // First see if we already have the modified material + const GeoMaterial* material = getAdditionalMaterial(newName); + + for (unsigned int i = 0; i < materialComponents.size(); i++) { + const GeoMaterial * origMaterial = getMaterial(materialComponents[i]); + components.push_back(origMaterial); + } + return getMaterial(components, newName); + } + */ + + +const GeoMaterial* +NeutrinoMaterialManager::getMaterial(const std::string& name, + const std::vector<std::string>& materialComponents, + const std::vector<double>& fracWeight, + double density) { + return extraScaledMaterial(name, getMaterialInternal(name, materialComponents, fracWeight, density)); +} + +const GeoMaterial* +NeutrinoMaterialManager::getMaterialInternal(const std::string& name, + const std::vector<std::string>& materialComponents, + const std::vector<double>& fracWeight, + double density) { + const GeoMaterial* newMaterial = 0; + + // First see if we already have the material + const GeoMaterial* material = getAdditionalMaterial(name); + + if (material) { + if (!compareDensity(material->getDensity(), density)) { + msg(MSG::WARNING) << "Density is not consistent for material " << name << endmsg; + } + newMaterial = material; + } else { + GeoMaterial* newMaterialTmp = new GeoMaterial(name, density); + for (unsigned int i = 0; i < materialComponents.size(); i++) { + const GeoMaterial* origMaterial = getMaterialInternal(materialComponents[i]); + if (origMaterial) { + newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), fracWeight[i]); + } else { + msg(MSG::ERROR) << "Material component missing " << materialComponents[i] << endmsg; + } + } + addMaterial(newMaterialTmp); + newMaterial = newMaterialTmp; + } + return newMaterial; +} + +const IGeometryDBSvc* +NeutrinoMaterialManager::db() { + if (m_athenaComps) return m_athenaComps->geomDB(); + + return 0; +} + +void +NeutrinoMaterialManager::addTextFileMaterials() { + const std::string materialTable = "ExtraMaterials"; + const std::string componentsTable = "ExtraMatComponents"; + + // Look for tables ExtraMaterials and ExtraMatComponents. + // These are text file only tables where extra materials are desired or + // one wants to override some database ones. + if (!db() || !db()->testField("", "TableSize:" + materialTable) || !db()->getTableSize(materialTable) + || !db()->testField("", "TableSize:" + componentsTable) || !db()->getTableSize(componentsTable)) return; + + + msg(MSG::INFO) << "Extra materials being read in from text file." << endmsg; + + typedef std::map<std::string, MaterialDef> MatMap; + MatMap materials; + + // read in material table + for (unsigned int iMat = 0; iMat < db()->getTableSize(materialTable); iMat++) { + std::string materialName = db()->getString(materialTable, "NAME", iMat); + double density = db()->getDouble(materialTable, "DENSITY", iMat) * Gaudi::Units::g / Gaudi::Units::cm3; + materials[materialName] = MaterialDef(materialName, density); + } + + // read in material component table + for (unsigned int iComp = 0; iComp < db()->getTableSize(componentsTable); iComp++) { + std::string materialName = db()->getString(componentsTable, "NAME", iComp); + std::string compName = db()->getString(componentsTable, "COMPNAME", iComp); + double fracWeight = db()->getDouble(componentsTable, "FRACTION", iComp); + MatMap::iterator iter = materials.find(materialName); + if (iter != materials.end()) { + iter->second.addComponent(compName, fracWeight); + } else { + msg(MSG::ERROR) << "Attemp to add material component, " << compName << ", to non-existing material: " << + materialName << endmsg; + } + } + + //Now create the materials + int matCount = 0; + int matCountLast = -1; + bool someUndefined = true; + // While there are still undefined materials keep creating materials. + // Check also that the matCount had change to avoid endless loop due to cyclicly + // defined materials. + while (someUndefined && matCount != matCountLast) { + matCountLast = matCount; + someUndefined = false; + for (MatMap::iterator iter = materials.begin(); iter != materials.end(); ++iter) { + MaterialDef& tmpMat = iter->second; + if (!tmpMat.isCreated()) { + // Check if any components are materials in this table and if they are defined. + // If not flag that there are undefined materials and go to next material + bool compsDefined = true; + for (unsigned int iComp = 0; iComp < tmpMat.numComponents(); ++iComp) { + std::string compName = tmpMat.compName(iComp); + MatMap::iterator iter2 = materials.find(compName); + if (iter2 != materials.end()) { + if (!iter2->second.isCreated()) { + compsDefined = false; + break; + } + } + } + if (compsDefined) { + createMaterial(tmpMat); + tmpMat.setCreated(); + matCount++; + } else { + someUndefined = true; + } + } + } + } + + + if (someUndefined) { + msg(MSG::ERROR) << "Not all materials could be defined due to cyclic definitions" << endmsg; + } +} + +void +NeutrinoMaterialManager::createMaterial(const MaterialDef& material) { + if (material.numComponents() == 0) { + msg(MSG::ERROR) << "Material has no components: " << material.name() << endmsg; + return; + } + + // If total of fractions is greater than 1.1 then assume material is define by ratio of atoms. + double totWeight = material.totalFraction(); + bool byAtomicRatio = false; + if (totWeight > 1.1) { + byAtomicRatio = true; + for (unsigned int i = 0; i < material.numComponents(); i++) { + if (material.compName(i).find("::") != std::string::npos) { + // If component name has "::" in it then its not an element. + msg(MSG::ERROR) << "Material, " << material.name() + << + ", is assumed to be defined by atomic ratio (due to total fraction > 1) but component is not an element: " + << material.compName(i) << endmsg; + return; + } + const GeoElement* element = getElement(material.compName(i)); + if (!element) { + msg(MSG::ERROR) << "Error making material " << material.name() << ". Element not found: " << + material.compName(i) << endmsg; + return; + } + totWeight += material.fraction(i) * element->getA(); + } + } else { + // Check if total fraction is close to 1. + if (std::abs(totWeight - 1) > 0.01) { + msg(MSG::WARNING) << "Total fractional weight does not sum to 1. Will renormalize. Total = " << totWeight << + endmsg; + } + } + // Now build the material + GeoMaterial* newMaterial = new GeoMaterial(material.name(), material.density()); + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Creating material: " << material.name() + << " with density: " << material.density() / (Gaudi::Units::g / Gaudi::Units::cm3) << + endmsg; + for (unsigned int i = 0; i < material.numComponents(); i++) { + double fracWeight = material.fraction(i) / totWeight; + if (material.compName(i).find("::") == std::string::npos) { + const GeoElement* element = getElement(material.compName(i)); + if (!element) { + msg(MSG::ERROR) << "Error making material " << material.name() << ". Element not found: " << + material.compName(i) << endmsg; + // delete the partially created material + newMaterial->ref(); + newMaterial->unref(); + return; + } + if (byAtomicRatio) { + fracWeight = material.fraction(i) * element->getA() / totWeight; + } + newMaterial->add(const_cast<GeoElement*>(element), fracWeight); + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << " Component: " << material.compName(i) << " " << fracWeight << endmsg; + } else { + const GeoMaterial* materialTmp = getMaterialInternal(material.compName(i)); + if (!materialTmp) { + msg(MSG::ERROR) << "Error making material " << material.name() << ". Component not found: " << + material.compName(i) << endmsg; + // delete the partially created material + newMaterial->ref(); + newMaterial->unref(); + return; + } + if (byAtomicRatio) { + // Should not happen as already checked that all components were elements. + msg(MSG::ERROR) << "Unexpected Error" << endmsg; + } + newMaterial->add(const_cast<GeoMaterial*>(materialTmp), fracWeight); + if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << " Component: " << material.compName(i) << " " << fracWeight << endmsg; + } + } + newMaterial->lock(); + addMaterial(newMaterial); +} + +NeutrinoMaterialManager::MaterialDef::MaterialDef() + : m_density(0), + m_created(false) +{} + +NeutrinoMaterialManager::MaterialDef::MaterialDef(const std::string& name, double density) + : m_name(name), + m_density(density), + m_created(false) +{} + +void +NeutrinoMaterialManager::MaterialDef::addComponent(const std::string& compName, double fraction) { + m_components.push_back(compName); + m_fractions.push_back(fraction); +} + +double +NeutrinoMaterialManager::MaterialDef::totalFraction() const { + double sum = 0; + + for (unsigned int i = 0; i < m_fractions.size(); i++) { + sum += m_fractions[i]; + } + return sum; +} + +// We need the original name as the GeoMaterial from the standard +// material manager has its namespace dropped. We have two versions +// of extraScaledMaterial. One where two names are provided. In this +// version if newName is not empty that is used, otherwise +// materialName is used. The other just has one name and that is the +// one that is used. + +const GeoMaterial* +NeutrinoMaterialManager::extraScaledMaterial(const std::string& materialName, + const std::string& newName, + const GeoMaterial* origMaterial) { + if (newName.empty()) { + return extraScaledMaterial(materialName, origMaterial); + } else { + return extraScaledMaterial(newName, origMaterial); + } +} + +const GeoMaterial* +NeutrinoMaterialManager::extraScaledMaterial(const std::string& materialName, const GeoMaterial* origMaterial) { + if (!origMaterial) throw std::runtime_error(std::string("Invalid material: ") + materialName); + + double scaleFactor = getExtraScaleFactor(materialName); + // -1 (or any -ve number) indicates material is not scaled. And if the scale factor + // is 1 then there is no need to create a new material. + if (scaleFactor < 0 || scaleFactor == 1 || materialName.find("Ether") != std::string::npos) return origMaterial; + + if (scaleFactor == 0) return getMaterialInternal("std::Vacuum"); + + std::string newName = materialName + "_ExtraScaling"; + + // Check if it is already made. + const GeoMaterial* newMaterial = getAdditionalMaterial(newName); + + // Already made so we return it. + if (newMaterial) return newMaterial; + + // Otherwise we need to make it. + double density = origMaterial->getDensity() * scaleFactor; + + // create new material + GeoMaterial* newMaterialTmp = new GeoMaterial(newName, density); + newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), 1.); + addMaterial(newMaterialTmp); + newMaterial = newMaterialTmp; + + return newMaterial; +} + +double +NeutrinoMaterialManager::getExtraScaleFactor(const std::string& materialName) { + // If name is found in map we return the corresponding scale factor. + // The special name "ALL" indicates all materials are scaled. + // Individual materials can be excluded from scaling by giving either + // a -ve scaling factor or just specifying a scaling factor of 1. + // A scaling factor of 0 means the material will be replaced by vacuum. + + ExtraScaleFactorMap::const_iterator iter = m_scalingMap.find(materialName); + if (iter != m_scalingMap.end()) { + return iter->second; + } else { + // Check for special names + // ALL means everything scaled. Do not scale air or vacuum (unless explicity requested) + iter = m_scalingMap.find("ALL"); + if (iter != m_scalingMap.end() && materialName != "std::Air" && materialName != "std::Vacuum") { + return iter->second; + } + } + + // If not found then return -1 to indicate material is not to be scaled. + return -1; +} diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TopLevelPlacements.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TopLevelPlacements.cxx new file mode 100644 index 00000000..2d269f24 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TopLevelPlacements.cxx @@ -0,0 +1,145 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "NeutrinoGeoModelUtils/TopLevelPlacements.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "RDBAccessSvc/IRDBRecordset.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include <iostream> + +GeoTrf::Transform3D TopLevelPlacements::s_identityTransform = GeoTrf::Transform3D::Identity(); + +TopLevelPlacements::TopLevelPlacements(IRDBRecordset_ptr topLevelTable) + : m_noTopLevelTable(true) { + fillPlacements(topLevelTable); +} + +TopLevelPlacements::~TopLevelPlacements() { + std::map<std::string, Part*>::const_iterator iter; + for (iter = m_parts.begin(); iter != m_parts.end(); ++iter) delete iter->second; +} + +const GeoTrf::Transform3D& +TopLevelPlacements::transform(const std::string& partName) const { + Part* part = getPart(partName); + + if (part) return part->transform; + + return s_identityTransform; +} + +bool +TopLevelPlacements::present(const std::string& partName) const { + // If no table present assume everything is present. + if (m_noTopLevelTable) return true; + + return(getPart(partName) != 0); +} + +void +TopLevelPlacements::fillPlacements(IRDBRecordset_ptr topLevelTable) { + if (topLevelTable.get() == 0) { + m_noTopLevelTable = true; + return; + } + m_noTopLevelTable = false; + int numParts = topLevelTable->size(); + for (int i = 0; i < numParts; i++) { + const IRDBRecord* record = (*topLevelTable)[i]; + std::string label = record->getString("LABEL"); + + Part* part = new Part; + part->label = label; + part->transform = partTransform(record); + + m_parts[label] = part; + } +} + +GeoTrf::Transform3D +TopLevelPlacements::partTransform(const IRDBRecord* record) const { + double posX = record->getDouble("POSX") * Gaudi::Units::mm; + double posY = record->getDouble("POSY") * Gaudi::Units::mm; + double posZ = record->getDouble("POSZ") * Gaudi::Units::mm; + double rotX = record->getDouble("ROTX") * Gaudi::Units::degree; + double rotY = record->getDouble("ROTY") * Gaudi::Units::degree; + double rotZ = record->getDouble("ROTZ") * Gaudi::Units::degree; + int rotOrder = record->getInt("ROTORDER"); + + // Translation part + GeoTrf::Translate3D transform(posX, posY, posZ); + + // If rotation is zero return translation + if (rotX == 0 && rotY == 0 && rotZ == 0) { + return transform; + } + + // For rotation have to look at order. + // 123 means rotate around X, then Y , then Z. + // 312 means rotate around Z, then X , then Y. + // etc + + int ixyz1 = rotOrder / 100 - 1; + int ixyz2 = (rotOrder % 100) / 10 - 1; + int ixyz3 = (rotOrder % 10) - 1; + + if (ixyz1 < 0 || ixyz1 > 2 || + ixyz2 < 0 || ixyz2 > 2 || + ixyz3 < 0 || ixyz3 > 2) { + std::cout << "ERROR: Invalid rotation order:" << rotOrder << std::endl; + ixyz1 = 0; + ixyz2 = 1; + ixyz3 = 2; + } + + GeoTrf::Transform3D rotation(GeoTrf::Translate3D::Identity()); + std::vector<int> order { ixyz1 , ixyz2, ixyz3 }; + for (int ixyz : order) + { + switch (ixyz) + { + case 0: + if (rotX != 0) rotation = GeoTrf::RotateX3D{rotX} * rotation; + break; + case 1: + if (rotY != 0) rotation = GeoTrf::RotateY3D{rotY} * rotation; + break; + case 2: + if (rotZ != 0) rotation = GeoTrf::RotateZ3D{rotZ} * rotation; + break; + } + } + + // This segfaults at runtime when deleting the pointers, + // I think because the base class of Transform3D + // does not have a virtual destructor + // + // List of the three transforms + // GeoTrf::Transform3D* xformList[] = { nullptr, nullptr, nullptr }; + // if (rotX != 0) xformList[0] = new GeoTrf::RotateX3D(rotX); + // if (rotY != 0) xformList[1] = new GeoTrf::RotateY3D(rotY); + // if (rotZ != 0) xformList[2] = new GeoTrf::RotateZ3D(rotZ); + + // GeoTrf::Transform3D rotation(GeoTrf::Transform3D::Identity()); + // if (xformList[ixyz1] != nullptr) rotation = *(xformList[ixyz1]) * rotation; + // if (xformList[ixyz2] != nullptr) rotation = *(xformList[ixyz2]) * rotation; + // if (xformList[ixyz3] != nullptr) rotation = *(xformList[ixyz3]) * rotation; + // if (xformList[0] != nullptr) + // delete xformList[0]; + // if (xformList[1] != nullptr) + // delete xformList[1]; + // if (xformList[2] != nullptr) + // delete xformList[2]; + + return transform * rotation; +} + +TopLevelPlacements::Part* +TopLevelPlacements::getPart(const std::string& partName) const { + std::map<std::string, Part*>::const_iterator iter; + iter = m_parts.find(partName); + if (iter == m_parts.end()) return 0; + + return iter->second; +} diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TubeVolData.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TubeVolData.cxx new file mode 100644 index 00000000..4059dc22 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoGeoModelUtils/src/TubeVolData.cxx @@ -0,0 +1,101 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#include "NeutrinoGeoModelUtils/TubeVolData.h" +#include "RDBAccessSvc/IRDBRecord.h" +#include "GaudiKernel/SystemOfUnits.h" + +#include <cmath> +#include <string> +#include <iostream> + +namespace NeutrinoDD { + std::string + TubeVolData::material() const { + return m_record->getString("MATERIAL"); + } + + double + TubeVolData::maxRadius() const { + return std::max(m_rmax1, m_rmax2); + } + + TubeVolData::TubeVolData(const IRDBRecord* record) + : m_record(record), + m_bothZ(false), + m_nRepeat(0), + m_radialDiv(0), + m_phiStart(0.), + m_phiDelta(0.), + m_phiStep(0.), + m_rmin1(0.), + m_rmin2(0.), + m_rmax1(0.), + m_rmax2(0.), + m_length(0.), + m_zMid(0.) { + // add an 2*epsilon gap between phi sectors. + const double phiepsilon = 0.001 * Gaudi::Units::degree; + + bool fullPhiSector = false; + + + // Get the parameters which we need to do some preprocessing with. + // The rest are obtained directly from RDB. + + if (m_record) { + m_phiStart = m_record->getDouble("PHISTART") * Gaudi::Units::degree; + m_phiDelta = m_record->getDouble("PHIDELTA") * Gaudi::Units::degree; + m_phiStep = m_record->getDouble("PHISTEP") * Gaudi::Units::degree; + m_nRepeat = m_record->getInt("NREPEAT"); + m_rmin1 = m_record->getDouble("RMIN") * Gaudi::Units::mm; + m_rmax1 = m_record->getDouble("RMAX") * Gaudi::Units::mm; + m_rmin2 = m_record->getDouble("RMIN2") * Gaudi::Units::mm; + m_rmax2 = m_record->getDouble("RMAX2") * Gaudi::Units::mm; + m_radialDiv = 0; + if (!m_record->isFieldNull("RADIAL")) { + m_radialDiv = m_record->getInt("RADIAL"); + } + m_bothZ = 0; + if (!m_record->isFieldNull("ZSYMM")) { + m_bothZ = m_record->getInt("ZSYMM"); + } + + double zmin = m_record->getDouble("ZMIN") * Gaudi::Units::mm; + double zmax = m_record->getDouble("ZMAX") * Gaudi::Units::mm; + m_length = std::abs(zmax - zmin); + m_zMid = 0.5 * (zmin + zmax); + + if (m_phiDelta == 0 || m_phiDelta >= 359.9 * Gaudi::Units::degree) { + m_phiDelta = 360 * Gaudi::Units::degree; + fullPhiSector = true; + } else { + m_phiDelta -= 2 * phiepsilon; + m_phiStart += phiepsilon; + } + + // Force nRepeat to be >= 1; + if (m_nRepeat <= 0) m_nRepeat = 1; + // if PHISTEP==0 then set it to be equi-distant steps filling up phi. + if (m_phiStep == 0) { + m_phiStep = 360 * Gaudi::Units::degree / m_nRepeat; + } + + if (m_rmin2 <= 0) m_rmin2 = m_rmin1; + if (m_rmax2 <= 0) m_rmax2 = m_rmax1; + + if (m_radialDiv > 0) { + m_shape = TubeVolData::RADIAL; + } else if (m_rmin1 == m_rmin2 && m_rmax1 == m_rmax2) { + if (fullPhiSector) { + m_shape = TubeVolData::TUBE; + } else { + m_shape = TubeVolData::TUBS; + } + } else { + m_shape = TubeVolData::CONS; + } + } else std::cout << "Unexpected ERROR in ExtraMaterial!" << std::endl; + } +} // end namespace diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoIdDictFiles/data/IdDictNeutrino.xml b/Neutrino/NeutrinoDetDescr/NeutrinoIdDictFiles/data/IdDictNeutrino.xml index 9faa43cf..45ef3be3 100644 --- a/Neutrino/NeutrinoDetDescr/NeutrinoIdDictFiles/data/IdDictNeutrino.xml +++ b/Neutrino/NeutrinoDetDescr/NeutrinoIdDictFiles/data/IdDictNeutrino.xml @@ -4,15 +4,16 @@ <label name="Emulsion" value="1" /> </field> - <field name="side"> + <field name="film"> <label name="Upstream" value="0" /> <label name="Downstream" value="1" /> </field> <region> <range field="part" value="Emulsion" /> - <range field="film" minvalue="0" maxvalue="999" /> - <range field="side" values="Upstream Downstream" /> + <range field="module" minvalue="0" maxvalue="34" /> + <range field="base" minvalue="0" maxvalue="21" /> + <range field="film" values="Upstream Downstream" /> </region> </IdDictionary> \ No newline at end of file diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/CMakeLists.txt b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/CMakeLists.txt new file mode 100644 index 00000000..804522b7 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/CMakeLists.txt @@ -0,0 +1,24 @@ +################################################################################ +# Package: NeutrinoIdentifier +################################################################################ + +# Declare the package name: +atlas_subdir( NeutrinoIdentifier ) + +# External dependencies: +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_library( NeutrinoIdentifier + src/EmulsionID.cxx + PUBLIC_HEADERS NeutrinoIdentifier + PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES AthenaKernel FaserDetDescr IdDict Identifier + PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} IdDictParser GaudiKernel ) + +atlas_add_dictionary( NeutrinoIdentifierDict + NeutrinoIdentifier/NeutrinoIdentifierDict.h + NeutrinoIdentifier/selection.xml + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} FaserDetDescr IdDict Identifier IdDictParser GaudiKernel NeutrinoIdentifier ) + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/EmulsionID.h b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/EmulsionID.h new file mode 100644 index 00000000..9e396dd7 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/EmulsionID.h @@ -0,0 +1,573 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOIDENTIFIER_EMULSIONID_H +#define NEUTRINOIDENTIFIER_EMULSIONID_H +/** + * @file EmulsionID.h + * + * @brief This is an Identifier helper class for the Emulsion + * subdetector. This class is a factory for creating compact + * Identifier objects and IdentifierHash or hash ids. And it also + * allows decoding of these ids. + * + */ + +//<<<<<< INCLUDES >>>>>> + +#include "FaserDetDescr/FaserDetectorID.h" +#include "Identifier/Identifier.h" +#include "Identifier/IdentifierHash.h" +#include "Identifier/Range.h" +#include "Identifier/IdHelper.h" +#include "IdDict/IdDictFieldImplementation.h" +#include "AthenaKernel/CLASS_DEF.h" + +#include <string> +#include <assert.h> +#include <algorithm> + +//<<<<<< PUBLIC DEFINES >>>>>> +//<<<<<< PUBLIC CONSTANTS >>>>>> +//<<<<<< PUBLIC TYPES >>>>>> + +class IdDictDictionary; + +//<<<<<< PUBLIC VARIABLES >>>>>> +//<<<<<< PUBLIC FUNCTIONS >>>>>> +//<<<<<< CLASS DECLARATIONS >>>>>> + +/** + ** @class EmulsionID + ** + ** @brief This is an Identifier helper class for the Emulsion + ** subdetector. This class is a factory for creating compact + ** Identifier objects and IdentifierHash or hash ids. And it also + ** allows decoding of these ids. + ** + ** Definition and the range of values for the levels of the + ** identifier are: + ** + ** @verbatim + ** element range meaning + ** ------- ----- ------- + ** + ** module 0 to 34 35 modules + ** base 0 to 21 22 bases per module + ** film side 0 to 1 2 films per base + ** + ** @endverbatim + ** + */ +class EmulsionID : public FaserDetectorID +{ +public: + + /// @name public typedefs + //@{ + typedef Identifier::size_type size_type; + typedef std::vector<Identifier>::const_iterator const_id_iterator; + typedef MultiRange::const_identifier_factory const_expanded_id_iterator; + //@} + + /// @name strutors + //@{ + EmulsionID(void); + virtual ~EmulsionID(void) = default; + //@} + + /// @name Creators for base ids and side ids + //@{ + /// For a single module + Identifier module_id ( int module ) const; + Identifier module_id ( int module, + bool checks) const; + + /// For a module from a base id + Identifier module_id ( const Identifier& base_id ) const; + + /// For a single base + Identifier base_id ( int module, + int base ) const; + Identifier base_id ( int module, + int base, + bool checks) const; + + /// For a single base from a film id + Identifier base_id ( const Identifier& film_id ) const; + + /// From hash - optimized + Identifier base_id ( IdentifierHash base_hash ) const; + Identifier film_id ( IdentifierHash film_hash ) const; + + /// For an individual film + Identifier film_id ( int module, + int base, + int film ) const; + + Identifier film_id ( int module, + int base, + int film, + bool check ) const; + + Identifier film_id ( const Identifier& base_id, + int film ) const; + + //@} + + + /// @name Hash table maximum sizes + //@{ + size_type base_hash_max (void) const; + size_type film_hash_max (void) const; + //@} + + /// @name Access to all ids + //@{ + /// Iterators over full set of ids. Base iterator is sorted + const_id_iterator base_begin (void) const; + const_id_iterator base_end (void) const; + /// For film ids, only expanded id iterators are available. Use + /// following "film_id" method to obtain a compact identifier + const_expanded_id_iterator film_begin (void) const; + const_expanded_id_iterator film_end (void) const; + //@} + + + /// @name Optimized accessors - ASSUMES id IS a veto id, i.e. NOT other + //@{ + /// base hash from id - optimized + IdentifierHash base_hash (Identifier base_id) const; + + IdentifierHash film_hash (Identifier film_id) const; + + /// Values of different levels (failure returns 0) + int module (const Identifier& id) const; + int base (const Identifier& id) const; + int film (const Identifier& id) const; + + /// Max/Min values for each field (-999 == failure) + int module_max (const Identifier& id) const; + int base_max (const Identifier& id) const; + int film_max (const Identifier& id) const; + //@} + + /// @name navigation + //@{ + /// Previous base in z + int get_prev_in_z(const IdentifierHash& id, IdentifierHash& prev) const; + /// Next base in z + int get_next_in_z(const IdentifierHash& id, IdentifierHash& next) const; + // /// Previous wafer hash in phi (return == 0 for neighbor found) + // int get_prev_in_phi (const IdentifierHash& id, IdentifierHash& prev) const; + // /// Next wafer hash in phi (return == 0 for neighbor found) + // int get_next_in_phi (const IdentifierHash& id, IdentifierHash& next) const; + // /// Previous wafer hash in eta (return == 0 for neighbor found) + // int get_prev_in_eta (const IdentifierHash& id, IdentifierHash& prev) const; + // /// Next wafer hash in eta (return == 0 for neighbor found) + // int get_next_in_eta (const IdentifierHash& id, IdentifierHash& next) const; + /// Film hash on other side + int get_other_side (const IdentifierHash& id, IdentifierHash& other) const; + + // // To check for when phi wrap around may be needed, use + // bool is_phi_module_max(const Identifier& id) const; + // /// For the barrel + // bool is_eta_module_min(const Identifier& id) const; + // /// For the barrel + // bool is_eta_module_max(const Identifier& id) const; + //@} + + /// @name contexts to distinguish base id from film id + //@{ + IdContext base_context (void) const; + IdContext film_context (void) const; + //@} + + /// @name methods from abstract interface - slower than opt version + //@{ + /// Create compact id from hash id (return == 0 for OK) + virtual int get_id (const IdentifierHash& hash_id, + Identifier& id, + const IdContext* context = 0) const; + + /// Create hash id from compact id (return == 0 for OK) + virtual int get_hash (const Identifier& id, + IdentifierHash& hash_id, + const IdContext* context = 0) const; + //@} + + /// Return the lowest bit position used in the channel id + int base_bit (void) const; + + /// Calculate a channel offset between the two identifiers. + Identifier::diff_type calc_offset(const Identifier& base, + const Identifier& target) const; + + /// Create an identifier with a given base and channel offset + Identifier film_id_offset(const Identifier& base, + Identifier::diff_type offset) const; + + /// @name interaction with id dictionary + //@{ + /// Create film Identifier from expanded id, which is returned by the + /// id_iterators + Identifier film_id (const ExpandedIdentifier& film_id) const; + + /// Create expanded id from compact id (return == 0 for OK) + void get_expanded_id (const Identifier& id, + ExpandedIdentifier& exp_id, + const IdContext* context = 0) const; + + /// Initialization from the identifier dictionary + virtual int initialize_from_dictionary(const IdDictMgr& dict_mgr); + + /// Tests of packing + void test_base_packing (void) const; + //@} + +private: + + enum {NOT_VALID_HASH = 64000}; + + typedef std::vector<Identifier> id_vec; + typedef id_vec::const_iterator id_vec_it; + typedef std::vector<unsigned short> hash_vec; + typedef hash_vec::const_iterator hash_vec_it; + + void base_id_checks ( int module, + int base ) const; + + void film_id_checks ( int module, + int base, + int film ) const; + + + int initLevelsFromDict(void); + + int init_hashes(void); + + int init_neighbors(void); + + // Temporary method for adapting an identifier for the MultiRange + // check - MR is missing the InnerDetector level + // Identifier idForCheck (const Identifier& id) const; + + size_type m_emulsion_region_index; + size_type m_NEUTRINO_INDEX; + size_type m_EMULSION_INDEX; + size_type m_MODULE_INDEX; + size_type m_BASE_INDEX; + size_type m_FILM_INDEX; + + const IdDictDictionary* m_dict; + MultiRange m_full_base_range; + MultiRange m_full_film_range; + size_type m_base_hash_max; + size_type m_film_hash_max; + // Range::field m_barrel_field; + id_vec m_base_vec; + id_vec m_film_vec; + hash_vec m_prev_z_base_vec; + hash_vec m_next_z_base_vec; + // hash_vec m_prev_phi_wafer_vec; + // hash_vec m_next_phi_wafer_vec; + // hash_vec m_prev_eta_wafer_vec; + // hash_vec m_next_eta_wafer_vec; + // bool m_hasRows ; + + IdDictFieldImplementation m_neutrino_impl ; + IdDictFieldImplementation m_emulsion_impl ; + IdDictFieldImplementation m_module_impl ; + IdDictFieldImplementation m_base_impl ; + IdDictFieldImplementation m_film_impl ; +}; + + +//<<<<<< INLINE PUBLIC FUNCTIONS >>>>>> + +///////////////////////////////////////////////////////////////////////////// +//<<<<<< INLINE MEMBER FUNCTIONS >>>>>> +///////////////////////////////////////////////////////////////////////////// + +//using the macros below we can assign an identifier (and a version) +//This is required and checked at compile time when you try to record/retrieve +CLASS_DEF(EmulsionID, 89852815, 1) + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::module_id ( int module, + bool checks) const +{ + + // Build identifier + Identifier result((Identifier::value_type)0); + + // Pack fields independently + m_neutrino_impl.pack (neutrino_field_value(), result); + m_emulsion_impl.pack (emulsion_field_value(), result); + m_module_impl.pack (module, result); + // Do checks + if(checks) + { + base_id_checks ( module, 0 ); + } + + return result; +} + +inline Identifier +EmulsionID::module_id ( int module ) const +{ + return module_id (module, do_checks()); +} + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::module_id ( const Identifier& base_id ) const +{ + Identifier result(base_id); + // Reset the base and film fields + m_base_impl.reset(result); + m_film_impl.reset(result); + return (result); +} + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::base_id ( int module, + int base, + bool checks) const +{ + // Build identifier + Identifier result((Identifier::value_type)0); + + // Pack fields independently + m_neutrino_impl.pack (neutrino_field_value(), result); + m_emulsion_impl.pack (emulsion_field_value(), result); + m_module_impl.pack (module, result); + m_base_impl.pack (base, result); + + // Do checks + if(checks) + { + base_id_checks ( module, base ); + } + return result; +} + +inline Identifier +EmulsionID::base_id ( int module, + int base ) const +{ + return base_id (module, base, do_checks()); +} + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::base_id ( const Identifier& film_id ) const +{ + Identifier result(film_id); + // reset the film field + m_film_impl.reset(result); + return (result); +} + +//---------------------------------------------------------------------------- +inline Identifier EmulsionID::base_id ( IdentifierHash base_hash ) const +{ + return (m_base_vec[base_hash]); +} + +inline Identifier EmulsionID::film_id ( IdentifierHash film_hash ) const +{ + return (m_film_vec[film_hash]); +} + +//---------------------------------------------------------------------------- +inline IdentifierHash EmulsionID::base_hash (Identifier base_id) const +{ + // MsgStream log(m_msgSvc, "EmulsionID"); + // log << MSG::VERBOSE << "m_plate_vec size: " << m_plate_vec.size() << endmsg; + // log << MSG::VERBOSE << "input id = " << plate_id << endmsg; + // for (size_t i = 0; i < m_plate_vec.size(); i++) + // { + // log << MSG::VERBOSE << "Hash = " << i << " : ID = " << m_plate_vec[i] << endmsg; + // } + id_vec_it it = std::lower_bound(m_base_vec.begin(), + m_base_vec.end(), + base_id); + // Require that base_id matches the one in vector + if (it != m_base_vec.end() && base_id == (*it)) { + return (it - m_base_vec.begin()); + } + IdentifierHash result; + return (result); // return hash in invalid state +} + +inline IdentifierHash EmulsionID::film_hash (Identifier film_id) const +{ + // MsgStream log(m_msgSvc, "EmulsionID"); + // log << MSG::VERBOSE << "m_plate_vec size: " << m_plate_vec.size() << endmsg; + // log << MSG::VERBOSE << "input id = " << plate_id << endmsg; + // for (size_t i = 0; i < m_plate_vec.size(); i++) + // { + // log << MSG::VERBOSE << "Hash = " << i << " : ID = " << m_plate_vec[i] << endmsg; + // } + id_vec_it it = std::lower_bound(m_film_vec.begin(), + m_film_vec.end(), + film_id); + // Require that base_id matches the one in vector + if (it != m_film_vec.end() && film_id == (*it)) { + return (it - m_film_vec.begin()); + } + IdentifierHash result; + return (result); // return hash in invalid state +} + + + + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::film_id ( int module, + int base, + int film, + bool checks) const +{ + // Build identifier + Identifier result((Identifier::value_type)0); + + // Pack fields independently + m_neutrino_impl.pack (neutrino_field_value(), result); + m_emulsion_impl.pack (emulsion_field_value(), result); + m_module_impl.pack (module, result); + m_base_impl.pack (base, result); + m_film_impl.pack (film, result); + + // Do checks + if(checks) { + film_id_checks ( module, base, film ); + } + return result; +} + +inline Identifier +EmulsionID::film_id ( int module, + int base, + int film ) const +{ + return film_id (module, base, film, do_checks()); +} + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::film_id (const ExpandedIdentifier& id) const +{ + // Build identifier + Identifier result((Identifier::value_type)0); + + // Pack fields independently + m_neutrino_impl.pack (neutrino_field_value(), result); + m_emulsion_impl.pack (emulsion_field_value(), result); + m_module_impl.pack (id[m_MODULE_INDEX], result); + m_base_impl.pack (id[m_BASE_INDEX], result); + m_film_impl.pack (id[m_FILM_INDEX], result); + + // Do checks + if(m_do_checks) + { + film_id_checks ( id[m_MODULE_INDEX], + id[m_BASE_INDEX], + id[m_FILM_INDEX]); + } + return result; +} + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::film_id ( const Identifier& base_id, int film ) const +{ + // Build identifier + Identifier result(base_id); + + // Reset strip and then add in value + m_film_impl.reset (result); + m_film_impl.pack (film, result); + + if(m_do_checks) + { + film_id_checks ( module(result), + base(result), + film ); + } + return result; +} + +//---------------------------------------------------------------------------- +inline Identifier::diff_type +EmulsionID::calc_offset(const Identifier& base, const Identifier& target) const +{ + Identifier::diff_type tval = static_cast<Identifier::diff_type>(target.get_compact() >> base_bit()); + Identifier::diff_type bval = static_cast<Identifier::diff_type>(base.get_compact() >> base_bit()); + return (tval - bval); +} + +//---------------------------------------------------------------------------- +inline Identifier +EmulsionID::film_id_offset(const Identifier& base, + Identifier::diff_type offset) const +{ + Identifier::value_type bval = base.get_compact() >> base_bit(); + return Identifier((bval + offset) << base_bit()); +} + +//---------------------------------------------------------------------------- +inline int +EmulsionID::base_bit ( void ) const +{ + int base = static_cast<int>(m_film_impl.shift()); // lowest field base + return (base > 32) ? 32 : base; + // max base is 32 so we can still read old strip id's and differences + // from non-SLHC releases. +} + +//---------------------------------------------------------------------------- +inline IdContext +EmulsionID::base_context (void) const +{ + ExpandedIdentifier id; + return (IdContext(id, 0, m_BASE_INDEX)); +} + +//---------------------------------------------------------------------------- +inline IdContext +EmulsionID::film_context (void) const +{ + ExpandedIdentifier id; + return (IdContext(id, 0, m_FILM_INDEX)); +} + +//---------------------------------------------------------------------------- +inline int +EmulsionID::module (const Identifier& id) const +{ + return (m_module_impl.unpack(id)); +} + +//---------------------------------------------------------------------------- +inline int +EmulsionID::base (const Identifier& id) const +{ + return (m_base_impl.unpack(id)); +} + +//---------------------------------------------------------------------------- +inline int +EmulsionID::film (const Identifier& id) const +{ + return (m_film_impl.unpack(id)); +} + + +#endif // NEUTRINOIDENTIFIER_EMULSIONID_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/NeutrinoIdentifierDict.h b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/NeutrinoIdentifierDict.h new file mode 100644 index 00000000..bd6cea52 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/NeutrinoIdentifierDict.h @@ -0,0 +1,17 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @file NeutrinoIdentifierDict.h + * + * @brief This file includes the class for dictionary definitions + * + * $Id: $ + */ +#ifndef NEUTRINOIDENTIFIER_NEUTRINOIDENTIFIERDICT_H +#define NEUTRINOIDENTIFIER_NEUTRINOIDENTIFIERDICT_H + +#include "NeutrinoIdentifier/EmulsionID.h" + +#endif // NEUTRINOIDENTIFIER_NEUTRINOIDENTIFIERDICT_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/selection.xml b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/selection.xml new file mode 100644 index 00000000..74a348f5 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/NeutrinoIdentifier/selection.xml @@ -0,0 +1,3 @@ +<lcgdict> + <class name="EmulsionID" /> +</lcgdict> diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/src/EmulsionID.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/src/EmulsionID.cxx new file mode 100644 index 00000000..39639714 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoIdentifier/src/EmulsionID.cxx @@ -0,0 +1,1068 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/*************************************************************************** + Neutrino identifier package + ------------------------------------------- +***************************************************************************/ + +//<<<<<< INCLUDES >>>>>> +#include "GaudiKernel/MsgStream.h" + +#include "NeutrinoIdentifier/EmulsionID.h" +#include "Identifier/IdentifierHash.h" +#include "IdDict/IdDictDefs.h" +#include <set> +#include <algorithm> +#include <iostream> + +//<<<<<< PRIVATE DEFINES >>>>>> +//<<<<<< PRIVATE CONSTANTS >>>>>> +//<<<<<< PRIVATE TYPES >>>>>> +//<<<<<< PRIVATE VARIABLE DEFINITIONS >>>>>> +//<<<<<< PUBLIC VARIABLE DEFINITIONS >>>>>> +//<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>> +//<<<<<< PRIVATE FUNCTION DEFINITIONS >>>>>> +//<<<<<< PUBLIC FUNCTION DEFINITIONS >>>>>> +//<<<<<< MEMBER FUNCTION DEFINITIONS >>>>>> + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + + +EmulsionID::EmulsionID(void) + : + m_emulsion_region_index(0), + m_NEUTRINO_INDEX(0), + m_EMULSION_INDEX(1), + m_MODULE_INDEX(2), + m_BASE_INDEX(3), + m_FILM_INDEX(4), + m_dict(0), + m_base_hash_max(0), + m_film_hash_max(0) +{ +} + +void +EmulsionID::base_id_checks ( int module, + int base ) const +{ + + // Check that id is within allowed range + + // Fill expanded id + ExpandedIdentifier id; + id << neutrino_field_value() << emulsion_field_value() + << module << base; + + if (!m_full_base_range.match(id)) { // module range check is sufficient + MsgStream log(m_msgSvc, "EmulsionID"); + log << MSG::ERROR << " EmulsionID::base_id result is NOT ok. ID, range " + << (std::string)id << " " << (std::string)m_full_base_range << endmsg; + } +} + +void +EmulsionID::film_id_checks ( int module, + int base, + int film) const +{ + + // Check that id is within allowed range + + // Fill expanded id + ExpandedIdentifier id; + id << neutrino_field_value() << emulsion_field_value() + << module << base << film; + + if (!m_full_film_range.match(id)) { + MsgStream log(m_msgSvc, "EmulsionID"); + log << MSG::ERROR << " EmulsionID::film_id result is NOT ok. ID, range " + << (std::string)id << " " << (std::string)m_full_film_range << std::endl; + } +} + +int +EmulsionID::module_max(const Identifier& id) const +{ + // get max from dictionary + ExpandedIdentifier expId; + IdContext base_context1 = base_context(); + get_expanded_id(id, expId, &base_context1); + for (unsigned int i = 0; i < m_full_base_range.size(); ++i) { + const Range& range = m_full_base_range[i]; + if (range.match(expId)) { + const Range::field& module_field = range[m_MODULE_INDEX]; + if (module_field.has_maximum()) { + return (module_field.get_maximum()); + } + } + } + return (-999); // default +} + +int +EmulsionID::film_max (const Identifier& id) const +{ + ExpandedIdentifier expId; + IdContext module_context(expId, 0, m_MODULE_INDEX); + get_expanded_id(id, expId, &module_context); + int result = -999; + for (unsigned int i = 0; i < m_full_film_range.size(); ++i) { + const Range& range = m_full_film_range[i]; + if (range.match(expId)) { + const Range::field& film_field = range[m_FILM_INDEX]; + if (film_field.has_maximum()) { + int film = film_field.get_maximum(); + if (result < film) result = film; + } + } + } + return (result); +} + +int +EmulsionID::base_max(const Identifier& id) const +{ + // get max from dictionary + ExpandedIdentifier expId; + IdContext base_context1 = base_context(); + get_expanded_id(id, expId, &base_context1); + for (unsigned int i = 0; i < m_full_base_range.size(); ++i) { + const Range& range = m_full_base_range[i]; + if (range.match(expId)) { + const Range::field& base_field = range[m_BASE_INDEX]; + if (base_field.has_maximum()) { + return (base_field.get_maximum()); + } + } + } + return -1; +} + +int +EmulsionID::initialize_from_dictionary(const IdDictMgr& dict_mgr) +{ + MsgStream log(m_msgSvc, "EmulsionID"); + log << MSG::INFO << "Initialize from dictionary" << endmsg; + + // Check whether this helper should be reinitialized + if (!reinitialize(dict_mgr)) { + log << MSG::INFO << "Request to reinitialize not satisfied - tags have not changed" << endmsg; + return (0); + } + else { + if (m_msgSvc) { + log << MSG::DEBUG << "(Re)initialize" << endmsg; + } + else { + std::cout << " DEBUG (Re)initialize" << std::endl; + } + } + + // init base object + if(FaserDetectorID::initialize_from_dictionary(dict_mgr)) return (1); + + // Register version of InnerDetector dictionary + if (register_dict_tag(dict_mgr, "Neutrino")) return(1); + + m_dict = dict_mgr.find_dictionary ("Neutrino"); + if(!m_dict) { + log << MSG::ERROR << " EmulsionID::initialize_from_dict - cannot access Neutrino dictionary " << endmsg; + return 1; + } + + // Initialize the field indices + if(initLevelsFromDict()) return (1); + + // + // Build multirange for the valid set of identifiers + // + + + // Find value for the field Neutrino + const IdDictDictionary* faserDict = dict_mgr.find_dictionary ("FASER"); + int neutrinoField = -1; + if (faserDict->get_label_value("subdet", "Neutrino", neutrinoField)) { + log << MSG::ERROR << "Could not get value for label 'Neutrino' of field 'subdet' in dictionary " + << faserDict->m_name + << endmsg; + return (1); + } + + // Find value for the field Emulsion + int emulsionField = -1; + if (m_dict->get_label_value("part", "Emulsion", emulsionField)) { + log << MSG::ERROR << "Could not get value for label 'Emulsion' of field 'part' in dictionary " + << m_dict->m_name + << endmsg; + return (1); + } + if (m_msgSvc) { + log << MSG::DEBUG << " EmulsionID::initialize_from_dict " + << "Found field values: Emulsion " + << emulsionField + << std::endl; + } + else { + std::cout << " DEBUG EmulsionID::initialize_from_dict " + << "Found field values: Emulsion " + << emulsionField + << std::endl; + } + + // Set up id for region and range prefix + ExpandedIdentifier region_id; + region_id.add(neutrinoField); + region_id.add(emulsionField); + Range prefix; + m_full_base_range = m_dict->build_multirange(region_id, prefix, "base"); + m_full_film_range = m_dict->build_multirange(region_id, prefix); + + // Setup the hash tables + if(init_hashes()) return (1); + + // Setup hash tables for finding neighbors + if(init_neighbors()) return (1); + + if (m_msgSvc) { + log << MSG::INFO << " EmulsionID::initialize_from_dict " << endmsg; + log << MSG::DEBUG + << "Base range -> " << (std::string)m_full_base_range + << endmsg; + log << MSG::DEBUG + << "Film range -> " << (std::string)m_full_film_range + << endmsg; + } + else { + std::cout << " INFO EmulsionID::initialize_from_dict " << std::endl; + std::cout << " DEBUG Base range -> " << (std::string)m_full_base_range + << std::endl; + std::cout << " DEBUG Film range -> " << (std::string)m_full_film_range + << std::endl; + } + + return 0; +} + +int +EmulsionID::init_hashes(void) +{ + + // + // create a vector(s) to retrieve the hashes for compact ids. For + // the moment, we implement a hash for bases but NOT for films + // + MsgStream log(m_msgSvc, "EmulsionID"); + // base hash + m_base_hash_max = m_full_base_range.cardinality(); + m_base_vec.resize(m_base_hash_max); + unsigned int nids = 0; + std::set<Identifier> ids; + for (unsigned int i = 0; i < m_full_base_range.size(); ++i) { + const Range& range = m_full_base_range[i]; + Range::const_identifier_factory first = range.factory_begin(); + Range::const_identifier_factory last = range.factory_end(); + for (; first != last; ++first) { + const ExpandedIdentifier& exp_id = (*first); + Identifier id = base_id(exp_id[m_MODULE_INDEX], + exp_id[m_BASE_INDEX]); + if(!(ids.insert(id)).second) { + log << MSG::ERROR << " EmulsionID::init_hashes " + << " Error: duplicated id for base id. nid " << nids + << " compact id " << id.getString() + << " id " << (std::string)exp_id << endmsg; + return (1); + } + nids++; + } + } + if(ids.size() != m_base_hash_max) { + log << MSG::ERROR << " EmulsionID::init_hashes " + << " Error: set size NOT EQUAL to hash max. size " << ids.size() + << " hash max " << m_base_hash_max + << endmsg; + return (1); + } + + nids = 0; + std::set<Identifier>::const_iterator first = ids.begin(); + std::set<Identifier>::const_iterator last = ids.end(); + for (; first != last && nids < m_base_vec.size(); ++first) { + m_base_vec[nids] = (*first); + nids++; + } + + // film hash - we do not keep a vec for the films + m_film_hash_max = m_full_film_range.cardinality(); + m_film_vec.resize(m_film_hash_max); + nids = 0; + ids.clear(); + for (unsigned int i = 0; i < m_full_film_range.size(); ++i) { + const Range& range = m_full_film_range[i]; + Range::const_identifier_factory first = range.factory_begin(); + Range::const_identifier_factory last = range.factory_end(); + for (; first != last; ++first) { + const ExpandedIdentifier& exp_id = (*first); + Identifier id = film_id(exp_id[m_MODULE_INDEX], + exp_id[m_BASE_INDEX], + exp_id[m_FILM_INDEX]); + if(!(ids.insert(id)).second) { + log << MSG::ERROR << " EmulsionID::init_hashes " + << " Error: duplicated id for film id. nid " << nids + << " compact id " << id.getString() + << " id " << (std::string)exp_id << endmsg; + return (1); + } + nids++; + } + } + if(ids.size() != m_film_hash_max) { + log << MSG::ERROR << " EmulsionID::init_hashes " + << " Error: set size for films NOT EQUAL to hash max. size " << ids.size() + << " hash max " << m_base_hash_max + << endmsg; + return (1); + } + + nids = 0; + first = ids.begin(); + last = ids.end(); + for (; first != last && nids < m_film_vec.size(); ++first) { + m_film_vec[nids] = (*first); + nids++; + } + + + return (0); +} + + int + EmulsionID::get_prev_in_z(const IdentifierHash& id, IdentifierHash& prev) const + { + unsigned short index = id; + if (index < m_prev_z_base_vec.size()) + { + if (m_prev_z_base_vec[index] == NOT_VALID_HASH) return (1); + prev = m_prev_z_base_vec[index]; + return (0); + } + return (1); + } + + int + EmulsionID::get_next_in_z(const IdentifierHash& id, IdentifierHash& next) const + { + unsigned short index = id; + if (index < m_next_z_base_vec.size()) + { + if (m_next_z_base_vec[index] == NOT_VALID_HASH) return (1); + next = m_next_z_base_vec[index]; + return (0); + } + return (1); + } + +// int +// EmulsionID::get_prev_in_phi(const IdentifierHash& id, IdentifierHash& prev) const +// { +// unsigned short index = id; +// if (index < m_prev_phi_wafer_vec.size()) { +// if (m_prev_phi_wafer_vec[index] == NOT_VALID_HASH) return (1); +// prev = m_prev_phi_wafer_vec[index]; +// return (0); +// } +// return (1); +// } + +// int +// EmulsionID::get_next_in_phi(const IdentifierHash& id, IdentifierHash& next) const +// { +// unsigned short index = id; +// if (index < m_next_phi_wafer_vec.size()) { +// if (m_next_phi_wafer_vec[index] == NOT_VALID_HASH) return (1); +// next = m_next_phi_wafer_vec[index]; +// return (0); +// } +// return (1); +// } + +// int +// EmulsionID::get_prev_in_eta(const IdentifierHash& id, IdentifierHash& prev) const +// { +// unsigned short index = id; +// if (index < m_prev_eta_wafer_vec.size()) { +// if (m_prev_eta_wafer_vec[index] == NOT_VALID_HASH) return (1); +// prev = m_prev_eta_wafer_vec[index]; +// return (0); +// } +// return (1); +// } + +// int +// EmulsionID::get_next_in_eta(const IdentifierHash& id, IdentifierHash& next) const +// { +// unsigned short index = id; +// if (index < m_next_eta_wafer_vec.size()) { +// if (m_next_eta_wafer_vec[index] == NOT_VALID_HASH) return (1); +// next = m_next_eta_wafer_vec[index]; +// return (0); +// } +// return (1); +// } + +int +EmulsionID::get_other_side (const IdentifierHash& hashId, IdentifierHash& other) const +{ + if (m_dict) { + // get max from dictionary + Identifier id; + IdContext film_context1 = film_context(); + if(!get_id(hashId, id, &film_context1)) { + other = film(id) ? hashId - 1 : hashId + 1; + return (0); + } + } + return (1); +} + +int +EmulsionID::init_neighbors(void) +{ + // + // create a vector(s) to retrieve the hashes for compact ids for + // base neighbors. + // + MsgStream log(m_msgSvc, "EmulsionID"); + + m_prev_z_base_vec.resize(m_base_hash_max, NOT_VALID_HASH); + m_next_z_base_vec.resize(m_base_hash_max, NOT_VALID_HASH); + for (unsigned int i = 0; i < m_full_base_range.size(); i++) + { + const Range& range = m_full_base_range[i]; + const Range::field& module_field = range[m_MODULE_INDEX]; + const Range::field& base_field = range[m_BASE_INDEX]; + Range::const_identifier_factory first = range.factory_begin(); + Range::const_identifier_factory last = range.factory_end(); + for (; first != last; ++first) + { + const ExpandedIdentifier& exp_id = (*first); + ExpandedIdentifier::element_type previous_base; + ExpandedIdentifier::element_type next_base; + ExpandedIdentifier::element_type previous_module; + ExpandedIdentifier::element_type next_module; + bool pbase = base_field.get_previous(exp_id[m_BASE_INDEX], previous_base); + bool nbase = base_field.get_next (exp_id[m_BASE_INDEX], next_base); + bool pmodule = module_field.get_previous(exp_id[m_MODULE_INDEX], previous_module); + bool nmodule = module_field.get_next (exp_id[m_MODULE_INDEX], next_module); + + IdContext pcontext = base_context(); + + IdentifierHash hash_id; + Identifier originalId = base_id(exp_id[m_MODULE_INDEX], + exp_id[m_BASE_INDEX]); + + if (get_hash(originalId, hash_id, &pcontext)) + { + log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get hash, exp/compact " + << show_to_string(originalId, &pcontext) + << " " << (std::string)m_full_base_range << endmsg; + return (1); + } + + // index for the subsequent arrays + unsigned short index = hash_id; + assert (hash_id < m_prev_z_base_vec.size()); + assert (hash_id < m_next_z_base_vec.size()); + + if (pbase) { + // Get previous base hash id + ExpandedIdentifier expId = exp_id; + expId[m_BASE_INDEX] = previous_base; + Identifier id = base_id(expId[m_MODULE_INDEX], + expId[m_BASE_INDEX]); + + if (get_hash(id, hash_id, &pcontext)) { + log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get previous base hash, exp/compact " << id.getString() << " " + << endmsg; + return (1); + } + m_prev_z_base_vec[index] = hash_id; + } + else if (pmodule) + { + ExpandedIdentifier expId = exp_id; + expId[m_MODULE_INDEX] = previous_module; + ExpandedIdentifier moduleId; + moduleId.add(expId[m_NEUTRINO_INDEX]); + moduleId.add(expId[m_EMULSION_INDEX]); + moduleId.add(previous_module); + Range prefix; + MultiRange moduleBaseRange = m_dict->build_multirange(moduleId, prefix, "base"); + const Range::field& upstream_base_field = range[m_BASE_INDEX]; + if (upstream_base_field.has_maximum()) + { + expId[m_BASE_INDEX] = upstream_base_field.get_maximum(); + Identifier id = base_id(expId[m_MODULE_INDEX], + expId[m_BASE_INDEX]); + if (get_hash(id, hash_id, &pcontext)) { + log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get last base hash from previous module, exp/compact " << id.getString() << " " + << endmsg; + return (1); + } + m_prev_z_base_vec[index] = hash_id; + } + else + { + log << MSG::ERROR << "EmulsionID::init_neighbors - unable to get base_max for previous module, exp/compact " << originalId.getString() << " " + << endmsg; + return (1); + } + } + + if (nbase) { + // Get next base hash id + ExpandedIdentifier expId = exp_id; + expId[m_BASE_INDEX] = next_base; + Identifier id = base_id(expId[m_MODULE_INDEX], + expId[m_BASE_INDEX]); + + if (get_hash(id, hash_id, &pcontext)) { + log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get next base hash, exp/compact " << id.getString() << " " + << endmsg; + return (1); + } + m_next_z_base_vec[index] = hash_id; + } + else if (nmodule) + { + ExpandedIdentifier expId = exp_id; + expId[m_MODULE_INDEX] = next_module; + ExpandedIdentifier moduleId; + moduleId.add(expId[m_NEUTRINO_INDEX]); + moduleId.add(expId[m_EMULSION_INDEX]); + moduleId.add(next_module); + Range prefix; + MultiRange moduleBaseRange = m_dict->build_multirange(moduleId, prefix, "base"); + const Range::field& downstream_base_field = range[m_BASE_INDEX]; + if (downstream_base_field.has_minimum()) + { + expId[m_BASE_INDEX] = downstream_base_field.get_minimum(); + Identifier id = base_id(expId[m_MODULE_INDEX], + expId[m_BASE_INDEX]); + if (get_hash(id, hash_id, &pcontext)) { + log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get previous base hash from next module, exp/compact " << id.getString() << " " + << endmsg; + return (1); + } + m_next_z_base_vec[index] = hash_id; + } + else + { + log << MSG::ERROR << "EmulsionID::init_neighbors - unable to get base_min for next module, exp/compact " << originalId.getString() << " " + << endmsg; + return (1); + } + } + + } + } + + // m_prev_phi_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH); + // m_next_phi_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH); + // m_prev_eta_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH); + // m_next_eta_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH); + + // for (unsigned int i = 0; i < m_full_wafer_range.size(); ++i) { + // const Range& range = m_full_wafer_range[i]; + // const Range::field& phi_field = range[m_PHI_MODULE_INDEX]; + // const Range::field& eta_field = range[m_ETA_MODULE_INDEX]; + // Range::const_identifier_factory first = range.factory_begin(); + // Range::const_identifier_factory last = range.factory_end(); + // for (; first != last; ++first) { + // const ExpandedIdentifier& exp_id = (*first); + // ExpandedIdentifier::element_type previous_phi; + // ExpandedIdentifier::element_type next_phi; + // ExpandedIdentifier::element_type previous_eta; + // ExpandedIdentifier::element_type next_eta; + // bool pphi = phi_field.get_previous(exp_id[m_PHI_MODULE_INDEX], previous_phi); + // bool nphi = phi_field.get_next (exp_id[m_PHI_MODULE_INDEX], next_phi); + // bool peta = eta_field.get_previous(exp_id[m_ETA_MODULE_INDEX], previous_eta); + // bool neta = eta_field.get_next (exp_id[m_ETA_MODULE_INDEX], next_eta); + + // IdContext wcontext = wafer_context(); + + // // First get primary hash id + // IdentifierHash hash_id; + // Identifier id = wafer_id(exp_id[m_BARREL_EC_INDEX], + // exp_id[m_LAYER_DISK_INDEX], + // exp_id[m_PHI_MODULE_INDEX], + // exp_id[m_ETA_MODULE_INDEX], + // exp_id[m_SIDE_INDEX]); + // if (get_hash(id, hash_id, &wcontext)) { + // log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get hash, exp/compact " + // << show_to_string(id, &wcontext) + // << " " << (std::string)m_full_wafer_range << endmsg; + // return (1); + // } + + // // index for the subsequent arrays + // unsigned short index = hash_id; + // assert (hash_id < m_prev_phi_wafer_vec.size()); + // assert (hash_id < m_next_phi_wafer_vec.size()); + // assert (hash_id < m_prev_eta_wafer_vec.size()); + // assert (hash_id < m_next_eta_wafer_vec.size()); + + // if (pphi) { + // // Get previous phi hash id + // ExpandedIdentifier expId = exp_id; + // expId[m_PHI_MODULE_INDEX] = previous_phi; + // Identifier id = wafer_id(expId[m_BARREL_EC_INDEX], + // expId[m_LAYER_DISK_INDEX], + // expId[m_PHI_MODULE_INDEX], + // expId[m_ETA_MODULE_INDEX], + // expId[m_SIDE_INDEX]); + // if (get_hash(id, hash_id, &wcontext)) { + // log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get previous phi hash, exp/compact " << id.getString() << " " + // << endmsg; + // return (1); + // } + // m_prev_phi_wafer_vec[index] = hash_id; + // } + + // if (nphi) { + // // Get next phi hash id + // ExpandedIdentifier expId = exp_id; + // expId[m_PHI_MODULE_INDEX] = next_phi; + // Identifier id = wafer_id(expId[m_BARREL_EC_INDEX], + // expId[m_LAYER_DISK_INDEX], + // expId[m_PHI_MODULE_INDEX], + // expId[m_ETA_MODULE_INDEX], + // expId[m_SIDE_INDEX]); + // if (get_hash(id, hash_id, &wcontext)) { + // log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get next phi hash, exp/compact " << id.getString() << + // " " << MSG::hex << id.getString() << MSG::dec << endmsg; + // return (1); + // } + // m_next_phi_wafer_vec[index] = hash_id; + // } + + // if (peta) { + // // Get previous eta hash id + // ExpandedIdentifier expId = exp_id; + // expId[m_ETA_MODULE_INDEX] = previous_eta; + // Identifier id = wafer_id(expId[m_BARREL_EC_INDEX], + // expId[m_LAYER_DISK_INDEX], + // expId[m_PHI_MODULE_INDEX], + // expId[m_ETA_MODULE_INDEX], + // expId[m_SIDE_INDEX]); + // if (get_hash(id, hash_id, &wcontext)) { + // log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get previous eta hash, exp/compact " << id.getString() + // << " " << std::endl; + // return (1); + // } + // m_prev_eta_wafer_vec[index] = hash_id; + // } + + // if (neta) { + // // Get next eta hash id + // ExpandedIdentifier expId = exp_id; + // expId[m_ETA_MODULE_INDEX] = next_eta; + // Identifier id = wafer_id(expId[m_BARREL_EC_INDEX], + // expId[m_LAYER_DISK_INDEX], + // expId[m_PHI_MODULE_INDEX], + // expId[m_ETA_MODULE_INDEX], + // expId[m_SIDE_INDEX]); + // if (get_hash(id, hash_id, &wcontext)) { + // log << MSG::ERROR << " EmulsionID::init_neighbors - unable to get next eta hash, exp/compact " << id.getString() + // << " " << endmsg; + // return (1); + // } + // m_next_eta_wafer_vec[index] = hash_id; + // } + + +// std::cout << " EmulsionID::init_neighbors " +// << " phi, previous, next " << id[m_PHI_MODULE_INDEX] +// << " " << pphi +// << " " << previous_phi +// << " " << nphi +// << " " << next_phi +// << " eta, previous, next " << id[m_ETA_MODULE_INDEX] +// << " " << peta +// << " " << previous_eta +// << " " << neta +// << " " << next_eta +// << " id " << (std::string)(*first) +// << std::endl; + // } + // } + return (0); +} + + + +int +EmulsionID::initLevelsFromDict() +{ + + + MsgStream log(m_msgSvc, "EmulsionID"); + if(!m_dict) { + log << MSG::ERROR << " EmulsionID::initLevelsFromDict - dictionary NOT initialized " << endmsg; + return (1); + } + + // Find out which identifier field corresponds to each level. Use + // names to find each field/leve. + + m_NEUTRINO_INDEX = 999; + m_EMULSION_INDEX = 999; + m_MODULE_INDEX = 999; + m_BASE_INDEX = 999; + m_FILM_INDEX = 999; + + // Save index to a Emulsion region for unpacking + ExpandedIdentifier id; + id << neutrino_field_value() << emulsion_field_value(); + if (m_dict->find_region(id, m_emulsion_region_index)) { + log << MSG::ERROR << "EmulsionID::initLevelsFromDict - unable to find emulsion region index: id, reg " + << (std::string)id << " " << m_emulsion_region_index + << endmsg; + return (1); + } + + // Find a Emulsion region + IdDictField* field = m_dict->find_field("subdet"); + if (field) { + m_NEUTRINO_INDEX = field->m_index; + } + else { + log << MSG::ERROR << "EmulsionID::initLevelsFromDict - unable to find 'subdet' field " << endmsg; + return (1); + } + field = m_dict->find_field("part"); + if (field) { + m_EMULSION_INDEX = field->m_index; + } + else { + log << MSG::ERROR << "EmulsionID::initLevelsFromDict - unable to find 'part' field " << endmsg; + return (1); + } + field = m_dict->find_field("module"); + if (field) { + m_MODULE_INDEX = field->m_index; + } + else { + log << MSG::ERROR << "EmulsionID::initLevelsFromDict - unable to find 'module' field " << endmsg; + return (1); + } + field = m_dict->find_field("base"); + if (field) { + m_BASE_INDEX = field->m_index; + } + else { + log << MSG::ERROR<< "EmulsionID::initLevelsFromDict - unable to find 'base' field " << endmsg; + return (1); + } + field = m_dict->find_field("film"); + if (field) { + m_FILM_INDEX = field->m_index; + } + else { + log << MSG::ERROR << "EmulsionID::initLevelsFromDict - unable to find 'film' field " << endmsg; + return (1); + } + + // Set the field implementations + + const IdDictRegion& region = *m_dict->m_regions[m_emulsion_region_index]; + + m_neutrino_impl = region.m_implementation[m_NEUTRINO_INDEX]; + m_emulsion_impl = region.m_implementation[m_EMULSION_INDEX]; + m_module_impl = region.m_implementation[m_MODULE_INDEX]; + m_base_impl = region.m_implementation[m_BASE_INDEX]; + m_film_impl = region.m_implementation[m_FILM_INDEX]; + + if (m_msgSvc) { + log << MSG::DEBUG << "decode index and bit fields for each level: " << endmsg; + log << MSG::DEBUG << "neutrino " << m_neutrino_impl.show_to_string() << endmsg; + log << MSG::DEBUG << "emulsion " << m_emulsion_impl.show_to_string() << endmsg; + log << MSG::DEBUG << "module " << m_module_impl.show_to_string() << endmsg; + log << MSG::DEBUG << "base " << m_base_impl.show_to_string() << endmsg; + log << MSG::DEBUG << "film " << m_film_impl.show_to_string() << endmsg; + } + else { + std::cout << " DEBUG decode index and bit fields for each level: " << std::endl; + std::cout << " DEBUG neutrino " << m_neutrino_impl.show_to_string() << std::endl; + std::cout << " DEBUG emulsion " << m_emulsion_impl.show_to_string() << std::endl; + std::cout << " DEBUG module " << m_module_impl.show_to_string() << std::endl; + std::cout << " DEBUG base " << m_base_impl.show_to_string() << std::endl; + std::cout << " DEBUG film " << m_film_impl.show_to_string() << std::endl; + } + + std::cout << "neutrino " << m_neutrino_impl.decode_index() << " " + << (std::string)m_neutrino_impl.ored_field() << " " + << std::hex << m_neutrino_impl.mask() << " " + << m_neutrino_impl.zeroing_mask() << " " + << std::dec << m_neutrino_impl.shift() << " " + << m_neutrino_impl.bits() << " " + << m_neutrino_impl.bits_offset() + << std::endl; + std::cout << "emulsion" << m_emulsion_impl.decode_index() << " " + << (std::string)m_emulsion_impl.ored_field() << " " + << std::hex << m_emulsion_impl.mask() << " " + << m_emulsion_impl.zeroing_mask() << " " + << std::dec << m_emulsion_impl.shift() << " " + << m_emulsion_impl.bits() << " " + << m_emulsion_impl.bits_offset() + << std::endl; + std::cout << "module"<< m_module_impl.decode_index() << " " + << (std::string)m_module_impl.ored_field() << " " + << std::hex << m_module_impl.mask() << " " + << m_module_impl.zeroing_mask() << " " + << std::dec << m_module_impl.shift() << " " + << m_module_impl.bits() << " " + << m_module_impl.bits_offset() + << std::endl; + std::cout << "base" << m_base_impl.decode_index() << " " + << (std::string)m_base_impl.ored_field() << " " + << std::hex << m_base_impl.mask() << " " + << m_base_impl.zeroing_mask() << " " + << std::dec << m_base_impl.shift() << " " + << m_base_impl.bits() << " " + << m_base_impl.bits_offset() + << std::endl; + std::cout << "film" << m_film_impl.decode_index() << " " + << (std::string)m_film_impl.ored_field() << " " + << std::hex << m_film_impl.mask() << " " + << m_film_impl.zeroing_mask() << " " + << std::dec << m_film_impl.shift() << " " + << m_film_impl.bits() << " " + << m_film_impl.bits_offset() + << std::endl; + + return (0); +} + +EmulsionID::size_type +EmulsionID::base_hash_max (void) const +{ + return m_base_hash_max; +} + +EmulsionID::size_type +EmulsionID::film_hash_max (void) const +{ + return m_film_hash_max; +} + +EmulsionID::const_id_iterator EmulsionID::base_begin (void) const +{ + return (m_base_vec.begin()); +} + +EmulsionID::const_id_iterator EmulsionID::base_end (void) const +{ + return (m_base_vec.end()); +} + +EmulsionID::const_expanded_id_iterator EmulsionID::film_begin (void) const +{ + return (m_full_film_range.factory_begin()); +} + +EmulsionID::const_expanded_id_iterator EmulsionID::film_end (void) const +{ + return (m_full_film_range.factory_end()); +} + +// From hash get Identifier +int +EmulsionID::get_id (const IdentifierHash& hash_id, + Identifier& id, + const IdContext* context) const +{ + + int result = 1; + id.clear(); + + size_t begin = (context) ? context->begin_index(): 0; + // cannot get hash if end is 0: + size_t end = (context) ? context->end_index() : 0; + if (0 == begin) { + // No hashes yet for ids with prefixes + if (m_BASE_INDEX == end) { + if (hash_id < (unsigned int)(m_base_vec.end() - m_base_vec.begin())) { + id = m_base_vec[hash_id]; + result = 0; + } + } + else if (m_FILM_INDEX == end) { + // Do not know how to calculate strip id from hash yet!! + std::cout << "Do not know how to calculate film id from hash yet!!" << std::endl; + } + } + return (result); +} + +void +EmulsionID::get_expanded_id (const Identifier& id, + ExpandedIdentifier& exp_id, + const IdContext* context) const +{ + exp_id.clear(); + exp_id << neutrino_field_value() + << emulsion_field_value() + << module(id) + << base(id); + if(!context || context->end_index() == m_FILM_INDEX) + { + exp_id << film(id); + } +} + +int +EmulsionID::get_hash (const Identifier& id, + IdentifierHash& hash_id, + const IdContext* context) const +{ + + // Get the hash code from either a vec (for base) or calculate + // it (films). For the former, we convert to compact and call + // get_hash again. For the latter, we calculate the hash from the + // Identifier. + + int result = 1; + hash_id = 0; + size_t begin = (context) ? context->begin_index(): 0; + size_t end = (context) ? context->end_index() : 0; + if (0 == begin) { + // No hashes yet for ids with prefixes + if (m_BASE_INDEX == end) { + hash_id = base_hash(id); + if (hash_id.is_valid()) result = 0; + } + else if (context && context->end_index() == m_FILM_INDEX) { + // Must calculate for strip hash + ExpandedIdentifier new_id; + get_expanded_id(id, new_id); + hash_id = m_full_film_range.cardinalityUpTo(new_id); + result = 0; + } + } + return (result); +} + + +void +EmulsionID::test_base_packing (void) const +{ + MsgStream log(m_msgSvc, "EmulsionID"); + + if (m_dict) { + + int nids = 0; + int nerr = 0; + IdContext context = base_context(); + const_id_iterator first = m_base_vec.begin(); + const_id_iterator last = m_base_vec.end(); + for (; first != last; ++first, ++nids) { + Identifier id = (*first); + ExpandedIdentifier exp_id; + get_expanded_id(id, exp_id, &context); + Identifier new_id = base_id(exp_id[m_MODULE_INDEX], + exp_id[m_BASE_INDEX]); + if (id != new_id) { + log << MSG::ERROR << "EmulsionID::test_base_packing: new and old compacts not equal. New/old/expanded ids " + << MSG::hex << show_to_string(id) << " " << show_to_string(new_id) << " " << MSG::dec + << (std::string)exp_id << endmsg; + nerr++; + continue; + } + // check module id + if (!exp_id[m_BASE_INDEX]) { + + Identifier new_id1 = module_id(exp_id[m_MODULE_INDEX]); + if (id != new_id1) { + log << MSG::ERROR << "EmulsionID::test_base_packing: new and old module ids not equal. New/old/expanded ids " + << MSG::hex << show_to_string(id) << " " << show_to_string(new_id1) << " " << MSG::dec + << (std::string)exp_id << endmsg; + nerr++; + continue; + } + } + } + + if (m_msgSvc) { + log << MSG::DEBUG << "EmulsionID::test_base_packing: tested base and module ids. nids, errors " + << nids << " " << nerr << endmsg; + } + else { + std::cout << " DEBUG EmulsionID::test_base_packing: tested base and module ids. nids, errors " + << nids << " " << nerr << std::endl; + } + + nids = 0; + context = film_context(); + const_expanded_id_iterator first_emulsion = film_begin(); + const_expanded_id_iterator last_emulsion = film_end(); + for (; first_emulsion != last_emulsion; ++first_emulsion, ++nids) { + // if (nids%10000 != 1) continue; + const ExpandedIdentifier& exp_id = *first_emulsion; + ExpandedIdentifier new_exp_id; + + Identifier id = base_id(exp_id[m_MODULE_INDEX], + exp_id[m_BASE_INDEX]); + get_expanded_id(id, new_exp_id, &context); + if (exp_id[0] != new_exp_id[0] || + exp_id[1] != new_exp_id[1] || + exp_id[2] != new_exp_id[2] || + exp_id[3] != new_exp_id[3]) + { + log << MSG::ERROR << "EmulsionID::test_base_packing: new and old ids not equal. New/old/compact ids " + << (std::string)new_exp_id << " " << (std::string)exp_id + << " " << show_to_string(id) << endmsg; + continue; + } + + Identifier filmid ; + Identifier filmid1 ; + filmid = film_id ( + exp_id[m_MODULE_INDEX], + exp_id[m_BASE_INDEX], + exp_id[m_FILM_INDEX]); + + filmid1 = film_id ( + module(filmid), + base(filmid), + film(filmid)); + + if (filmid != filmid1) { + log << MSG::ERROR << "EmulsionID::test_base_packing: new and old pixel ids not equal. New/old ids " + << " " << show_to_string(filmid1) << " " + << show_to_string(filmid) << endmsg; + } + } + + if (m_msgSvc) { + log << MSG::DEBUG << "EmulsionID::test_base_packing: Successful tested " + << nids << " ids. " + << endmsg; + } + else { + std::cout << " DEBUG EmulsionID::test_base_packing: Successful tested " + << nids << " ids. " + << std::endl; + } + } + else { + log << MSG::ERROR << "EmulsionID::test_base_packing: Unable to test base packing - no dictionary has been defined. " + << endmsg; + } +} + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/CMakeLists.txt b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/CMakeLists.txt new file mode 100644 index 00000000..744ed53c --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/CMakeLists.txt @@ -0,0 +1,21 @@ +################################################################################ +# Package: NeutrinoReadoutGeometry +################################################################################ + +# Declare the package name: +atlas_subdir( NeutrinoReadoutGeometry ) + +# External dependencies: +find_package( CLHEP ) +find_package( Eigen ) +find_package( GeoModel ) + +# Component(s) in the package: +atlas_add_library( NeutrinoReadoutGeometry + src/*.cxx + PUBLIC_HEADERS NeutrinoReadoutGeometry + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} + DEFINITIONS ${CLHEP_DEFINITIONS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} ${GEOMODEL_LIBRARIES} AthenaKernel CxxUtils FaserDetDescr GeoModelFaserUtilities GeoPrimitives Identifier GaudiKernel NeutrinoIdentifier TrkDetElementBase TrkSurfaces TrkEventPrimitives StoreGateLib SGtests AthenaBaseComps DetDescrConditions + PRIVATE_LINK_LIBRARIES AthenaPoolUtilities IdDictDetDescr ) + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/EmulsionDetectorManager.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/EmulsionDetectorManager.h new file mode 100644 index 00000000..29be29e1 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/EmulsionDetectorManager.h @@ -0,0 +1,163 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// EmulsionDetectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_EMULSIONDETECTORMANAGER_H +#define NEUTRINOREADOUTGEOMETRY_EMULSIONDETECTORMANAGER_H + +#include "GeoPrimitives/GeoPrimitives.h" + +#include "GeoModelKernel/GeoVPhysVol.h" + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorManager.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" + +#include "NeutrinoIdentifier/EmulsionID.h" + +class StoreGateSvc; +class Identifier; +class IdentifierHash; +class GeoAlignableTransform; +class GeoVFullPhysVol; +class GeoVPhysVol; +class GeoVAlignmentStore; +class CondAttrListCollection; + +namespace NeutrinoDD { + + class NeutrinoDetectorElement; + class ExtendedAlignableTransform; + class EmulsionDetectorDesign; + + /** @class EmulsionDetectorManager + + Dedicated detector manager extending the functionality of the NeutrinoDetectorManager + with dedicated Emulsion information, access. + + @author: Grant Gorfine + - modified and maintained by Nick Styles & Andreas Salzburger + - modified for FASER by D. Casper + */ + + class EmulsionDetectorManager : public NeutrinoDetectorManager { + + public: + + // Constructor + EmulsionDetectorManager( StoreGateSvc* detStore ); + + // Destructor + virtual ~EmulsionDetectorManager(); + + /** Access Raw Geometry */ + virtual unsigned int getNumTreeTops() const override; + virtual PVConstLink getTreeTop(unsigned int i) const override; + /** Add tree top */ + void addTreeTop(PVLink); + + + // + // Access Readout Elements + // + + /** access to individual elements via Identifier */ + virtual NeutrinoDetectorElement * getDetectorElement(const Identifier &id) const override; + + /** access to individual elements via IdentifierHash */ + virtual NeutrinoDetectorElement * getDetectorElement(const IdentifierHash &idHash) const override; + + /** access to individual elements via module numbering schema */ + NeutrinoDetectorElement * getDetectorElement(int module, int base, int film) const; + + /** access to whole collectiom via iterators */ + virtual const NeutrinoDetectorElementCollection * getDetectorElementCollection() const override; + virtual NeutrinoDetectorElementCollection::const_iterator getDetectorElementBegin() const override; + virtual NeutrinoDetectorElementCollection::const_iterator getDetectorElementEnd() const override; + + /** Add elememts during construction */ + virtual void addDetectorElement(NeutrinoDetectorElement * element) override; + + /** Add alignable transforms. No access to these, they will be changed by manager: */ + virtual void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *xf, + const GeoVFullPhysVol * child); + + /** As above but does a dynamic_cast to GeoVFullPhysVol */ + virtual void addAlignableTransform (int level, + const Identifier &id, + GeoAlignableTransform *xf, + const GeoVPhysVol * child); + + /** Initialize the neighbours. This can only be done when all elements are built. */ + virtual void initNeighbours() override; + + /** Check identifier is for this detector */ + virtual bool identifierBelongs(const Identifier & id) const override; + + /** Access to module design, casts to EmulsionDetectorDesign */ + const NeutrinoDetectorDesign * getEmulsionDesign() const; + + /** Process new global DB folders for L1 and L2 **/ + virtual + bool processGlobalAlignment(const std::string &, int level, FrameType frame, + const CondAttrListCollection* obj, + GeoVAlignmentStore* alignStore) const override; + + // comply with NeutrinoDetectorManager interface + bool processSpecialAlignment(const std::string & key, + NeutrinoDD::AlignFolderType alignfolder) const override; + + bool processSpecialAlignment(const std::string& key, + const CondAttrListCollection* obj=nullptr, + GeoVAlignmentStore* alignStore=nullptr) const override; + + + private: + /** implements the main alignment update for delta transforms in different frames, + it translates into the LocalDelta or GlobalDelta function of NeutrinoDetectorManager + */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame, + GeoVAlignmentStore* alignStore) const override; + + /** Prevent copy and assignment */ + const EmulsionDetectorManager & operator=(const EmulsionDetectorManager &right); + EmulsionDetectorManager(const EmulsionDetectorManager &right); + + virtual const EmulsionID* getIdHelper() const override; + + // Private member data + std::vector<PVLink> m_volume; + NeutrinoDetectorElementCollection m_elementCollection; + typedef std::map<Identifier, ExtendedAlignableTransform *> AlignableTransformMap; + std::vector< AlignableTransformMap > m_higherAlignableTransforms; + std::vector< ExtendedAlignableTransform *> m_alignableTransforms; + const EmulsionID* m_idHelper; + + /** This variable switches the how the local alignment corrections are applied + If true they will be calcualted on top of all of other corrections but in the default reference frame + If false they will be calcualted on top of all of other corrections but in the globally aligned reference frame + */ + bool m_isLogical; + + + }; + +} // namespace NeutrinoDD + +#ifndef GAUDI_NEUTRAL +#include "AthenaKernel/CLASS_DEF.h" +CLASS_DEF(NeutrinoDD::EmulsionDetectorManager, 196479620, 1) +#endif + +#endif // NEUTRINOREADOUTGEOMETRY_EMULSIONDETECTORMANAGER_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/ExtendedAlignableTransform.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/ExtendedAlignableTransform.h new file mode 100644 index 00000000..95b8ef11 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/ExtendedAlignableTransform.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// ExtendedAlignableTransform.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef SCINTREADOUTGEOMETRY_EXTENDEDALIGNABLETRANSFORM_H +#define SCINTREADOUTGEOMETRY_EXTENDEDALIGNABLETRANSFORM_H + +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoVFullPhysVol.h" + +namespace NeutrinoDD { + + /** @class ExtendedAlignableTransform + + Class to hold alignable transform plus a pointer to the child volume and + optionally a frame volume. + + @author: Grant Gorfine + - modified & maintained: Nick Styles & Andreas Salzburger + */ + + class ExtendedAlignableTransform + { + + public: + + ExtendedAlignableTransform(GeoAlignableTransform * alignableTransform, + const GeoVFullPhysVol * child, + const GeoVFullPhysVol * frame = 0) + : m_alignableTransform(alignableTransform), + m_child(child), + m_frame(frame) + {}; + + GeoAlignableTransform * alignableTransform() {return m_alignableTransform;} + const GeoVFullPhysVol * child() {return m_child;} + const GeoVFullPhysVol * frame() {return m_frame;} + + private: + + GeoAlignableTransform * m_alignableTransform; + const GeoVFullPhysVol * m_child; + const GeoVFullPhysVol * m_frame; + + }; + + +} // end namespace + +#endif // SCINTREADOUTGEOMETRY_EXTENDEDALIGNABLETRANSFORM_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoCommonItems.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoCommonItems.h new file mode 100644 index 00000000..ef57e62d --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoCommonItems.h @@ -0,0 +1,92 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoCommonItems.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINOCOMMONITEMS_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINOCOMMONITEMS_H + +class FaserDetectorID; + +// Message Stream Member +#include "AthenaKernel/MsgStreamMember.h" +#include "CxxUtils/checker_macros.h" +// #include "InDetCondTools/ISiLorentzAngleTool.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/RCBase.h" + + +#include "GaudiKernel/ServiceHandle.h" +#include "CLHEP/Geometry/Transform3D.h" + +#include <mutex> + +// mutable Athena::MsgStreamMember issues warnings. +ATLAS_NO_CHECK_FILE_THREAD_SAFETY; + +namespace NeutrinoDD { + + /** @class NeutrinoCommonItems + + Helper class to concentrate common items, such as the pointer to the IdHelper, + + To be used for Emulsion + + @author: Grant Gorfine + mondified & maintained: Nick Styles, Andreas Salzburger + modified: Dave Casper + */ + + class NeutrinoCommonItems: public RCBase + { + + public: + + NeutrinoCommonItems(const FaserDetectorID* const idHelper); + + const FaserDetectorID* getIdHelper() const; + // const HepGeom::Transform3D & solenoidFrame() const; + // void setSolenoidFrame(const HepGeom::Transform3D & transform) const; + + //Declaring the Message method for further use + MsgStream& msg (MSG::Level lvl) const { return m_msg.get() << lvl; } + + //Declaring the Method providing Verbosity Level + bool msgLvl (MSG::Level lvl) const { return m_msg.get().level() <= lvl; } + + private: + + //Declaring private message stream member. + mutable Athena::MsgStreamMember m_msg; + + const FaserDetectorID* m_idHelper; + // mutable HepGeom::Transform3D m_solenoidFrame ATLAS_THREAD_SAFE; // Guarded by m_mutex + + mutable std::mutex m_mutex; + }; + + + inline const FaserDetectorID* NeutrinoCommonItems::getIdHelper() const + { + return m_idHelper; + } + + + // inline const HepGeom::Transform3D & SiCommonItems::solenoidFrame() const + // { + // std::lock_guard<std::mutex> lock{m_mutex}; + // return m_solenoidFrame; + // // This reference might be changed by setSolenoidFrame. + // // However, it occurrs very rarely. + // } + + + +} // End namespace ScintDD + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINOCOMMONITEMSS_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDD_Defs.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDD_Defs.h new file mode 100644 index 00000000..3953b3f0 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDD_Defs.h @@ -0,0 +1,22 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoDD_Defs.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINODD_Defs_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINODD_Defs_H + + +namespace NeutrinoDD { + enum FrameType {local, global, other}; +// enum CarrierType {holes, electrons}; + // new enumerator to select given align-folder structure + enum AlignFolderType {none = -1, static_run1 = 0, timedependent_run2 = 1}; +} + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINODD_DEFS_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h new file mode 100644 index 00000000..a44bb7d6 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h @@ -0,0 +1,171 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoDetectorDesign.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORDESIGN_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORDESIGN_H + +// Input/output classes +#include "CLHEP/Geometry/Point3D.h" +#include "CLHEP/Geometry/Vector3D.h" +#include "FaserDetDescr/FaserDetectorID.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/RCBase.h" +#include "NeutrinoDD_Defs.h" + +#include <list> +#include <vector> + + +class Identifier; + +namespace Trk { +class SurfaceBounds; +class RectangleBounds; +} + +namespace NeutrinoDD { +// class SiReadoutCellId; +// class SiCellId; +// class SiDiode; +// class SiReadoutCell; +class NeutrinoLocalPosition; +class NeutrinoIntersect; + +enum DetectorShape { + Box=0, Other +}; + +/** @class NeutrinoDetectorDesign + + Base class for the detector design classes for Emulsion. + These hold the local description of the detector elements which are + shared by a number of detector elements. + + @author A. Calvet, Grant Gorfine + */ + +class NeutrinoDetectorDesign: public RCBase { +public: + enum Axis { + xAxis = 0, yAxis, zAxis + }; + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// +public: + /** Constructor + */ + + NeutrinoDetectorDesign( const double width, + const double height, + const double thickness ); + + /** Destructor: */ + virtual ~NeutrinoDetectorDesign(); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** Test if point is in the active part of the detector with specified tolerances */ + NeutrinoIntersect inDetector(const NeutrinoLocalPosition &localPosition, double xTol, + double yTol) const; + + /** which axis in hit frame is horizontal */ + /** phi corresponds to "width" */ + NeutrinoDetectorDesign::Axis phiAxis() const; + + /** which axis in hit frame is vertical */ + /** eta corresponds to "length" */ + NeutrinoDetectorDesign::Axis etaAxis() const; + + /** which axis in hit frame is thickness/beam direction */ + NeutrinoDetectorDesign::Axis depthAxis() const; + + /////////////////////////////////////////////////////////////////// + // Pure virtual methods: + /////////////////////////////////////////////////////////////////// + + /** Returns distance to nearest detector active edge + +ve = inside + -ve = outside */ + virtual void distanceToDetectorEdge(const NeutrinoLocalPosition &localPosition, + double &xDist, double &yDist) const; + + /** Method to calculate height of a module */ + virtual double height() const; + + /** Method to calculate average width of a module */ + virtual double width() const; + + /** Method which returns thickness of the silicon wafer */ + double thickness() const; + + // /** Shape of element */ + virtual DetectorShape shape() const; + + /** Element boundary */ + virtual const Trk::SurfaceBounds &bounds() const; + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// +private: + NeutrinoDetectorDesign(); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// +private: + double m_thickness; // !< thickness of plate + double m_width; // !< dimension in "phi" direction + double m_height; // !< dimnesion in "eta" direction + + NeutrinoDetectorDesign::Axis m_phiAxis; // which axis in hit frame is horizontal ("width" axis) + NeutrinoDetectorDesign::Axis m_etaAxis; // which axis in hit frame is vertical ("length" axis) + NeutrinoDetectorDesign::Axis m_depthAxis; // which axis in hit frame is depth/beam? + + const Trk::RectangleBounds* m_bounds; + + // Disallow Copy and assignment; + NeutrinoDetectorDesign(const NeutrinoDetectorDesign &design); + NeutrinoDetectorDesign &operator = (const NeutrinoDetectorDesign &design); +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline double NeutrinoDetectorDesign::thickness() const { + return m_thickness; +} + +inline double NeutrinoDetectorDesign::width() const { + return m_width; +} + +inline double NeutrinoDetectorDesign::height() const { + return m_height; +} + +inline NeutrinoDetectorDesign::Axis NeutrinoDetectorDesign::phiAxis() const { + return m_phiAxis; +} + +inline NeutrinoDetectorDesign::Axis NeutrinoDetectorDesign::etaAxis() const { + return m_etaAxis; +} + +inline NeutrinoDetectorDesign::Axis NeutrinoDetectorDesign::depthAxis() const { + return m_depthAxis; +} + +} // namespace NeutrinoDD +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORDESIGN_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h new file mode 100644 index 00000000..14641723 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElement.h @@ -0,0 +1,687 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @file NeutrinoDetectorElement.h +**/ + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORELEMENT_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORELEMENT_H + +// Base class. +#include "TrkDetElementBase/TrkDetElementBase.h" + +// Data member classes +#include "CxxUtils/CachedUniquePtr.h" +#include "Identifier/Identifier.h" +#include "Identifier/IdentifierHash.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" +#include "NeutrinoReadoutGeometry/NeutrinoLocalPosition.h" +#include "TrkEventPrimitives/ParamDefs.h" +#include "NeutrinoReadoutGeometry/NeutrinoIntersect.h" +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "GeoModelKernel/GeoDefinitions.h" + +#include "CLHEP/Geometry/Point3D.h" + +#include <atomic> +#include <mutex> + +class FaserDetectorID; +class GeoVFullPhysVol; +class GeoAlignmentStore; + +namespace Trk{ + class Surface; + class SurfaceBounds; +} + +namespace NeutrinoDD { + + /** + + @class NeutrinoDetectorElement + + Class to hold geometrical description of a neutrino detector element. + A detector element is a single emulsion film. + + @par Coordinate Frames. + + The following coordinate frames are used in these elements. + + - Global frame:\n + Currently global frame in G4/GeoModel. Probably eventually + will be global frame most suitable for reconstruction + (eg solenoid axis). + + - Local hit frame:\n + Local frame for hits. It is the same as local frame in G4 and GeoModel. + I also refer to this as the local simulation frame. + In FASER: + - hitDepth = local z = global z (always beam direction) + - hitEta = local y = global y (always vertical up) + - hitPhi = local x (right-handed wrt y cross z, hence same as global x; left of beam direction) + (hitPhi, hitEta, hitDepth) is right-handed + In ATLAS (retained for reference): + By convention elements are orientated such that: + - hitDepth = local x + - hitPhi = local y + - hitEta = local z + Directions of these correspond to the physical wafer. Consequently hitDepth and hitPhi axes go in + different directions depending on the orientation of the module. + The readout side is determined from design()->readoutSide(). + + - Local reconstruction frame:\n + - distPhi = local x (= global x in FASER) + - distEta = local y (= global y in FASER) + - distDepth = local z (= global z in FASER) + . + (In ATLAS:) + The directions of the axes are defined as + - distPhi in direction of increasing phi + - distEta in direction of increasing z in barrel and increasing r in endcap. + - distDepth (normal) choosen to give right-handed coordinate. + => away from intersection point for barrel, decreasing z for endcap + + @par Overview of Methods + + Methods are grouped into the the following categories + + - Identification + - Navigation + - Transformation/Orientation + - Module Frame + - Element Extent + - Design methods + - Intersection Tests + - Lorentz Correction + - Readout cell id + - Miscellaneous + - Cache handling. + + + @author Grant Gorfine + - modified & maintained: Nick Styles, Andreas Salzburger + - modified Nigel Hessey: get directions from the design instead of hard-wiring them + - modified for Faser: Dave Casper + + */ + + class NeutrinoDetectorElement : public Trk::TrkDetElementBase { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + + /// Constructor: + NeutrinoDetectorElement(const Identifier &id, + const NeutrinoDetectorDesign *design, + const GeoVFullPhysVol *geophysvol, + const NeutrinoCommonItems * commonItems, + const GeoAlignmentStore* geoAlignStore=nullptr); + + /// Destructor: + virtual ~NeutrinoDetectorElement(); + + + /////////////////////////////////////////////////////////////////// + // + /// @name Identification + /// Methods to identify the element and identifier manipulation. + // + /////////////////////////////////////////////////////////////////// + + //@{ + + /// identifier of this detector element: + Identifier identify() const; + + /// identifier hash + IdentifierHash identifyHash() const; + + /// Returns the id helper + const FaserDetectorID* getIdHelper() const; + + bool isEmulsion() const; + + // Identifier <-> pmt + + /// Identifier from pmt + Identifier identifierFromCellId(const int& cellId) const; + + /// pmt from Identifier + int cellIdFromIdentifier(const Identifier & identifier) const; + + //@} + + + /////////////////////////////////////////////////////////////////// + // + /// @name Navigation + /// Methods to access neighbours. + // + /////////////////////////////////////////////////////////////////// + + //@{ + const NeutrinoDetectorElement* nextInZ() const; + const NeutrinoDetectorElement* prevInZ() const; + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Transformation/Orientation + // + /////////////////////////////////////////////////////////////////// + + //@{ + // Position + /// Local (simulation/hit frame) to global transform + virtual const GeoTrf::Transform3D & transformHit() const; + /// Local (reconstruction frame) to global transform + const Amg::Transform3D & transform() const; + /// Default Local (reconstruction frame) to global transform + /// ie with no misalignment. + const HepGeom::Transform3D defTransformCLHEP() const; + const Amg::Transform3D defTransform() const; + /// Center in global coordinates + const Amg::Vector3D & center() const; + + const HepGeom::Transform3D & transformCLHEP() const; + + /// Simulation/Hit local frame to reconstruction local frame. 2D. + // TODO: Will change order of parameters at some point. + Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const; + /// Same as previuos method but 3D. + HepGeom::Point3D<double> hitLocalToLocal3D(const HepGeom::Point3D<double> & hitPosition) const; + + /// Transform to go from local reconstruction frame to local hit frame. + const HepGeom::Transform3D recoToHitTransform() const; + + /// Directions of hit depth,phi,eta axes relative to reconstruction local position + /// axes (LocalPosition). Returns +/-1. + double hitDepthDirection() const; + /// See previous method. + double hitPhiDirection() const; + /// See previous method. + double hitEtaDirection() const; + + // To determine if readout direction between online and offline needs swapping, see methods + // swapPhiReadoutDirection() and swapEtaReadoutDirection() below in "Readout Cell id" section + + // Orientation. + // Directions. + // phiAxis - in same direction as increasing phi and identifier phi_index/strip. + // NB. This requires some flipping of axes with repsect to the hits. + // etaAxis - in direction of increasing z in the barrel and increasing r in the endcap. + // normal - choosen to give right-handed coordinate frame (x=normal,y=phiAxis,z=etaAxis) + // NB. This requires some flipping of axes with repsect to the hits. + + /// Get reconstruction local x axes in global frame. + const Amg::Vector3D & phiAxis() const; + const HepGeom::Vector3D<double> & phiAxisCLHEP() const; + /// Get reconstruction local y axes in global frame. + const Amg::Vector3D & etaAxis() const; + const HepGeom::Vector3D<double> & etaAxisCLHEP() const; + /// Get reconstruction local normal axes in global frame. Choosen to give right-handed coordinate frame. + const Amg::Vector3D & normal() const; + + /// transform a hit local position into a global position: + HepGeom::Point3D<double> globalPositionHit(const HepGeom::Point3D<double> &simulationLocalPos) const; + Amg::Vector3D globalPositionHit(const Amg::Vector3D &simulationLocalPos) const; + + /// transform a reconstruction local position into a global position: + HepGeom::Point3D<double> globalPosition(const HepGeom::Point3D<double> &localPos) const; + Amg::Vector3D globalPosition(const Amg::Vector3D &localPos) const; + + /// as in previous method but for 2D local position + HepGeom::Point3D<double> globalPositionCLHEP(const Amg::Vector2D &localPos) const; + + Amg::Vector3D globalPosition(const Amg::Vector2D &localPos) const; + + /// transform a global position into a 2D local position (reconstruction frame) + Amg::Vector2D localPosition(const HepGeom::Point3D<double> & globalPosition) const; + + Amg::Vector2D localPosition(const Amg::Vector3D& globalPosition) const; + + /// Element Surface + virtual Trk::Surface & surface(); + virtual const Trk::Surface & surface() const; + + //@} + + /** Returns the full list of surfaces associated to this detector element */ + virtual const std::vector<const Trk::Surface*>& surfaces() const; + + /** + + @name Base Frame + Methods to help work with the film frame. + */ + + //@{ + + /// Film to global frame transform. + /// Includes misalignment. + //const HepGeom::Transform3D & moduleTransform() const; + const Amg::Transform3D & filmTransform() const; + + /// Default film to global frame transform, ie with no misalignment. + Amg::Transform3D defFilmTransform() const; + + /// Take a transform of the local element frame and return its equivalent in the base frame. + //HepGeom::Transform3D localToModuleFrame(const HepGeom::Transform3D & localTransform) const; + Amg::Transform3D localToBaseFrame(const Amg::Transform3D & localTransform) const; + + + /// Transformation from local element to base frame. This can be + /// used to take a local position in the element frame and transform + /// it to a position in the base frame. If one is already in the + /// base frame it will return the Identity transform. + //HepGeom::Transform3D localToModuleTransform() const; + Amg::Transform3D localToBaseTransform() const; + + + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Element Extent + /// Methods to get extent of element in x, y and z. + /////////////////////////////////////////////////////////////////// + + //@{ + // Extent in x,y and z + double xMin() const; + double xMax() const; + double yMin() const; + double yMax() const; + double zMin() const; + double zMax() const; + + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Design methods + // + /////////////////////////////////////////////////////////////////// + //@{ + + /// access to the local description: + const NeutrinoDetectorDesign &design() const; + + // Methods from design + double width() const; // Width in x direction. + double height() const; // Length in y direction + double thickness() const; // Thickness in z direction + + virtual const Trk::SurfaceBounds & bounds() const; + + // Test that it is in the active region + // Intersect has 3 states + // bool SiIntersect::in() const // definitely in + // bool SiIntersect::out() const // definitely out + // bool SiIntersect::nearBoundary() const // near a boundary within the tolerances + // bool SiIntersect::mayIntersect() const // in() OR nearBoundary() + NeutrinoIntersect inDetector(const Amg::Vector2D & localPosition, double phiTol, double etaTol) const; + NeutrinoIntersect inDetector(const HepGeom::Point3D<double> & globalPosition, double phiTol, double etaTol) const; + + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Cache handling. + // + /////////////////////////////////////////////////////////////////// + //@{. + // - Methods to handle invalidating and updating caches. The cached values include values that are affected by alignment + // Surface are only created on demand. The method updateAllCaches also creates the surfaces as well as calling updateCache. + // Conditions cache contains Lorentz angle related quantities. + + /// Signal that cached values are no longer valid. + /// Invalidate general cache + // void invalidate ATLAS_NOT_THREAD_SAFE () const; + void invalidate(); + + ///Set/calculate cache values + void setCache(){ + updateCache(); + } + ///Set/calculate all cache values including surfaces. + void setAllCaches(){ + updateAllCaches(); + } + //@} + + /////////////////////////////////////////////////////////////////// + // + /// @name Methods to satisfy TrkDetElementBase interface + // + /////////////////////////////////////////////////////////////////// + //{@ + virtual const Amg::Transform3D & transform(const Identifier&) const {return transform();} + virtual const Trk::Surface& surface (const Identifier&) const {return surface();} + virtual const Amg::Vector3D& center (const Identifier&) const {return center();} + virtual const Amg::Vector3D& normal (const Identifier&) const {return normal();} + virtual const Trk::SurfaceBounds & bounds(const Identifier&) const {return bounds();} + //@} + + ////////////////////////////////////////////////////////////////////////////////////// + + void setNextInZ(const NeutrinoDetectorElement* element); + void setPrevInZ(const NeutrinoDetectorElement* element); + + ////////////////////////////////////////////////////////////////////////////////////// + + public: + + const NeutrinoCommonItems* getCommonItems() const; + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + + private: + /// Recalculate cached values. + void updateCache() const; + + /// Update all caches including surfaces. + void updateAllCaches() const; + + + // Common code for constructors. + void commonConstructor(); + + // Calculate extent in x, y and z. The values are cached and there + // are xMin(), xMax etc methods. + void getExtent(double &xMin, double &xMax, + double &yMin, double &yMax, + double &zMin, double &zMax) const; + + // Return the four corners of an element in local coordinates. + // Pass it an array of length 4. + // This function is used by getEtaPhiRegion() + void getCorners(HepGeom::Point3D<double> *corners) const; + + //Declaring the Message method for further use + MsgStream& msg (MSG::Level lvl) const { return m_commonItems->msg(lvl);} + + //Declaring the Method providing Verbosity Level + bool msgLvl (MSG::Level lvl) const { return m_commonItems->msgLvl(lvl);} + + + /////////////////////////////////////////////////////////////////// + // Private methods: + /////////////////////////////////////////////////////////////////// + private: + // Don't allow copying. + NeutrinoDetectorElement(); + NeutrinoDetectorElement(const NeutrinoDetectorElement&); + NeutrinoDetectorElement &operator=(const NeutrinoDetectorElement&); + + /////////////////////////////////////////////////////////////////// + // Protected data: + /////////////////////////////////////////////////////////////////// + protected: + Identifier m_id; // identifier of this detector element + IdentifierHash m_idHash; // hash id + const NeutrinoDetectorDesign *m_design; // local description of this detector element + const NeutrinoCommonItems * m_commonItems; + + const NeutrinoDetectorElement* m_prevInZ; + const NeutrinoDetectorElement* m_nextInZ; + + // + // Cached values. + // + // Axes + NeutrinoDetectorDesign::Axis m_hitEta; + NeutrinoDetectorDesign::Axis m_hitPhi; + NeutrinoDetectorDesign::Axis m_hitDepth; + + // Directions of axes. These are true if the hit/simulation and reconstruction local frames are + // in the same direction and false if they are opposite. + mutable bool m_depthDirection ATLAS_THREAD_SAFE; // Guarded by m_mutex // Direction of depth axis. + // Also direction of readout implant (n+ for pixel, p+ for SCT). + mutable bool m_phiDirection ATLAS_THREAD_SAFE; // + mutable bool m_etaDirection ATLAS_THREAD_SAFE; // + + mutable std::atomic_bool m_cacheValid; // Alignment associated quatities. + mutable std::atomic_bool m_firstTime; + + mutable bool m_isEmulsion; + + mutable std::recursive_mutex m_mutex; + + mutable Amg::Transform3D m_transform ATLAS_THREAD_SAFE; // Guarded by m_mutex + mutable HepGeom::Transform3D m_transformCLHEP ATLAS_THREAD_SAFE; // Guarded by m_mutex + + mutable Amg::Vector3D m_normal ATLAS_THREAD_SAFE; // Guarded by m_mutex + mutable Amg::Vector3D m_etaAxis ATLAS_THREAD_SAFE; // Guarded by m_mutex + mutable HepGeom::Vector3D<double> m_etaAxisCLHEP ATLAS_THREAD_SAFE; // Guarded by m_mutex + mutable Amg::Vector3D m_phiAxis ATLAS_THREAD_SAFE; // Guarded by m_mutex + mutable HepGeom::Vector3D<double> m_phiAxisCLHEP ATLAS_THREAD_SAFE; // Guarded by m_mutex + mutable Amg::Vector3D m_center ATLAS_THREAD_SAFE; // Guarded by m_mutex + mutable HepGeom::Vector3D<double> m_centerCLHEP ATLAS_THREAD_SAFE; // Guarded by m_mutex + + mutable double m_minX ATLAS_THREAD_SAFE;// Guarded by m_mutex + mutable double m_maxX ATLAS_THREAD_SAFE;// Guarded by m_mutex + mutable double m_minY ATLAS_THREAD_SAFE;// Guarded by m_mutex + mutable double m_maxY ATLAS_THREAD_SAFE;// Guarded by m_mutex + mutable double m_minZ ATLAS_THREAD_SAFE;// Guarded by m_mutex + mutable double m_maxZ ATLAS_THREAD_SAFE;// Guarded by m_mutex + + CxxUtils::CachedUniquePtrT<Trk::Surface> m_surface; + mutable std::vector<const Trk::Surface*> m_surfaces ATLAS_THREAD_SAFE; // Guarded by m_mutex + + const GeoAlignmentStore* m_geoAlignStore{}; + }; + + /////////////////////////////////////////////////////////////////// + // Inline methods: + /////////////////////////////////////////////////////////////////// + + inline HepGeom::Point3D<double> NeutrinoDetectorElement::globalPositionHit(const HepGeom::Point3D<double> &localPos) const + { + return Amg::EigenTransformToCLHEP(transformHit())*localPos; + } + + inline Amg::Vector3D NeutrinoDetectorElement::globalPosition(const Amg::Vector2D &localPos) const + { + if (!m_cacheValid) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_center + localPos[Trk::distEta] * m_etaAxis + localPos[Trk::distPhi] * m_phiAxis; + } + + inline Amg::Vector3D NeutrinoDetectorElement::globalPositionHit(const Amg::Vector3D &localPos) const + { + return transformHit() * localPos; + } + + inline HepGeom::Point3D<double> NeutrinoDetectorElement::globalPositionCLHEP(const Amg::Vector2D &localPos) const + { + if (!m_cacheValid) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_centerCLHEP + localPos[Trk::distEta] * m_etaAxisCLHEP + localPos[Trk::distPhi] * m_phiAxisCLHEP; + } + //here + inline Amg::Vector3D NeutrinoDetectorElement::globalPosition(const Amg::Vector3D &localPos) const + { + return transform() * localPos; + } + + inline HepGeom::Point3D<double> NeutrinoDetectorElement::globalPosition(const HepGeom::Point3D<double> &localPos) const + { + return transformCLHEP() * localPos; + } + + inline Amg::Vector2D NeutrinoDetectorElement::localPosition(const HepGeom::Point3D<double> & globalPosition) const + { + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + HepGeom::Vector3D<double> relativePos = globalPosition - m_centerCLHEP; + return Amg::Vector2D(relativePos.dot(m_phiAxisCLHEP), relativePos.dot(m_etaAxisCLHEP)); + } + + inline Amg::Vector2D NeutrinoDetectorElement::localPosition(const Amg::Vector3D & globalPosition) const + { + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + Amg::Vector3D relativePos = globalPosition - m_center; + return Amg::Vector2D(relativePos.dot(m_phiAxis), relativePos.dot(m_etaAxis)); + } + + inline const NeutrinoDetectorDesign &NeutrinoDetectorElement::design() const + { + return *m_design; + } + + inline const FaserDetectorID* NeutrinoDetectorElement::getIdHelper() const + { + return m_commonItems->getIdHelper(); + } + + inline Identifier NeutrinoDetectorElement::identify() const + { + return m_id; + } + + inline IdentifierHash NeutrinoDetectorElement::identifyHash() const + { + return m_idHash; + } + + inline double NeutrinoDetectorElement::hitDepthDirection() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return (m_depthDirection) ? 1. : -1.; + } + + inline double NeutrinoDetectorElement::hitPhiDirection() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return (m_phiDirection) ? 1. : -1.; + } + + inline double NeutrinoDetectorElement::hitEtaDirection() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return (m_etaDirection) ? 1. : -1.; + } + + inline void NeutrinoDetectorElement::invalidate() + { + m_cacheValid = false; + } + + inline void NeutrinoDetectorElement::updateAllCaches() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + if (not m_surface) surface(); + } + + + inline double NeutrinoDetectorElement::xMin() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return m_minX; + } + + inline double NeutrinoDetectorElement::xMax() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return m_maxX; + } + + inline double NeutrinoDetectorElement::yMin() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return m_minY; + } + + inline double NeutrinoDetectorElement::yMax() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return m_maxY; + } + + inline double NeutrinoDetectorElement::zMin() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return m_minZ; + } + + inline double NeutrinoDetectorElement::zMax() const + { + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + return m_maxZ; + } + + inline double NeutrinoDetectorElement::width() const + { + return m_design->width(); + } + + inline double NeutrinoDetectorElement::height() const + { + return m_design->height(); + } + + inline double NeutrinoDetectorElement::thickness() const + { + return m_design->thickness(); + } + + inline const NeutrinoCommonItems* NeutrinoDetectorElement::getCommonItems() const + { + return m_commonItems; + } + + inline const NeutrinoDetectorElement* NeutrinoDetectorElement::prevInZ() const + { + return m_prevInZ; + } + + inline const NeutrinoDetectorElement* NeutrinoDetectorElement::nextInZ() const + { + return m_nextInZ; + } + + inline void NeutrinoDetectorElement::setPrevInZ(const NeutrinoDetectorElement* element) + { + m_prevInZ = element; + } + + inline void NeutrinoDetectorElement::setNextInZ(const NeutrinoDetectorElement* element) + { + m_nextInZ = element; + } + +} // namespace NeutrinoDD + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORELEMENT_H + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h new file mode 100644 index 00000000..32d13f48 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoDetectorElementCollection.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORELEMENTCOLLECTION_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORELEMENTCOLLECTION_H + +#include <vector> + +class IdentifierHash; + +namespace NeutrinoDD { + + class NeutrinoDetectorElement; + + /** @class NeutrinoDetectorElementCollection + + Class to hold the NeutrinoDetectorElement objects to be put in the detector store + + @author Grant Gorfine + @author Dave Casper + */ + + class NeutrinoDetectorElementCollection : public std::vector<NeutrinoDetectorElement *> { + public: + ~NeutrinoDetectorElementCollection(); + const NeutrinoDetectorElement* getDetectorElement(const IdentifierHash& hash) const; + }; + +} // namespace NeutrinoDD + +#include "AthenaKernel/CLASS_DEF.h" +CLASS_DEF( NeutrinoDD::NeutrinoDetectorElementCollection , 1277872151 , 1 ) +#include "AthenaKernel/CondCont.h" +CONDCONT_DEF( NeutrinoDD::NeutrinoDetectorElementCollection, 1081260291 ); + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORELEMENTCOLLECTION_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManager.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManager.h new file mode 100644 index 00000000..b760d726 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManager.h @@ -0,0 +1,147 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoDetectorManager.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORMANAGER_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORMANAGER_H + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorManagerBase.h" + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "NeutrinoReadoutGeometry/NeutrinoNumerology.h" + +// Amg stuff +#include "GeoPrimitives/GeoPrimitives.h" + +#include "CLHEP/Geometry/Transform3D.h" + +#include <string> +#include <map> + +class StoreGateSvc; +class Identifier; +class IdentifierHash; +class FaserDetectorID; +class GeoAlignableTransform; +class GeoVAlignmentStore; + +namespace NeutrinoDD { + +class NeutrinoDetectorElement; +class NeutrinoDetectorDesign; +class ExtendedAlignableTransform; +class NeutrinoNumerology; + + /** @class NeutrinoDetectorManager + + Base class for Neutrino Detector managers. + + The Detector manager has methods to retrieve the Identifier + helper and methods to retrieve the detector elements. It also + manages the alignment with methods to register the call backs + and infrastructure to associate the alignment transforms with + the appropriate alignable transform in GeoModel. + + @author: Grant Gorfine + - modified and maintained by Nick Styles & Andreas Salzburger + */ + + class NeutrinoDetectorManager : public NeutrinoDetectorManagerBase { + + + public: + + // Constructor + NeutrinoDetectorManager(StoreGateSvc * detStore, const std::string & name); + + // Destructor + virtual ~NeutrinoDetectorManager() {}; + + + // + // Access Readout Elements + // + + /** access to individual elements using Identifier or IdentiferHash */ + virtual NeutrinoDetectorElement * getDetectorElement(const Identifier &id) const = 0; + virtual NeutrinoDetectorElement * getDetectorElement(const IdentifierHash &idHash) const = 0; + + /** access to whole collectiom */ + virtual const NeutrinoDetectorElementCollection * getDetectorElementCollection() const = 0; + virtual NeutrinoDetectorElementCollection::const_iterator getDetectorElementBegin() const = 0; + virtual NeutrinoDetectorElementCollection::const_iterator getDetectorElementEnd() const = 0; + + + /** Add elememts */ + virtual void addDetectorElement(NeutrinoDetectorElement * element) = 0; + + /** Initialize the neighbours. This can only be done when all elements are built */ + virtual void initNeighbours() = 0; + + /** Get tag used in dictionary */ + const std::string & tag() const; + + /** Invalidate cache for all detector elements */ + virtual void invalidateAll() const; + + /** Update all caches */ + virtual void updateAll() const; + + + /** Helper method to set delta transform from a global delta - Amg interface*/ + bool setAlignableTransformGlobalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & delta, + GeoVAlignmentStore* alignStore=nullptr) const; + + /** Helper method to set delta transform from a local delta - Amg interface */ + bool setAlignableTransformLocalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & localToGlobalXF, + const Amg::Transform3D & delta, + GeoVAlignmentStore* alignStore=nullptr) const; + + /** Access to module design */ + + void setDesign(const NeutrinoDetectorDesign*); + const NeutrinoDetectorDesign* getDesign() const; + + /** Access Numerology */ + const NeutrinoNumerology & numerology() const {return m_numerology;} + NeutrinoNumerology & numerology() {return m_numerology;} + + private: + //** Prevent copy and assignment */ + const NeutrinoDetectorManager & operator=(const NeutrinoDetectorManager &right); + NeutrinoDetectorManager(const NeutrinoDetectorManager &right); + + /** This method is called by the NeutrinoDetectorManagerBase */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame, + GeoVAlignmentStore* alignStore) const = 0; + + + + std::string m_tag; + NeutrinoNumerology m_numerology; + const NeutrinoDetectorDesign * m_design; + + }; + + +} // namespace NeutrinoDD + +#ifndef GAUDI_NEUTRAL +#include "AthenaKernel/CLASS_DEF.h" + +CLASS_DEF(NeutrinoDD::NeutrinoDetectorManager, 203251628, 1) +#endif + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORMANAGER_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManagerBase.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManagerBase.h new file mode 100644 index 00000000..8bce2c0e --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoDetectorManagerBase.h @@ -0,0 +1,204 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoDectorManagerBase.h (was InDetDetectorManager.h) +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORMANAGERBASE_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORMANAGERBASE_H + +// Amg +#include "GeoPrimitives/GeoPrimitives.h" +// GeoModel stuff +#include "GeoModelKernel/GeoVDetectorManager.h" +#include "NeutrinoReadoutGeometry/NeutrinoDD_Defs.h" +#include "NeutrinoReadoutGeometry/Version.h" +#include "CLHEP/Geometry/Transform3D.h" +// Message Stream Member +#include "AthenaKernel/MsgStreamMember.h" + +// IOV SVC for alignment: +#include "AthenaKernel/IIOVSvc.h" + +#include "DetDescrConditions/AlignableTransformContainer.h" + +#include "CxxUtils/checker_macros.h" + +#include <atomic> +#include <string> +#include <map> +#include <set> +#include <list> + +class StoreGateSvc; +class AlignableTransform; +class Identifier; +class FaserDetectorID; +class GeoVAlignmentStore; +class CondAttrListCollection; + +// mutable Athena::MsgStreamMember issues warnings. +ATLAS_NO_CHECK_FILE_THREAD_SAFETY; + +namespace NeutrinoDD { + + typedef std::map<std::string, const void*> RawAlignmentObjects; + + /** @class NeutrinoDetectorManagerBase + + Virtual base class for all neutrino detector managers. + + It implements the processKey() method for alingment + which calls the setAlignableTransformDelta() method which + is specified in the extended classes. This method supports both, + local and global delta's in the frame and translates it to the + underlying GeoModel transform. As GeoModel (CLHEP) and tracking + (Amg) use different geo libraries, these are the methods that + act as the CLHEP <--> Amg interface + + @author: Grant Gorfine + - modified & maintained: Nick Styles & Andreas Salzburger + */ + class NeutrinoDetectorManagerBase : public GeoVDetectorManager { + + public: + + // Constructor + NeutrinoDetectorManagerBase(StoreGateSvc * detStore, const std::string & name); + + // Destructor + virtual ~NeutrinoDetectorManagerBase(); + + + /** Get version information */ + const Version & getVersion() const; + const std::string & getLayout() const; // eg Initial, Final, TestBeam + void setVersion(const Version & version); + + /** Alignment access */ + void addChannel(const std::string & key, int level, FrameType frame); + void addFolder(const std::string & key); + void addSpecialFolder(const std::string & key); + void addGlobalFolder(const std::string & key); + void addAlignFolderType(const AlignFolderType alignfolder); + + StatusCode align( IOVSVC_CALLBACK_ARGS ) const; + + StatusCode align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) const; + + /** Invalidate cache for all detector elements */ + virtual void invalidateAll() const = 0; + + /** Update all caches */ + virtual void updateAll() const = 0; + + /** Check identifier is for this detector */ + virtual bool identifierBelongs(const Identifier & id) const = 0; + + /** Declaring the Message method for further use */ + MsgStream& msg (MSG::Level lvl) const { return m_msg.get() << lvl; } + + /** Declaring the Method providing Verbosity Level */ + bool msgLvl (MSG::Level lvl) const { return m_msg.get().level() <= lvl; } + + AlignFolderType m_alignfoldertype; + + protected: + StoreGateSvc * m_detStore; + + private: + /** @class LevelInfo + Private helper class definition. + */ + class LevelInfo { + + private: + int m_level; + FrameType m_type; + + public: + LevelInfo(): m_level(-1), m_type(NeutrinoDD::global) {}; + LevelInfo(int level, FrameType frame): m_level(level), m_type(frame) {}; + + int level() const {return m_level;} + FrameType frame() const {return m_type;} + bool isGlobalDelta() const {return m_type == NeutrinoDD::global;} + bool isLocalDelta() const {return m_type == NeutrinoDD::local;} + bool isValid() const {return (m_level >= 0);} + + }; + + class AlignInfo { + + private: + AlignFolderType m_aligntype; + + public: + AlignInfo(): m_aligntype(NeutrinoDD::none) {}; + AlignInfo(AlignFolderType alignfolder): m_aligntype(alignfolder) {}; + AlignFolderType AlignFolder() const {return m_aligntype;} + bool isValidAlign() const {return (m_aligntype != NeutrinoDD::none);} + + }; + + + /** Retrieve level information */ + const LevelInfo & getLevel(const std::string & key) const; + + /** return align folder string to use **/ + // NeutrinoDD::AlignFolderType getAlignInfo(); + + /** Process the alignment container, calls processKey */ + bool processAlignmentContainer(const std::string & key) const; + bool processAlignmentContainer(const AlignableTransformContainer* container, GeoVAlignmentStore* alignStore) const; + + /** Called by processAlignmentContainer, + applies only one key on the transform Collections */ + bool processKey(const std::string key, + const AlignableTransform* transformCollection, + GeoVAlignmentStore* alignStore=nullptr) const; + + /** Set method applying the delta transform (in global or local frame) + onto the geoModel transform : CLHEP <--> Amg interface */ + virtual bool setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame, + GeoVAlignmentStore* alignStore=nullptr) const = 0; + + virtual bool processSpecialAlignment(const std::string & key, + NeutrinoDD::AlignFolderType alignfolder) const = 0; + + virtual bool processSpecialAlignment(const std::string& key, + const CondAttrListCollection* obj=nullptr, + GeoVAlignmentStore* alignStore=nullptr) const = 0; + + bool processGlobalAlignmentContainer(const std::string & key, + const CondAttrListCollection* obj=nullptr, + GeoVAlignmentStore* alignStore=nullptr) const; + + virtual bool processGlobalAlignment(const std::string & key, int level, FrameType frame, + const CondAttrListCollection* obj=nullptr, + GeoVAlignmentStore* alignStore=nullptr) const; + + virtual const FaserDetectorID* getIdHelper() const = 0; + + //Declaring private message stream member. + mutable Athena::MsgStreamMember m_msg; + + Version m_version; + std::map<std::string, LevelInfo> m_keys; + std::set<std::string> m_folders; + std::set<std::string> m_specialFolders; + std::set<std::string> m_globalFolders; // new time-dependent global folders + + static const LevelInfo s_invalidLevel; + }; + +} // namespace NeutrinoDD + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINODETECTORMANAGERBASE_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoIntersect.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoIntersect.h new file mode 100644 index 00000000..6716572f --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoIntersect.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoIntersect.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINOINTERSECT_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINOINTERSECT_H + +namespace NeutrinoDD { + + /** @class NeutrinoIntersect + + class to run intersection tests + + @author Grant Gorfine + */ + + class NeutrinoIntersect { + + public: + + enum IntersectState {OUT = 0, BOUNDARY = 1, IN = 2}; + + NeutrinoIntersect(IntersectState state = OUT); + + bool in() const; // Definitely in + bool out() const; // Definitely out + bool nearBoundary() const; // Near boundary within tolerences + bool mayIntersect() const; // in() || nearBoundary() + operator bool() const; // Equivalent to mayIntersect(). + + void setIn(); + void setOut(); + void setNearBoundary(); + + private: + IntersectState m_state; + + }; + +inline NeutrinoIntersect::NeutrinoIntersect(IntersectState state) + : m_state(state) +{} + +inline bool NeutrinoIntersect::in() const +{ + return (m_state == IN); +} + +inline bool NeutrinoIntersect::out() const +{ + return (m_state == OUT); +} + +inline bool NeutrinoIntersect::nearBoundary() const +{ + return (m_state == BOUNDARY); +} + + +inline bool NeutrinoIntersect::mayIntersect() const +{ + return (m_state == BOUNDARY || m_state == IN); +} + +inline NeutrinoIntersect::operator bool() const +{ + return mayIntersect(); +} + +inline void NeutrinoIntersect::setIn() +{ + m_state = IN; +} + +inline void NeutrinoIntersect::setOut() +{ + m_state = OUT; +} + +inline void NeutrinoIntersect::setNearBoundary() +{ + m_state = BOUNDARY; +} + +} // namespace NeutrinoDD + +#endif //NEUTRINOREADOUTGEOMETRY_NEUTRINOINTERSECT_H + diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoLocalPosition.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoLocalPosition.h new file mode 100644 index 00000000..06f3decb --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoLocalPosition.h @@ -0,0 +1,173 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoLocalPosition.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINOLOCALPOSITION_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINOLOCALPOSITION_H + +#include "GeoPrimitives/GeoPrimitives.h" +#include "TrkEventPrimitives/ParamDefs.h" +#include <cmath> + +namespace NeutrinoDD { + enum ExtraLocalPosParam {distDepth = 2}; // These will be defined in Trk soon. +} + +namespace NeutrinoDD { + + /** @class NeutrinoLocalPosition + Class to represent a position in the natural frame of an emulsion sensor + */ + + class NeutrinoLocalPosition { + + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Default constructor: */ + NeutrinoLocalPosition(); + + /** Copy constructor: */ + NeutrinoLocalPosition(const NeutrinoLocalPosition &position) = default; + + /** This allows one to pass a Amg::Vector2D to a NeutrinoLocalPosition */ + NeutrinoLocalPosition(const Amg::Vector2D &position); + + /** Constructor with parameters: + position along eta direction + position along phi direction + position along depth direction (default is 0) */ + NeutrinoLocalPosition(const double eta,const double phi, + const double xDepth=0); + + /** Destructor: */ + ~NeutrinoLocalPosition(); + + /** Assignment operator: */ + NeutrinoLocalPosition &operator=(const NeutrinoLocalPosition &) = default; + + /** Move assignment **/ + NeutrinoLocalPosition &operator=(NeutrinoLocalPosition &&) = default; + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /** position along local eta direction:*/ + double xEta() const; + + /** position along local phi direction:*/ + double xPhi() const; + + /** Cylindrical coordinate r:*/ + double r() const; + + /** Cylindrical coordinate phi:*/ + double phi() const; + + /** position along depth direction: */ + double xDepth() const; + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + void xEta(const double eta); + + void xPhi(const double phi); + + void xDepth(const double xDepth); + + // addition of positions: + NeutrinoLocalPosition &operator+=(const NeutrinoLocalPosition &position); + + // so we can go from NeutrinoLocalPosition to Trk::LocalPosition + operator Amg::Vector2D(void) const; + + // scaling: + NeutrinoLocalPosition &operator*=(const double factor); + NeutrinoLocalPosition &operator/=(const double factor); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// + + private: + double m_eta; //!< position along eta direction + double m_phi; //!< position along phi direction + double m_xDepth; //!< position along depth direction + }; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// +inline NeutrinoLocalPosition::~NeutrinoLocalPosition() +{} + +inline double NeutrinoLocalPosition::xEta() const +{ + return m_eta; +} + +inline double NeutrinoLocalPosition::xPhi() const +{ + return m_phi; +} + +inline double NeutrinoLocalPosition::xDepth() const +{ + return m_xDepth; +} + +inline double NeutrinoLocalPosition::r() const +{ + return std::sqrt(m_eta * m_eta + m_phi * m_phi); +} + +inline double NeutrinoLocalPosition::phi() const +{ + return std::atan2(m_phi, m_eta); +} + +inline void NeutrinoLocalPosition::xEta(const double x) +{ + m_eta=x; +} + +inline void NeutrinoLocalPosition::xPhi(const double y) +{ + m_phi=y; +} + +inline void NeutrinoLocalPosition::xDepth(const double xDepth) +{ + m_xDepth=xDepth; +} + +/////////////////////////////////////////////////////////////////// +// Binary operators: +/////////////////////////////////////////////////////////////////// +NeutrinoLocalPosition operator+(const NeutrinoLocalPosition &position1, + const NeutrinoLocalPosition &position2); + +NeutrinoLocalPosition operator*(const NeutrinoLocalPosition &position,const double factor); + +inline NeutrinoLocalPosition operator*(const double factor,const NeutrinoLocalPosition &position) +{ + return position*factor; +} + +NeutrinoLocalPosition operator/(const NeutrinoLocalPosition &position,const double factor); + +} // namespace NeutrinoDD + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINOLOCALPOSITION_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.h new file mode 100644 index 00000000..333a0202 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoNumerology.h +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// + + +#ifndef NEUTRINOREADOUTGEOMETRY_NEUTRINONUMEROLOGY_H +#define NEUTRINOREADOUTGEOMETRY_NEUTRINONUMEROLOGY_H + +#include <set> + +namespace NeutrinoDD { + + /** @class NeutrinoNumerology + + Class to extract numerology for emulsion. For example number of modules, bases, films, etc. + + @author Grant Gorfine + */ + + class NeutrinoNumerology { + + + public: + + /** Constructor: */ + NeutrinoNumerology(); + + // Accessors: + + /** Number of modules */ + int numModules() const; + + /** Number of bases in a module */ + int numBasesPerModule() const; + + /** Number of films per base */ + int numFilmsPerBase() const; + + const std::set<int>& moduleIds() const; + + // Check presence of station + /** Check if station exists */ + bool useModule(int module) const; + + + // Modifiers: + void addModule(int id); + void setNumBasesPerModule(int bases); + void setNumFilmsPerBase(int films); + + private: + + int m_numBasesPerModule; + int m_numFilmsPerBase; + std::set<int> m_moduleIds; + }; + +}// End namespace + +#include "NeutrinoNumerology.icc" + +#endif // NEUTRINOREADOUTGEOMETRY_NEUTRINONUMEROLOGY_H diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.icc b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.icc new file mode 100644 index 00000000..d0647996 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/NeutrinoNumerology.icc @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +namespace NeutrinoDD { + + +inline int NeutrinoNumerology::numModules() const +{ + return m_moduleIds.size(); +} + +inline int NeutrinoNumerology::numBasesPerModule() const +{ + return m_numBasesPerModule; +} + +inline int NeutrinoNumerology::numFilmsPerBase() const +{ + return m_numFilmsPerBase; +} + +inline bool NeutrinoNumerology::useModule(int module) const +{ + return (m_moduleIds.count(module) > 0); +} + +inline const std::set<int>& NeutrinoNumerology::moduleIds() const +{ + return m_moduleIds; +} + +} // End namespace diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/Version.h b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/Version.h new file mode 100644 index 00000000..85ba12e4 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/NeutrinoReadoutGeometry/Version.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//////////////////////////////////////////////////////////// +// Version.h +//////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +//////////////////////////////////////////////////////////// + +#ifndef NEUTRINOREADOUTGEOMETRY_VERSION +#define NEUTRINOREADOUTGEOMETRY_VERSION + +#include <string> + +namespace NeutrinoDD { + + /** @class Version + + Class to hold version information consisting of tag, name layout and description as strings, + such as their integer regpresentation in the major-minor-tag scheme + */ + + class Version { + + public: + + /** Constructor. */ + Version(const std::string & tag, + const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch); + + /** Constructor. DEPRECATED */ + Version(const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch); + + /** Empty Constructor */ + Version(); + + /** Version tag */ + const std::string & tag() const; + + /** Version label */ + const std::string & name() const; + + /** Layout (eg Initial, Final, TestBeam) */ + const std::string & layout() const; + + /** Description or comment. */ + const std::string & description() const; + + /** Major version number */ + int majorNum() const; + + /** Minor version number */ + int minorNum() const; + + /** Patch version number */ + int patchNum() const; + + /** Print out version number (eg. 2.00.00) */ + std::string versionNumber() const; + + /** Full Description + For example, + Version: SCT-DC1-00, Name: DC1, Layout: Final, Code Version: 2.00.00, Description: DC1 Geometry */ + std::string fullDescription() const; + + + private: + + std::string m_tag; + std::string m_name; + std::string m_layout; + std::string m_description; + int m_major; + int m_minor; + int m_patch; + }; + +} // namespace NeutrinoDD + +#endif // NEUTRINOREADOUTGEOMETRY_VERSION diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/EmulsionDetectorManager.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/EmulsionDetectorManager.cxx new file mode 100644 index 00000000..b5009b6d --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/EmulsionDetectorManager.cxx @@ -0,0 +1,350 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" + +#include "AthenaBaseComps/AthMsgStreamMacros.h" +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" +#include "Identifier/Identifier.h" +#include "Identifier/IdentifierHash.h" +#include "NeutrinoIdentifier/EmulsionID.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/ExtendedAlignableTransform.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" +#include "StoreGate/StoreGateSvc.h" + +#include <iostream> + +namespace NeutrinoDD { + + const int FIRST_HIGHER_LEVEL = 1; + + EmulsionDetectorManager::EmulsionDetectorManager( StoreGateSvc* detStore ) + : NeutrinoDetectorManager(detStore, "Emulsion"), + m_idHelper(0), + m_isLogical(false) // Change to true to change the definition of local module corrections + { + // + // Initialized the Identifier helper. + // + StatusCode sc = detStore->retrieve(m_idHelper, "EmulsionID"); + if (sc.isFailure()) { + ATH_MSG_ERROR("Could not retrieve Emulsion id helper"); + } + // Initialize the collections. + if (m_idHelper) { + m_elementCollection.resize(m_idHelper->film_hash_max()); + m_alignableTransforms.resize(m_idHelper->film_hash_max()); + // m_moduleAlignableTransforms.resize(m_idHelper->film_hash_max()); + } + } + + + + EmulsionDetectorManager::~EmulsionDetectorManager() + { + // Clean up + for (size_t i=0; i < m_volume.size(); i++) { + m_volume[i]->unref(); + } + + for (size_t j=0; j < m_higherAlignableTransforms.size(); j++){ + AlignableTransformMap::iterator iterMap; + for (iterMap = m_higherAlignableTransforms[j].begin(); + iterMap != m_higherAlignableTransforms[j].end(); + ++iterMap) { + delete iterMap->second; + } + } + + for (size_t k=0; k < m_alignableTransforms.size(); k++){ + delete m_alignableTransforms[k]; + } + + // for (size_t l=0; l < m_moduleAlignableTransforms.size(); l++){ + // delete m_moduleAlignableTransforms[l]; + // } + } + + unsigned int EmulsionDetectorManager::getNumTreeTops() const + { + return m_volume.size(); + } + + PVConstLink EmulsionDetectorManager::getTreeTop(unsigned int i) const + { + return m_volume[i]; + } + + void EmulsionDetectorManager::addTreeTop(PVLink vol){ + vol->ref(); + m_volume.push_back(vol); + } + + + NeutrinoDetectorElement* EmulsionDetectorManager::getDetectorElement(const Identifier & id) const + { + // NB the id helpers implementation for getting a hash is not optimal. + // Essentially does a binary search. + // Make sure it is a wafer Id + // Identifier waferId = m_idHelper->film_id(id); + Identifier filmId = id; + IdentifierHash idHash = m_idHelper->film_hash(filmId); + if (idHash.is_valid()) { + return m_elementCollection[idHash]; + } else { + return 0; + } + } + + NeutrinoDetectorElement* EmulsionDetectorManager::getDetectorElement(const IdentifierHash & idHash) const + { + return m_elementCollection[idHash]; + } + + NeutrinoDetectorElement* EmulsionDetectorManager::getDetectorElement(int module, int base, int film) const + { + return getDetectorElement(m_idHelper->film_id(module, base, film)); + } + + const NeutrinoDetectorElementCollection* EmulsionDetectorManager::getDetectorElementCollection() const + { + return &m_elementCollection; + } + + NeutrinoDetectorElementCollection::const_iterator EmulsionDetectorManager::getDetectorElementBegin() const + { + return m_elementCollection.begin(); + } + + NeutrinoDetectorElementCollection::const_iterator EmulsionDetectorManager::getDetectorElementEnd() const + { + return m_elementCollection.end(); + } + + + void EmulsionDetectorManager::addDetectorElement(NeutrinoDetectorElement * element) + { + IdentifierHash idHash = element->identifyHash(); + if (idHash >= m_elementCollection.size()) + throw std::runtime_error("EmulsionDetectorManager: Error adding detector element."); + m_elementCollection[idHash] = element; + } + + void EmulsionDetectorManager::initNeighbours() + { + NeutrinoDetectorElementCollection::iterator iter; + + // Loop over all elements and set the neighbours + for (iter = m_elementCollection.begin(); iter != m_elementCollection.end(); ++iter){ + + NeutrinoDetectorElement * element = *iter; + if (element) { + + IdentifierHash idHash = element->identifyHash(); + IdentifierHash idHashOther; + + int result; + // If no neighbour, result != 0 in which case we leave neighbour as null + result = m_idHelper->get_next_in_z(idHash, idHashOther); + if (result==0) element->setNextInZ(m_elementCollection[idHashOther]); + + result = m_idHelper->get_prev_in_z(idHash, idHashOther); + if (result==0) element->setPrevInZ(m_elementCollection[idHashOther]); + } + } + } + + const EmulsionID* EmulsionDetectorManager::getIdHelper() const + { + return m_idHelper; + } + + + bool EmulsionDetectorManager::setAlignableTransformDelta(int level, + const Identifier & id, + const Amg::Transform3D & delta, + FrameType frame, + GeoVAlignmentStore* alignStore) const + { + + if (level == 0) { // 0 - At the element level + + // We retrieve it via a hashId. + IdentifierHash idHash = m_idHelper->film_hash(id); + if (!idHash.is_valid()) return false; + + if (frame == NeutrinoDD::global) { // global shift + // Its a global transform + return setAlignableTransformGlobalDelta(m_alignableTransforms[idHash], delta, alignStore); + + } else if (frame == NeutrinoDD::local) { // local shift + + NeutrinoDetectorElement * element = m_elementCollection[idHash]; + if (!element) return false; + + + // Its a local transform + //See header file for definition of m_isLogical + if( m_isLogical ){ + //Ensure cache is up to date and use the alignment corrected local to global transform + element->setCache(); + return setAlignableTransformLocalDelta(m_alignableTransforms[idHash], element->transform(), delta, alignStore); + } else + //Use default local to global transform + return setAlignableTransformLocalDelta(m_alignableTransforms[idHash], element->defTransform(), delta, alignStore); + + } else { + // other not supported + ATH_MSG_WARNING("Frames other than global or local are not supported."); + return false; + } + } else { // higher level + if (frame != NeutrinoDD::global) { + ATH_MSG_WARNING("Non global shift at higher levels is not supported."); + return false; + } + + int index = level - FIRST_HIGHER_LEVEL; // level 0 is treated separately. + if (index >= static_cast<int>(m_higherAlignableTransforms.size())) return false; + + // We retrieve it from a map. + AlignableTransformMap::const_iterator iter; + iter = m_higherAlignableTransforms[index].find(id); + if (iter == m_higherAlignableTransforms[index].end()) return false; + + // Its a global transform + return setAlignableTransformGlobalDelta(iter->second, delta, alignStore); + } + } + + void EmulsionDetectorManager::addAlignableTransform (int level, + const Identifier & id, + GeoAlignableTransform *transform, + const GeoVPhysVol * child) + { + if (m_idHelper) { + + const GeoVFullPhysVol * childFPV = dynamic_cast<const GeoVFullPhysVol *>(child); + if (!childFPV) { + ATH_MSG_ERROR("Child of alignable transform is not a full physical volume"); + } else { + addAlignableTransform (level, id, transform, childFPV); + } + } + } + + void EmulsionDetectorManager::addAlignableTransform (int level, + const Identifier & id, + GeoAlignableTransform *transform, + const GeoVFullPhysVol * child) + { + if (m_idHelper) { + if (level == 0) { + // Element + IdentifierHash idHash = m_idHelper->film_hash(id); + if (idHash.is_valid()) { + m_alignableTransforms[idHash]= new ExtendedAlignableTransform(transform, child); + } + } else { + // Higher levels are saved in a map. NB level=0 is treated above. + int index = level - FIRST_HIGHER_LEVEL; // level 0 is treated separately. + if (index >= static_cast<int>(m_higherAlignableTransforms.size())) m_higherAlignableTransforms.resize(index+1); + m_higherAlignableTransforms[index][id] = new ExtendedAlignableTransform(transform, child); + } + } + } + + bool + EmulsionDetectorManager::identifierBelongs(const Identifier & id) const + { + return getIdHelper()->is_emulsion(id); + } + + + const NeutrinoDetectorDesign* EmulsionDetectorManager::getEmulsionDesign() const + { + return dynamic_cast<const NeutrinoDetectorDesign *>(getDesign()); + } + + // New global alignment folders + bool EmulsionDetectorManager::processGlobalAlignment(const std::string & key, int level, FrameType frame, + const CondAttrListCollection* obj, GeoVAlignmentStore* alignStore) const + { + ATH_MSG_INFO("Processing new global alignment containers with key " << key << " in the " << frame << " frame at level "); + + const CondAttrListCollection* atrlistcol=obj; + if(atrlistcol==nullptr and m_detStore->retrieve(atrlistcol,key)!=StatusCode::SUCCESS) { + ATH_MSG_INFO("Cannot find new global align Container for key " + << key << " - no new global alignment "); + return false; + } + + bool alignmentChange = false; + Identifier ident=Identifier(); + + // loop over objects in collection + for (CondAttrListCollection::const_iterator citr=atrlistcol->begin(); citr!=atrlistcol->end();++citr) { + const coral::AttributeList& atrlist=citr->second; + // SCT manager, therefore ignore all that is not a SCT Identifier + // if (atrlist["det"].data<int>()!=2) continue; + ATH_MSG_FATAL("Using invalid alignment data for Emulsion detector (correct treatment not yet implemented"); + ident = getIdHelper()->film_id(atrlist["module"].data<int>(), + atrlist["base"].data<int>(), + atrlist["film"].data<int>()); // The last is the module side which is at this ident-level always the 0-side + + // construct new transform + // Order of rotations is defined as around z, then y, then x. + Amg::Translation3D newtranslation(atrlist["Tx"].data<float>(),atrlist["Ty"].data<float>(),atrlist["Tz"].data<float>()); + Amg::Transform3D newtrans = newtranslation * Amg::RotationMatrix3D::Identity(); + newtrans *= Amg::AngleAxis3D(atrlist["Rz"].data<float>()*CLHEP::mrad, Amg::Vector3D(0.,0.,1.)); + newtrans *= Amg::AngleAxis3D(atrlist["Ry"].data<float>()*CLHEP::mrad, Amg::Vector3D(0.,1.,0.)); + newtrans *= Amg::AngleAxis3D(atrlist["Rx"].data<float>()*CLHEP::mrad, Amg::Vector3D(1.,0.,0.)); + + ATH_MSG_DEBUG("New global DB -- channel: " << citr->first + << " ,det: " << atrlist["det"].data<int>() + << " ,bec: " << atrlist["bec"].data<int>() + << " ,layer: " << atrlist["layer"].data<int>() + << " ,ring: " << atrlist["ring"].data<int>() + << " ,sector: " << atrlist["sector"].data<int>() + << " ,Tx: " << atrlist["Tx"].data<float>() + << " ,Ty: " << atrlist["Ty"].data<float>() + << " ,Tz: " << atrlist["Tz"].data<float>() + << " ,Rx: " << atrlist["Rx"].data<float>() + << " ,Ry: " << atrlist["Ry"].data<float>() + << " ,Rz: " << atrlist["Rz"].data<float>()); + + // Set the new transform; Will replace existing one with updated transform + bool status = setAlignableTransformDelta(level, + ident, + newtrans, + frame, + alignStore); + + if (!status) { + ATH_MSG_DEBUG("Cannot set AlignableTransform for identifier." + << getIdHelper()->show_to_string(ident) + << " at level " << level << " for new global DB "); + } + + alignmentChange = (alignmentChange || status); + } + return alignmentChange; + } + +bool EmulsionDetectorManager::processSpecialAlignment( + const std::string &, NeutrinoDD::AlignFolderType) const { + return false; +} + +bool EmulsionDetectorManager::processSpecialAlignment(const std::string& /*key*/, + const CondAttrListCollection* /*obj*/, + GeoVAlignmentStore* /*alignStore*/) const { + return false; + +} + +} // namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoCommonItems.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoCommonItems.cxx new file mode 100644 index 00000000..87ec9c5b --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoCommonItems.cxx @@ -0,0 +1,22 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" + +namespace NeutrinoDD { + +NeutrinoCommonItems::NeutrinoCommonItems(const FaserDetectorID* const idHelper) + : m_msg("NeutrinoDetectorElement"), + m_idHelper(idHelper), + m_mutex{} +{} + +// void +// SiCommonItems::setSolenoidFrame(const HepGeom::Transform3D & transform) const +// { +// std::lock_guard<std::mutex> lock{m_mutex}; +// m_solenoidFrame = transform; +// } + +} // End namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorDesign.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorDesign.cxx new file mode 100644 index 00000000..8461f494 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorDesign.cxx @@ -0,0 +1,99 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoDetectorDesign.cxx +// Implementation file for class NeutrinoDetectorDesign +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 3.0 05/05/2001 David Calvet +// Modified: Grant Gorfine +// Modified: Dave Casper +/////////////////////////////////////////////////////////////////// + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" +#include "NeutrinoReadoutGeometry/NeutrinoIntersect.h" +#include "NeutrinoReadoutGeometry/NeutrinoLocalPosition.h" +#include "TrkSurfaces/RectangleBounds.h" + +namespace NeutrinoDD { +// Constructor: +NeutrinoDetectorDesign::NeutrinoDetectorDesign( const double width, + const double height, + const double thickness ) : + m_thickness(thickness), + m_width{width}, + m_height{height}, + m_phiAxis(Axis::xAxis), + m_etaAxis(Axis::yAxis), + m_depthAxis(Axis::zAxis) +{ + m_bounds = new Trk::RectangleBounds(0.5*width, 0.5*height); +} + + +// Destructor: +NeutrinoDetectorDesign::~NeutrinoDetectorDesign() { + if (m_bounds != nullptr) delete m_bounds; +} + +NeutrinoIntersect NeutrinoDetectorDesign::inDetector(const NeutrinoLocalPosition &localPosition, + double xTol, double yTol) const { + double xDist = 0; + double yDist = 0; + + distanceToDetectorEdge(localPosition, xDist, yDist); + + NeutrinoIntersect state; + + if (xDist < -xTol || yDist < -yTol) { + state.setOut(); + return state; + } + + if (xDist > xTol && yDist > yTol) { + state.setIn(); + return state; + } + + // Near boundary. + state.setNearBoundary(); + return state; +} + +DetectorShape NeutrinoDetectorDesign::shape() const { + // Default is Box. + return NeutrinoDD::Box; +} + +const Trk::SurfaceBounds & +NeutrinoDetectorDesign::bounds() const +{ + return *m_bounds; +} + +// Returns distance to nearest detector edge +// +ve = inside +// -ve = outside +void +NeutrinoDetectorDesign::distanceToDetectorEdge(const NeutrinoLocalPosition & localPosition, + double & etaDist, double & phiDist) const +{ + // As the calculation is symmetric around 0,0 we only have to test it for one side. + double xEta = abs(localPosition.xEta()); + double xPhi = abs(localPosition.xPhi()); + + double xEtaEdge = 0.5 * height(); + double xPhiEdge = 0.5 * width(); + + // Distance to top/bottom + etaDist = xEtaEdge - xEta; + + // Distance to right/left edge + phiDist = xPhiEdge - xPhi; + +} + +} // namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElement.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElement.cxx new file mode 100644 index 00000000..8588ea23 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElement.cxx @@ -0,0 +1,930 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @file NeutrinoDetectorElement.cxx + * Implementation file for class NeutrinoDetectorElement + * @author Grant Gorfine + * Based on version developed by David Calvet. +**/ + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" + +#include "NeutrinoIdentifier/EmulsionID.h" + +#include "GeoModelKernel/GeoVFullPhysVol.h" +#include "GeoModelFaserUtilities/GeoAlignmentStore.h" +#include "FaserDetDescr/FaserDetectorID.h" + +#include "CLHEP/Geometry/Point3D.h" +#include "CLHEP/Geometry/Vector3D.h" +#include "CLHEP/Vector/ThreeVector.h" +#include "CLHEP/Units/PhysicalConstants.h" // for M_PI +#include "CLHEP/Units/SystemOfUnits.h" + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorDesign.h" + + +#include "NeutrinoReadoutGeometry/NeutrinoCommonItems.h" + +#include "TrkSurfaces/PlaneSurface.h" +#include "TrkSurfaces/SurfaceBounds.h" + +#include <cmath> +#include <cassert> +#include <limits> + +namespace NeutrinoDD { +using Trk::distEta; +using Trk::distPhi; +// using Trk::distDepth; + +// Constructor with parameters: +NeutrinoDetectorElement::NeutrinoDetectorElement(const Identifier &id, + const NeutrinoDetectorDesign *design, + const GeoVFullPhysVol *geophysvol, + const NeutrinoCommonItems * commonItems, + const GeoAlignmentStore* geoAlignStore) : + TrkDetElementBase(geophysvol), + m_id(id), + m_idHash(64000), + m_design(design), + m_commonItems(commonItems), + m_prevInZ(nullptr), + m_nextInZ(nullptr), + m_cacheValid(false), + m_firstTime(true), + m_isEmulsion(true), + m_mutex(), + m_surface{}, + m_surfaces{}, + m_geoAlignStore(geoAlignStore) +{ + //The following are fixes for coverity bug 11955, uninitialized scalars: + const bool boolDefault(true); + m_depthDirection=boolDefault; + m_phiDirection=boolDefault; + m_etaDirection=boolDefault; + const double defaultMin(std::numeric_limits<double>::max()); + const double defaultMax(std::numeric_limits<double>::lowest()); + m_minX=defaultMin; + m_maxX=defaultMax; + m_minY=defaultMin; + m_maxY=defaultMax; + m_minZ=defaultMin; + m_maxZ=defaultMax; + m_hitEta = m_design->etaAxis(); + m_hitPhi = m_design->phiAxis(); + m_hitDepth = m_design->depthAxis(); + /// + + commonConstructor(); +} + +void +NeutrinoDetectorElement::commonConstructor() +{ + if (!m_id.is_valid()) throw std::runtime_error("NeutrinoDetectorElement: Invalid identifier"); + + // Set booleans for wether we are veto/trigger/preshower + m_isEmulsion = getIdHelper()->is_emulsion(m_id); + if (!m_isEmulsion) + { + if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Element id is not for emulsion" << endmsg; + } + + // // Set IdHash. + const EmulsionID* emulsionId = dynamic_cast<const EmulsionID* >(getIdHelper()); + m_idHash = emulsionId->film_hash(m_id); + + if (!m_idHash.is_valid()) throw std::runtime_error("NeutrinoDetectorElement: Unable to set IdentifierHash"); + + // Increase the reference count of the NeutrinoDetectorDesign objects. + m_design->ref(); + + // Increase the reference count of the NeutrinoCommonItems objects. + m_commonItems->ref(); + + // Should we reference count the geophysvol as well? + +} + + +// Destructor: +NeutrinoDetectorElement::~NeutrinoDetectorElement() +{ + // The design is reference counted so that it will not be deleted until the last element is deleted. + m_design->unref(); + + m_commonItems->unref(); +} + +bool NeutrinoDetectorElement::isEmulsion() const +{ + return m_isEmulsion; +} + + +void +NeutrinoDetectorElement::updateCache() const +{ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + + bool firstTimeTmp = m_firstTime; + m_firstTime = false; + m_cacheValid = true; + + const GeoTrf::Transform3D & geoTransform = transformHit(); + + HepGeom::Point3D<double> centerGeoModel(0., 0., 0.); + m_centerCLHEP = Amg::EigenTransformToCLHEP(geoTransform) * centerGeoModel; + m_center = Amg::Vector3D(m_centerCLHEP[0],m_centerCLHEP[1],m_centerCLHEP[2]); + + // (In ATLAS:) + // Determine directions depth, eta and phi axis in reconstruction local frame + // ie depth away from interaction point + // phi in direction of increasing phi + // eta in direction of increasing z in barrel, and increasing r in endcap + // + // depthAxis, phiAxis, and etaAxis are defined to be x,y,z respectively for all detectors for hit local frame. + // depthAxis, phiAxis, and etaAxis are defined to be z,x,y respectively for all detectors for reco local frame. + // + // In FASER: + // depthAxis, phiAxis and etaAxis are defined to be z,x,y respectively for all detectors in hit local AND reco local frames + // This is accomplished simply by the fixed initialization of m_hitEta, m_hitPhi and m_hitDepth in NeutrinoDetectorDesign + // + + static const HepGeom::Vector3D<double> localAxes[3] = { + HepGeom::Vector3D<double>(1,0,0), + HepGeom::Vector3D<double>(0,1,0), + HepGeom::Vector3D<double>(0,0,1) + }; + + static const HepGeom::Vector3D<double> & localRecoPhiAxis = localAxes[distPhi]; // Defined to be same as x axis + static const HepGeom::Vector3D<double> & localRecoEtaAxis = localAxes[distEta]; // Defined to be same as y axis + static const HepGeom::Vector3D<double> & localRecoDepthAxis = localAxes[distDepth]; // Defined to be same as z axis + + // We only need to calculate the rough orientation once. + //For it to change would require extreme unrealistic misalignment changes. + if (firstTimeTmp) { + // Determine the unit vectors in global frame + + const HepGeom::Vector3D<double> &geoModelPhiAxis = localAxes[m_hitPhi]; + const HepGeom::Vector3D<double> &geoModelEtaAxis = localAxes[m_hitEta]; + const HepGeom::Vector3D<double> &geoModelDepthAxis = localAxes[m_hitDepth]; + + HepGeom::Vector3D<double> globalDepthAxis(Amg::EigenTransformToCLHEP(geoTransform) * geoModelDepthAxis); + HepGeom::Vector3D<double> globalPhiAxis(Amg::EigenTransformToCLHEP(geoTransform) * geoModelPhiAxis); + HepGeom::Vector3D<double> globalEtaAxis(Amg::EigenTransformToCLHEP(geoTransform) * geoModelEtaAxis); + + // unit radial vector + // HepGeom::Vector3D<double> unitR(m_center.x(), m_center.y(), 0.); + + // unitR.setMag(1.); + + // HepGeom::Vector3D<double> nominalEta; + // HepGeom::Vector3D<double> nominalNormal; + // HepGeom::Vector3D<double> nominalPhi(-unitR.y(), unitR.x(), 0); + + // In Barrel like geometry, the etaAxis is along increasing z, and normal is in increasing radial direction. + // In Endcap like geometry, the etaAxis is along increasing r, and normal is in decreasing z direction, + // We base whether it is barrel like or endcap like by the orientation of the local z axis of the + // the element. This allows the use of endcap identifiers in a TB setup. A warning message is issued however if + // the orientation and identifier are not consistent (ie a barrel like orientation with an endcap identifier). + + // bool barrelLike = true; + // nominalEta.setZ(1); + // if (std::abs(globalEtaAxis.dot(nominalEta)) < 0.5) { // Check that it is in roughly the right direction. + // barrelLike = false; + // } + + // if (isBarrel() && !barrelLike) { + // if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Element has endcap like orientation with barrel identifier." + // << endmsg; + // } else if (!isBarrel() && barrelLike) { + // if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Element has barrel like orientation with endcap identifier." + // << endmsg; + // } + + // if (barrelLike) { + // nominalEta.setZ(1); + // nominalNormal = unitR; + // } else { // endcap like + // nominalNormal.setZ(-1); + // nominalEta = unitR; + // } + + // Determine if axes are to have their directions swapped. + + // + // Depth axis. + // + // double depthDir = globalDepthAxis.dot(nominalNormal); + // m_depthDirection = true; + // if (depthDir < 0) { + // if (m_design->depthSymmetric()) { + // m_depthDirection = false; + // } else { + // if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Unable to swap local depth axis." << endmsg; + // } + // } + // if (std::abs(depthDir) < 0.5) { // Check that it is in roughly the right direction. + // msg(MSG::ERROR) << "Orientation of local depth axis does not follow correct convention." << endmsg; + // // throw std::runtime_error("Orientation of local depth axis does not follow correct convention."); + // m_depthDirection = true; // Don't swap. + // } + + // + // Phi axis (unclear how to handle for FASER - never swap for now) + // + // double phiDir = globalPhiAxis.dot(nominalPhi); + // m_phiDirection = true; + // if (phiDir < 0) { + // if (m_design->phiSymmetric()) { + // m_phiDirection = false; + // } else { + // if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Unable to swap local xPhi axis." << endmsg; + // } + // } + + // if (std::abs(phiDir) < 0.5) { // Check that it is in roughly the right direction. + // msg(MSG::ERROR) << "Orientation of local xPhi axis does not follow correct convention." << endmsg; + // // throw std::runtime_error("Orientation of local xPhi axis does not follow correct convention."); + // m_phiDirection = true; // Don't swap. + // } + + // + // Eta axis (unclear how to handle for FASER - never swap for now) + // + // double etaDir = globalEtaAxis.dot(nominalEta); + // m_etaDirection = true; + // if (etaDir < 0) { + // if (m_design->etaSymmetric()) { + // m_etaDirection = false; + // } else { + // if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Unable to swap local xEta axis." << endmsg; + // } + // } + // if (std::abs(etaDir) < 0.5) { // Check that it is in roughly the right direction. + // msg(MSG::ERROR) << "Orientation of local xEta axis does not follow correct convention." << endmsg; + // // throw std::runtime_error("Orientation of local xEta axis does not follow correct convention."); + // m_etaDirection = true; // Don't swap + // } + + } // end if (firstTimeTmp) + + + + m_transformCLHEP = Amg::EigenTransformToCLHEP(geoTransform) * recoToHitTransform(); + //m_transform = m_commonItems->solenoidFrame() * geoTransform * recoToHitTransform(); + m_transform = Amg::CLHEPTransformToEigen(m_transformCLHEP); + + // Check that local frame is right-handed. (ie transform has no reflection) + // This can be done by checking that the determinant is >0. + // if (firstTimeTmp) { // Only need to check this once. + // HepGeom::Transform3D & t = m_transformCLHEP; + // double det = t(0,0) * (t(1,1)*t(2,2) - t(1,2)*t(2,1)) - + // t(0,1) * (t(1,0)*t(2,2) - t(1,2)*t(2,0)) + + // t(0,2) * (t(1,0)*t(2,1) - t(1,1)*t(2,0)); + // if (det < 0) { + // if (m_design->depthSymmetric()) { + // if (msgLvl(MSG::DEBUG)) + // msg(MSG::DEBUG) << "Local frame is left-handed, Swapping depth axis to make it right handed." + // << endmsg; + // m_depthDirection = !m_depthDirection; + // m_transformCLHEP = Amg::EigenTransformToCLHEP(geoTransform) * recoToHitTransform(); + // m_transform = Amg::CLHEPTransformToEigen(m_transformCLHEP); + //m_transform = m_commonItems->solenoidFrame() * geoTransform * recoToHitTransform(); + // } else { + // if (msgLvl(MSG::WARNING)) msg(MSG::WARNING) << "Local frame is left-handed." << endmsg; + // } + // } + // } + + + // Initialize various cached members + // The unit vectors + HepGeom::Vector3D<double> normalCLHEP = m_transformCLHEP * localRecoDepthAxis; + m_normal = Amg::Vector3D( normalCLHEP[0], normalCLHEP[1], normalCLHEP[2]); + + + m_phiAxisCLHEP = m_transformCLHEP * localRecoPhiAxis; + m_etaAxisCLHEP = m_transformCLHEP * localRecoEtaAxis; + + m_phiAxis = Amg::Vector3D(m_phiAxisCLHEP[0],m_phiAxisCLHEP[1],m_phiAxisCLHEP[2]); + m_etaAxis = Amg::Vector3D(m_etaAxisCLHEP[0],m_etaAxisCLHEP[1],m_etaAxisCLHEP[2]); + + getExtent(m_minX, m_maxX, m_minY, m_maxY, m_minZ, m_maxZ); + + + // Determin isStereo +// if (firstTimeTmp) { +// if (isSCT() && m_otherSide) { +// double sinStereoThis = std::abs(sinStereo()); +// double sinStereoOther = std::abs(m_otherSide->sinStereo()); +// if (sinStereoThis == sinStereoOther) { +// // If they happend to be equal then set side0 as axial and side1 as stereo. +// const SCT_ID* sctId = dynamic_cast<const SCT_ID *>(getIdHelper()); +// if (sctId) { +// int side = sctId->side(m_id); +// m_isStereo = (side == 1); +// } +// } else { +// // set the stereo side as the one with largest absolute sinStereo. +// m_isStereo = (sinStereoThis > sinStereoOther); +// } +// } else { +// m_isStereo = false; +// } +// } +} + + +const GeoTrf::Transform3D & +NeutrinoDetectorElement::transformHit() const +{ + if (m_geoAlignStore) { + const GeoTrf::Transform3D* ptrXf = m_geoAlignStore->getAbsPosition(getMaterialGeom()); + if (ptrXf) return *ptrXf; + } + return getMaterialGeom()->getAbsoluteTransform(); +} + +const Amg::Transform3D & +NeutrinoDetectorElement::transform() const +{ + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_transform; +} + +const HepGeom::Transform3D & +NeutrinoDetectorElement::transformCLHEP() const +{ + //stuff to get the CLHEP version of the local to global transform. + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_transformCLHEP; +} + +const HepGeom::Transform3D +NeutrinoDetectorElement::defTransformCLHEP() const +{ + if (m_geoAlignStore) { + const GeoTrf::Transform3D* ptrXf = m_geoAlignStore->getDefAbsPosition(getMaterialGeom()); + if (ptrXf) return Amg::EigenTransformToCLHEP(*ptrXf) * recoToHitTransform(); + } + return Amg::EigenTransformToCLHEP(getMaterialGeom()->getDefAbsoluteTransform()) * recoToHitTransform(); +} + +const Amg::Transform3D +NeutrinoDetectorElement::defTransform() const +{ + HepGeom::Transform3D tmpTransform = defTransformCLHEP(); + return Amg::CLHEPTransformToEigen(tmpTransform); +} + +const HepGeom::Transform3D +NeutrinoDetectorElement::recoToHitTransform() const +{ + + // Determine the reconstruction local (LocalPosition) to global transform. + + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (m_firstTime) updateCache(); + + // global = transform * recoLocal + // = transformHit * hitLocal + // = transformHit * recoToHitTransform * recoLocal + // + // (In ATLAS:) recoToHitTransform takes recoLocal to hitLocal + // x,y,z -> y,z,x + // equiv to a rotation around Y of 90 deg followed by a rotation around X of 90deg + // + // recoToHit is static as it needs to be calculated once only. + // We use the HepGeom::Transform3D constructor which takes one coordinates system to another where the + // coordinate system is defined by it center and two axes. + // distPhi, distEta are the reco local axes and hitPhi and hitEta are the hit local axes. + // It assume phi, eta, depth makes a right handed system which is the case. + static const HepGeom::Vector3D<double> localAxes[3] = { + HepGeom::Vector3D<double>(1,0,0), + HepGeom::Vector3D<double>(0,1,0), + HepGeom::Vector3D<double>(0,0,1) + }; + //static + + const HepGeom::Transform3D recoToHit(HepGeom::Point3D<double>(0,0,0),localAxes[distPhi],localAxes[distEta], + HepGeom::Point3D<double>(0,0,0),localAxes[m_hitPhi],localAxes[m_hitEta]); + + // Swap direction of axis as appropriate + CLHEP::Hep3Vector scale(1,1,1); + if (!m_phiDirection) scale[distPhi] = -1; + if (!m_etaDirection) scale[distEta] = -1; + if (!m_depthDirection) scale[distDepth] = -1; + return recoToHit * HepGeom::Scale3D(scale[0],scale[1],scale[2]); +} + +const Amg::Transform3D & +NeutrinoDetectorElement::filmTransform() const +{ + return transform(); + // return (isModuleFrame()) ? transform() : m_otherSide->transform(); +} + + Amg::Transform3D + NeutrinoDetectorElement::defFilmTransform() const +{ + return defTransform(); +// return (isModuleFrame()) ? defTransform() : m_otherSide->defTransform(); +} + + +// Take a transform in the local reconstruction and return it in the module frame +// For a given transform l in frame A. The equivalent transform in frame B is +// B.inverse() * A * l * A.inverse() * B +// Here A is the local to global transform of the element and B is the local to global +// transform of the module. +// If we are already in the module frame then there is nothing to do, we just return the +// transform that is input. Otherwise we use the above formula. +Amg::Transform3D +NeutrinoDetectorElement::localToBaseFrame(const Amg::Transform3D & localTransform) const +{ + // if (isModuleFrame()) { + return localTransform; + // } else { + // return m_otherSide->transform().inverse() * transform() * localTransform * transform().inverse() * m_otherSide->transform(); + // } +} + +Amg::Transform3D +NeutrinoDetectorElement::localToBaseTransform() const +{ + // if (isModuleFrame()) { + return Amg::Transform3D(); // Identity + // } else { + // return m_otherSide->transform().inverse() * transform(); + // } +} + + +// bool +// NeutrinoDetectorElement::isModuleFrame() const +// { +// // The module frame is the axial side. +// // NB isStereo returns false for the pixel and so +// // isModuleFrame is always true for the pixel. + +// return !isStereo(); +// } + + +const Amg::Vector3D & +NeutrinoDetectorElement::center() const +{ + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_center; +} + +const Amg::Vector3D & +NeutrinoDetectorElement::normal() const +{ + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_normal; +} + +const HepGeom::Vector3D<double> & +NeutrinoDetectorElement::etaAxisCLHEP() const +{ + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_etaAxisCLHEP; +} + +const HepGeom::Vector3D<double> & +NeutrinoDetectorElement::phiAxisCLHEP() const +{ + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_phiAxisCLHEP; +} + +const Amg::Vector3D & +NeutrinoDetectorElement::etaAxis() const +{ + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_etaAxis; +} + +const Amg::Vector3D & +NeutrinoDetectorElement::phiAxis() const +{ + if (!m_cacheValid){ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + } + return m_phiAxis; +} + +Amg::Vector2D +NeutrinoDetectorElement::hitLocalToLocal(double xEta, double xPhi) const // Will change order to phi,eta +{ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + if (!m_etaDirection) xEta = -xEta; + if (!m_phiDirection) xPhi = -xPhi; + return Amg::Vector2D(xPhi, xEta); +} + +HepGeom::Point3D<double> +NeutrinoDetectorElement::hitLocalToLocal3D(const HepGeom::Point3D<double> & hitPosition) const +{ + // Equiv to transform().inverse * transformHit() * hitPosition + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + double xDepth = hitPosition[m_hitDepth]; + double xPhi = hitPosition[m_hitPhi]; + double xEta = hitPosition[m_hitEta]; + if (!m_depthDirection) xDepth = -xDepth; + if (!m_phiDirection) xPhi = -xPhi; + if (!m_etaDirection) xEta = -xEta; + return HepGeom::Point3D<double>(xPhi, xEta, xDepth); +} + +Trk::Surface & +NeutrinoDetectorElement::surface() +{ + if (not m_surface) m_surface.set(std::make_unique<Trk::PlaneSurface>(*this)); + return *m_surface; +} + +const Trk::Surface & +NeutrinoDetectorElement::surface() const +{ + if (not m_surface) m_surface.set(std::make_unique<Trk::PlaneSurface>(*this)); + return *m_surface; +} + +const std::vector<const Trk::Surface*>& NeutrinoDetectorElement::surfaces() const +{ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_surfaces.size()) { + // get this surface + m_surfaces.push_back(&surface()); + // get the other side surface + // if (otherSide()) { + // m_surfaces.push_back(&(otherSide()->surface())); + // } + } + // return the surfaces + return m_surfaces; +} + +const Trk::SurfaceBounds & +NeutrinoDetectorElement::bounds() const +{ + return m_design->bounds(); +} + +// Get min/max or r, z,and phi +void NeutrinoDetectorElement::getExtent(double &xMin, double &xMax, + double &yMin, double &yMax, + double &zMin, double &zMax) const +{ + + HepGeom::Point3D<double> corners[4]; + getCorners(corners); + + bool first = true; + + // double phiOffset = 0.; + + double radialShift = 0.; + const HepGeom::Transform3D rShift = HepGeom::TranslateX3D(radialShift);//in local frame, radius is x + + for (int i = 0; i < 4; i++) { + + // if (testDesign) corners[i].transform(rShift); + + HepGeom::Point3D<double> globalPoint = globalPosition(corners[i]); + + // double rPoint = globalPoint.perp(); + double xPoint = globalPoint.x(); + double yPoint = globalPoint.y(); + double zPoint = globalPoint.z(); + // double phiPoint = globalPoint.phi(); + + // Use first point to initializa min/max values. + if (first) { + + // // Put phi in a range so that we are not near -180/+180 division. + // // Do this by adding an offset if phi > 90 CLHEP::deg or < -90 CLHEP::deg. + // // This offset is later removed. + // if (phiPoint < -0.5 * M_PI) { + // phiOffset = -0.5 * M_PI; + // } else if (phiPoint > 0.5 * M_PI) { + // phiOffset = 0.5 * M_PI; + // } + // phiMin = phiMax = phiPoint - phiOffset; + // rMin = rMax = rPoint; + xMin = xMax = xPoint; + yMin = yMax = yPoint; + zMin = zMax = zPoint; + + } else { + // phiPoint -= phiOffset; + // // put phi back in -M_PI < phi < +M_PI range + // if (phiPoint < -M_PI) phiPoint += 2. * M_PI; + // if (phiPoint > M_PI) phiPoint -= 2. * M_PI; + // phiMin = std::min(phiMin, phiPoint); + // phiMax = std::max(phiMax, phiPoint); + // rMin = std::min(rMin, rPoint); + // rMax = std::max(rMax, rPoint); + xMin = std::min(xMin, xPoint); + xMax = std::max(xMax, xPoint); + yMin = std::min(yMin, yPoint); + yMax = std::max(yMax, yPoint); + zMin = std::min(zMin, zPoint); + zMax = std::max(zMax, zPoint); + } + first = false; + } + + // // put phi back in -M_PI < phi < +M_PI range + // phiMin += phiOffset; + // phiMax += phiOffset; + // if (phiMin < -M_PI) phiMin += 2. * M_PI; + // if (phiMin > M_PI) phiMin -= 2. * M_PI; + // if (phiMax < -M_PI) phiMax += 2. * M_PI; + // if (phiMax > M_PI) phiMax -= 2. * M_PI; + +} + + + +// Get eta/phi extent. Returns min/max eta and phi and r (for barrel) +// or z (for endcap) Takes as input the vertex spread in z (+-deltaZ). +// Gets 4 corners of the sensor and calculates eta phi for each corner +// for both +/- vertex spread. The returned phi is between -M_PI and M_PI +// with the direction minPhi to maxPhi always in the positive sense, +// so if the element extends across the -180/180 boundary then minPhi will +// be greater than maxPhi. +// void NeutrinoDetectorElement::getEtaPhiRegion(double deltaZ, double &etaMin, double &etaMax, double &phiMin, +// double &phiMax, double &rz) const +// { +// std::lock_guard<std::recursive_mutex> lock(m_mutex); +// if (!m_cacheValid) updateCache(); + +// HepGeom::Point3D<double> corners[4]; +// getCorners(corners); + +// bool first = true; + +// double phiOffset = 0.; + +// for (int i = 0; i < 4; i++) { +// double etaMinPoint; +// double etaMaxPoint; +// double phiPoint; + +// // Get the eta phi value for this corner. +// getEtaPhiPoint(corners[i], deltaZ, etaMinPoint, etaMaxPoint, phiPoint); + +// if (first) { // Use the first point to initialize the min/max values. + +// // Put phi in a range so that we are not near -180/+180 division. +// // Do this by adding an offset if phi > 90 CLHEP::deg or < -90 CLHEP::deg. +// // This offset is later removed. +// if (phiPoint < -0.5 * M_PI) { +// phiOffset = -0.5 * M_PI; +// } else if (phiPoint > 0.5 * M_PI) { +// phiOffset = 0.5 * M_PI; +// } +// phiMin = phiMax = phiPoint - phiOffset; +// etaMin = etaMinPoint; +// etaMax = etaMaxPoint; +// } else { +// phiPoint -= phiOffset; +// // put phi back in -M_PI < phi < +M_PI range +// if (phiPoint < -M_PI) phiPoint += 2. * M_PI; +// if (phiPoint > M_PI) phiPoint -= 2. * M_PI; +// phiMin = std::min(phiMin, phiPoint); +// phiMax = std::max(phiMax, phiPoint); +// etaMin = std::min(etaMin, etaMinPoint); +// etaMax = std::max(etaMax, etaMaxPoint); +// } +// first = false; +// } + +// // put phi back in -M_PI < phi < +M_PI range +// phiMin += phiOffset; +// phiMax += phiOffset; +// if (phiMin < -M_PI) phiMin += 2. * M_PI; +// if (phiMin > M_PI) phiMin -= 2. * M_PI; +// if (phiMax < -M_PI) phiMax += 2. * M_PI; +// if (phiMax > M_PI) phiMax -= 2. * M_PI; + +// // Calculate rz = r (barrel) or z (endcap) +// // Use center of sensor ((0,0,0) in local coordinates) for determining this. +// // HepGeom::Point3D<double> globalCenter = globalPosition(HepGeom::Point3D<double>(0,0,0)); +// if (isBarrel()) { +// rz = center().perp(); // r +// } else { +// rz = center().z(); // z +// } + +// } + +// Gets eta phi for a point given in local coordinates. deltaZ is specified to +// account for the vertex spread. phi is independent of this vertex +// spread. etaMax will correspond to zMin (-deltaZ) and etaMin will +// correspond to zMax (+deltaZ). +// void NeutrinoDetectorElement::getEtaPhiPoint(const HepGeom::Point3D<double> & point, double deltaZ, +// double &etaMin, double &etaMax, double &phi) const +// { +// // Get the point in global coordinates. +// HepGeom::Point3D<double> globalPoint = globalPosition(point); + +// double r = globalPoint.perp(); +// double z = globalPoint.z(); + +// double thetaMin = atan2(r,(z + deltaZ)); +// etaMax = -log(tan(0.5 * thetaMin)); +// double thetaMax = atan2(r,(z - deltaZ)); +// etaMin = -log(tan(0.5 * thetaMax)); + +// phi = globalPoint.phi(); +// } + +void NeutrinoDetectorElement::getCorners(HepGeom::Point3D<double> *corners) const +{ + std::lock_guard<std::recursive_mutex> lock(m_mutex); + if (!m_cacheValid) updateCache(); + + // This makes the assumption that the forward SCT detectors are orientated such that + // the positive etaAxis corresponds to the top of the detector where the width is largest. + // This is currently always the case. + // For the SCT barrel and pixel detectors minWidth and maxWidth are the same and so should + // work for all orientations. + + // double minWidth = m_design->minWidth(); + // double maxWidth = m_design->maxWidth(); + double width = m_design->width(); + double height = m_design->height(); + + // Lower left + corners[0][distPhi] = -0.5 * width; + corners[0][distEta] = -0.5 * height; + corners[0][distDepth] = 0.; + + // Lower right + corners[1][distPhi] = 0.5 * width; + corners[1][distEta] = -0.5 * height; + corners[1][distDepth] = 0.; + + // Upper Right + corners[2][distPhi] = 0.5 * width; + corners[2][distEta] = 0.5 * height; + corners[2][distDepth] = 0.; + + // Upper left + corners[3][distPhi] = -0.5 * width; + corners[3][distEta] = 0.5 * height; + corners[3][distDepth] = 0.; +} + +NeutrinoIntersect +NeutrinoDetectorElement::inDetector(const Amg::Vector2D & localPosition, + double phiTol, double etaTol) const +{ + return m_design->inDetector(localPosition, phiTol, etaTol); +} + + +NeutrinoIntersect +NeutrinoDetectorElement::inDetector(const HepGeom::Point3D<double> & globalPosition, double phiTol, double etaTol) const +{ + return m_design->inDetector(localPosition(globalPosition), phiTol, etaTol); +} + +// bool +// NeutrinoDetectorElement::nearBondGap(Amg::Vector2D localPosition, double etaTol) const +// { +// return m_design->nearBondGap(localPosition, etaTol); +// } + +// bool +// NeutrinoDetectorElement::nearBondGap(HepGeom::Point3D<double> globalPosition, double etaTol) const +// { +// return m_design->nearBondGap(localPosition(globalPosition), etaTol); +// } + +// Amg::Vector2D +// NeutrinoDetectorElement::rawLocalPositionOfCell(const SiCellId &cellId) const +// { +// return m_design->localPositionOfCell(cellId); +// } + +// Amg::Vector2D +// NeutrinoDetectorElement::rawLocalPositionOfCell(const Identifier & id) const +// { +// SiCellId cellId = cellIdFromIdentifier(id); +// return m_design->localPositionOfCell(cellId); +// } + +// int +// NeutrinoDetectorElement::numberOfConnectedCells(const SiCellId cellId) const +// { +// SiReadoutCellId readoutId = m_design->readoutIdOfCell(cellId); +// return m_design->numberOfConnectedCells(readoutId); +// } + +// SiCellId +// NeutrinoDetectorElement::connectedCell(const SiCellId cellId, int number) const +// { +// SiReadoutCellId readoutId = m_design->readoutIdOfCell(cellId); +// return m_design->connectedCell(readoutId, number); +// } + + +// SiCellId +// NeutrinoDetectorElement::cellIdOfPosition(const Amg::Vector2D &localPosition) const +// { +// return m_design->cellIdOfPosition(localPosition); +// } + +// Identifier +// NeutrinoDetectorElement::identifierOfPosition(const Amg::Vector2D &localPosition) const +// { +// SiCellId cellId = m_design->cellIdOfPosition(localPosition); +// return identifierFromCellId(cellId); +// } + +// Identifier +// NeutrinoDetectorElement::identifierFromCellId(const SiCellId & cellId) const +// { +// Identifier id; // Will be initialized in an invalid state. + +// // If something fails it returns the id in an invalid state. + +// if (cellId.isValid()) { + +// if (isPixel()) { +// const PixelID * pixelIdHelper = static_cast<const PixelID *>(getIdHelper()); +// if (pixelIdHelper) { +// id = pixelIdHelper->pixel_id(m_id, cellId.phiIndex(), cellId.etaIndex()); +// } +// } else { +// const SCT_ID * sctIdHelper = static_cast<const SCT_ID *>(getIdHelper()); +// if (sctIdHelper) { +// id = sctIdHelper->strip_id(m_id, cellId.strip()); +// } +// } +// } + +// return id; +// } + +// SiCellId +// NeutrinoDetectorElement::cellIdFromIdentifier(const Identifier & identifier) const +// { +// SiCellId cellId; // Initialized in invalid state. + +// // If something fails it returns the cellId in an invalid state. + +// if (identifier.is_valid()) { + +// if (isPixel()) { +// const PixelID * pixelIdHelper = static_cast<const PixelID *>(getIdHelper()); +// if (pixelIdHelper) { +// cellId = SiCellId(pixelIdHelper->phi_index(identifier), pixelIdHelper->eta_index(identifier)); +// } +// } else { +// const SCT_ID * sctIdHelper = static_cast<const SCT_ID *>(getIdHelper()); +// if (sctIdHelper) { +// cellId = SiCellId(sctIdHelper->strip(identifier)); +// } +// } +// } + +// return cellId; +// } + +} // namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElementCollection.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElementCollection.cxx new file mode 100644 index 00000000..318ea304 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorElementCollection.cxx @@ -0,0 +1,19 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h" + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "Identifier/IdentifierHash.h" + +NeutrinoDD::NeutrinoDetectorElementCollection::~NeutrinoDetectorElementCollection() { + for (NeutrinoDD::NeutrinoDetectorElement* ele: *this) delete ele; +} + +const NeutrinoDD::NeutrinoDetectorElement* +NeutrinoDD::NeutrinoDetectorElementCollection::getDetectorElement(const IdentifierHash& hash) const { + const unsigned int value{hash.value()}; + if (this->size()<=value) return nullptr; + return this->at(value); +} diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManager.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManager.cxx new file mode 100644 index 00000000..a3b335d4 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManager.cxx @@ -0,0 +1,144 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorManager.h" +#include "FaserDetDescr/FaserDetectorID.h" +#include "IdDictDetDescr/IdDictManager.h" +#include "StoreGate/StoreGateSvc.h" + +#include "GeoModelKernel/GeoXF.h" +#include "GeoGenericFunctions/Variable.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "DetDescrConditions/AlignableTransformContainer.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElementCollection.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/ExtendedAlignableTransform.h" + +#include <iostream> + +namespace NeutrinoDD +{ + + NeutrinoDetectorManager::NeutrinoDetectorManager(StoreGateSvc * detStore, const std::string & name) + : NeutrinoDetectorManagerBase(detStore, name), + m_design {nullptr} + { + // Add default folder + // addFolder("/Neutrino/Align"); + } + + const std::string& NeutrinoDetectorManager::tag() const + { + return m_tag; + } + + void NeutrinoDetectorManager::invalidateAll() const + { + for (NeutrinoDetectorElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + + if (*element_iter) { + (*element_iter)->invalidate(); + } + } + } + + void NeutrinoDetectorManager::updateAll() const + { + for (NeutrinoDetectorElementCollection::const_iterator element_iter = getDetectorElementBegin(); + element_iter != getDetectorElementEnd(); + ++element_iter) { + if (*element_iter) { + (*element_iter)->setAllCaches(); + } + } + } + + bool NeutrinoDetectorManager::setAlignableTransformLocalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D & localToGlobalXF, + const Amg::Transform3D & delta, + GeoVAlignmentStore* alignStore) const + { + // ATTENTION -------------------------------------------------------- (A.S.) + // CLHEP < -- > AMG interface method + + // Sets the alignable transform delta when the supplied delta is in the local + // reconstruction frame + + // If the default transform to the local recostruction frame is + // T = A*B*C*D*E + // and the alignable transform is C with delta c and the delat in the local frame is l, then + // A*B*C*c*D*E = A*B*C*D*E*l + // c = (D*E) * l * (D*E).inverse() + // c = (A*B*C).inverse * T * l * T.inverse() * (A*B*C) + + // To get default transform up and including the alignable transform, + // we assume the next volume down is a fullphys volume and so its + // transform is the transform we want (ie A*B*C in the above example). + + if (!extXF) return false; + + const GeoVFullPhysVol* child = extXF->child(); + if (child && extXF->alignableTransform()) { + // the definitiv absolut transform is in CLHEP -> do the calculation in CLHEP + const GeoTrf::Transform3D& transform = child->getDefAbsoluteTransform(alignStore); + // calucluate the corrected delta according to the formula above + GeoTrf::Transform3D correctedDelta = transform.inverse()*localToGlobalXF // (A*B*C).inverse() * T + * delta // l + * localToGlobalXF.inverse() * transform; // T.inverse() * (A*B*C) + extXF->alignableTransform()->setDelta(correctedDelta, alignStore); + return true; + } else { + return false; + } + } + + bool NeutrinoDetectorManager::setAlignableTransformGlobalDelta(ExtendedAlignableTransform * extXF, + const Amg::Transform3D& delta, + GeoVAlignmentStore* alignStore) const { + // ATTENTION -------------------------------------------------------- (A.S.) + // CLHEP < -- > AMG interface method + + // Sets the alignable transform delta when the supplied delta is in the global frame. + + // If the default transform down to the alignable transform is + // T = A*B*C + // and the alignable transform is C with delta c and the delta in the global frame is g, then + // A*B*C*c = g*A*B*C + // T*c = g*T + // c = T.inverse() * g * T + + // To get default transform up and including the alignable transform, + // we assume the next volume down is a fullphys volume and so its + // transform is the transform we want (ie T=A*B*C in the above example). + + + if (!extXF) return false; + + const GeoVFullPhysVol * child = extXF->child(); + if (child && extXF->alignableTransform()) { + // do the calculation in CLHEP + const GeoTrf::Transform3D& transform = child->getDefAbsoluteTransform(alignStore); + extXF->alignableTransform()->setDelta(transform.inverse() * delta * transform, alignStore); + return true; + } else { + return false; + } + } + + void NeutrinoDetectorManager::setDesign(const NeutrinoDetectorDesign * design) + { + m_design = design; + } + + const NeutrinoDetectorDesign* NeutrinoDetectorManager::getDesign() const + { + return m_design; + } + +}// namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManagerBase.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManagerBase.cxx new file mode 100644 index 00000000..5048b842 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoDetectorManagerBase.cxx @@ -0,0 +1,424 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "NeutrinoReadoutGeometry/NeutrinoDetectorManagerBase.h" + +#include "StoreGate/StoreGateSvc.h" +#include "DetDescrConditions/AlignableTransform.h" +#include "FaserDetDescr/FaserDetectorID.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "AthenaBaseComps/AthMsgStreamMacros.h" + +#include <map> + +namespace NeutrinoDD +{ + + NeutrinoDetectorManagerBase::NeutrinoDetectorManagerBase(StoreGateSvc * detStore, const std::string & name) + : m_alignfoldertype{none},m_detStore(detStore), + m_msg(name+"DetectorManager") + { + setName(name); + } + + // Destructor + NeutrinoDetectorManagerBase::~NeutrinoDetectorManagerBase() + {} + + + const Version& NeutrinoDetectorManagerBase::getVersion() const + { + return m_version; + } + + const std::string& NeutrinoDetectorManagerBase::getLayout() const + { + return m_version.layout(); + } + + void NeutrinoDetectorManagerBase::setVersion(const Version & version) + { + m_version = version; + } + + void NeutrinoDetectorManagerBase::addChannel(const std::string & key, int level, FrameType frame) + { + std::string frameStr = "other"; + if (frame == NeutrinoDD::global) frameStr = "global"; + if (frame == NeutrinoDD::local) frameStr = "local"; + ATH_MSG_INFO("Registering alignment channel with key " << key << ", level " << level + << ", with frame " << frameStr << "."); + m_keys[key] = LevelInfo(level, frame); + } + + void NeutrinoDetectorManagerBase::addFolder(const std::string & key) + { + m_folders.insert(key); + } + + void NeutrinoDetectorManagerBase::addSpecialFolder(const std::string & key) + { + m_specialFolders.insert(key); + } + + void NeutrinoDetectorManagerBase::addGlobalFolder(const std::string & key) + { + m_globalFolders.insert(key); + } + + void NeutrinoDetectorManagerBase::addAlignFolderType(const AlignFolderType alignfolder) + { + m_alignfoldertype = alignfolder; + } + + // Return the level in the hierarchy (user defined) corresponding to the key. + const NeutrinoDetectorManagerBase::LevelInfo& NeutrinoDetectorManagerBase::getLevel(const std::string & key) const + { + std::map<std::string, LevelInfo>::const_iterator iter; + iter = m_keys.find(key); + if (iter == m_keys.end()) return s_invalidLevel; + return iter->second; + } + + StatusCode NeutrinoDetectorManagerBase::align( IOVSVC_CALLBACK_ARGS_P(I,keys) ) const + { + + (void) I; // avoid warning about unused parameter + + ATH_MSG_DEBUG("AlignmentCallback called "); + + if (!getIdHelper()) return StatusCode::SUCCESS; + + bool alignmentChange = false; + const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype); + + // If dummy arguments + if (keys.empty()) { + + + // New global aligment folders should be processed first + for (std::set<std::string>::const_iterator iterFolders = m_globalFolders.begin(); + iterFolders != m_globalFolders.end(); + ++iterFolders) { + + try { + bool status = processGlobalAlignmentContainer(*iterFolders); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // keys are empty when running simualtion. It is normal for detector specific aligments not to exist. + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + + // Regular alignments. Loop through folder keys. Normally only one. + for (std::set<std::string>::const_iterator iterFolders = m_folders.begin(); + iterFolders != m_folders.end(); + ++iterFolders) { + + try { + bool status = processAlignmentContainer(*iterFolders); + alignmentChange = (alignmentChange || status); + } + catch(std::runtime_error& err) { + // alignments should always exist so we return fatal if we could not process the alignment for this key + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + // Detector specific aligments + for (std::set<std::string>::const_iterator iterFolders = m_specialFolders.begin(); + iterFolders != m_specialFolders.end(); + ++iterFolders) { + try { + bool status = processSpecialAlignment(*iterFolders, aligninfo.AlignFolder()); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // keys are empty when running simualtion. It is normal for detector specific aligments not to exist. + ATH_MSG_INFO(err.what()); + // We continue as detector specific aligments don't always exist. + } + } + + } else { + // Loop over all the keys. + for (std::list<std::string>::const_iterator itr=keys.begin(); itr!=keys.end(); ++itr) { + + const std::string & key = *itr; + + ATH_MSG_DEBUG(" Processing call back key " << key); + + if ( m_globalFolders.find(key) != m_globalFolders.end() ) { + + try { + // New global alignemnts + bool status = processGlobalAlignmentContainer(key); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // alignments should always exist so we return fatal if we could not process the alignment for this key + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + + } else if ( m_folders.find(key) != m_folders.end() ) { + + try { + // Regular alignemnts + bool status = processAlignmentContainer(key); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // alignments should always exist so we return fatal if we could not process the alignment for this key + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + + } else if ( m_specialFolders.find(key) != m_specialFolders.end() ) { + try { + // Detector specific alignments + bool status = processSpecialAlignment(key, aligninfo.AlignFolder()); + alignmentChange = (alignmentChange || status); + } + catch(std::runtime_error& err) { + // Should always exist if the folder was requested so we return fatal if we could not process the alignment for this key + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } else { + // Should not be any other keys specified in call back. + ATH_MSG_ERROR("Unrecognized key in call back."); + return StatusCode::RECOVERABLE; + } + } + } + + // We invalidate all the elements if at least one alignment changed. + if (alignmentChange) { + invalidateAll(); + } + + return StatusCode::SUCCESS; + } + + StatusCode NeutrinoDetectorManagerBase::align(const RawAlignmentObjects& alignObjects, GeoVAlignmentStore* alignStore) const + { + + ATH_MSG_DEBUG("align() called from an alignment CondAlg"); + if (!getIdHelper()) return StatusCode::SUCCESS; // To Do: is it really a success? + + bool alignmentChange = false; + // const AlignInfo &aligninfo = AlignInfo(m_alignfoldertype); + + for(const auto& alignObj : alignObjects) { + const std::string& key = alignObj.first; + + ATH_MSG_DEBUG(" Processing folder " << key); + + if(m_globalFolders.find(key)!=m_globalFolders.end()) { + try { + // New global alignemnts + const CondAttrListCollection* obj = static_cast<const CondAttrListCollection*>(alignObj.second); + bool status = processGlobalAlignmentContainer(key,obj,alignStore); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // alignments should always exist so we return fatal if we could not process the alignment for this key + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + else if(m_folders.find(key)!=m_folders.end()) { + try { + // Regular alignemnts + const AlignableTransformContainer* container = static_cast<const AlignableTransformContainer*>(alignObj.second); + bool status = processAlignmentContainer(container,alignStore); + alignmentChange = (alignmentChange || status); + } catch(std::runtime_error& err) { + // alignments should always exist so we return fatal if we could not process the alignment for this key + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + else if(m_specialFolders.find(key)!=m_specialFolders.end()) { + try { + // Detector specific alignments + const CondAttrListCollection *obj = + static_cast<const CondAttrListCollection*>(alignObj.second); + bool status = processSpecialAlignment(key, obj, alignStore); + alignmentChange = (alignmentChange || status); + } + catch(std::runtime_error& err) { + // Should always exist if the folder was requested so we return fatal if + // we could not process the alignment for this key + ATH_MSG_FATAL(err.what()); + return StatusCode::FAILURE; + } + } + else { + // Should not be any other keys specified in raw alignment object. + ATH_MSG_ERROR("Unrecognized folder name."); + return StatusCode::RECOVERABLE; + } + } + // To Do: custom caching is not going to work in MT + /* + if(alignmentChange) invalidateAll(); + */ + + return StatusCode::SUCCESS; + } + + bool NeutrinoDetectorManagerBase::processAlignmentContainer(const std::string & key) const + { + bool alignmentChange = false; + + ATH_MSG_DEBUG("Dealing with key as container"); + const AlignableTransformContainer* container; + if (StatusCode::SUCCESS!=m_detStore->retrieve(container, key)) { + ATH_MSG_ERROR("Cannot find AlignableTransformContainer for key " + << key << " - no misalignment"); + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Neutrino alignments"); + } + // Check if container is empty - this can occur if it is an invalid IOV. + if (container->empty()) { + ATH_MSG_ERROR("AlignableTransformContainer for key " + << key << " is empty. Probably due to out of range IOV"); + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Neutrino alignments."); + } + // loop over all the AlignableTransform objects in the collection + for (DataVector<AlignableTransform>::const_iterator pat=container->begin(); + pat!=container->end();++pat) { + + bool status = processKey((*pat)->tag(),*pat); + alignmentChange = (alignmentChange || status); + } + return alignmentChange; + } + + bool NeutrinoDetectorManagerBase::processAlignmentContainer(const AlignableTransformContainer* container, GeoVAlignmentStore* alignStore) const + { + bool alignmentChange = false; + + // Check if container is empty - this can occur if it is an invalid IOV. + if (container->empty()) { + ATH_MSG_ERROR("AlignableTransformContainer " + << " is empty. Probably due to out of range IOV"); // To Do: add key to this printout for making it more informative + // This should not occur in normal situations so we force job to abort. + throw std::runtime_error("Unable to apply Neutrino alignments."); + } + // loop over all the AlignableTransform objects in the collection + // use only the last ones. + std::map<const std::string, const AlignableTransform*> stringToTransform; + for (DataVector<AlignableTransform>::const_iterator pat=container->begin(); + pat!=container->end();++pat) { + stringToTransform[(*pat)->tag()] = *pat; + } + for (std::pair<const std::string, const AlignableTransform*> value: stringToTransform) { + bool status = processKey(value.first, value.second, alignStore); + alignmentChange = (alignmentChange || status); + } + return alignmentChange; + } + + bool NeutrinoDetectorManagerBase::processKey(const std::string key, + const AlignableTransform* transformCollection, + GeoVAlignmentStore* alignStore) const + { + bool alignmentChange = false; + + // From the key determine what level in hierarchy we are dealing with. + // returns -1 if unrecognized. + const LevelInfo & levelInfo = getLevel(key); + if (levelInfo.isValid()) { + ATH_MSG_VERBOSE("Processing channel: " << key); + } else { + ATH_MSG_DEBUG("Channel " << key << " not registered in this manager"); + } + // return silently if unrecognised - this can happen in container mode + // when a single container holds transforms for both pixel and SCT + if (!levelInfo.isValid() ) return false; + + //Loop over the effected nodes. + for (AlignableTransform::AlignTransMem_citr trans_iter = transformCollection->begin(); + trans_iter != transformCollection->end(); + ++trans_iter) { + ATH_MSG_DEBUG( "Get alignment for identifier " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level()); + + // The delta in the conditions DB is not necessarily the same as what is needed in the + // alignable transform. At the moment we support global frame, local frame or an alternative frame + // The setAlignableTransformDelta method takes care of this correction - this is CLHEP <--> Amg interfaced + bool status = setAlignableTransformDelta(levelInfo.level(), + trans_iter->identify(), + Amg::CLHEPTransformToEigen(trans_iter->transform()), + levelInfo.frame(), + alignStore); + + alignmentChange = (alignmentChange || status); + + if (!status) { + if (!identifierBelongs(trans_iter->identify())) { + ATH_MSG_DEBUG("Cannot set AlignableTransform for identifier." + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level()); + } else { + ATH_MSG_WARNING("Cannot set AlignableTransform for identifier " + << getIdHelper()->show_to_string(trans_iter->identify()) + << " at level " << levelInfo.level()); + ATH_MSG_WARNING("Subsequent WARNINGS will be printed at DEBUG level."); + } + } + } + return alignmentChange; + } + + // We provide a default implementation of any detector specific alignment. + bool NeutrinoDetectorManagerBase::processGlobalAlignmentContainer(const std::string & key, + const CondAttrListCollection* obj, + GeoVAlignmentStore* alignStore) const + { + bool alignmentChange = false; + + ATH_MSG_DEBUG("processing GlobalAlignmentContainer with key: " << key); + // From the key determine what level in hierarchy we are dealing with. + // returns -1 if unrecognized. + const LevelInfo & levelInfo = getLevel(key); + if (levelInfo.isValid()) { + ATH_MSG_VERBOSE("Processing channel: " << key); + } else { + ATH_MSG_DEBUG("Channel " << key << " not registered in this manager"); + } + // return silently if unrecognised - this can happen in container mode + // when a single container holds transforms for both pixel and SCT + if (!levelInfo.isValid() ) return false; + + // Within detector specific code + bool status = processGlobalAlignment(key, levelInfo.level(), levelInfo.frame(), obj, alignStore); + + alignmentChange = (alignmentChange || status); + + return alignmentChange; + + } + + // We provide a default implementation of any detector specific alignment. + bool NeutrinoDetectorManagerBase::processGlobalAlignment(const std::string &, int /*level*/, FrameType /*frame*/, + const CondAttrListCollection* /*obj*/, GeoVAlignmentStore* /*alignStore*/) const + { + return false; + } + + + // We provide a default implementation of any detector specific alignment. + bool NeutrinoDetectorManagerBase::processSpecialAlignment(const std::string &, NeutrinoDD::AlignFolderType) const + { + return false; + } + + const NeutrinoDetectorManagerBase::LevelInfo NeutrinoDetectorManagerBase::s_invalidLevel; + +} // namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoLocalPosition.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoLocalPosition.cxx new file mode 100644 index 00000000..c2dc61f7 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoLocalPosition.cxx @@ -0,0 +1,100 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoLocalPosition.cxx +// Implementation file for class NeutrinoLocalPosition +/////////////////////////////////////////////////////////////////// +// (c) ATLAS Detector software +/////////////////////////////////////////////////////////////////// +// Version 2.1 01/08/2001 David Calvet +/////////////////////////////////////////////////////////////////// + +#include "NeutrinoReadoutGeometry/NeutrinoLocalPosition.h" + +namespace NeutrinoDD { + +// Default constructor: +NeutrinoLocalPosition::NeutrinoLocalPosition() : + m_eta(0), + m_phi(0), + m_xDepth(0) +{} + + + +// Constructor with parameters: +NeutrinoLocalPosition::NeutrinoLocalPosition(const double x,const double y, + const double xDepth) : + m_eta(x), + m_phi(y), + m_xDepth(xDepth) +{} + +NeutrinoLocalPosition::NeutrinoLocalPosition(const Amg::Vector2D &position) + : m_eta(position[Trk::distEta]), + m_phi(position[Trk::distPhi]), + m_xDepth(0) +{} + + +NeutrinoLocalPosition::operator Amg::Vector2D(void) const +{ + return Amg::Vector2D(m_phi, m_eta); +} + + + +// addition of positions: +NeutrinoLocalPosition &NeutrinoLocalPosition::operator+=(const NeutrinoLocalPosition &position) +{ + m_eta+=position.m_eta; + m_phi+=position.m_phi; + m_xDepth+=position.m_xDepth; + return *this; +} + +// scaling: +NeutrinoLocalPosition &NeutrinoLocalPosition::operator*=(const double factor) +{ + m_eta*=factor; + m_phi*=factor; + m_xDepth*=factor; + return *this; +} + +// scaling: +NeutrinoLocalPosition &NeutrinoLocalPosition::operator/=(const double factor) +{ + if (0!=factor) { + m_eta/=factor; + m_phi/=factor; + m_xDepth/=factor; + } else {} + return *this; +} + +NeutrinoLocalPosition operator+(const NeutrinoLocalPosition &position1, + const NeutrinoLocalPosition &position2) +{ + NeutrinoLocalPosition result(position1); + result+=position2; + return result; +} + +NeutrinoLocalPosition operator*(const NeutrinoLocalPosition &position,const double factor) +{ + NeutrinoLocalPosition result(position); + result*=factor; + return result; +} + +NeutrinoLocalPosition operator/(const NeutrinoLocalPosition &position,const double factor) +{ + NeutrinoLocalPosition result(position); + result/=factor; + return result; +} + +} // namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoNumerology.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoNumerology.cxx new file mode 100644 index 00000000..f8ea063f --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/NeutrinoNumerology.cxx @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoReadoutGeometry/NeutrinoNumerology.h" + + +namespace NeutrinoDD { + +NeutrinoNumerology::NeutrinoNumerology() + : m_numBasesPerModule(0), + m_numFilmsPerBase(0) +{} + +void NeutrinoNumerology::addModule(int id) +{ + m_moduleIds.insert(id); +} + +void NeutrinoNumerology::setNumBasesPerModule(int nBases) +{ + m_numBasesPerModule = nBases; +} + +void NeutrinoNumerology::setNumFilmsPerBase(int nFilms) +{ + m_numFilmsPerBase = nFilms; +} + + +} // End namespace diff --git a/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/Version.cxx b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/Version.cxx new file mode 100644 index 00000000..418315a4 --- /dev/null +++ b/Neutrino/NeutrinoDetDescr/NeutrinoReadoutGeometry/src/Version.cxx @@ -0,0 +1,121 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoReadoutGeometry/Version.h" + +#include <sstream> +#include <string> +#include <iomanip> + +namespace NeutrinoDD { + +Version::Version(const std::string & tag, + const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch) + : m_tag(tag), + m_name(name), + m_layout(layout), + m_description(description), + m_major(major), + m_minor(minor), + m_patch(patch) +{} + +// For backward compatibility +Version::Version(const std::string & name, + const std::string & layout, + const std::string & description, + int major, + int minor, + int patch) + : m_tag("-"), + m_name(name), + m_layout(layout), + m_description(description), + m_major(major), + m_minor(minor), + m_patch(patch) +{} + + + +Version::Version() + : m_major(0), + m_minor(0), + m_patch(0) +{} + +const std::string & +Version::tag() const +{ + return m_tag; +} + +const std::string & +Version::name() const +{ + return m_name; +} + +const std::string & +Version::layout() const +{ + return m_layout; +} + +const std::string & +Version::description() const +{ + return m_description; +} + +int +Version::majorNum() const +{ + return m_major; +} + +int +Version::minorNum() const +{ + return m_minor; +} + +int +Version::patchNum() const +{ + return m_patch; +} + +std::string +Version::versionNumber() const +{ + std::ostringstream ostr; + ostr << m_major + << "." << std::setfill('0') << std::setw(2) << m_minor + << "." << std::setfill('0') << std::setw(2) << m_patch; + return ostr.str(); +} + +std::string +Version::fullDescription() const +{ + + // Output of the form + // Version: SCT-DC1-00, Name: DC1, Layout: Final, Code Version: 02.01.01, Description: DC1 Geometry + + std::ostringstream ostr; + ostr << "Version: " << m_tag << ", Name: " << m_name << ", Layout: " << m_layout + << ", Code Version: " << versionNumber(); + if (!m_description.empty()) { + ostr << ", Description: " << m_description; + } + return ostr.str(); +} + +} // namespace NeutrinoDD diff --git a/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/CMakeLists.txt b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/CMakeLists.txt new file mode 100644 index 00000000..fe777075 --- /dev/null +++ b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/CMakeLists.txt @@ -0,0 +1,15 @@ +################################################################################ +# Package: NeutrinoIdCnv +################################################################################ + +# Declare the package name: +atlas_subdir( NeutrinoIdCnv ) + +# Component(s) in the package: +atlas_add_component( NeutrinoIdCnv + src/*.cxx + LINK_LIBRARIES StoreGateLib SGtests DetDescrCnvSvcLib IdDictDetDescr GaudiKernel NeutrinoIdentifier ) + +# Install files from the package: +atlas_install_joboptions( share/*.py ) + diff --git a/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/share/NeutrinoIdCnv_jobOptions.py b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/share/NeutrinoIdCnv_jobOptions.py new file mode 100644 index 00000000..611694cf --- /dev/null +++ b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/share/NeutrinoIdCnv_jobOptions.py @@ -0,0 +1,6 @@ +# +# Joboptions for the loading of the of NeutrinoIdCnv +# + +# DLLs +theApp.Dlls += [ "NeutrinoIdCnv" ] diff --git a/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.cxx b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.cxx new file mode 100644 index 00000000..fc8cde7b --- /dev/null +++ b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.cxx @@ -0,0 +1,239 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*************************************************************************** + Neutrino DetDescrCnv package + ----------------------------------------- + ***************************************************************************/ + +//<<<<<< INCLUDES >>>>>> + +#include "EmulsionIDDetDescrCnv.h" + +#include "DetDescrCnvSvc/DetDescrConverter.h" +#include "DetDescrCnvSvc/DetDescrAddress.h" +#include "GaudiKernel/MsgStream.h" +#include "StoreGate/StoreGateSvc.h" + +#include "IdDictDetDescr/IdDictManager.h" +#include "NeutrinoIdentifier/EmulsionID.h" + + +//<<<<<< PRIVATE DEFINES >>>>>> +//<<<<<< PRIVATE CONSTANTS >>>>>> +//<<<<<< PRIVATE TYPES >>>>>> +//<<<<<< PRIVATE VARIABLE DEFINITIONS >>>>>> +//<<<<<< PUBLIC VARIABLE DEFINITIONS >>>>>> +//<<<<<< CLASS STRUCTURE INITIALIZATION >>>>>> +//<<<<<< PRIVATE FUNCTION DEFINITIONS >>>>>> +//<<<<<< PUBLIC FUNCTION DEFINITIONS >>>>>> +//<<<<<< MEMBER FUNCTION DEFINITIONS >>>>>> + +//-------------------------------------------------------------------- + +long int +EmulsionIDDetDescrCnv::repSvcType() const +{ + return (storageType()); +} + +//-------------------------------------------------------------------- + +StatusCode +EmulsionIDDetDescrCnv::initialize() +{ + // First call parent init + StatusCode sc = DetDescrConverter::initialize(); + MsgStream log(msgSvc(), "EmulsionIDDetDescrCnv"); + log << MSG::DEBUG << "in initialize" << endmsg; + + if (sc.isFailure()) { + log << MSG::ERROR << "DetDescrConverter::initialize failed" << endmsg; + return sc; + } + + // The following is an attempt to "bootstrap" the loading of a + // proxy for EmulsionID into the detector store. However, + // EmulsionIDDetDescrCnv::initialize is NOT called by the conversion + // service. So for the moment, this cannot be use. Instead the + // DetDescrCnvSvc must do the bootstrap from a parameter list. + + +// // Add Neutrino_DetDescrManager proxy as entry point to the detector store +// // - this is ONLY needed for the manager of each system +// sc = addToDetStore(classID(), "EmulsionID"); +// if (sc.isFailure()) { +// log << MSG::FATAL << "Unable to add proxy for EmulsionID to the Detector Store!" << endmsg; +// return StatusCode::FAILURE; +// } else {} + + return StatusCode::SUCCESS; +} + +//-------------------------------------------------------------------- + +StatusCode +EmulsionIDDetDescrCnv::finalize() +{ + MsgStream log(msgSvc(), "EmulsionIDDetDescrCnv"); + log << MSG::DEBUG << "in finalize" << endmsg; + + return StatusCode::SUCCESS; +} + +//-------------------------------------------------------------------- + +StatusCode +EmulsionIDDetDescrCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) +{ + //StatusCode sc = StatusCode::SUCCESS; + MsgStream log(msgSvc(), "EmulsionIDDetDescrCnv"); + log << MSG::INFO << "in createObj: creating a EmulsionID helper object in the detector store" << endmsg; + + // Create a new EmulsionID + + DetDescrAddress* ddAddr; + ddAddr = dynamic_cast<DetDescrAddress*> (pAddr); + if(!ddAddr) { + log << MSG::FATAL << "Could not cast to DetDescrAddress." << endmsg; + return StatusCode::FAILURE; + } + + // Get the StoreGate key of this container. + std::string helperKey = *( ddAddr->par() ); + if ("" == helperKey) { + log << MSG::DEBUG << "No Helper key " << endmsg; + } + else { + log << MSG::DEBUG << "Helper key is " << helperKey << endmsg; + } + + + // get DetectorStore service + StoreGateSvc * detStore; + StatusCode status = serviceLocator()->service("DetectorStore", detStore); + if (status.isFailure()) { + log << MSG::FATAL << "DetectorStore service not found !" << endmsg; + return StatusCode::FAILURE; + } else {} + + // Get the dictionary manager from the detector store + const DataHandle<IdDictManager> idDictMgr; + status = detStore->retrieve(idDictMgr, "IdDict"); + if (status.isFailure()) { + log << MSG::FATAL << "Could not get IdDictManager !" << endmsg; + return StatusCode::FAILURE; + } + else { + log << MSG::DEBUG << " Found the IdDictManager. " << endmsg; + } + + // Only create new helper if it is the first pass or if there is a + // change in the the file or tag + bool initHelper = false; + + const IdDictMgr* mgr = idDictMgr->manager(); + + // Internal Neutrino id tag + std::string neutrinoIDTag = mgr->tag(); + + // DoChecks flag + bool doChecks = mgr->do_checks(); + + IdDictDictionary* dict = mgr->find_dictionary("Neutrino"); + if (!dict) { + log << MSG::ERROR + << "unable to find idDict for Neutrino" + << endmsg; + return StatusCode::FAILURE; + } + + // File to be read for Neutrino ids + std::string neutrinoIDFileName = dict->file_name(); + + // Tag of RDB record for Neutrino ids + std::string neutrinoIdDictTag = dict->dict_tag(); + + + if (m_emulsionId) { + + // Emulsion id helper already exists - second pass. Check for a + // change + if (neutrinoIDTag != m_neutrinoIDTag) { + // Internal Neutrino id tag + initHelper = true; + log << MSG::DEBUG << " Changed internal Neutrino id tag: " + << neutrinoIDTag << endmsg; + } + if (neutrinoIDFileName != m_neutrinoIDFileName) { + // File to be read for Neutrino ids + initHelper = true; + log << MSG::DEBUG << " Changed NeutrinoFileName:" + << neutrinoIDFileName << endmsg; + } + if (neutrinoIdDictTag != m_neutrinoIdDictTag) { + // Tag of RDB record for Neutrino ids + initHelper = true; + log << MSG::DEBUG << " Changed NeutrinoIdDictTag: " + << neutrinoIdDictTag + << endmsg; + } + if (doChecks != m_doChecks) { + // DoChecks flag + initHelper = true; + log << MSG::DEBUG << " Changed doChecks flag: " + << doChecks + << endmsg; + } + } + else { + // create the helper + m_emulsionId = new EmulsionID; + initHelper = true; + // add in message service for printout + m_emulsionId->setMessageSvc(msgSvc()); + } + + if (initHelper) { + if (idDictMgr->initializeHelper(*m_emulsionId)) { + log << MSG::ERROR << "Unable to initialize EmulsionID" << endmsg; + return StatusCode::FAILURE; + } + // Save state: + m_neutrinoIDTag = neutrinoIDTag; + m_neutrinoIDFileName = neutrinoIDFileName; + m_neutrinoIdDictTag = neutrinoIdDictTag; + m_doChecks = doChecks; + } + + // Pass a pointer to the container to the Persistency service by reference. + pObj = StoreGateSvc::asStorable(m_emulsionId); + + return StatusCode::SUCCESS; + +} + +//-------------------------------------------------------------------- + +long +EmulsionIDDetDescrCnv::storageType() +{ + return DetDescr_StorageType; +} + +//-------------------------------------------------------------------- +const CLID& +EmulsionIDDetDescrCnv::classID() { + return ClassID_traits<EmulsionID>::ID(); +} + +//-------------------------------------------------------------------- +EmulsionIDDetDescrCnv::EmulsionIDDetDescrCnv(ISvcLocator* svcloc) + : + DetDescrConverter(ClassID_traits<EmulsionID>::ID(), svcloc), + m_emulsionId(0), + m_doChecks(false) + +{} + diff --git a/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.h b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.h new file mode 100644 index 00000000..717e4c4b --- /dev/null +++ b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/EmulsionIDDetDescrCnv.h @@ -0,0 +1,71 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*************************************************************************** + Neutrino DetDescrCnv package + ----------------------------------------- + ***************************************************************************/ + +#ifndef NEUTRINOIDCNV_EMULSIONIDDETDESCRCNV_H +#define NEUTRINOIDCNV_EMULSIONIDDETDESCRCNV_H + +//<<<<<< INCLUDES >>>>>> + +#include "DetDescrCnvSvc/DetDescrConverter.h" + +//<<<<<< PUBLIC DEFINES >>>>>> +//<<<<<< PUBLIC CONSTANTS >>>>>> +//<<<<<< PUBLIC TYPES >>>>>> + +class EmulsionID; + +//<<<<<< PUBLIC VARIABLES >>>>>> +//<<<<<< PUBLIC FUNCTIONS >>>>>> +//<<<<<< CLASS DECLARATIONS >>>>>> + + +/** + ** This class is a converter for the EmulsionID an IdHelper which is + ** stored in the detector store. This class derives from + ** DetDescrConverter which is a converter of the DetDescrCnvSvc. + ** + **/ + +class EmulsionIDDetDescrCnv: public DetDescrConverter { + +public: + virtual long int repSvcType() const; + virtual StatusCode initialize(); + virtual StatusCode finalize(); + virtual StatusCode createObj(IOpaqueAddress* pAddr, DataObject*& pObj); + + // Storage type and class ID (used by CnvFactory) + static long storageType(); + static const CLID& classID(); + + EmulsionIDDetDescrCnv(ISvcLocator* svcloc); + +private: + /// The helper - only will create it once + EmulsionID* m_emulsionId; + + /// File to be read for Neutrino ids + std::string m_neutrinoIDFileName; + + /// Tag of RDB record for Neutrino ids + std::string m_neutrinoIdDictTag; + + /// Internal Neutrino id tag + std::string m_neutrinoIDTag; + + /// Whether or not + bool m_doChecks; + +}; + + +//<<<<<< INLINE PUBLIC FUNCTIONS >>>>>> +//<<<<<< INLINE MEMBER FUNCTIONS >>>>>> + +#endif // NEUTRINOIDCNV_EMULSIONIDDETDESCRCNV_H diff --git a/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/NeutrinoIdCnv_entries.cxx b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/NeutrinoIdCnv_entries.cxx new file mode 100644 index 00000000..b3dfd901 --- /dev/null +++ b/Neutrino/NeutrinoDetDescrCnv/NeutrinoIdCnv/src/NeutrinoIdCnv_entries.cxx @@ -0,0 +1,3 @@ +#include "EmulsionIDDetDescrCnv.h" + +DECLARE_CONVERTER(EmulsionIDDetDescrCnv) diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/CMakeLists.txt b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/CMakeLists.txt new file mode 100644 index 00000000..ecaa1b03 --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/CMakeLists.txt @@ -0,0 +1,27 @@ +################################################################################ +# Package: NeutrinoSimEventAthenaPool +################################################################################ + +# Declare the package name: +atlas_subdir( NeutrinoSimEventAthenaPool ) + +# External dependencies: +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_poolcnv_library( NeutrinoSimEventAthenaPoolPoolCnv + src/*.cxx + FILES NeutrinoSimEvent/NeutrinoHitCollection.h + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib AthenaPoolUtilities AtlasSealCLHEP GaudiKernel NeutrinoSimEventTPCnv NeutrinoSimEvent ) + +atlas_add_dictionary( NeutrinoSimEventAthenaPoolCnvDict + NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPoolCnvDict.h + NeutrinoSimEventAthenaPool/selection.xml + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaPoolCnvSvcLib AthenaPoolUtilities AtlasSealCLHEP GaudiKernel NeutrinoSimEventTPCnv NeutrinoSimEvent ) + +# Install files from the package: +atlas_install_headers( NeutrinoSimEventAthenaPool ) +#atlas_install_joboptions( share/*.py ) + diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimDataCollection_p1.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimDataCollection_p1.h new file mode 100644 index 00000000..2298acde --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimDataCollection_p1.h @@ -0,0 +1,4 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimData_p1.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimData_p1.h new file mode 100644 index 00000000..2298acde --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimData_p1.h @@ -0,0 +1,4 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPoolCnvDict.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPoolCnvDict.h new file mode 100644 index 00000000..de99042f --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPoolCnvDict.h @@ -0,0 +1,9 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOSIMEVENTATHENAPOOLDICT_H +#define NEUTRINOSIMEVENTATHENAPOOLDICT_H + + +#endif diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/selection.xml b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/selection.xml new file mode 100644 index 00000000..2eff49df --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/NeutrinoSimEventAthenaPool/selection.xml @@ -0,0 +1,2 @@ +<lcgdict> +</lcgdict> diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.cxx b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.cxx new file mode 100644 index 00000000..36ff6569 --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.cxx @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHit_p1.h" +#include "NeutrinoHitCollectionCnv.h" + + +NeutrinoHitCollection_PERS* NeutrinoHitCollectionCnv::createPersistent(NeutrinoHitCollection* transCont) { + MsgStream mlog(msgSvc(), "NeutrinoHitCollectionConverter" ); + NeutrinoHitCollectionCnv_PERS converter; + NeutrinoHitCollection_PERS *persObj = converter.createPersistent( transCont, mlog ); + return persObj; +} + + +NeutrinoHitCollection* NeutrinoHitCollectionCnv::createTransient() { + MsgStream mlog(msgSvc(), "NeutrinoHitCollectionConverter" ); + NeutrinoHitCollectionCnv_p1 converter_p1; + + static const pool::Guid p1_guid("2CA7AF71-1494-4378-BED4-AFB5C54398AA"); + // static const pool::Guid p1_guid("B2573A16-4B46-4E1E-98E3-F93421680779"); + + NeutrinoHitCollection *trans_cont(0); + if( this->compareClassGuid(p1_guid)) { + std::unique_ptr< NeutrinoHitCollection_p1 > col_vect( this->poolReadObject< NeutrinoHitCollection_p1 >() ); + trans_cont = converter_p1.createTransient( col_vect.get(), mlog ); + } else { + throw std::runtime_error("Unsupported persistent version of Data container"); + } + return trans_cont; +} diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.h new file mode 100644 index 00000000..5ccd3e1b --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventAthenaPool/src/NeutrinoHitCollectionCnv.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOHITCOLLECTIONCNV +#define NEUTRINOHITCOLLECTIONCNV + +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollection_p1.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h" +#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h" +// Gaudi +#include "GaudiKernel/MsgStream.h" +// typedef to the latest persistent version +typedef NeutrinoHitCollection_p1 NeutrinoHitCollection_PERS; +typedef NeutrinoHitCollectionCnv_p1 NeutrinoHitCollectionCnv_PERS; + +class NeutrinoHitCollectionCnv : public T_AthenaPoolCustomCnv<NeutrinoHitCollection, NeutrinoHitCollection_PERS > { + friend class CnvFactory<NeutrinoHitCollectionCnv>; +public: + NeutrinoHitCollectionCnv(ISvcLocator* svcloc) : + T_AthenaPoolCustomCnv<NeutrinoHitCollection, NeutrinoHitCollection_PERS >( svcloc) {} +protected: + NeutrinoHitCollection_PERS* createPersistent(NeutrinoHitCollection* transCont); + NeutrinoHitCollection* createTransient (); +}; + + +#endif diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/CMakeLists.txt b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/CMakeLists.txt new file mode 100644 index 00000000..defef98b --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/CMakeLists.txt @@ -0,0 +1,26 @@ +############################################################################### +# Package: NeutrinoSimEventTPCnv +################################################################################ + +# Declare the package name: +atlas_subdir( NeutrinoSimEventTPCnv ) + +# External dependencies: +find_package( CLHEP ) +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_library( NeutrinoSimEventTPCnv + src/NeutrinoHits/*.cxx + PUBLIC_HEADERS NeutrinoSimEventTPCnv + PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} + PRIVATE_DEFINITIONS ${CLHEP_DEFINITIONS} + LINK_LIBRARIES GaudiKernel GeneratorObjectsTPCnv NeutrinoSimEvent AthenaPoolCnvSvcLib StoreGateLib SGtests + PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} TestTools Identifier ) + +atlas_add_dictionary( NeutrinoSimEventTPCnvDict + NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnvDict.h + NeutrinoSimEventTPCnv/selection.xml + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaPoolCnvSvcLib GaudiKernel GeneratorObjectsTPCnv NeutrinoSimEvent TestTools StoreGateLib SGtests Identifier NeutrinoSimEventTPCnv ) + diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCnv_p1.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCnv_p1.h new file mode 100644 index 00000000..c33946cf --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCnv_p1.h @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOHITCNV_P1_H +#define NEUTRINOHITCNV_P1_H + +/* +Transient/Persistent converter for NeutrinoHit class +Author: Davide Costanzo +*/ + +#include "NeutrinoSimEvent/NeutrinoHit.h" +#include "NeutrinoHit_p1.h" + +#include "AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h" + +class MsgStream; + + +class NeutrinoHitCnv_p1 : public T_AthenaPoolTPCnvBase<NeutrinoHit, NeutrinoHit_p1> +{ +public: + + NeutrinoHitCnv_p1() {} + + virtual void persToTrans(const NeutrinoHit_p1* persObj, NeutrinoHit* +transObj, MsgStream &log); + virtual void transToPers(const NeutrinoHit* transObj, NeutrinoHit_p1* +persObj, MsgStream &log); +}; + + +#endif diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h new file mode 100644 index 00000000..4adb5b46 --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOHITCOLLECTIONCNV_P1_H +#define NEUTRINOHITCOLLECTIONCNV_P1_H + +// NeutrinoHitCollectionCnv_p1, T/P separation of Neutrino Hits +// author D.Costanzo <davide.costanzo@cern.ch> +// author O.Arnaez <olivier.arnaez@cern.ch> + +#include "AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h" +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" +#include "NeutrinoHitCollection_p1.h" + + +class NeutrinoHitCollectionCnv_p1 : public T_AthenaPoolTPCnvBase<NeutrinoHitCollection, NeutrinoHitCollection_p1> +{ + public: + + NeutrinoHitCollectionCnv_p1() {}; + + virtual NeutrinoHitCollection* createTransient(const NeutrinoHitCollection_p1* persObj, MsgStream &log); + + virtual void persToTrans(const NeutrinoHitCollection_p1* persCont, + NeutrinoHitCollection* transCont, + MsgStream &log) ; + virtual void transToPers(const NeutrinoHitCollection* transCont, + NeutrinoHitCollection_p1* persCont, + MsgStream &log) ; + + private: + + static const double m_persEneUnit; + static const double m_persLenUnit; + static const double m_persAngUnit; + static const double m_2bHalfMaximum; + static const int m_2bMaximum; +}; + +#endif diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollection_p1.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollection_p1.h new file mode 100644 index 00000000..631fab9d --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollection_p1.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOHITCOLLECTION_P1_H +#define NEUTRINOHITCOLLECTION_P1_H + +/* + +Authors: Davide Costanzo Rob Duxfield + +*/ + +#include <vector> +#include <string> + +class NeutrinoHitCollection_p1 +{ + public: +/// Default constructor + NeutrinoHitCollection_p1 (); + //private: + + std::vector<float> m_hit1_meanTime; // 1 element per string + std::vector<float> m_hit1_x0; // + std::vector<float> m_hit1_y0; // + std::vector<float> m_hit1_z0; // + std::vector<float> m_hit1_theta; // + std::vector<float> m_hit1_phi; // + std::vector<unsigned short> m_nHits; // + + std::vector<unsigned short> m_hitEne_2b; // 1 element per hit + std::vector<unsigned short> m_hitLength_2b; // + + std::vector<unsigned short> m_dTheta; // 1 element per hit except for first hit in string + std::vector<unsigned short> m_dPhi; // + + std::vector<float> m_hitEne_4b; // 1 element per hit with m_hitEne_2b[i] == 2**16 + + std::vector<float> m_hitLength_4b; // 1 element per hit with m_hitLength_2b[i] == 2**16 + + std::vector<unsigned long> m_barcode; + std::vector<unsigned short> m_mcEvtIndex; + std::vector<char> m_evtColl; + std::vector<unsigned short> m_nBC; + + std::vector<unsigned long> m_id; + std::vector<unsigned short> m_nId; +}; + + +// inlines + +inline +NeutrinoHitCollection_p1::NeutrinoHitCollection_p1 () {} + +#endif diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHit_p1.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHit_p1.h new file mode 100644 index 00000000..0e2bd215 --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHit_p1.h @@ -0,0 +1,19 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOHIT_P1_H +#define NEUTRINOHIT_P1_H + +#include "GeneratorObjectsTPCnv/HepMcParticleLink_p2.h" + +class NeutrinoHit_p1 { + public: + float m_stX, m_stY, m_stZ; + float m_enX, m_enY, m_enZ; + float m_energyLoss; // deposited energy + float m_meanTime; // time of energy deposition + HepMcParticleLink_p2 m_partLink; + unsigned int m_ID; +}; +#endif diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnvDict.h b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnvDict.h new file mode 100644 index 00000000..064ad71a --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnvDict.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOEVENTTPCNV_NEUTRINOSIMEVENTTPCNVDICT_H +#define NEUTRINOEVENTTPCNV_NEUTRINOSIMEVENTTPCNVDICT_H + +//----------------------------------------------------------------------------- +// +// file: NeutrinoSimEventTPCnvDict_p1.h +// +//----------------------------------------------------------------------------- + + +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCnv_p1.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollection_p1.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHit_p1.h" + +#endif // NEUTRINOEVENTTPCNV_NEUTRINOSIMEVENTTPCNVDICT_H diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/selection.xml b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/selection.xml new file mode 100644 index 00000000..6808c217 --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/NeutrinoSimEventTPCnv/selection.xml @@ -0,0 +1,7 @@ +<lcgdict> + + <!-- NeutrinoHits --> + <class name="NeutrinoHit_p1" /> + <class name="std::vector<NeutrinoHit_p1>" /> + <class name="NeutrinoHitCollection_p1" id="2CA7AF71-1494-4378-BED4-AFB5C54398AA" /> +</lcgdict> diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCnv_p1.cxx b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCnv_p1.cxx new file mode 100644 index 00000000..27325697 --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCnv_p1.cxx @@ -0,0 +1,54 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoSimEvent/NeutrinoHit.h" +#include "Identifier/Identifier.h" +#include "GeneratorObjectsTPCnv/HepMcParticleLinkCnv_p2.h" + +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHit_p1.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCnv_p1.h" + + +void +NeutrinoHitCnv_p1::persToTrans(const NeutrinoHit_p1* persObj, NeutrinoHit* transObj, MsgStream &log) +{ + HepMcParticleLinkCnv_p2 HepMcPLCnv; + HepMcParticleLink link; + HepMcPLCnv.persToTrans(&(persObj->m_partLink),&link, log); + + *transObj = NeutrinoHit (HepGeom::Point3D<double> (persObj->m_stX, + persObj->m_stY, + persObj->m_stZ), + HepGeom::Point3D<double> (persObj->m_enX, + persObj->m_enY, + persObj->m_enZ), + persObj->m_energyLoss, + persObj->m_meanTime, + link, + persObj->m_ID + ); +} + + +void +NeutrinoHitCnv_p1::transToPers(const NeutrinoHit* transObj, NeutrinoHit_p1* persObj, MsgStream &log) +{ +// if (log.level() <= MSG::DEBUG) log << MSG::DEBUG << "NeutrinoHitCnv_p1::transToPers called " << endmsg; + HepMcParticleLinkCnv_p2 HepMcPLCnv; + + HepGeom::Point3D<double> st = transObj->localStartPosition(); + persObj->m_stX = st.x(); + persObj->m_stY = st.y(); + persObj->m_stZ = st.z(); + + HepGeom::Point3D<double> en = transObj->localEndPosition(); + persObj->m_enX = en.x(); + persObj->m_enY = en.y(); + persObj->m_enZ = en.z(); + + persObj->m_energyLoss = transObj->energyLoss(); + persObj->m_meanTime = transObj->meanTime(); + persObj->m_ID = transObj->identify(); + HepMcPLCnv.transToPers(&(transObj->particleLink()),&(persObj->m_partLink), log); +} diff --git a/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCollectionCnv_p1.cxx b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCollectionCnv_p1.cxx new file mode 100644 index 00000000..3b85676a --- /dev/null +++ b/Neutrino/NeutrinoEventCnv/NeutrinoSimEventTPCnv/src/NeutrinoHits/NeutrinoHitCollectionCnv_p1.cxx @@ -0,0 +1,312 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoSimEvent/NeutrinoHit.h" +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollection_p1.h" +#include "NeutrinoSimEventTPCnv/NeutrinoHits/NeutrinoHitCollectionCnv_p1.h" +#include "GeneratorObjects/HepMcParticleLink.h" + +#include <cmath> + +//CLHEP +#include "CLHEP/Geometry/Point3D.h" +// Gaudi +#include "GaudiKernel/MsgStream.h" +// Athena +#include "StoreGate/StoreGateSvc.h" + +// * * * stolen from eflowRec * * * // +inline double phicorr(double a) +{ + if (a <= -M_PI) + { + return a+(2*M_PI*floor(-(a-M_PI)/(2*M_PI))); + } + else if (a > M_PI) + { + return a-(2*M_PI*floor((a+M_PI)/(2*M_PI))); + } + else + { + return a; + } +} + +// * * * stolen from eflowRec * * * // +inline double cycle(double a, double b) +{ + double del = b-a; + if (del > M_PI) + { + return a+2.0*M_PI; + } + else if (del < -M_PI) + { + return a-2.0*M_PI; + } + else + { + return a; + } +} + + +const double NeutrinoHitCollectionCnv_p1::m_persEneUnit = 1.0e-5; +const double NeutrinoHitCollectionCnv_p1::m_persLenUnit = 1.0e-5; +const double NeutrinoHitCollectionCnv_p1::m_persAngUnit = 1.0e-5; +const double NeutrinoHitCollectionCnv_p1::m_2bHalfMaximum = pow(2.0, 15.0); +const int NeutrinoHitCollectionCnv_p1::m_2bMaximum = (unsigned short)(-1); + + +void NeutrinoHitCollectionCnv_p1::transToPers(const NeutrinoHitCollection* transCont, NeutrinoHitCollection_p1* persCont, MsgStream &/*log*/) +{ + // Finds hits belonging to a "string" (in which the end point of one hit is the same as the start point of the next) and + // persistifies the end point of each hit plus the start point of the first hit in each string. + // + // Further compression is achieved by optimising the storage of the position vectors:- start (x,y,z) and (theta,phi) of + // first hit are stored as floats, (delta_theta,delta_phi) relative to the fisrst hit are stored as 2 byte numbers and + // used to specify the hit direction. All hit lengths are stored as 2 byte numbers. + // + // Additional savings are achieved by storing the energy loss for each hit as a 2 byte number and only storing the mean + // time of the first hit per string. + // + // See http://indico.cern.ch/getFile.py/access?contribId=11&resId=2&materialId=slides&confId=30893 for more info. + + static const double dRcut = 1.0e-7; + static const double dTcut = 1.0; + + const HepMcParticleLink * lastLink=nullptr; + int lastId = -1; + double stringFirstTheta = 0.0; + double stringFirstPhi = 0.0; + double lastT = 0.0; + double persSumE = 0.0; + double transSumE = 0.0; + unsigned int idx = 0; + unsigned int endBC = 0; + unsigned int endId = 0; + unsigned int endHit = 0; + HepGeom::Point3D<double> lastTransEnd(0.0, 0.0, 0.0); + HepGeom::Point3D<double> lastPersEnd(0.0, 0.0, 0.0); + + for (NeutrinoHitCollection::const_iterator it = transCont->begin(); it != transCont->end(); ++it) { + + NeutrinoHitCollection::const_iterator siHit = it; + + + if ( !lastLink || (siHit->particleLink() != *lastLink) ) { + + // store barcode once for set of consecutive hits with same barcode + + lastLink = &(siHit->particleLink()); + persCont->m_barcode.push_back(lastLink->barcode()); + persCont->m_mcEvtIndex.push_back(lastLink->eventIndex()); + persCont->m_evtColl.push_back(lastLink->getEventCollectionAsChar()); + + if (idx > 0) { + persCont->m_nBC.push_back(idx - endBC); + endBC = idx; + } + } + + if ( (int)siHit->identify() != lastId ) { + + // store id once for set of consecutive hits with same barcode + + lastId = siHit->identify(); + persCont->m_id.push_back(lastId); + + if (idx > 0) { + persCont->m_nId.push_back(idx - endId); + endId = idx; + } + } + + HepGeom::Point3D<double> st = siHit->localStartPosition(); + HepGeom::Point3D<double> en = siHit->localEndPosition(); + + const double dx = st.x() - lastTransEnd.x(); + const double dy = st.y() - lastTransEnd.y(); + const double dz = st.z() - lastTransEnd.z(); + const double t = siHit->meanTime(); + + const double dRLast = sqrt(dx * dx + dy * dy + dz * dz); // dR between end of previous hit and start of current one + const double dTLast = fabs(t - lastT); + + CLHEP::Hep3Vector direction(0.0, 0.0, 0.0); + double theta = 0.0; + double phi = 0.0; + bool startNewString = false; + + if (dRLast < dRcut && dTLast < dTcut) { + + // hit is part of existing string + + direction = CLHEP::Hep3Vector( en.x() - lastPersEnd.x(), en.y() - lastPersEnd.y(), en.z() - lastPersEnd.z() ); + + theta = direction.theta(); + phi = phicorr( direction.phi() ); + + const int dTheta_2b = (int)( (theta - stringFirstTheta) / m_persAngUnit + m_2bHalfMaximum + 0.5 ); + const int dPhi_2b = (int)( (cycle(phi, stringFirstPhi) - stringFirstPhi) / m_persAngUnit + m_2bHalfMaximum + 0.5 ); + + if ( dTheta_2b < m_2bMaximum && dTheta_2b >= 0 && dPhi_2b < m_2bMaximum && dPhi_2b >= 0) { + persCont->m_dTheta.push_back(dTheta_2b); + persCont->m_dPhi.push_back(dPhi_2b); + theta = stringFirstTheta + ( (double)dTheta_2b - m_2bHalfMaximum ) * m_persAngUnit; + phi = stringFirstPhi + ( (double)dPhi_2b - m_2bHalfMaximum ) * m_persAngUnit; + phi = phicorr(phi); + } + else { + startNewString = true; + } + } + + if (startNewString || dRLast >= dRcut || dTLast >= dTcut) { + + // begin new hit string + + direction = CLHEP::Hep3Vector( en.x() - st.x(), en.y() - st.y(), en.z() - st.z() ); + + theta = direction.theta(); + phi = phicorr( direction.phi() ); + + persCont->m_hit1_meanTime.push_back(t); + persCont->m_hit1_x0.push_back(st.x()); + persCont->m_hit1_y0.push_back(st.y()); + persCont->m_hit1_z0.push_back(st.z()); + persCont->m_hit1_theta.push_back(theta); + persCont->m_hit1_phi.push_back(phi); + + lastPersEnd = HepGeom::Point3D<double>(st.x(), st.y(), st.z()); + + stringFirstTheta = theta; + stringFirstPhi = phi; + + if (idx > 0) { + persCont->m_nHits.push_back(idx - endHit); + endHit = idx; + } + } + + lastTransEnd = HepGeom::Point3D<double>(en.x(), en.y(), en.z()); + transSumE += siHit->energyLoss(); + + const int eneLoss_2b = (int)((transSumE - persSumE) / m_persEneUnit + 0.5); // calculated to allow recovery sum over + // whole hit string to chosen precision + + const int hitLength_2b = (int)(direction.mag() / m_persLenUnit + 0.5); // calculated to give the correct position to + // the chosen precision, NOT the length of the + // hit (small difference in practice). + double eneLoss = 0.0; + + if (eneLoss_2b >= m_2bMaximum) { + eneLoss = siHit->energyLoss(); + persCont->m_hitEne_2b.push_back(m_2bMaximum); + persCont->m_hitEne_4b.push_back(eneLoss); + } + else { + eneLoss = eneLoss_2b * m_persEneUnit; + persCont->m_hitEne_2b.push_back(eneLoss_2b); + } + + double length = 0.0; + + if (hitLength_2b >= m_2bMaximum) { + length = direction.mag(); + persCont->m_hitLength_2b.push_back(m_2bMaximum); + persCont->m_hitLength_4b.push_back(direction.mag()); + } + else { + length = hitLength_2b * m_persLenUnit; + persCont->m_hitLength_2b.push_back(hitLength_2b); + } + + CLHEP::Hep3Vector persDir(length, 0.0, 0.0); + persDir.setTheta(theta); + persDir.setPhi(phi); + + lastPersEnd = (CLHEP::Hep3Vector)lastPersEnd + persDir; + persSumE += eneLoss; + lastT = t; + + ++idx; + } + + persCont->m_nBC.push_back(idx - endBC); + persCont->m_nId.push_back(idx - endId); + persCont->m_nHits.push_back(idx - endHit); +} + + +NeutrinoHitCollection* NeutrinoHitCollectionCnv_p1::createTransient(const NeutrinoHitCollection_p1* persObj, MsgStream &log) { + std::unique_ptr<NeutrinoHitCollection> trans(std::make_unique<NeutrinoHitCollection>("DefaultCollectionName",persObj->m_nHits.size())); + persToTrans(persObj, trans.get(), log); + return(trans.release()); +} + + +void NeutrinoHitCollectionCnv_p1::persToTrans(const NeutrinoHitCollection_p1* persCont, NeutrinoHitCollection* transCont, MsgStream &/*log*/) +{ + unsigned int hitCount = 0; + unsigned int angleCount = 0; + unsigned int idxBC = 0; + unsigned int idxId = 0; + unsigned int idxEne4b = 0; + unsigned int idxLen4b = 0; + unsigned int endHit = 0; + unsigned int endBC = 0; + unsigned int endId = 0; + + for (unsigned int i = 0; i < persCont->m_nHits.size(); i++) { + + if (persCont->m_nHits[i]) { + + const unsigned int start = endHit; + endHit += persCont->m_nHits[i]; + + const double t0 = persCont->m_hit1_meanTime[i]; + const double theta0 = persCont->m_hit1_theta[i]; + const double phi0 = persCont->m_hit1_phi[i]; + HepGeom::Point3D<double> endLast(persCont->m_hit1_x0[i], persCont->m_hit1_y0[i], persCont->m_hit1_z0[i]); + + for (unsigned int j = start; j < endHit; j++) { + + if (j >= endBC + persCont->m_nBC[idxBC]) + endBC += persCont->m_nBC[idxBC++]; + + if (j >= endId + persCont->m_nId[idxId]) + endId += persCont->m_nId[idxId++]; + + const double eneLoss_2b = persCont->m_hitEne_2b[hitCount]; + const double hitLength_2b = persCont->m_hitLength_2b[hitCount]; + + const double eneLoss = (eneLoss_2b < m_2bMaximum) ? eneLoss_2b * m_persEneUnit : persCont->m_hitEne_4b[idxEne4b++]; + const double length = (hitLength_2b < m_2bMaximum) ? hitLength_2b * m_persLenUnit : persCont->m_hitLength_4b[idxLen4b++]; + + const double dTheta = (j > start) ? ((double)persCont->m_dTheta[angleCount] - m_2bHalfMaximum) * m_persAngUnit : 0.0; + const double dPhi = (j > start) ? ((double)persCont->m_dPhi[angleCount] - m_2bHalfMaximum) * m_persAngUnit : 0.0; + + const double meanTime = t0; + const double theta = theta0 + dTheta; + const double phi = phicorr(phi0 + dPhi); + + CLHEP::Hep3Vector r(length, 0.0, 0.0); + r.setTheta(theta); + r.setPhi(phi); + + HepGeom::Point3D<double> endThis( endLast + r ); + + HepMcParticleLink partLink( persCont->m_barcode[idxBC], persCont->m_mcEvtIndex[idxBC], HepMcParticleLink::ExtendedBarCode::eventCollectionFromChar(persCont->m_evtColl[idxBC]), HepMcParticleLink::IS_INDEX ); + transCont->Emplace( endLast, endThis, eneLoss, meanTime, partLink, persCont->m_id[idxId]); + + endLast = endThis; + + ++hitCount; + if (j > start) ++angleCount; + } + } + } +} diff --git a/Neutrino/NeutrinoG4/EmulsionG4_SD/CMakeLists.txt b/Neutrino/NeutrinoG4/EmulsionG4_SD/CMakeLists.txt new file mode 100644 index 00000000..5ce584bd --- /dev/null +++ b/Neutrino/NeutrinoG4/EmulsionG4_SD/CMakeLists.txt @@ -0,0 +1,22 @@ +################################################################################ +# Package: EmulsionG4_SD +################################################################################ + +# Declare the package name: +atlas_subdir( EmulsionG4_SD ) + +# External dependencies: +find_package( CLHEP ) +find_package( Geant4 ) +find_package( XercesC ) + +# Component(s) in the package: +atlas_add_component( EmulsionG4_SD + src/*.cxx + src/components/*.cxx + INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} + LINK_LIBRARIES ${GEANT4_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} StoreGateLib SGtests GaudiKernel NeutrinoSimEvent G4AtlasToolsLib FaserMCTruth ) + +# Install files from the package: +atlas_install_python_modules( python/*.py ) + diff --git a/Neutrino/NeutrinoG4/EmulsionG4_SD/python/EmulsionG4_SDToolConfig.py b/Neutrino/NeutrinoG4/EmulsionG4_SD/python/EmulsionG4_SDToolConfig.py new file mode 100644 index 00000000..391e572a --- /dev/null +++ b/Neutrino/NeutrinoG4/EmulsionG4_SD/python/EmulsionG4_SDToolConfig.py @@ -0,0 +1,21 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AthenaConfiguration.ComponentFactory import CompFactory + +EmulsionSensorSDTool=CompFactory.EmulsionSensorSDTool + +def EmulsionSensorSDCfg(ConfigFlags, name="EmulsionSensorSD", **kwargs): + + result = ComponentAccumulator() + bare_collection_name = "EmulsionHits" + # mergeable_collection_suffix = "_G4" + # merger_input_property = "PreshowerHits" + + # acc, hits_collection_name = CollectionMergerCfg(ConfigFlags, bare_collection_name, mergeable_collection_suffix, merger_input_property, "SCINT") + # kwargs.setdefault("OutputCollectionNames", [hits_collection_name]) + kwargs.setdefault("LogicalVolumeNames", ["Emulsion::FrontFilm", "Emulsion::BackFilm"]) + kwargs.setdefault("OutputCollectionNames", [bare_collection_name]) + + # result.merge(acc) + return result, EmulsionSensorSDTool(name, **kwargs) diff --git a/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.cxx b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.cxx new file mode 100644 index 00000000..1f0fb78f --- /dev/null +++ b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.cxx @@ -0,0 +1,119 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +// +// Emulsion Sensitive Detector. +// The Hits are processed here. For every hit I get the position and +// an information on the sensor in which the interaction happened +// + +// class headers +#include "EmulsionSensorSD.h" + +// athena includes +#include "FaserMCTruth/FaserTrackHelper.h" + +// Geant4 includes +#include "G4Step.hh" +#include "G4ThreeVector.hh" +#include "G4SDManager.hh" +#include "G4Geantino.hh" +#include "G4ChargedGeantino.hh" + +// CLHEP transform +#include "CLHEP/Geometry/Transform3D.h" + +#include <memory> // For make unique + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +EmulsionSensorSD::EmulsionSensorSD( const std::string& name, const std::string& hitCollectionName ) + : G4VSensitiveDetector( name ) + , m_HitColl( hitCollectionName ) +{ +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +void EmulsionSensorSD::Initialize(G4HCofThisEvent *) +{ + if (!m_HitColl.isValid()) m_HitColl = std::make_unique<NeutrinoHitCollection>(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +G4bool EmulsionSensorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* /*ROhist*/) +{ + double edep = aStep->GetTotalEnergyDeposit(); + if(edep==0.) { + if(aStep->GetTrack()->GetDefinition()!=G4Geantino::GeantinoDefinition() && + aStep->GetTrack()->GetDefinition()!=G4ChargedGeantino::ChargedGeantinoDefinition()) + return false; + } + edep *= CLHEP::MeV; + + // + // Get the Touchable History: + // + const G4TouchableHistory *myTouch = dynamic_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable()); + // + // Get the hit coordinates. Start and End Point + // + G4ThreeVector coord1 = aStep->GetPreStepPoint()->GetPosition(); + G4ThreeVector coord2 = aStep->GetPostStepPoint()->GetPosition(); + // + // Calculate the local step begin and end position. + // From a G4 FAQ: + // http://geant4-hn.slac.stanford.edu:5090/HyperNews/public/get/geometry/17/1.html + // + const G4AffineTransform transformation = myTouch->GetHistory()->GetTopTransform(); + + G4ThreeVector localPosition1 = transformation.TransformPoint(coord1); + G4ThreeVector localPosition2 = transformation.TransformPoint(coord2); + // + // Get it into a vector in local coords and with the right units: + // + HepGeom::Point3D<double> lP1,lP2; + + // No funny business with coordinates like ATLAS... + lP1[2] = localPosition1[2]*CLHEP::mm; + lP1[1] = localPosition1[1]*CLHEP::mm; + lP1[0] = localPosition1[0]*CLHEP::mm; + + lP2[2] = localPosition2[2]*CLHEP::mm; + lP2[1] = localPosition2[1]*CLHEP::mm; + lP2[0] = localPosition2[0]*CLHEP::mm; + + // Now Navigate the history to know in what detector the step is: + // and finally set the ID of det element in which the hit is. + // + //G4int History; + // + // Get station and plate + // + int module = 0; + int base = 0; + int film = 0; + this->indexMethod(myTouch, module, base, film); + // get the HepMcParticleLink from the TrackHelper + FaserTrackHelper trHelp(aStep->GetTrack()); + m_HitColl->Emplace(lP1, + lP2, + edep, + aStep->GetPreStepPoint()->GetGlobalTime(),//use the global time. i.e. the time from the beginning of the event + trHelp.GetParticleLink(), + module,base,film); + return true; +} + +void EmulsionSensorSD::indexMethod(const G4TouchableHistory *myTouch, + int &module, int &base, int &film) { + + film = myTouch->GetVolume()->GetCopyNo(); + G4int moduleAndBase = myTouch->GetVolume(1)->GetCopyNo(); + base = moduleAndBase%100; + module = moduleAndBase/100; + // std::cout << "Emulsion hit at " << module << " / " << base << " / " << film << std::endl; + return; +} diff --git a/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.h b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.h new file mode 100644 index 00000000..9f344194 --- /dev/null +++ b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSD.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +/**************************************************************** + Emulsion Sensitive Detector class +****************************************************************/ + +#ifndef EMULSIONG4_SD_EMULSIONSENSORSD_H +#define EMULSIONG4_SD_EMULSIONSENSORSD_H + +// Base class +#include "G4VSensitiveDetector.hh" + +// For the hits +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" +#include "StoreGate/WriteHandle.h" + +// G4 needed classes +class G4Step; +class G4TouchableHistory; + +// G4 needed classes +#include "Geant4/G4EnergyLossTables.hh" +#include "Geant4/G4Material.hh" +#include "Geant4/G4MaterialCutsCouple.hh" + +class EmulsionSensorSD : public G4VSensitiveDetector +{ +public: + // Constructor + EmulsionSensorSD(const std::string& name, const std::string& hitCollectionName); + + // Destructor + ~EmulsionSensorSD() { /* If all goes well we do not own myHitColl here */ } + + // Deal with each G4 hit + G4bool ProcessHits(G4Step*, G4TouchableHistory*) override; + + // For setting up the hit collection + void Initialize(G4HCofThisEvent*) override final; + + /** Templated method to stuff a single hit into the sensitive detector class. This + could get rather tricky, but the idea is to allow fast simulations to use the very + same SD classes as the standard simulation. */ + template <class... Args> void AddHit(Args&&... args){ m_HitColl->Emplace( args... ); } + +private: + void indexMethod(const G4TouchableHistory *myTouch, int &module, int &base, int &film); + +protected: + // The hits collection + SG::WriteHandle<NeutrinoHitCollection> m_HitColl; + +}; + +#endif //EMULSIONG4_SD_EMULSIONSENSORSD_H diff --git a/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.cxx b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.cxx new file mode 100644 index 00000000..bea30a8c --- /dev/null +++ b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.cxx @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// Emulsion Sensitive Detector Tool. +// + +// class header +#include "EmulsionSensorSDTool.h" + +// package includes +#include "EmulsionSensorSD.h" + +// STL includes +#include <exception> + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +EmulsionSensorSDTool::EmulsionSensorSDTool(const std::string& type, const std::string& name, const IInterface* parent) + : SensitiveDetectorBase( type , name , parent ) +{ + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +G4VSensitiveDetector* EmulsionSensorSDTool::makeSD() const +{ + ATH_MSG_DEBUG( "Creating Emulsion SD: " << name() ); + + EmulsionSensorSD* ecsd = new EmulsionSensorSD(name(), m_outputCollectionNames[0]); + + return ecsd; +} + diff --git a/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.h b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.h new file mode 100644 index 00000000..ce68d061 --- /dev/null +++ b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/EmulsionSensorSDTool.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/**************************************************************** + Emulsion Sensitive Detector Tool + ****************************************************************/ + +#ifndef EMULSIONG4_SD_EMULSIONSENSORSDTOOL_H +#define EMULSIONG4_SD_EMULSIONSENSORSDTOOL_H + +// Base class +#include "G4AtlasTools/SensitiveDetectorBase.h" + +// STL headers +#include <string> + +class G4VSensitiveDetector; + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... + +class EmulsionSensorSDTool : public SensitiveDetectorBase +{ + +public: + // Constructor + EmulsionSensorSDTool(const std::string& type, const std::string& name, const IInterface *parent); + + // Destructor + ~EmulsionSensorSDTool() { /* If all goes well we do not own myHitColl here */ } + +protected: + // Make me an SD! + G4VSensitiveDetector* makeSD() const override final; + +private: + +}; + +#endif //EMULSIONG4_SD_EMULSIONSENSORSDTOOL_H diff --git a/Neutrino/NeutrinoG4/EmulsionG4_SD/src/components/EmulsionG4_SD_entries.cxx b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/components/EmulsionG4_SD_entries.cxx new file mode 100644 index 00000000..4fda433c --- /dev/null +++ b/Neutrino/NeutrinoG4/EmulsionG4_SD/src/components/EmulsionG4_SD_entries.cxx @@ -0,0 +1,3 @@ +#include "../EmulsionSensorSDTool.h" + +DECLARE_COMPONENT( EmulsionSensorSDTool ) diff --git a/Neutrino/NeutrinoSimEvent/CMakeLists.txt b/Neutrino/NeutrinoSimEvent/CMakeLists.txt new file mode 100644 index 00000000..bedc06bd --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/CMakeLists.txt @@ -0,0 +1,28 @@ +################################################################################ +# Package: NeutrinoSimEvent +################################################################################ + +# Declare the package name: +atlas_subdir( NeutrinoSimEvent ) + +# External dependencies: +find_package( CLHEP ) +find_package( Geant4 ) +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_library( NeutrinoSimEvent + src/*.cxx + PUBLIC_HEADERS NeutrinoSimEvent + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} + PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} + DEFINITIONS ${CLHEP_DEFINITIONS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} AthAllocators AthenaKernel CxxUtils GeneratorObjects HitManagement StoreGateLib SGtests + PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} NeutrinoIdentifier ) + +atlas_add_dictionary( NeutrinoSimEventDict + NeutrinoSimEvent/NeutrinoSimEventDict.h + NeutrinoSimEvent/selection.xml + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthAllocators CxxUtils GeneratorObjects HitManagement StoreGateLib SGtests NeutrinoIdentifier NeutrinoSimEvent ) + diff --git a/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHit.h b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHit.h new file mode 100644 index 00000000..1d28bd3e --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHit.h @@ -0,0 +1,183 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// NeutrinoHit.h +// Header file for class NeutrinoHit +/////////////////////////////////////////////////////////////////// +// Class for Emulsion hits +/////////////////////////////////////////////////////////////////// + +#ifndef NEUTRINOSIMEVENT_NEUTRINOHIT_H +#define NEUTRINOSIMEVENT_NEUTRINOHIT_H + +// Data members classes +#include "CLHEP/Geometry/Point3D.h" +#include "GeneratorObjects/HepMcParticleLink.h" + +class NeutrinoHit { + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// +public: + + // Constructor with parameters: + // local start position of the energy deposit + // local end position of the energy deposit + // deposited energy + // time of energy deposition + // number of track which released this energy + // + NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const int trackNumber, + const unsigned int id); + + NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const int trackNumber, + const int, const int, const int); + // Constructor with parameters: + // local start position of the energy deposit + // local end position of the energy deposit + // deposited energy + // time of energy deposition + // link to particle which released this energy + // + NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const HepMcParticleLink &track, + const unsigned int id); + + NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const HepMcParticleLink &track, + const int, const int, const int); + // needed by athenaRoot + NeutrinoHit(); + + // Destructor: + virtual ~NeutrinoHit(); + + //move assignment defaulted + NeutrinoHit & operator = (NeutrinoHit &&) = default; + //assignment defaulted + NeutrinoHit & operator = (const NeutrinoHit &) = default; + //copy c'tor defaulted + NeutrinoHit(const NeutrinoHit &) = default; + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + unsigned int identify() const; + + // local start position of the energy deposit: + HepGeom::Point3D<double> localStartPosition() const; + + HepGeom::Point3D<double> localEndPosition() const; + + // deposited energy: + double energyLoss() const; + + // time of energy deposition: FIXME name! + double meanTime() const; + + // Set the time of energy deposition: FIXME name! + void setMeanTime(float meanTime); + + // number of track which released this energy: + int trackNumber() const; + + // link to the particle generating the hit + const HepMcParticleLink& particleLink() const; + + // Film + int getFilm() const; + + // Base + int getBase() const; + + // Module + int getModule() const; + + // some print-out: + void print() const; + + bool operator < (const NeutrinoHit& rhs) const + {return m_ID < rhs.m_ID;} + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + // Scale the length, used to go from cm to mm, of whatever we like. + void ScaleLength(double); + + /////////////////////////////////////////////////////////////////// + // Private data: + /////////////////////////////////////////////////////////////////// +private: + + float m_stX, m_stY, m_stZ; + float m_enX, m_enY, m_enZ; + float m_energyLoss; // deposited energy + float m_meanTime; // time of energy deposition + HepMcParticleLink m_partLink; + unsigned int m_ID; +public: + // enum + // { xDep = 2, xPhi = 0, xEta = 1}; +}; + + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// + +inline unsigned int NeutrinoHit::identify() const +{ + return m_ID; +} + +inline double NeutrinoHit::energyLoss() const +{ + return (double) m_energyLoss; +} + +inline double NeutrinoHit::meanTime() const +{ + return (double) m_meanTime; +} + +inline void NeutrinoHit::setMeanTime(float meanTime) +{ + m_meanTime=meanTime; +} + +inline const HepMcParticleLink& NeutrinoHit::particleLink() const +{ + return m_partLink; +} + + + +/////////////////////////////////////////////////////////////////// +// open functions: +/////////////////////////////////////////////////////////////////// + +inline float hitTime(const NeutrinoHit& hit) +{ + return (float) hit.meanTime(); +} + +#endif // CALOSIMEVENT_CALOHIT_H diff --git a/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitCollection.h b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitCollection.h new file mode 100644 index 00000000..68461270 --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitCollection.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOSIMEVENT_NEUTRINOHITCOLLECTION_H +#define NEUTRINOSIMEVENT_NEUTRINOHITCOLLECTION_H + +#include "NeutrinoSimEvent/NeutrinoHit.h" +#include "HitManagement/AtlasHitsVector.h" +#include "AthenaKernel/CLASS_DEF.h" + +typedef AtlasHitsVector<NeutrinoHit> NeutrinoHitCollection; +typedef AtlasHitsVector<NeutrinoHit>::iterator NeutrinoHitIterator; +typedef AtlasHitsVector<NeutrinoHit>::const_iterator NeutrinoHitConstIterator; + +#ifndef __CINT__ + CLASS_DEF(NeutrinoHitCollection, 1232962600, 1 ) +#endif + +#endif // NEUTRINOSIMEVENT_NEUTRINOHITCOLLECTION_H diff --git a/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitIdHelper.h b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitIdHelper.h new file mode 100644 index 00000000..afa362e6 --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoHitIdHelper.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOSIMEVENT_NEUTRINOHITIDHELPER +#define NEUTRINOSIMEVENT_NEUTRINOHITIDHELPER + +// +// This is a helper class to build an identifing integer used by +// the simulation. It inherits from HitIdHelper, in order to get +// all the packing and shifting for free. +// The class is a singleton and a static GetHelper() is provided +// the constructor calls the Initialize() method which sets all the +// field dimensions +// Methods are provided to get access to the Geometry +// description +// + + +// +// Base Class +#include "HitManagement/HitIdHelper.h" + +// This class is singleton and static method and variable are used. +#include "CxxUtils/checker_macros.h" +ATLAS_NO_CHECK_FILE_THREAD_SAFETY; + +class NeutrinoHitIdHelper : HitIdHelper { + public: + // + // Access to the helper + static NeutrinoHitIdHelper* GetHelper(); + // + + // Front or back + int getFilm(const int& hid) const; + + // Which base + int getBase(const int& hid) const; + + // Which module + int getModule(const int& hid) const; + + // + // Info packing: + int buildHitId(const int module, const int base, const int film) const; + + private: + // + // private constructor to have a singleton + NeutrinoHitIdHelper(); + // + // Initialize the helper, only called by the constructor + void Initialize(); +}; + +#endif // NEUTRINOSIMEVENT_NEUTRINOHITIDHELPER diff --git a/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoSimEventDict.h b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoSimEventDict.h new file mode 100644 index 00000000..6f47010a --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/NeutrinoSimEventDict.h @@ -0,0 +1,10 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NEUTRINOSIMEVENT_NEUTRINOSIMEVENTDICT_H +#define NEUTRINOSIMEVENT_NEUTRINOSIMEVENTDICT_H + +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" + +#endif \ No newline at end of file diff --git a/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/selection.xml b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/selection.xml new file mode 100644 index 00000000..fd375268 --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/NeutrinoSimEvent/selection.xml @@ -0,0 +1,5 @@ +<lcgdict> + <class name="AtlasHitsVector<NeutrinoHit>" /> + <class name="std::vector<NeutrinoHit>" /> + <class name="NeutrinoHit" /> +</lcgdict> diff --git a/Neutrino/NeutrinoSimEvent/src/NeutrinoHit.cxx b/Neutrino/NeutrinoSimEvent/src/NeutrinoHit.cxx new file mode 100644 index 00000000..0101b412 --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/src/NeutrinoHit.cxx @@ -0,0 +1,159 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "NeutrinoSimEvent/NeutrinoHit.h" +#include "NeutrinoSimEvent/NeutrinoHitIdHelper.h" + +// Default consdtructor needed by athenaroot +// +NeutrinoHit::NeutrinoHit( ) : + m_stX(0.), + m_stY(0.), + m_stZ(0.), + m_enX(0.), + m_enY(0.), + m_enZ(0.), + m_energyLoss(0.), + m_meanTime(0.), + m_partLink(), + m_ID(0xffff) +{ + +} + +NeutrinoHit::~NeutrinoHit() {} + + +// Constructor +NeutrinoHit::NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const int trackNumber, + const unsigned int id) : + m_stX( (float) localStartPosition.x() ), + m_stY( (float) localStartPosition.y() ), + m_stZ( (float) localStartPosition.z() ), + m_enX( (float) localEndPosition.x() ), + m_enY( (float) localEndPosition.y() ), + m_enZ( (float) localEndPosition.z() ), + m_energyLoss(energyLoss), + m_meanTime(meanTime), + m_partLink(trackNumber), + m_ID(id) +{ +} + +// Constructor +NeutrinoHit::NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const int trackNumber, + // const int veto_trigger_preshower, + const int module, + const int base, + const int film) : + m_stX( (float) localStartPosition.x() ), + m_stY( (float) localStartPosition.y() ), + m_stZ( (float) localStartPosition.z() ), + m_enX( (float) localEndPosition.x() ), + m_enY( (float) localEndPosition.y() ), + m_enZ( (float) localEndPosition.z() ), + m_energyLoss(energyLoss), + m_meanTime(meanTime), + m_partLink(trackNumber), + m_ID(0) +{ + // Compress the location info into the integer: + m_ID = NeutrinoHitIdHelper::GetHelper()->buildHitId( module, base, film); +} + +// Constructor +NeutrinoHit::NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const HepMcParticleLink &track, + const unsigned int id) : + m_stX( (float) localStartPosition.x() ), + m_stY( (float) localStartPosition.y() ), + m_stZ( (float) localStartPosition.z() ), + m_enX( (float) localEndPosition.x() ), + m_enY( (float) localEndPosition.y() ), + m_enZ( (float) localEndPosition.z() ), + m_energyLoss(energyLoss), + m_meanTime(meanTime), + m_partLink(track), + m_ID(id) +{ +} + +// Constructor +NeutrinoHit::NeutrinoHit(const HepGeom::Point3D<double> &localStartPosition, + const HepGeom::Point3D<double> &localEndPosition, + const double energyLoss, + const double meanTime, + const HepMcParticleLink &track, + // const int veto_trigger_preshower, + const int module, + const int base, + const int film) : + m_stX( (float) localStartPosition.x() ), + m_stY( (float) localStartPosition.y() ), + m_stZ( (float) localStartPosition.z() ), + m_enX( (float) localEndPosition.x() ), + m_enY( (float) localEndPosition.y() ), + m_enZ( (float) localEndPosition.z() ), + m_energyLoss(energyLoss), + m_meanTime(meanTime), + m_partLink(track), + m_ID(0) +{ + // Compress the location info into the integer: + m_ID = NeutrinoHitIdHelper::GetHelper()->buildHitId( module, base, film); +} + +void NeutrinoHit::ScaleLength(double sfactor) { + m_stX *= (float) sfactor; + m_stY *= (float) sfactor; + m_stZ *= (float) sfactor; + m_enX *= (float) sfactor; + m_enY *= (float) sfactor; + m_enZ *= (float) sfactor; +} + +HepGeom::Point3D<double> NeutrinoHit::localStartPosition() const +{ + return HepGeom::Point3D<double>((double) m_stX, (double) m_stY, (double) m_stZ); +} + +HepGeom::Point3D<double> NeutrinoHit::localEndPosition() const +{ + return HepGeom::Point3D<double>((double) m_enX, (double) m_enY, (double) m_enZ); +} + +int NeutrinoHit::getFilm() const { + return NeutrinoHitIdHelper::GetHelper()->getFilm(m_ID); +} + +int NeutrinoHit::getBase() const { + return NeutrinoHitIdHelper::GetHelper()->getBase(m_ID); +} + +int NeutrinoHit::getModule() const { + return NeutrinoHitIdHelper::GetHelper()->getModule(m_ID); +} + +void NeutrinoHit::print() const { + std::cout << "*** Neutrino Hit" << std::endl; + std::cout << " Module Number " << getModule() << std::endl; + std::cout << " Base Number " << getBase() << std::endl; + std::cout << " Film Number " << getFilm() << std::endl; +} + +int NeutrinoHit::trackNumber() const +{ + return m_partLink.barcode(); +} diff --git a/Neutrino/NeutrinoSimEvent/src/NeutrinoHitIdHelper.cxx b/Neutrino/NeutrinoSimEvent/src/NeutrinoHitIdHelper.cxx new file mode 100644 index 00000000..8b60d732 --- /dev/null +++ b/Neutrino/NeutrinoSimEvent/src/NeutrinoHitIdHelper.cxx @@ -0,0 +1,85 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include <mutex> + +#include "NeutrinoSimEvent/NeutrinoHitIdHelper.h" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/StoreGateSvc.h" +#include "NeutrinoIdentifier/EmulsionID.h" + +#include "G4Types.hh" +#ifdef G4MULTITHREADED +# include "GaudiKernel/ContextSpecificPtr.h" +#endif + +static std::mutex sgMutex; + +// This class is singleton and static method and variable are used. +ATLAS_NO_CHECK_FILE_THREAD_SAFETY; + +// +// private constructor +NeutrinoHitIdHelper::NeutrinoHitIdHelper() :HitIdHelper() { + Initialize(); +} + +NeutrinoHitIdHelper* NeutrinoHitIdHelper::GetHelper() { +#ifdef G4MULTITHREADED + // Context-specific singleton + static Gaudi::Hive::ContextSpecificPtr<NeutrinoHitIdHelper> helperPtr; + if(!helperPtr) helperPtr = new NeutrinoHitIdHelper(); + return helperPtr.get(); +#else + static NeutrinoHitIdHelper helper; + return &helper; +#endif +} + +void NeutrinoHitIdHelper::Initialize() { + + // determine whether hits were created with an SLHC dictionary + // in which case eta module field is expanded. + // Need to lock this thread-unsafe retrieval + const EmulsionID* pix; + ServiceHandle<StoreGateSvc> detStore ("DetectorStore", "NeutrinoHitIdHelper"); + if (detStore.retrieve().isSuccess()) { + if (detStore->retrieve(pix, "EmulsionID").isFailure()) { pix = 0; } + } + + InitializeField("Module", 0, 34); + InitializeField("Base", 0, 21); + InitializeField("Film", 0, 1); +} + +// Module +int NeutrinoHitIdHelper::getModule(const int& hid) const +{ + return this->GetFieldValue("Module", hid); +} + +// Base +int NeutrinoHitIdHelper::getBase(const int& hid) const +{ + return this->GetFieldValue("Base", hid); +} + +// Film +int NeutrinoHitIdHelper::getFilm(const int& hid) const +{ + return this->GetFieldValue("Film", hid); +} + +// +// Info packing: +int NeutrinoHitIdHelper::buildHitId( const int module, + const int base, + const int film) const +{ + int theID(0); + this->SetFieldValue("Module", module, theID); + this->SetFieldValue("Base", base, theID); + this->SetFieldValue("Film", film, theID); + return theID; +} diff --git a/README.md b/README.md index 5e46f46f..00cfe12e 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,27 @@ cd build cmake -DCMAKE_INSTALL_PREFIX=../run ../calypso ; make ; make install ``` +Before running anything, it is MANDATORY to do: + +``` +cd ../run +source ./setup.sh +``` + +Don't omit the dot in the `source ./setup.sh` command! + It can be convenient to alias the "asetup --input=calypso/asetup.faser" to something like "fsetup" ## Known issues: -* The "WriteAlignment" example program does not compile, and is disabled. The example will be replaced eventually. +* It is now essential to use the tags `ConfigFlags.GeoModel.FaserVersion` and `ConfigFlags.IOVDb.GlobalTag` in a consistent way. If nothing is specified the first option (baseline) should be chosen by default. + +** `ConfigFlags.GeoModel.FaserVersion = "FASER-01"` and `ConfigFlags.IOVDb.GlobalTag = OFLCOND-FASER-01` enables the baseline TI-12 detector + +** `ConfigFlags.GeoModel.FaserVersion = "FASER-02"` and `ConfigFlags.IOVDb.GlobalTag = OFLCOND-FASER-02` enables the interface tracker and repositioned Veto + +** `ConfigFlags.GeoModel.FaserVersion = "FASERNU-02"` and `ConfigFlags.IOVDb.GlobalTag = OFLCOND-FASER-02` enables the full FaserNu (IFT + emulsion) setup * The "FaserActsKalmanFilter" package is temporarily disabled. -* The command `lsetup "lcgenv -p LCG_98python3_ATLAS_8 x86_64-centos7-gcc8-opt sqlite` may be necessary to avoid errors when generating a database +* The command `lsetup "lcgenv -p LCG_98python3_ATLAS_8 x86_64-centos7-gcc8-opt sqlite"` may be necessary to avoid errors when generating a database diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/test/PreshowerGMConfig_test.py b/Scintillator/ScintDetDescr/PreshowerGeoModel/test/PreshowerGMConfig_test.py index 2c250126..fd370954 100644 --- a/Scintillator/ScintDetDescr/PreshowerGeoModel/test/PreshowerGMConfig_test.py +++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/test/PreshowerGMConfig_test.py @@ -10,7 +10,7 @@ if __name__ == "__main__": from AthenaConfiguration.TestDefaults import defaultTestFiles ConfigFlags.Input.Files = defaultTestFiles.HITS - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() diff --git a/Scintillator/ScintDetDescr/TriggerGeoModel/test/TriggerGMConfig_test.py b/Scintillator/ScintDetDescr/TriggerGeoModel/test/TriggerGMConfig_test.py index 4c88d31e..3752d03b 100644 --- a/Scintillator/ScintDetDescr/TriggerGeoModel/test/TriggerGMConfig_test.py +++ b/Scintillator/ScintDetDescr/TriggerGeoModel/test/TriggerGMConfig_test.py @@ -10,7 +10,7 @@ if __name__ == "__main__": from AthenaConfiguration.TestDefaults import defaultTestFiles ConfigFlags.Input.Files = defaultTestFiles.HITS - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/test/VetoGMConfig_test.py b/Scintillator/ScintDetDescr/VetoGeoModel/test/VetoGMConfig_test.py index b38d833d..ba3f59f3 100644 --- a/Scintillator/ScintDetDescr/VetoGeoModel/test/VetoGMConfig_test.py +++ b/Scintillator/ScintDetDescr/VetoGeoModel/test/VetoGMConfig_test.py @@ -10,7 +10,7 @@ if __name__ == "__main__": from AthenaConfiguration.TestDefaults import defaultTestFiles ConfigFlags.Input.Files = defaultTestFiles.HITS - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() diff --git a/Simulation/G4Faser/G4FaserAlg/test/runEcal.py b/Simulation/G4Faser/G4FaserAlg/test/runEcal.py index cbae412c..eaef5c20 100755 --- a/Simulation/G4Faser/G4FaserAlg/test/runEcal.py +++ b/Simulation/G4Faser/G4FaserAlg/test/runEcal.py @@ -43,7 +43,7 @@ if __name__ == "__main__": 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 + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) # Workaround to avoid problematic ISF code diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4.py b/Simulation/G4Faser/G4FaserAlg/test/runG4.py index 50546847..9538edac 100644 --- a/Simulation/G4Faser/G4FaserAlg/test/runG4.py +++ b/Simulation/G4Faser/G4FaserAlg/test/runG4.py @@ -43,7 +43,7 @@ if __name__ == "__main__": 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 + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) # Workaround to avoid problematic ISF code diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py b/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py index 2479a9d1..56618f6c 100644 --- a/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py +++ b/Simulation/G4Faser/G4FaserAlg/test/runG4Cosmics.py @@ -44,7 +44,7 @@ if __name__ == "__main__": 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 + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) # Workaround to avoid problematic ISF code diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4DecayInFlight.py b/Simulation/G4Faser/G4FaserAlg/test/runG4DecayInFlight.py index d3353381..8110c6ee 100644 --- a/Simulation/G4Faser/G4FaserAlg/test/runG4DecayInFlight.py +++ b/Simulation/G4Faser/G4FaserAlg/test/runG4DecayInFlight.py @@ -44,7 +44,7 @@ if __name__ == "__main__": 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 + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) # Workaround to avoid problematic ISF code diff --git a/Simulation/G4Faser/G4FaserAlg/test/runG4FaserNu.py b/Simulation/G4Faser/G4FaserAlg/test/runG4FaserNu.py new file mode 100644 index 00000000..486b628c --- /dev/null +++ b/Simulation/G4Faser/G4FaserAlg/test/runG4FaserNu.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +if __name__ == "__main__": + import os + import sys + import GaudiPython + import ParticleGun as PG + 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 = "FASERNU-02" # Always needed + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-02" # Always needed; must match FaserVersion +# 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 = "myFaserNu.HITS.pool.root" + ConfigFlags.GeoModel.GeoExportFile = "faserGeo.db" # Optional dump of geometry for browsing in vp1light +# +# Geometry-related settings +# Do not change! +# + detectors = ['Emulsion', 'Veto', 'Trigger', 'Preshower', 'FaserSCT', 'Dipole', 'Ecal'] + from CalypsoConfiguration.DetectorConfigFlags import setupDetectorsFromList + setupDetectorsFromList(ConfigFlags, detectors, toggle_geometry=True) + ConfigFlags.GeoModel.Align.Dynamic = False + ConfigFlags.Sim.ReleaseGeoModel = False +# +# Physics list +# + ConfigFlags.Sim.PhysicsList = "FTFP_BERT" +# +# 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.pid = -13 + pg.sampler.mom = PG.EThetaMPhiSampler(energy=1*TeV, theta=[0, pi/20], phi=[0, 2*pi], mass=105.71) + pg.sampler.pos = PG.PosSampler(x=[-5, 5], y=[-5, 5], z=-3750.0, t=0.0) + 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", + "NeutrinoHitCollection#*", + "ScintHitCollection#*", + "FaserSiHitCollection#*", + "CaloHitCollection#*" + ], 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=50).isFailure())) diff --git a/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py b/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py index 249968df..99c94f3c 100644 --- a/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py +++ b/Simulation/G4Faser/G4FaserAlg/test/runGeantinoScan.py @@ -44,7 +44,7 @@ if __name__ == "__main__": 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 + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) # Workaround to avoid problematic ISF code diff --git a/Simulation/G4Faser/G4FaserAlg/test/runGen.py b/Simulation/G4Faser/G4FaserAlg/test/runGen.py index a53f8aab..21668816 100755 --- a/Simulation/G4Faser/G4FaserAlg/test/runGen.py +++ b/Simulation/G4Faser/G4FaserAlg/test/runGen.py @@ -43,7 +43,7 @@ if __name__ == "__main__": 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 + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) # Workaround to avoid problematic ISF code diff --git a/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py b/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py index c9d461ce..21357a02 100644 --- a/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py +++ b/Simulation/G4Faser/G4FaserServices/python/G4FaserServicesConfigNew.py @@ -7,7 +7,7 @@ DetectorGeometrySvc, G4AtlasSvc, G4GeometryNotifierSvc, PhysicsListSvc=CompFacto # # Physics region tools # -from G4FaserTools.G4PhysicsRegionConfigNew import ScintillatorPhysicsRegionToolCfg, TrackerPhysicsRegionToolCfg, EcalPhysicsRegionToolCfg +from G4FaserTools.G4PhysicsRegionConfigNew import NeutrinoPhysicsRegionToolCfg, ScintillatorPhysicsRegionToolCfg, TrackerPhysicsRegionToolCfg, EcalPhysicsRegionToolCfg # # Geometry tools # @@ -15,7 +15,7 @@ from G4FaserTools.G4GeometryToolConfig import MaterialDescriptionToolCfg, G4Atla # # Magnetic field tools - start simple # -from G4FaserTools.G4FieldConfigNew import FASERFieldManagerToolCfg, VetoFieldManagerToolCfg, TriggerFieldManagerToolCfg, PreshowerFieldManagerToolCfg +from G4FaserTools.G4FieldConfigNew import FASERFieldManagerToolCfg, EmulsionFieldManagerToolCfg, VetoFieldManagerToolCfg, TriggerFieldManagerToolCfg, PreshowerFieldManagerToolCfg # # Future field managers (?) # @@ -32,6 +32,9 @@ def getFASER_RegionCreatorList(ConfigFlags): # if ConfigFlags.Beam.Type == 'cosmics' or ConfigFlags.Sim.CavernBG != 'Signal': # regionCreatorList += [SX1PhysicsRegionToolCfg(ConfigFlags), BedrockPhysicsRegionToolCfg(ConfigFlags), CavernShaftsConcretePhysicsRegionToolCfg(ConfigFlags)] + if ConfigFlags.Detector.EnableNeutrino: + regionCreatorList += [NeutrinoPhysicsRegionToolCfg(ConfigFlags)] + if ConfigFlags.Detector.EnableScintillator: regionCreatorList += [ScintillatorPhysicsRegionToolCfg(ConfigFlags)] @@ -56,6 +59,10 @@ def FASER_FieldMgrListCfg(ConfigFlags): acc = DipoleFieldManagerToolCfg(ConfigFlags) tool = result.popToolsAndMerge(acc) fieldMgrList += [tool] + if ConfigFlags.Detector.GeometryEmulsion: + acc = EmulsionFieldManagerToolCfg(ConfigFlags) + tool = result.popToolsAndMerge(acc) + fieldMgrList += [tool] if ConfigFlags.Detector.GeometryVeto: acc = VetoFieldManagerToolCfg(ConfigFlags) tool = result.popToolsAndMerge(acc) diff --git a/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py b/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py index 6f091f84..6f3d50a2 100644 --- a/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py +++ b/Simulation/G4Faser/G4FaserTools/python/G4FaserToolsConfigNew.py @@ -7,12 +7,25 @@ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator from AthenaCommon import CfgMgr SensitiveDetectorMasterTool=CompFactory.SensitiveDetectorMasterTool +from EmulsionG4_SD.EmulsionG4_SDToolConfig import EmulsionSensorSDCfg from VetoG4_SD.VetoG4_SDToolConfig import VetoSensorSDCfg from TriggerG4_SD.TriggerG4_SDToolConfig import TriggerSensorSDCfg from PreshowerG4_SD.PreshowerG4_SDToolConfig import PreshowerSensorSDCfg from FaserSCT_G4_SD.FaserSCT_G4_SDToolConfig import SctSensorSDCfg from EcalG4_SD.EcalG4_SDToolConfig import EcalSensorSDCfg +def generateNeutrinoSensitiveDetectorList(ConfigFlags): + + result = ComponentAccumulator() + SensitiveDetectorList=[] + + if ConfigFlags.Detector.EnableEmulsion: + accEmulsion,toolEmulsion = EmulsionSensorSDCfg(ConfigFlags) + SensitiveDetectorList += [ toolEmulsion ] + result.merge(accEmulsion) + + return result, SensitiveDetectorList #List of tools here now! (CALL IT TOOL LIST?) + def generateScintSensitiveDetectorList(ConfigFlags): result = ComponentAccumulator() @@ -70,6 +83,9 @@ def generateSensitiveDetectorList(ConfigFlags): SensitiveDetectorList=[] # SensitiveDetectorList += generateEnvelopeSensitiveDetectorList(ConfigFlags) # to update + acc_NeutrinoSensitiveDetector, NeutrinoSensitiveDetectorList = generateNeutrinoSensitiveDetectorList(ConfigFlags) + SensitiveDetectorList += NeutrinoSensitiveDetectorList + acc_ScintSensitiveDetector, ScintSensitiveDetectorList = generateScintSensitiveDetectorList(ConfigFlags) SensitiveDetectorList += ScintSensitiveDetectorList @@ -79,6 +95,7 @@ def generateSensitiveDetectorList(ConfigFlags): acc_CaloSensitiveDetector, CaloSensitiveDetectorList = generateCaloSensitiveDetectorList(ConfigFlags) SensitiveDetectorList += CaloSensitiveDetectorList + result.merge(acc_NeutrinoSensitiveDetector) result.merge(acc_ScintSensitiveDetector) result.merge(acc_TrackerSensitiveDetector) result.merge(acc_CaloSensitiveDetector) diff --git a/Simulation/G4Faser/G4FaserTools/python/G4FieldConfigNew.py b/Simulation/G4Faser/G4FaserTools/python/G4FieldConfigNew.py index 81b780f3..33d34f72 100644 --- a/Simulation/G4Faser/G4FaserTools/python/G4FieldConfigNew.py +++ b/Simulation/G4Faser/G4FaserTools/python/G4FieldConfigNew.py @@ -52,6 +52,16 @@ def BasicDetectorConstantFieldManagerToolCfg(ConfigFlags, name='BasicDetectorCon # # Same numerical values as ATLAS Inner Detector # + +def EmulsionFieldManagerToolCfg(ConfigFlags, name='EmulsionFieldManager', **kwargs): + kwargs.setdefault("LogicalVolumes", ['Emulsion::Emulsion']) + #kwargs.setdefault('DeltaChord', 0.00001) + kwargs.setdefault('DeltaIntersection', 0.00001) + kwargs.setdefault('DeltaOneStep', 0.0001) + kwargs.setdefault('MaximumEpsilonStep', 0.001) + kwargs.setdefault('MinimumEpsilonStep', 0.00001) + return BasicDetectorFieldManagerToolCfg(ConfigFlags, name, **kwargs) + def VetoFieldManagerToolCfg(ConfigFlags, name='VetoFieldManager', **kwargs): kwargs.setdefault("LogicalVolumes", ['Veto::Veto']) #kwargs.setdefault('DeltaChord', 0.00001) diff --git a/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py b/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py index d08fd6f4..85b372fa 100644 --- a/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py +++ b/Simulation/G4Faser/G4FaserTools/python/G4GeometryToolConfig.py @@ -1,5 +1,4 @@ # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration -from __future__ import print_function from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator from AthenaConfiguration.ComponentFactory import CompFactory @@ -9,6 +8,7 @@ GeoDetectorTool=CompFactory.GeoDetectorTool BoxEnvelope,MaterialDescriptionTool,G4AtlasDetectorConstructionTool=CompFactory.getComps("BoxEnvelope","MaterialDescriptionTool","G4AtlasDetectorConstructionTool",) from AthenaCommon.SystemOfUnits import mm +from EmulsionGeoModel.EmulsionGeoModelConfig import EmulsionGeometryCfg from VetoGeoModel.VetoGeoModelConfig import VetoGeometryCfg from TriggerGeoModel.TriggerGeoModelConfig import TriggerGeometryCfg from PreshowerGeoModel.PreshowerGeoModelConfig import PreshowerGeometryCfg @@ -21,6 +21,12 @@ from EcalGeoModel.EcalGeoModelConfig import EcalGeometryCfg #to still migrate: getCavernWorld, getCavernInfraGeoDetectorTool #from ForwardRegionProperties.ForwardRegionPropertiesToolConfig import ForwardRegionPropertiesCfg +def EmulsionGeoDetectorToolCfg(ConfigFlags, name='Emulsion', **kwargs): + #set up geometry + result=EmulsionGeometryCfg(ConfigFlags) + kwargs.setdefault("DetectorName", "Emulsion") + return result, GeoDetectorTool(name, **kwargs) + def VetoGeoDetectorToolCfg(ConfigFlags, name='Veto', **kwargs): #set up geometry result=VetoGeometryCfg(ConfigFlags) @@ -61,6 +67,11 @@ def generateSubDetectorList(ConfigFlags): result = ComponentAccumulator() SubDetectorList=[] + if ConfigFlags.Detector.GeometryEmulsion: + accEmulsion, toolEmulsion = EmulsionGeoDetectorToolCfg(ConfigFlags) + SubDetectorList += [ toolEmulsion ] + result.merge(accEmulsion) + if ConfigFlags.Detector.GeometryVeto: accVeto, toolVeto = VetoGeoDetectorToolCfg(ConfigFlags) SubDetectorList += [ toolVeto ] diff --git a/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py b/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py index 15750a0c..c910e2b8 100644 --- a/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py +++ b/Simulation/G4Faser/G4FaserTools/python/G4PhysicsRegionConfigNew.py @@ -63,6 +63,16 @@ RegionCreator=CompFactory.RegionCreator # return RegionCreator(name, **kwargs) # Values identical to ATLAS SCT + +def NeutrinoPhysicsRegionToolCfg(ConfigFlags, name="NeutrinoPhysicsRegionTool", **kwargs): + kwargs.setdefault("RegionName", "Neutrino") + volumeList = ['Emulsion::FrontFilm', 'Emulsion::BackFilm', 'Emulsion::Baseboard', 'Emulsion::EmulsionStationA'] + kwargs.setdefault("VolumeList", volumeList) + kwargs.setdefault("ElectronCut", 0.01) + kwargs.setdefault("PositronCut", 0.01) + kwargs.setdefault("GammaCut", 0.01) + return RegionCreator(name, **kwargs) + def ScintillatorPhysicsRegionToolCfg(ConfigFlags, name='ScintillatorPhysicsRegionTool', **kwargs): kwargs.setdefault("RegionName", 'Scintillator') volumeList = ['Veto::Plate' , 'Trigger::Plate', 'Preshower::Plate'] diff --git a/Simulation/ISF/ISF_HepMC/FaserISF_HepMC_Tools/python/FaserISF_HepMC_ToolsConfigNew.py b/Simulation/ISF/ISF_HepMC/FaserISF_HepMC_Tools/python/FaserISF_HepMC_ToolsConfigNew.py index 4fe1606a..a49c0499 100644 --- a/Simulation/ISF/ISF_HepMC/FaserISF_HepMC_Tools/python/FaserISF_HepMC_ToolsConfigNew.py +++ b/Simulation/ISF/ISF_HepMC/FaserISF_HepMC_Tools/python/FaserISF_HepMC_ToolsConfigNew.py @@ -156,17 +156,16 @@ def FaserParticleGenericFilterCfg(ConfigFlags, name="ISF_FaserGenericFilter", ** def FaserDipoleTruthStrategyCfg(ConfigFlags, name="ISF_FaserDipoleTruthStrategy", **kwargs): result = ComponentAccumulator() - import PyUtils.RootUtils as rootUtils - ROOT = rootUtils.import_root() - import cppyy + import ROOT, cppyy cppyy.load_library('FaserDetDescrDict') - from ROOT.FaserDetDescr import FaserRegion + FaserRegion = ROOT.FaserDetDescr.FaserRegion # # Save truth in Dipole region # - kwargs.setdefault('Regions', [FaserRegion.fFaserDipole]) - kwargs.setdefault('ParentMinEkin', 5.0*MeV) - kwargs.setdefault('ChildMinEkin', 5.0*MeV) + kwargs.setdefault('Regions', [FaserRegion.fFaserDipole, + FaserRegion.fFaserNeutrino]) + kwargs.setdefault('ParentMinEkin', 1000.0*MeV) + kwargs.setdefault('ChildMinEkin', 1000.0*MeV) result.setPrivateTools(ISF__FaserTruthStrategy(name, **kwargs)) return result @@ -174,16 +173,14 @@ def FaserDipoleTruthStrategyCfg(ConfigFlags, name="ISF_FaserDipoleTruthStrategy" def FaserTruthStrategyCfg(ConfigFlags, name="ISF_FaserTruthStrategy", **kwargs): result = ComponentAccumulator() - import PyUtils.RootUtils as rootUtils - ROOT = rootUtils.import_root() - - import cppyy + import ROOT, cppyy cppyy.load_library('FaserDetDescrDict') - from ROOT.FaserDetDescr import FaserRegion + FaserRegion = ROOT.FaserDetDescr.FaserRegion # # Save truth in all regions except Dipole # - kwargs.setdefault('Regions', [FaserRegion.fFaserNeutrino, + kwargs.setdefault('Regions', [ + # FaserRegion.fFaserNeutrino, FaserRegion.fFaserScintillator, FaserRegion.fFaserTracker, # FaserRegion.fFaserDipole, diff --git a/Simulation/README.md b/Simulation/README.md index 9ad2f25f..350d7ab9 100644 --- a/Simulation/README.md +++ b/Simulation/README.md @@ -8,3 +8,8 @@ To generate Calypso MC data from an installation (run) directory: 3) runG4.py (setup.sh will put the script in your path) + +To generate events with the emulsion detector, use + +3a) runG4FaserNu.py + diff --git a/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx b/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx index 8ab67fbf..a92e78dc 100644 --- a/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx +++ b/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx @@ -99,6 +99,7 @@ StatusCode TrackerAlignDBTool::initialize() for (int i=0;i<3;++i) chan[i]=100*i; + int minStation = 3; std::string man_name; for (const TrackerDD::SiDetectorElement* element : *(m_sctman->getDetectorElementCollection())) { @@ -111,6 +112,7 @@ StatusCode TrackerAlignDBTool::initialize() std::string level[3]; for (int i=TransfLevel_low; i<3; ++i) { + minStation = std::min(station, minStation); level[i]=dirkey(station, layer, 1+i, phi); // add this to list if not seen already std::vector<std::string>::const_iterator ix = @@ -129,7 +131,7 @@ StatusCode TrackerAlignDBTool::initialize() } } } - + m_ift =(minStation == 0); ATH_CHECK(m_outputTool.retrieve()); if (msgLvl(MSG::DEBUG)) @@ -244,6 +246,12 @@ StatusCode TrackerAlignDBTool::createDB() const { Amg::Transform3D globshift; globshift.setIdentity(); + // Tracker interface + if (m_ift) + { + ident1 = m_sctid->wafer_id(0, 0, 0, 0, 0); + pat->add(ident1, Amg::EigenTransformToCLHEP(globshift)); + } // Tracker upstream ident1 = m_sctid->wafer_id(1, 0, 0, 0, 0); pat->add(ident1, Amg::EigenTransformToCLHEP(globshift)); @@ -651,7 +659,7 @@ StatusCode TrackerAlignDBTool::outputObjs() const { ATH_CHECK(m_outputTool->streamObjects(typekeys)); // commit output - ATH_CHECK(m_outputTool->commitOutput()); + ATH_CHECK(m_outputTool->commitOutput(true)); ATH_MSG_DEBUG( "Written " << typekeys.size() << " objects to stream " << m_outputTool); return StatusCode::SUCCESS; } diff --git a/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.h b/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.h index 47d7e8ee..9ff68007 100644 --- a/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.h +++ b/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.h @@ -185,6 +185,7 @@ class TrackerAlignDBTool: virtual public ITrackerAlignDBTool, public AthAlgTool const AlignableTransform* cgetTransPtr(const std::string key) const; bool m_dynamicDB; bool m_forceUserDBConfig; + bool m_ift {false}; mutable ToolHandle<IAthenaOutputStreamTool> m_outputTool { this, "OutputTool", "AthenaOutputStreamTool/CondStream1"} ; diff --git a/Tracker/TrackerConditions/FaserSCT_ConditionsData/data/SCT_Conditions.py b/Tracker/TrackerConditions/FaserSCT_ConditionsData/data/SCT_Conditions.py index 7e4a9dca..899f0037 100644 --- a/Tracker/TrackerConditions/FaserSCT_ConditionsData/data/SCT_Conditions.py +++ b/Tracker/TrackerConditions/FaserSCT_ConditionsData/data/SCT_Conditions.py @@ -9,7 +9,19 @@ sctChannels = [ '2348810240', '2350907392', '2353004544', '2355101696', '2357198848', '2359296000', '2361393152', '2363490304', '2365587456', '2367684608', '2369781760', '2371878912', '2373976064', '2376073216', '2378170368', '2380267520', '2415919104', '2418016256', '2420113408', '2422210560', '2424307712', '2426404864', '2428502016', '2430599168', '2432696320', '2434793472', '2436890624', '2438987776', '2441084928', '2443182080', '2445279232', '2447376384', '2449473536', '2451570688', '2453667840', '2455764992', '2457862144', '2459959296', '2462056448', '2464153600', '2466250752', '2468347904', '2470445056', '2472542208', '2474639360', '2476736512', '2478833664', '2480930816', '2483027968', '2485125120', '2487222272', '2489319424', '2491416576', '2493513728', '2495610880', '2497708032', '2499805184', '2501902336', '2503999488', '2506096640', - '2508193792', '2510290944', '2512388096', '2514485248'] + '2508193792', '2510290944', '2512388096', '2514485248' ] + +iftChannels = [ + '2147483648', '2149580800', '2151677952', '2153775104', '2155872256', '2157969408', '2160066560', '2162163712', '2164260864', '2166358016', '2168455168', '2170552320', '2172649472', '2174746624', '2176843776', '2178940928', '2181038080', '2183135232', '2185232384', '2187329536', + '2189426688', '2191523840', '2193620992', '2195718144', '2197815296', '2199912448', '2202009600', '2204106752', '2206203904', '2208301056', '2210398208', '2212495360', '2214592512', '2216689664', '2218786816', '2220883968', '2222981120', '2225078272', '2227175424', '2229272576', + '2231369728', '2233466880', '2235564032', '2237661184', '2239758336', '2241855488', '2243952640', '2246049792', '2281701376', '2283798528', '2285895680', '2287992832', '2290089984', '2292187136', '2294284288', '2296381440', '2298478592', '2300575744', '2302672896', '2304770048', + '2306867200', '2308964352', '2311061504', '2313158656', '2315255808', '2317352960', '2319450112', '2321547264', '2323644416', '2325741568', '2327838720', '2329935872', '2332033024', '2334130176', '2336227328', '2338324480', '2340421632', '2342518784', '2344615936', '2346713088', + '2348810240', '2350907392', '2353004544', '2355101696', '2357198848', '2359296000', '2361393152', '2363490304', '2365587456', '2367684608', '2369781760', '2371878912', '2373976064', '2376073216', '2378170368', '2380267520', '2415919104', '2418016256', '2420113408', '2422210560', + '2424307712', '2426404864', '2428502016', '2430599168', '2432696320', '2434793472', '2436890624', '2438987776', '2441084928', '2443182080', '2445279232', '2447376384', '2449473536', '2451570688', '2453667840', '2455764992', '2457862144', '2459959296', '2462056448', '2464153600', + '2466250752', '2468347904', '2470445056', '2472542208', '2474639360', '2476736512', '2478833664', '2480930816', '2483027968', '2485125120', '2487222272', '2489319424', '2491416576', '2493513728', '2495610880', '2497708032', '2499805184', '2501902336', '2503999488', '2506096640', + '2508193792', '2510290944', '2512388096', '2514485248', '2550136832', '2552233984', '2554331136', '2556428288', '2558525440', '2560622592', '2562719744', '2564816896', '2566914048', '2569011200', '2571108352', '2573205504', '2575302656', '2577399808', '2579496960', '2581594112', + '2583691264', '2585788416', '2587885568', '2589982720', '2592079872', '2594177024', '2596274176', '2598371328', '2600468480', '2602565632', '2604662784', '2606759936', '2608857088', '2610954240', '2613051392', '2615148544', '2617245696', '2619342848', '2621440000', '2623537152', + '2625634304', '2627731456', '2629828608', '2631925760', '2634022912', '2636120064', '2638217216', '2640314368', '2642411520', '2644508672', '2646605824', '2648702976' ] description = '<timeStamp>run-lumi</timeStamp><addrHeader><address_header clid="1238547719" service_type="71" /></addrHeader><typeName>CondAttrListCollection</typeName>' @@ -25,6 +37,37 @@ print('recreating database') dbSvc.dropDatabase( connectString ) db = dbSvc.createDatabase( connectString ) +tracker = db.createFolderSet("/Tracker") +# tracker_align = db.createFolderSet("/Tracker/Align") +sct = db.createFolderSet("/SCT") +sct_dcs = db.createFolderSet("/SCT/DCS") +sct_daq = db.createFolderSet("/SCT/DAQ") +sct_daq_calibration = db.createFolderSet("/SCT/DAQ/Calibration") + +# tracker_align.createTagRelation("TRACKER-01", "TRACKER-ALIGN-01") +tracker.createTagRelation("OFLCOND-FASER-01","TRACKER-01") +sct_daq_calibration.createTagRelation("SCT-DAQ-01", "SCT-DAQ-Calibration-01") +sct_daq.createTagRelation("SCT-01", "SCT-DAQ-01") +sct_dcs.createTagRelation("SCT-01", "SCT-DCS-01") +sct.createTagRelation("OFLCOND-FASER-01", "SCT-01") + +# tracker_align.createTagRelation("TRACKER-02", "TRACKER-ALIGN-02") +tracker.createTagRelation("OFLCOND-FASER-02","TRACKER-02") +sct_daq_calibration.createTagRelation("SCT-DAQ-02", "SCT-DAQ-Calibration-02") +sct_daq.createTagRelation("SCT-02", "SCT-DAQ-02") +sct_dcs.createTagRelation("SCT-02", "SCT-DCS-02") +sct.createTagRelation("OFLCOND-FASER-02", "SCT-02") + +glob = db.createFolderSet("/GLOBAL") +glob_bfield = db.createFolderSet("/GLOBAL/BField") + +glob_bfield.createTagRelation("GLOBAL-01", "GLOBAL-BField-01") +glob.createTagRelation("OFLCOND-FASER-01", "GLOBAL-01") + +glob_bfield.createTagRelation("GLOBAL-02", "GLOBAL-BField-02") +glob.createTagRelation("OFLCOND-FASER-02", "GLOBAL-02") + + gainSpec = cool.RecordSpecification() gainSpec.extend( 'serialNumber' , cool.StorageType.UInt63 ) gainSpec.extend( 'runNumber' , cool.StorageType.UInt32 ) @@ -47,11 +90,12 @@ gainRecord[ 'offsetRMSByChip' ] = '1.75 1.75 1.75 1.75 1.75 1.75 1.75 1.75 1.75 gainRecord[ 'noiseByChip' ] = '1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0' gainRecord[ 'noiseRMSByChip' ] = '45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0' -gainFolderSpec = cool.FolderSpecification(gainSpec) +gainFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, gainSpec) gainFolder = db.createFolder('/SCT/DAQ/Calibration/ChipGain', gainFolderSpec, description, True) for channel in sctChannels: - gainFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, gainRecord, int(channel) ) + gainFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, gainRecord, int(channel), "SCT-DAQ-Calibration-ChipGain-01", True ) +gainFolder.createTagRelation("SCT-DAQ-Calibration-01", "SCT-DAQ-Calibration-ChipGain-01") noiseSpec = cool.RecordSpecification() noiseSpec.extend( 'serialNumber' , cool.StorageType.UInt63 ) @@ -70,11 +114,12 @@ noiseRecord[ 'offsetByChip' ] = '60.0 60.0 60.0 60.0 60.0 60.0 60.0 60.0 6 noiseRecord[ 'occupancyByChip' ] = '3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05' noiseRecord[ 'occupancyRMSByChip' ] = '2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05' -noiseFolderSpec = cool.FolderSpecification(noiseSpec) -noiseFolder = db.createFolder('/SCT/DAQ/Calibration/ChipNoise', noiseFolderSpec, description, True) +noiseFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, noiseSpec) +noiseFolder = db.createFolder('/SCT/DAQ/Calibration/ChipNoise', noiseFolderSpec, description, True ) for channel in sctChannels: - noiseFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, noiseRecord, int(channel) ) + noiseFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, noiseRecord, int(channel), "SCT-DAQ-Calibration-Noise-01", True ) +noiseFolder.createTagRelation("SCT-DAQ-Calibration-01", "SCT-DAQ-Calibration-Noise-01") chanstatSpec = cool.RecordSpecification() chanstatSpec.extend( 'LVCHSTAT_RECV' , cool.StorageType.Int32 ) @@ -84,11 +129,12 @@ chanstatRecord = cool.Record(chanstatSpec) chanstatRecord[ 'LVCHSTAT_RECV' ] = 209 chanstatRecord[ 'STATE' ] = 17 -chanstatFolderSpec = cool.FolderSpecification(chanstatSpec) -chanstatFolder = db.createFolder('/SCT/DCS/CHANSTAT', chanstatFolderSpec, descriptionDCS, True) +chanstatFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, chanstatSpec) +chanstatFolder = db.createFolder('/SCT/DCS/CHANSTAT', chanstatFolderSpec, descriptionDCS, True ) for channel in sctChannels: - chanstatFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, chanstatRecord, int(channel) ) + chanstatFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, chanstatRecord, int(channel), "SCT-DCS-Status-01", True ) +chanstatFolder.createTagRelation("SCT-DCS-01", "SCT-DCS-Status-01") hvSpec = cool.RecordSpecification() hvSpec.extend( 'HVCHVOLT_RECV' , cool.StorageType.Float ) @@ -98,11 +144,12 @@ hvRecord = cool.Record(hvSpec) hvRecord[ 'HVCHVOLT_RECV' ] = 150.0 hvRecord[ 'HVCHCURR_RECV' ] = 10.0 -hvFolderSpec = cool.FolderSpecification(hvSpec) -hvFolder = db.createFolder('/SCT/DCS/HV', hvFolderSpec, descriptionDCS, True) +hvFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, hvSpec) +hvFolder = db.createFolder('/SCT/DCS/HV', hvFolderSpec, descriptionDCS, True ) for channel in sctChannels: - hvFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, hvRecord, int(channel) ) + hvFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, hvRecord, int(channel), "SCT-DCS-HV-01", True ) +hvFolder.createTagRelation("SCT-DCS-01", "SCT-DCS-HV-01") modtempSpec = cool.RecordSpecification() modtempSpec.extend( 'MOCH_TM0_RECV' , cool.StorageType.Float ) @@ -112,11 +159,13 @@ modtempRecord = cool.Record(modtempSpec) modtempRecord[ 'MOCH_TM0_RECV' ] = 7.0 modtempRecord[ 'MOCH_TM1_RECV' ] = 7.0 -modtempFolderSpec = cool.FolderSpecification(modtempSpec) -modtempFolder = db.createFolder('/SCT/DCS/MODTEMP', modtempFolderSpec, descriptionDCS, True) +modtempFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, modtempSpec) +modtempFolder = db.createFolder('/SCT/DCS/MODTEMP', modtempFolderSpec, descriptionDCS, True ) for channel in sctChannels: - modtempFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, modtempRecord, int(channel) ) + modtempFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, modtempRecord, int(channel), "SCT-DCS-Temp-01", True ) +modtempFolder.createTagRelation("SCT-DCS-01", "SCT-DCS-Temp-01") + mapSpec = cool.RecordSpecification() mapSpec.extend( 'FieldType', cool.StorageType.String4k ) @@ -126,10 +175,12 @@ mapRecord = cool.Record(mapSpec) mapRecord['FieldType'] = "GlobalMap" mapRecord['MapFileName'] = "file:MagneticFieldMaps/FaserFieldTable.root" -mapFolderSpec = cool.FolderSpecification(mapSpec) -mapFolder = db.createFolder('/GLOBAL/BField/Maps', mapFolderSpec, descriptionDCS, True) +mapFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, mapSpec) +mapFolder = db.createFolder('/GLOBAL/BField/Maps', mapFolderSpec, descriptionDCS, True ) + +mapFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, mapRecord, 1, "GLOBAL-BField-Maps-01", True ) +mapFolder.createTagRelation("GLOBAL-BField-01", "GLOBAL-BField-Maps-01") -mapFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, mapRecord, 1 ) scaleSpec = cool.RecordSpecification() scaleSpec.extend( 'value', cool.StorageType.Float ) @@ -137,11 +188,141 @@ scaleSpec.extend( 'value', cool.StorageType.Float ) scaleRecord = cool.Record(scaleSpec) scaleRecord['value'] = 1.0 -scaleFolderSpec = cool.FolderSpecification(scaleSpec) -scaleFolder = db.createFolder('/GLOBAL/BField/Scales', scaleFolderSpec, descriptionDCS, True) +scaleFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, scaleSpec) +scaleFolder = db.createFolder('/GLOBAL/BField/Scales', scaleFolderSpec, descriptionDCS, True ) # Channel names don't seem to be handled properly by Athena scaleFolder.createChannel( 1, "Dipole_Scale" ) -scaleFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, scaleRecord, 1 ) +scaleFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, scaleRecord, 1, "GLOBAL-BField-Scale-01", True ) +scaleFolder.createTagRelation("GLOBAL-BField-01", "GLOBAL-BField-Scale-01") + +# Start of IFT + +gainSpec = cool.RecordSpecification() +gainSpec.extend( 'serialNumber' , cool.StorageType.UInt63 ) +gainSpec.extend( 'runNumber' , cool.StorageType.UInt32 ) +gainSpec.extend( 'scanNumber' , cool.StorageType.UInt32 ) +gainSpec.extend( 'gainByChip' , cool.StorageType.String4k ) +gainSpec.extend( 'gainRMSByChip' , cool.StorageType.String4k ) +gainSpec.extend( 'offsetByChip' , cool.StorageType.String4k ) +gainSpec.extend( 'offsetRMSByChip' , cool.StorageType.String4k ) +gainSpec.extend( 'noiseByChip' , cool.StorageType.String4k ) +gainSpec.extend( 'noiseRMSByChip' , cool.StorageType.String4k ) + +gainRecord = cool.Record(gainSpec) +gainRecord[ 'serialNumber' ] = 0 +gainRecord[ 'runNumber' ] = 0 +gainRecord[ 'scanNumber' ] = 0 +gainRecord[ 'gainByChip' ] = '52.0 52.0 52.0 52.0 52.0 52.0 52.0 52.0 52.0 52.0 52.0 52.0' +gainRecord[ 'gainRMSByChip' ] = '1.25 1.25 1.25 1.25 1.25 1.25 1.25 1.25 1.25 1.25 1.25 1.25' +gainRecord[ 'offsetByChip' ] = '45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0' +gainRecord[ 'offsetRMSByChip' ] = '1.75 1.75 1.75 1.75 1.75 1.75 1.75 1.75 1.75 1.75 1.75 1.75' +gainRecord[ 'noiseByChip' ] = '1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0 1600.0' +gainRecord[ 'noiseRMSByChip' ] = '45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0 45.0' + +# gainFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, gainSpec) +# gainFolder = db.createFolder('/SCT/DAQ/Calibration/ChipGain', gainFolderSpec, description, True) + +for channel in iftChannels: + gainFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, gainRecord, int(channel), "SCT-DAQ-Calibration-ChipGain-02", True ) +gainFolder.createTagRelation("SCT-DAQ-Calibration-02", "SCT-DAQ-Calibration-ChipGain-02") + +noiseSpec = cool.RecordSpecification() +noiseSpec.extend( 'serialNumber' , cool.StorageType.UInt63 ) +noiseSpec.extend( 'runNumber' , cool.StorageType.UInt32 ) +noiseSpec.extend( 'scanNumber' , cool.StorageType.UInt32 ) +noiseSpec.extend( 'offsetByChip' , cool.StorageType.String4k ) +noiseSpec.extend( 'occupancyByChip' , cool.StorageType.String4k ) +noiseSpec.extend( 'occupancyRMSByChip' , cool.StorageType.String4k ) +noiseSpec.extend( 'noiseByChip' , cool.StorageType.String4k ) + +noiseRecord = cool.Record(noiseSpec) +noiseRecord[ 'serialNumber' ] = 0 +noiseRecord[ 'runNumber' ] = 0 +noiseRecord[ 'scanNumber' ] = 0 +noiseRecord[ 'offsetByChip' ] = '60.0 60.0 60.0 60.0 60.0 60.0 60.0 60.0 60.0 60.0 60.0 60.0' +noiseRecord[ 'occupancyByChip' ] = '3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05 3.50e-05' +noiseRecord[ 'occupancyRMSByChip' ] = '2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05 2.50e-05' + +# noiseFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, noiseSpec) +# noiseFolder = db.createFolder('/SCT/DAQ/Calibration/ChipNoise', noiseFolderSpec, description, True ) + +for channel in iftChannels: + noiseFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, noiseRecord, int(channel), "SCT-DAQ-Calibration-Noise-02", True ) +noiseFolder.createTagRelation("SCT-DAQ-Calibration-02", "SCT-DAQ-Calibration-Noise-02") + +chanstatSpec = cool.RecordSpecification() +chanstatSpec.extend( 'LVCHSTAT_RECV' , cool.StorageType.Int32 ) +chanstatSpec.extend( 'STATE' , cool.StorageType.UInt32 ) + +chanstatRecord = cool.Record(chanstatSpec) +chanstatRecord[ 'LVCHSTAT_RECV' ] = 209 +chanstatRecord[ 'STATE' ] = 17 + +# chanstatFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, chanstatSpec) +# chanstatFolder = db.createFolder('/SCT/DCS/CHANSTAT', chanstatFolderSpec, descriptionDCS, True ) + +for channel in iftChannels: + chanstatFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, chanstatRecord, int(channel), "SCT-DCS-Status-02", True ) +chanstatFolder.createTagRelation("SCT-DCS-02", "SCT-DCS-Status-02") + +hvSpec = cool.RecordSpecification() +hvSpec.extend( 'HVCHVOLT_RECV' , cool.StorageType.Float ) +hvSpec.extend( 'HVCHCURR_RECV' , cool.StorageType.Float ) + +hvRecord = cool.Record(hvSpec) +hvRecord[ 'HVCHVOLT_RECV' ] = 150.0 +hvRecord[ 'HVCHCURR_RECV' ] = 10.0 + +# hvFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, hvSpec) +# hvFolder = db.createFolder('/SCT/DCS/HV', hvFolderSpec, descriptionDCS, True ) + +for channel in iftChannels: + hvFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, hvRecord, int(channel), "SCT-DCS-HV-02", True ) +hvFolder.createTagRelation("SCT-DCS-02", "SCT-DCS-HV-02") + +modtempSpec = cool.RecordSpecification() +modtempSpec.extend( 'MOCH_TM0_RECV' , cool.StorageType.Float ) +modtempSpec.extend( 'MOCH_TM1_RECV' , cool.StorageType.Float ) + +modtempRecord = cool.Record(modtempSpec) +modtempRecord[ 'MOCH_TM0_RECV' ] = 7.0 +modtempRecord[ 'MOCH_TM1_RECV' ] = 7.0 + +# modtempFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, modtempSpec) +# modtempFolder = db.createFolder('/SCT/DCS/MODTEMP', modtempFolderSpec, descriptionDCS, True ) + +for channel in iftChannels: + modtempFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, modtempRecord, int(channel), "SCT-DCS-Temp-02", True ) +modtempFolder.createTagRelation("SCT-DCS-02", "SCT-DCS-Temp-02") + + +mapSpec = cool.RecordSpecification() +mapSpec.extend( 'FieldType', cool.StorageType.String4k ) +mapSpec.extend( 'MapFileName', cool.StorageType.String4k ) + +mapRecord = cool.Record(mapSpec) +mapRecord['FieldType'] = "GlobalMap" +mapRecord['MapFileName'] = "file:MagneticFieldMaps/FaserFieldTable.root" + +# mapFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, mapSpec) +# mapFolder = db.createFolder('/GLOBAL/BField/Maps', mapFolderSpec, descriptionDCS, True ) + +mapFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, mapRecord, 1, "GLOBAL-BField-Maps-02", True ) +mapFolder.createTagRelation("GLOBAL-BField-02", "GLOBAL-BField-Maps-02") + +scaleSpec = cool.RecordSpecification() +scaleSpec.extend( 'value', cool.StorageType.Float ) + +scaleRecord = cool.Record(scaleSpec) +scaleRecord['value'] = 1.0 + +# scaleFolderSpec = cool.FolderSpecification(cool.FolderVersioning.MULTI_VERSION, scaleSpec) +# scaleFolder = db.createFolder('/GLOBAL/BField/Scales', scaleFolderSpec, descriptionDCS, True ) + +# Channel names don't seem to be handled properly by Athena +# scaleFolder.createChannel( 1, "Dipole_Scale" ) +scaleFolder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, scaleRecord, 1, "GLOBAL-BField-Scale-02", True ) +scaleFolder.createTagRelation("GLOBAL-BField-02", "GLOBAL-BField-Scale-02") db.closeDatabase() diff --git a/Tracker/TrackerDetDescr/DipoleGeoModel/test/DipoleGMConfig_test.py b/Tracker/TrackerDetDescr/DipoleGeoModel/test/DipoleGMConfig_test.py index e9b1cf75..f893af72 100755 --- a/Tracker/TrackerDetDescr/DipoleGeoModel/test/DipoleGMConfig_test.py +++ b/Tracker/TrackerDetDescr/DipoleGeoModel/test/DipoleGMConfig_test.py @@ -10,7 +10,7 @@ if __name__ == "__main__": from AthenaConfiguration.TestDefaults import defaultTestFiles ConfigFlags.Input.Files = defaultTestFiles.HITS - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() diff --git a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/test/FaserSCT_GMConfig_test.py b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/test/FaserSCT_GMConfig_test.py index 9349cdf7..75eb5c42 100755 --- a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/test/FaserSCT_GMConfig_test.py +++ b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/test/FaserSCT_GMConfig_test.py @@ -10,7 +10,7 @@ if __name__ == "__main__": from AthenaConfiguration.TestDefaults import defaultTestFiles ConfigFlags.Input.Files = defaultTestFiles.HITS - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() diff --git a/Tracker/TrackerDetDescr/TrackerIdDictFiles/data/IdDictTracker_Interface.xml b/Tracker/TrackerDetDescr/TrackerIdDictFiles/data/IdDictInterface.xml similarity index 100% rename from Tracker/TrackerDetDescr/TrackerIdDictFiles/data/IdDictTracker_Interface.xml rename to Tracker/TrackerDetDescr/TrackerIdDictFiles/data/IdDictInterface.xml diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/test/FaserSCT_DigitizationDbg.py b/Tracker/TrackerDigitization/FaserSCT_Digitization/test/FaserSCT_DigitizationDbg.py index 33389e15..801349de 100644 --- a/Tracker/TrackerDigitization/FaserSCT_Digitization/test/FaserSCT_DigitizationDbg.py +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/test/FaserSCT_DigitizationDbg.py @@ -24,7 +24,8 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.HITS.pool.root'] ConfigFlags.Output.RDOFileName = "my.RDO.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.GeoModel.FaserVersion = "FASER-01" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.Beam.NumberOfCollisions = 0. diff --git a/Tracker/TrackerDigitization/FaserSCT_Digitization/test/SCT_DigitizationConfigNew_test.py b/Tracker/TrackerDigitization/FaserSCT_Digitization/test/SCT_DigitizationConfigNew_test.py index b880cc07..36bcd84d 100644 --- a/Tracker/TrackerDigitization/FaserSCT_Digitization/test/SCT_DigitizationConfigNew_test.py +++ b/Tracker/TrackerDigitization/FaserSCT_Digitization/test/SCT_DigitizationConfigNew_test.py @@ -19,7 +19,7 @@ log.setLevel(DEBUG) Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = defaultTestFiles.HITS -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.lock() # Construct our accumulator to run diff --git a/Tracker/TrackerRecAlgs/FaserSpacePoints/python/FaserSpacePointsCosmics.py b/Tracker/TrackerRecAlgs/FaserSpacePoints/python/FaserSpacePointsCosmics.py index 1859efa6..48197207 100644 --- a/Tracker/TrackerRecAlgs/FaserSpacePoints/python/FaserSpacePointsCosmics.py +++ b/Tracker/TrackerRecAlgs/FaserSpacePoints/python/FaserSpacePointsCosmics.py @@ -50,7 +50,7 @@ if __name__ == "__main__": # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "mySeeds.ESD.pool.root" - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.Input.ProjectName = "data20" # Needed to bypass autoconfig ConfigFlags.Input.isMC = False # Needed to bypass autoconfig diff --git a/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TrackerClusterFitDbg.py b/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TrackerClusterFitDbg.py index 0f9c27fa..308b5ff3 100644 --- a/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TrackerClusterFitDbg.py +++ b/Tracker/TrackerRecAlgs/TrackerClusterFit/test/TrackerClusterFitDbg.py @@ -93,7 +93,7 @@ ConfigFlags.Input.Files = [ ] #ConfigFlags.Output.ESDFileName = "run608.ESD.pool.root" ConfigFlags.Output.ESDFileName = "run001332.ESD.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.Input.ProjectName = "data21" # Needed to bypass autoconfig ConfigFlags.Input.isMC = False # Needed to bypass autoconfig diff --git a/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbg.py b/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbg.py index ee9db620..26f6dfc5 100644 --- a/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbg.py +++ b/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbg.py @@ -24,7 +24,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "myClusters.ESD.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.Beam.NumberOfCollisions = 0. diff --git a/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbgCosmics.py b/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbgCosmics.py index cbc4beec..3cf2d857 100644 --- a/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbgCosmics.py +++ b/Tracker/TrackerRecAlgs/TrackerPrepRawDataFormation/test/FaserSCT_ClusterizationDbgCosmics.py @@ -24,7 +24,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "myClusters.ESD.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" # Needed to bypass autoconfig, only the "OFLCOND" matters at the moment +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.Input.ProjectName = "data20" # Needed to bypass autoconfig ConfigFlags.Input.isMC = False # Needed to bypass autoconfig diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/StatisticsDbg.py b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/StatisticsDbg.py index 1fb37bb3..55d4ee20 100644 --- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/StatisticsDbg.py +++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/StatisticsDbg.py @@ -25,7 +25,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "mySpacePoints.ESD.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.Beam.NumberOfCollisions = 0. diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbg.py b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbg.py index b7ac51e0..a3d520ee 100644 --- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbg.py +++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbg.py @@ -25,7 +25,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "mySpacePoints.ESD.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.Beam.NumberOfCollisions = 0. diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbgCosmics.py b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbgCosmics.py index a02500c2..a197c227 100644 --- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbgCosmics.py +++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/test/TrackerSpacePointFormationDbgCosmics.py @@ -25,7 +25,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "mySpacePoints.ESD.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.Input.ProjectName = "data20" # Needed to bypass autoconfig ConfigFlags.Input.isMC = False # Needed to bypass autoconfig diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py index cd284784..9eea2476 100644 --- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py +++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py @@ -26,7 +26,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "mySeeds.ESD.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False #ConfigFlags.Concurrency.NumThreads = 1 ConfigFlags.Beam.NumberOfCollisions = 0. diff --git a/Tracker/TrackerSimEvent/src/FaserSiHitIdHelper.cxx b/Tracker/TrackerSimEvent/src/FaserSiHitIdHelper.cxx index 149466cf..204399b8 100644 --- a/Tracker/TrackerSimEvent/src/FaserSiHitIdHelper.cxx +++ b/Tracker/TrackerSimEvent/src/FaserSiHitIdHelper.cxx @@ -46,8 +46,8 @@ void FaserSiHitIdHelper::Initialize() { if (detStore->retrieve(pix, "FaserSCT_ID").isFailure()) { pix = 0; } } - InitializeField("Station", 1, 3); - InitializeField("Plane", 0, 3); + InitializeField("Station", 0, 3); + InitializeField("Plane", 0, 2); InitializeField("Row", 0, 4); InitializeField("Module", -1, 1); InitializeField("Sensor", 0, 1); diff --git a/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py b/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py index 40e7eb69..23270e4e 100644 --- a/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py +++ b/Tracking/Acts/FaserActsGeometry/python/FaserActsMaterialMapping_jobOptions.py @@ -61,7 +61,7 @@ if "__main__" == __name__: ConfigFlags.Input.isMC = True ConfigFlags.Beam.Type = "collisions" ConfigFlags.GeoModel.FaserVersion = "FASER-01" - ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.TrackingGeometry.MaterialSource = "geometry-maps.json" ConfigFlags.Concurrency.NumThreads = 1 ConfigFlags.Concurrency.NumConcurrentEvents = 1 diff --git a/Tracking/Acts/FaserActsGeometry/test/FaserActsExtrapolationAlg.py b/Tracking/Acts/FaserActsGeometry/test/FaserActsExtrapolationAlg.py index 71be0017..de8c40ac 100644 --- a/Tracking/Acts/FaserActsGeometry/test/FaserActsExtrapolationAlg.py +++ b/Tracking/Acts/FaserActsGeometry/test/FaserActsExtrapolationAlg.py @@ -20,7 +20,7 @@ Configurable.configurableRun3Behavior = True #ConfigFlags.Input.Files = ["/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/esd/100evts10lumiblocks.ESD.root"] #ConfigFlags.Output.RDOFileName = "myRDO_sp.pool.root" ConfigFlags.Input.isMC = True # Needed to bypass autoconfig -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Always needed # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) diff --git a/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py index 1124fd8f..899134b3 100644 --- a/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py +++ b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py @@ -19,7 +19,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ["/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/esd/100evts10lumiblocks.ESD.root"] #ConfigFlags.Output.RDOFileName = "myRDO_sp.pool.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Always needed # Workaround for bug/missing flag; unimportant otherwise ConfigFlags.addFlag("Input.InitialTimeStamp", 0) diff --git a/Tracking/Acts/FaserActsKalmanFilter/test/FaserActsKalmanFilterAlg.py b/Tracking/Acts/FaserActsKalmanFilter/test/FaserActsKalmanFilterAlg.py index a0f8db8f..06975170 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/test/FaserActsKalmanFilterAlg.py +++ b/Tracking/Acts/FaserActsKalmanFilter/test/FaserActsKalmanFilterAlg.py @@ -22,7 +22,7 @@ Configurable.configurableRun3Behavior = True # Configure ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "tmp.root" -ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-01" # Always needed; must match FaserVersion ConfigFlags.GeoModel.Align.Dynamic = False ConfigFlags.Beam.NumberOfCollisions = 0. #ConfigFlags.Concurrency.NumThreads = 1 diff --git a/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ATLAS_CHECK_THREAD_SAFETY b/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ATLAS_CHECK_THREAD_SAFETY index c57ea6eb..7155ed94 100644 --- a/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ATLAS_CHECK_THREAD_SAFETY +++ b/Tracking/TrkEventCnv/TrkEventCnvTools/TrkEventCnvTools/ATLAS_CHECK_THREAD_SAFETY @@ -1,3 +1,2 @@ - Tracking/TrkEventCnv/TrkEventCnvTools diff --git a/graphics/VTI12/README.md b/graphics/VTI12/README.md index 91f52743..47e64e0a 100644 --- a/graphics/VTI12/README.md +++ b/graphics/VTI12/README.md @@ -8,10 +8,6 @@ To run on Calypso MC data (from an installation (run) directory): Note that VP1PLUGINPATH can be ninja-changed by asetup, and if it does not include the Calypso installation library folder, nothing will work -To run on cosmic ray data (RDO output from the TrackerDataAccess example programs), with the correct geometry, do the following commands instead: +You can also give the -detdescr="FASER-01" or -detdescr="FASER-02" and -globcond="OFLCOND-FASER-01" or -globcond="OFLCOND-FASER-02" flags to specify the detector geometry and conditions. -% source ./setup.sh - -% export VP1PLUGINPATH=./lib - -% vti12 -noautoconf -nosortdbreplicas -detdescr='FASER-CR' <input RDO file> \ No newline at end of file +The event display has no way to determine the right values for these settings (it defaults to FASER-01 and OFLCOND-FASER-01). \ No newline at end of file diff --git a/graphics/VTI12/VTI12Algs/share/vti12.py b/graphics/VTI12/VTI12Algs/share/vti12.py index d05dcb15..3878899d 100644 --- a/graphics/VTI12/VTI12Algs/share/vti12.py +++ b/graphics/VTI12/VTI12Algs/share/vti12.py @@ -91,11 +91,11 @@ if (vp1InputFiles == []): # Set geometry version if (not "DetDescrVersion" in dir()): DetDescrVersion = "FASER-01" - globalflags.DetDescrVersion = DetDescrVersion + globalflags.DetDescrVersion = DetDescrVersion # Set conditions tag if not 'vp1GlobCond' in dir(): - vp1GlobCond="OFLCOND-XXXX-XXX-XX" + vp1GlobCond="OFLCOND-FASER-01" from IOVDbSvc.CondDB import conddb conddb.setGlobalTag(vp1GlobCond) @@ -145,7 +145,7 @@ else: # Set conditions tag if not 'vp1GlobCond' in dir(): if (vp1Mc): - vp1GlobCond="OFLCOND-XXXX-XXX-XX" + vp1GlobCond="OFLCOND-FASER-01" else: vp1GlobCond="COMCOND-BLKPST-004-01" diff --git a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/VTI12GeometrySystems/VP1GeoFlags.h b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/VTI12GeometrySystems/VP1GeoFlags.h index 6d26dc45..a50cf0d1 100644 --- a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/VTI12GeometrySystems/VP1GeoFlags.h +++ b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/VTI12GeometrySystems/VP1GeoFlags.h @@ -26,14 +26,15 @@ public: enum SubSystemFlag { // 32-bits hexadecimal bitmask None = 0x00000000, - Veto = 0x00000001, - Trigger = 0x00000002, - Preshower = 0x00000004, + Emulsion = 0x00000001, + Veto = 0x00000002, + Trigger = 0x00000004, + Preshower = 0x00000008, - SCT = 0x00000008, - Dipole = 0x00000010, + SCT = 0x00000010, + Dipole = 0x00000020, - Ecal = 0x00000020, + Ecal = 0x00000040, // Pixel = 0x00000001, // bit 0 // SCT = 0x00000002, // 1 // TRT = 0x00000004, // 2 diff --git a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/GeoSysController.cxx b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/GeoSysController.cxx index 10a54115..e6325f8f 100644 --- a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/GeoSysController.cxx +++ b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/GeoSysController.cxx @@ -146,6 +146,9 @@ GeoSysController::GeoSysController(IVP1System * sys) setLastSelectedVolume(0); + // Neutrino + m_d->subSysCheckBoxMap[VP1GeoFlags::Emulsion] = m_d->ui.checkBox_Emulsion; + // SCINTILLATOR m_d->subSysCheckBoxMap[VP1GeoFlags::Veto] = m_d->ui.checkBox_Veto; m_d->subSysCheckBoxMap[VP1GeoFlags::Trigger] = m_d->ui.checkBox_Trigger; diff --git a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VP1GeometrySystem.cxx b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VP1GeometrySystem.cxx index 31252be9..8e4b6192 100644 --- a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VP1GeometrySystem.cxx +++ b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VP1GeometrySystem.cxx @@ -328,6 +328,7 @@ QWidget * VP1GeometrySystem::buildController() const QString& grandchildrenregexp="", // the regex for granchildren of the main sub-detector bool negategrandchildrenregexp = false // wheter we want to negate teh granchildren regex */ + m_d->addSubSystem( VP1GeoFlags::Emulsion, "Emulsion"); m_d->addSubSystem( VP1GeoFlags::Veto, "Veto"); m_d->addSubSystem( VP1GeoFlags::Trigger, "Trigger"); m_d->addSubSystem( VP1GeoFlags::Preshower,"Preshower"); @@ -1096,6 +1097,12 @@ void VP1GeometrySystem::Imp::applyTopVolStates(const QMap<quint32,QByteArray>&to void VP1GeometrySystem::Imp::createPathExtras(const VolumeHandle* volhandle, QString& prefix, QStack<QString>& entries) { switch(volhandle->subsystem()){ + case VP1GeoFlags::Emulsion:{ + prefix = QString("Emulsion::"); + entries.push("NEUTRINO::NEUTRINO"); + entries.push("Emulsion::Emulsion"); + return; + } case VP1GeoFlags::Veto:{ prefix = QString("Veto::"); entries.push("SCINT::SCINT"); diff --git a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx index 44621c5f..e1df8c9a 100644 --- a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx +++ b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VisAttributes.cxx @@ -143,6 +143,15 @@ void VisAttributes::overrideTransparencies(float transpfact) //////////////////////////////// Attributes for detectors //////////////////////////////// DetVisAttributes::DetVisAttributes() { + { + SoMaterial *material = new SoMaterial; + material->ambientColor.setValue(.187004, .157811, 0); + material->diffuseColor.setValue(.748016, .631244, 0); + material->specularColor.setValue(.915152, .915152, .915152); + material->shininess.setValue(0.642424); + add("Emulsion",material); + } + { SoMaterial *material = new SoMaterial; @@ -363,7 +372,24 @@ MatVisAttributes::MatVisAttributes() { add("Ether",m); } */ - + { + SoMaterial *material = new SoMaterial; + material->ambientColor.setValue(.187004*1.2, .157811*1.2, 0); + material->diffuseColor.setValue(.748016*1.2, .631244*1.2, 0); + material->specularColor.setValue(.915152, .915152, .915152); + material->shininess.setValue(0.642424); + add("Emulsion",material); + } + + { + SoMaterial *material = new SoMaterial; + material->ambientColor.setValue(.187004/1.2, .157811/1.2, 0); + material->diffuseColor.setValue(.748016/1.2, .631244/1.2, 0); + material->specularColor.setValue(.915152, .915152, .915152); + material->shininess.setValue(0.642424); + add("Polystyrene",material); + } + { // C02: diff --git a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VolumeTreeModel.cxx b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VolumeTreeModel.cxx index 5ad7fca0..b1aff16c 100644 --- a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VolumeTreeModel.cxx +++ b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/VolumeTreeModel.cxx @@ -31,7 +31,7 @@ class VolumeTreeModel::Imp { public: //Static definitions of sections and which subsystems goes in which sections: - enum SECTION { UNKNOWN, SCINT, TRACKER, CALO, MISC }; + enum SECTION { UNKNOWN, NEUTRINO, SCINT, TRACKER, CALO, MISC }; static std::map<SECTION,QString> section2string; static std::map<VP1GeoFlags::SubSystemFlag,SECTION> subsysflag2section; static std::map<VP1GeoFlags::SubSystemFlag,QString> subsysflag2string; @@ -104,6 +104,7 @@ VolumeTreeModel::VolumeTreeModel( QObject * parent ) { if (Imp::section2string.empty()) { Imp::section2string[Imp::UNKNOWN] = "Unknown"; + Imp::section2string[Imp::NEUTRINO] = "Neutrino"; Imp::section2string[Imp::SCINT] = "Scintillators"; Imp::section2string[Imp::TRACKER] = "Tracker"; Imp::section2string[Imp::CALO] = "Calorimeter"; @@ -111,6 +112,8 @@ VolumeTreeModel::VolumeTreeModel( QObject * parent ) } if (Imp::subsysflag2section.empty()) { Imp::defineSubSystem(VP1GeoFlags::None,"None",Imp::UNKNOWN); + // Neutrino + Imp::defineSubSystem(VP1GeoFlags::Emulsion, "Emulsion", Imp::NEUTRINO); // Scintillator Imp::defineSubSystem(VP1GeoFlags::Veto, "Veto", Imp::SCINT); Imp::defineSubSystem(VP1GeoFlags::Trigger, "Trigger", Imp::SCINT); diff --git a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/geometrysystemcontroller.ui b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/geometrysystemcontroller.ui index 57805e11..be9ac807 100644 --- a/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/geometrysystemcontroller.ui +++ b/graphics/VTI12/VTI12Systems/VTI12GeometrySystems/src/geometrysystemcontroller.ui @@ -150,6 +150,54 @@ <number>4</number> </property> <item> + <widget class="QGroupBox" name="groupBox_neutrino"> + <property name="title"> + <string>FaserNu</string> + </property> + <layout class="QVBoxLayout" name="_12"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>4</number> + </property> + <property name="topMargin"> + <number>4</number> + </property> + <property name="rightMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item> + <layout class="QHBoxLayout" name="_14"> + <item> + <widget class="QCheckBox" name="checkBox_Emulsion"> + <property name="text"> + <string>Emulsion</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> <widget class="QGroupBox" name="groupBox_scintillator"> <property name="title"> <string>Scintillator</string> diff --git a/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/CMakeLists.txt b/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/CMakeLists.txt index bcb9cacd..0451aa18 100644 --- a/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/CMakeLists.txt +++ b/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/CMakeLists.txt @@ -24,5 +24,5 @@ atlas_add_library( VTI12SimHitSystems VTI12SimHitSystems/*.h src/*.h src/*.cxx s PUBLIC_HEADERS VTI12SimHitSystems PRIVATE_INCLUDE_DIRS ${COIN3D_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} LINK_LIBRARIES VP1Base Qt5::Core Qt5::Widgets GL StoreGateLib SGtests - PRIVATE_LINK_LIBRARIES ${COIN3D_LIBRARIES} ${EIGEN_LIBRARIES} FaserGeoAdaptors GeoPrimitives ScintSimEvent FaserCaloSimEvent TrackerSimEvent VTI12Utils ) + PRIVATE_LINK_LIBRARIES ${COIN3D_LIBRARIES} ${EIGEN_LIBRARIES} FaserGeoAdaptors GeoPrimitives NeutrinoSimEvent ScintSimEvent FaserCaloSimEvent TrackerSimEvent VTI12Utils ) diff --git a/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/VP1SimHitSystem.cxx b/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/VP1SimHitSystem.cxx index 60a7cda9..19634a20 100755 --- a/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/VP1SimHitSystem.cxx +++ b/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/VP1SimHitSystem.cxx @@ -22,6 +22,8 @@ #include "FaserCaloSimEvent/CaloHitCollection.h" #include "ScintSimEvent/ScintHitCollection.h" #include "FaserGeoAdaptors/GeoScintHit.h" +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" +#include "FaserGeoAdaptors/GeoNeutrinoHit.h" #include "TrackerSimEvent/FaserSiHitCollection.h" #include "FaserGeoAdaptors/GeoFaserSiHit.h" #include "FaserGeoAdaptors/GeoFaserCaloHit.h" @@ -61,6 +63,7 @@ QWidget* VP1SimHitSystem::buildController() ui.setupUi(controller); // Populate Check Box Names Map + m_clockwork->checkBoxNamesMap.insert(ui.chbxEmulsionHits,"Emulsion"); m_clockwork->checkBoxNamesMap.insert(ui.chbxVetoHits,"Veto"); m_clockwork->checkBoxNamesMap.insert(ui.chbxTriggerHits,"Trigger"); m_clockwork->checkBoxNamesMap.insert(ui.chbxPreshowerHits,"Preshower"); @@ -80,6 +83,7 @@ QWidget* VP1SimHitSystem::buildController() void VP1SimHitSystem::systemcreate(StoreGateSvc* /*detstore*/) { // Populate Color Map + m_clockwork->colorMap.insert("Emulsion",SbColor(1,0,1)); m_clockwork->colorMap.insert("Veto",SbColor(0,0,1)); m_clockwork->colorMap.insert("Trigger",SbColor(1,1,1)); m_clockwork->colorMap.insert("Preshower",SbColor(1,0,0)); @@ -185,7 +189,26 @@ void VP1SimHitSystem::buildHitTree(const QString& detector) sw->addChild(material); // Take hits from SG - if(detector=="Veto") + if(detector=="Emulsion") + { + // + // Emulsion: + // + const NeutrinoHitCollection* p_collection = nullptr; + if(sg->retrieve(p_collection, "EmulsionHits")==StatusCode::SUCCESS) + { + for(NeutrinoHitConstIterator i_hit=p_collection->begin(); i_hit!=p_collection->end(); ++i_hit) + { + GeoNeutrinoHit ghit(*i_hit); + if(!ghit) continue; + HepGeom::Point3D<double> u = ghit.getGlobalPosition(); + hitVtxProperty->vertex.set1Value(hitCount++,u.x(),u.y(),u.z()); + } + } + else + message("Unable to retrieve Emulsion Hits"); + } + else if(detector=="Veto") { // // Veto: diff --git a/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/simhitcontrollerform.ui b/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/simhitcontrollerform.ui index b12880a8..67f62d51 100755 --- a/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/simhitcontrollerform.ui +++ b/graphics/VTI12/VTI12Systems/VTI12SimHitSystems/src/simhitcontrollerform.ui @@ -84,6 +84,22 @@ </property> </layout> </item> + <item> + <widget class="QGroupBox" name="groupBox_Nu"> + <property name="title"> + <string>Neutrino</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QCheckBox" name="chbxEmulsionHits"> + <property name="text"> + <string>Emulsion Hits</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> <item> <widget class="QGroupBox" name="groupBox"> <property name="title"> @@ -114,6 +130,22 @@ </layout> </widget> </item> + + + <item> + <layout class="QVBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>0</number> + </property> + </layout> + </item> + </layout> + </item> + </layout> + </item> <item> <spacer> <property name="orientation"> @@ -143,20 +175,7 @@ </layout> </widget> </item> - <item> - <layout class="QVBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>0</number> - </property> - </layout> - </item> - </layout> - </item> - </layout> - </item> + <item> <widget class="QGroupBox" name="groupBox_3"> <property name="title"> diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt index 8c6fd2c6..a93fb1a1 100644 --- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt +++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/CMakeLists.txt @@ -30,6 +30,7 @@ atlas_add_library( VTI12TrackSystems VTI12TrackSystems/*.h src/*.cxx Qt5::Core Qt5::Gui TrackRecordLib PRIVATE_LINK_LIBRARIES ${COIN3D_LIBRARIES} ${CLHEP_LIBRARIES} AtlasHepMCLib AthContainers FaserDetDescr EventPrimitives + NeutrinoIdentifier NeutrinoSimEvent NeutrinoReadoutGeometry ScintIdentifier ScintSimEvent ScintReadoutGeometry TrackerIdentifier TrackerReadoutGeometry TrackerSimEvent FaserCaloIdentifier CaloReadoutGeometry FaserCaloSimEvent diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/VTI12TrackSystems/SimHitHandle_NeutrinoHit.h b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/VTI12TrackSystems/SimHitHandle_NeutrinoHit.h new file mode 100644 index 00000000..91e2d6fa --- /dev/null +++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/VTI12TrackSystems/SimHitHandle_NeutrinoHit.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +//////////////////////////////////////////////////////////////// +// // +// Header file for class SimHitHandle_NeutrinoHit // +// // +// Description: Handle for NeutrinoHit's // +// // +// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) // +// Initial version: March 2008 // +// // +//////////////////////////////////////////////////////////////// + +#ifndef SIMHITHANDLE_NEUTRINOHIT_H +#define SIMHITHANDLE_NEUTRINOHIT_H + +#include "VTI12TrackSystems/SimHitHandleBase.h" + +#include "GeoPrimitives/GeoPrimitives.h" +#include "TrkParameters/TrackParameters.h" + +class NeutrinoHit; +class SimHitHandle_NeutrinoHit : public SimHitHandleBase { +public: + + SimHitHandle_NeutrinoHit( const NeutrinoHit * ); + virtual ~SimHitHandle_NeutrinoHit(); + + QString type() const { return "NeutrinoHit"; }; + + Amg::Vector3D momentumDirection() const; + Amg::Vector3D posStart() const; + Amg::Vector3D posEnd() const; + double hitTime() const; + + const HepMcParticleLink& particleLink() const; + + Trk::TrackParameters * createTrackParameters() const; + +private: + + class Imp; + Imp * m_d; + +}; + +#endif diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_NeutrinoHit.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_NeutrinoHit.cxx new file mode 100644 index 00000000..9a207706 --- /dev/null +++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/SimHitHandle_NeutrinoHit.cxx @@ -0,0 +1,157 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +//////////////////////////////////////////////////////////////// +// // +// Implementation of class SimHitHandle_NeutrinoHit // +// // +// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) // +// Initial version: March 2008 // +// // +//////////////////////////////////////////////////////////////// + +#include "VTI12TrackSystems/SimHitHandle_NeutrinoHit.h" +#include "VP1Base/VP1Msg.h" +#include "VTI12Utils/VP1DetInfo.h" +#include "VTI12Utils/VP1ParticleData.h" + +#include "NeutrinoSimEvent/NeutrinoHit.h" +#include "NeutrinoReadoutGeometry/NeutrinoDetectorElement.h" +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" +#include "NeutrinoIdentifier/EmulsionID.h" +#include "VTI12TrackSystems/VP1TrackSanity.h" + +//____________________________________________________________________ +class SimHitHandle_NeutrinoHit::Imp { +public: + Imp( const NeutrinoHit * h ) : thehit(h),detelem(0) {} + const NeutrinoHit * thehit; + mutable const NeutrinoDD::NeutrinoDetectorElement * detelem; + bool ensureDetElemInit() const; + Amg::Vector3D localToGlobal(const HepGeom::Point3D<double>&) const; +}; + + +//____________________________________________________________________ +SimHitHandle_NeutrinoHit::SimHitHandle_NeutrinoHit(const NeutrinoHit * h) + : SimHitHandleBase(), m_d(new Imp(h)) +{ + if (!h) + VP1Msg::message("SimHitHandle_NeutrinoHit constructor ERROR: Received null hit pointer"); +} + +//____________________________________________________________________ +SimHitHandle_NeutrinoHit::~SimHitHandle_NeutrinoHit() +{ + delete m_d; +} + +//____________________________________________________________________ +bool SimHitHandle_NeutrinoHit::Imp::ensureDetElemInit() const +{ + if (detelem) + return true; + int module = thehit->getModule(); + int base = thehit->getBase(); + int film = thehit->getFilm(); + + Identifier id = VP1DetInfo::emulsionIDHelper()->film_id( module, base, film); + //fixme: id is_valid ? + detelem = VP1DetInfo::emulsionDetMgr()->getDetectorElement(id); + //Fixme : Handle case where detelem can not be found gracefully. And check pointers from VP1DetInfo!! + if (!detelem) + VP1Msg::messageDebug("SimHitHandle_NeutrinoHit ERROR: Could not get detector element for hit!"); + return detelem!=0; +} + +//____________________________________________________________________ +Amg::Vector3D SimHitHandle_NeutrinoHit::momentumDirection() const +{ + if (VP1Msg::verbose()&&m_d->thehit->localEndPosition()==m_d->thehit->localStartPosition()) + VP1Msg::messageVerbose("SimHitHandle_NeutrinoHit::momentumDirection() ERROR: posStart()==posEnd()"); + return (posEnd()-posStart()).unit(); +} + +//____________________________________________________________________ +Amg::Vector3D SimHitHandle_NeutrinoHit::Imp::localToGlobal( const HepGeom::Point3D<double>& local ) const +{ + if (!ensureDetElemInit()) + return Amg::Vector3D(0,0,0); + return Amg::Vector3D(Amg::EigenTransformToCLHEP(detelem->transformHit()) * local); +} + +//____________________________________________________________________ +Amg::Vector3D SimHitHandle_NeutrinoHit::posStart() const +{ + return m_d->localToGlobal(m_d->thehit->localStartPosition()); +} + +//____________________________________________________________________ +Amg::Vector3D SimHitHandle_NeutrinoHit::posEnd() const +{ + return m_d->localToGlobal(m_d->thehit->localEndPosition()); +} + +//____________________________________________________________________ +double SimHitHandle_NeutrinoHit::hitTime() const +{ + return m_d->thehit->meanTime(); +} + +//____________________________________________________________________ +const HepMcParticleLink& SimHitHandle_NeutrinoHit::particleLink() const +{ + return m_d->thehit->particleLink(); +} + +//____________________________________________________________________ +Trk::TrackParameters * SimHitHandle_NeutrinoHit::createTrackParameters() const +{ + //Find charge and magnitude of momentum: + double c; + if ( !hasCharge() ) { + bool ok; + c = VP1ParticleData::particleCharge(pdg(),ok); + if (!ok) { + VP1Msg::message("SimHitHandle_NeutrinoHit::createTrackParameters ERROR: Could not find particle charge (pdg=" + +QString::number(pdg())+"). Assuming charge=+1."); + c = +1.0; + } else { + if (VP1Msg::verbose()) + VP1Msg::messageVerbose("Looked up particle charge for scintillator simhit with pdg code "+VP1Msg::str(pdg())+": "+VP1Msg::str(c)); + } + const_cast<SimHitHandle_NeutrinoHit*>(this)->setCharge(c); + } else { + c = charge(); + } + + double mom = momentum(); + if (mom<=0) { + VP1Msg::message("SimHitHandle_NeutrinoHit::createTrackParameters ERROR: Unknown momentum. Using 1 GeV"); + mom = 1*CLHEP::GeV; + } + + ////We could in principle get a surface like this: + // if (!m_d->ensureDetElemInit()) { + // VP1Msg::messageDebug("SimHitHandle_NeutrinoHit WARNING: Could not get detector element!"); + // return 0; + // } + // const Trk::PlaneSurface * surf + // = dynamic_cast<const Trk::PlaneSurface *>( &(m_d->detelem->surface())); + // if (!surf) { + // VP1Msg::message("SimHitHandle_NeutrinoHit::createTrackParameters ERROR: could not get Trk::PlaneSurface"); + // return 0; + // } + ////And then proceed to construct a new AtaPlane parameter with that + ////surface. However, that gives some problems, so instead we simply + ////create a perigee: + + const Amg::Vector3D globpos = posStart(); + +// const Trk::GlobalMomentum u(momentumDirection()); + const Amg::Vector3D u(momentumDirection()); + + return new Trk::Perigee(0, 0, u.phi(), u.theta(), c/mom, globpos); +} diff --git a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandle_TruthTracks.cxx b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandle_TruthTracks.cxx index 05c3f75b..ef731fa9 100644 --- a/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandle_TruthTracks.cxx +++ b/graphics/VTI12/VTI12Systems/VTI12TrackSystems/src/TrackCollHandle_TruthTracks.cxx @@ -16,6 +16,7 @@ #include "VTI12TrackSystems/TrackHandle_TruthTrack.h" #include "VTI12TrackSystems/SimHitHandleBase.h" #include "VTI12TrackSystems/SimHitHandle_TrackRecord.h" +#include "VTI12TrackSystems/SimHitHandle_NeutrinoHit.h" #include "VTI12TrackSystems/SimHitHandle_ScintHit.h" #include "VTI12TrackSystems/SimHitHandle_FaserSiHit.h" #include "VTI12TrackSystems/SimHitHandle_CaloHit.h" @@ -39,6 +40,7 @@ #include "ScintSimEvent/ScintHitCollection.h" #include "TrackerSimEvent/FaserSiHitCollection.h" #include "FaserCaloSimEvent/CaloHitCollection.h" +#include "NeutrinoSimEvent/NeutrinoHitCollection.h" #include "CLHEP/Units/PhysicalConstants.h" @@ -67,6 +69,7 @@ public: // static SimHitHandleBase * createHitHandle( const TrackRecord * h ) { return new SimHitHandle_TrackRecord(h); } static SimHitHandleBase * createHitHandle( const TrackRecord& h ) { return new SimHitHandle_TrackRecord(&h); } + static SimHitHandleBase * createHitHandle( const NeutrinoHit& h ) { return new SimHitHandle_NeutrinoHit(&h); } static SimHitHandleBase * createHitHandle( const ScintHit& h ) { return new SimHitHandle_ScintHit(&h); } static SimHitHandleBase * createHitHandle( const FaserSiHit& h ) { return new SimHitHandle_FaserSiHit(&h); } static SimHitHandleBase * createHitHandle( const CaloHit& h) { return new SimHitHandle_CaloHit(&h); } @@ -117,7 +120,10 @@ QStringList TrackCollHandle_TruthTracks::availableCollections( IVP1System*sys ) QStringList mcevent_keys = sgcont.getKeys<McEventCollection>(); QStringList trackrecord_keys = sgcont.getKeys<TrackRecordCollection>(); - QStringList keys_siliconhits,keys_scintillatorhits,keys_calorimeterhits; + QStringList keys_neutrinohits, keys_siliconhits,keys_scintillatorhits,keys_calorimeterhits; + + if (VP1JobConfigInfo::hasEmulsionGeometry()) + keys_neutrinohits = sgcont.getKeys<NeutrinoHitCollection>();//"EmulsionHits" if (VP1JobConfigInfo::hasVetoGeometry() || VP1JobConfigInfo::hasTriggerGeometry() || @@ -128,7 +134,8 @@ QStringList TrackCollHandle_TruthTracks::availableCollections( IVP1System*sys ) if (VP1JobConfigInfo::hasEcalGeometry()) keys_calorimeterhits = sgcont.getKeys<CaloHitCollection>(); - bool extrainfo = ! ( keys_scintillatorhits.empty() && + bool extrainfo = ! ( keys_neutrinohits.empty() && + keys_scintillatorhits.empty() && keys_siliconhits.empty() && trackrecord_keys.empty() ); @@ -254,7 +261,8 @@ bool TrackCollHandle_TruthTracks::Imp::loadHitLists(std::map<SimBarCode,SimHitLi addHitCollections<TrackRecordCollection>(hitLists); //Important that collections which inherently contains pdg codes are loaded first! - + if (VP1JobConfigInfo::hasEmulsionGeometry()) + addHitCollections<NeutrinoHitCollection>(hitLists); if (VP1JobConfigInfo::hasVetoGeometry() || VP1JobConfigInfo::hasTriggerGeometry() || VP1JobConfigInfo::hasPreshowerGeometry()) diff --git a/graphics/VTI12/VTI12Utils/CMakeLists.txt b/graphics/VTI12/VTI12Utils/CMakeLists.txt index ae773679..beff2bb1 100644 --- a/graphics/VTI12/VTI12Utils/CMakeLists.txt +++ b/graphics/VTI12/VTI12Utils/CMakeLists.txt @@ -35,5 +35,6 @@ atlas_add_library( VTI12Utils VTI12Utils/*.h src/*.cxx src/*.cpp ScintIdentifier ScintReadoutGeometry TrackerIdentifier TrackerReadoutGeometry FaserCaloIdentifier CaloReadoutGeometry + NeutrinoIdentifier NeutrinoReadoutGeometry #InDetRIO_OnTrack TrkSurfaces TrkRIO_OnTrack VP1HEPVis ) diff --git a/graphics/VTI12/VTI12Utils/VTI12Utils/VP1DetInfo.h b/graphics/VTI12/VTI12Utils/VTI12Utils/VP1DetInfo.h index 1adebf82..ff521e60 100644 --- a/graphics/VTI12/VTI12Utils/VTI12Utils/VP1DetInfo.h +++ b/graphics/VTI12/VTI12Utils/VTI12Utils/VP1DetInfo.h @@ -20,6 +20,7 @@ class IVP1System; class StoreGateSvc; +namespace NeutrinoDD { class EmulsionDetectorManager; } namespace TrackerDD { class SCT_DetectorManager; } namespace ScintDD { class VetoDetectorManager; } namespace ScintDD { class TriggerDetectorManager; } @@ -27,12 +28,14 @@ namespace ScintDD { class PreshowerDetectorManager; } namespace CaloDD { class EcalDetectorManager; } class FaserDetectorID; +class EmulsionDetectorID; class ScintDetectorID; class VetoID; class TriggerID; class PreshowerID; class FaserSCT_ID; class EcalID; +class EmulsionID; class Identifier; @@ -45,6 +48,8 @@ public: //return null. And it is never allowed to delete any of the returned //pointers! + static const NeutrinoDD::EmulsionDetectorManager * emulsionDetMgr(); + static const ScintDD::VetoDetectorManager * vetoDetMgr(); static const ScintDD::TriggerDetectorManager * triggerDetMgr(); static const ScintDD::PreshowerDetectorManager * preshowerDetMgr(); @@ -58,6 +63,8 @@ public: //Common specialised identifier helpers: + static const EmulsionID * emulsionIDHelper(); + static const VetoID * vetoIDHelper(); static const TriggerID * triggerIDHelper(); static const PreshowerID * preshowerIDHelper(); diff --git a/graphics/VTI12/VTI12Utils/VTI12Utils/VP1JobConfigInfo.h b/graphics/VTI12/VTI12Utils/VTI12Utils/VP1JobConfigInfo.h index d9ad784c..a9091090 100644 --- a/graphics/VTI12/VTI12Utils/VTI12Utils/VP1JobConfigInfo.h +++ b/graphics/VTI12/VTI12Utils/VTI12Utils/VP1JobConfigInfo.h @@ -32,6 +32,8 @@ public: //These next methods tells us what geomodel parts are initialised: static bool hasGeoModelExperiment();//If GeoModelExperiment/"FASER" can be retrieved + static bool hasEmulsionGeometry(); + static bool hasVetoGeometry(); static bool hasTriggerGeometry(); static bool hasPreshowerGeometry(); diff --git a/graphics/VTI12/VTI12Utils/src/VP1DetInfo.cxx b/graphics/VTI12/VTI12Utils/src/VP1DetInfo.cxx index 6f5a72e9..ba2ecb3f 100644 --- a/graphics/VTI12/VTI12Utils/src/VP1DetInfo.cxx +++ b/graphics/VTI12/VTI12Utils/src/VP1DetInfo.cxx @@ -22,6 +22,8 @@ #include "GeoModelKernel/GeoPVConstLink.h" +#include "NeutrinoReadoutGeometry/EmulsionDetectorManager.h" + #include "ScintReadoutGeometry/VetoDetectorManager.h" #include "ScintReadoutGeometry/TriggerDetectorManager.h" #include "ScintReadoutGeometry/PreshowerDetectorManager.h" @@ -32,6 +34,8 @@ #include "FaserDetDescr/FaserDetectorID.h" +#include "NeutrinoIdentifier/EmulsionID.h" + #include "ScintIdentifier/VetoID.h" #include "ScintIdentifier/TriggerID.h" #include "ScintIdentifier/PreshowerID.h" @@ -51,6 +55,8 @@ public: static bool m_initialised; static const char m_badInitFlag;//Address of this means bad initialisation. + static const NeutrinoDD::EmulsionDetectorManager * m_emulsionDetMgr; + static const ScintDD::VetoDetectorManager * m_vetoDetMgr; static const ScintDD::TriggerDetectorManager * m_triggerDetMgr; static const ScintDD::PreshowerDetectorManager * m_preshowerDetMgr; @@ -61,6 +67,8 @@ public: static const FaserDetectorID * m_faserIDHelper; + static const EmulsionID * m_emulsionIDHelper; + static const VetoID * m_vetoIDHelper; static const TriggerID * m_triggerIDHelper; static const PreshowerID * m_preshowerIDHelper; @@ -73,6 +81,8 @@ public: bool VP1DetInfo::Imp::m_initialised = false; const char VP1DetInfo::Imp::m_badInitFlag = ' '; +const NeutrinoDD::EmulsionDetectorManager * VP1DetInfo::Imp::m_emulsionDetMgr = 0; + const ScintDD::VetoDetectorManager * VP1DetInfo::Imp::m_vetoDetMgr = 0; const ScintDD::TriggerDetectorManager * VP1DetInfo::Imp::m_triggerDetMgr = 0; const ScintDD::PreshowerDetectorManager * VP1DetInfo::Imp::m_preshowerDetMgr = 0; @@ -83,6 +93,8 @@ const CaloDD::EcalDetectorManager * VP1DetInfo::Imp::m_ecalDetMgr = 0; const FaserDetectorID * VP1DetInfo::Imp::m_faserIDHelper = 0; +const EmulsionID * VP1DetInfo::Imp::m_emulsionIDHelper = 0; + const VetoID * VP1DetInfo::Imp::m_vetoIDHelper = 0; const TriggerID * VP1DetInfo::Imp::m_triggerIDHelper = 0; const PreshowerID * VP1DetInfo::Imp::m_preshowerIDHelper = 0; @@ -129,6 +141,8 @@ const T * VP1DetInfo::Imp::cachedRetrieve(const T*& cachedPtr, const char* prefe } +const NeutrinoDD::EmulsionDetectorManager * VP1DetInfo::emulsionDetMgr() { return Imp::cachedRetrieve(Imp::m_emulsionDetMgr,"Emulsion",VP1JobConfigInfo::hasEmulsionGeometry()); } + const ScintDD::VetoDetectorManager * VP1DetInfo::vetoDetMgr() { return Imp::cachedRetrieve(Imp::m_vetoDetMgr,"Veto",VP1JobConfigInfo::hasVetoGeometry()); } const ScintDD::TriggerDetectorManager * VP1DetInfo::triggerDetMgr() { return Imp::cachedRetrieve(Imp::m_triggerDetMgr,"Trigger",VP1JobConfigInfo::hasTriggerGeometry()); } const ScintDD::PreshowerDetectorManager * VP1DetInfo::preshowerDetMgr() { return Imp::cachedRetrieve(Imp::m_preshowerDetMgr,"Preshower",VP1JobConfigInfo::hasPreshowerGeometry()); } @@ -139,6 +153,8 @@ const CaloDD::EcalDetectorManager * VP1DetInfo::ecalDetMgr() { return Imp::cache const FaserDetectorID * VP1DetInfo::faserIDHelper() { return Imp::cachedRetrieve(Imp::m_faserIDHelper,"FaserID",true); } +const EmulsionID * VP1DetInfo::emulsionIDHelper() { return Imp::cachedRetrieve(Imp::m_emulsionIDHelper,"EmulsionID",VP1JobConfigInfo::hasEmulsionGeometry()); } + const VetoID * VP1DetInfo::vetoIDHelper() { return Imp::cachedRetrieve(Imp::m_vetoIDHelper,"VetoID",VP1JobConfigInfo::hasVetoGeometry()); } const TriggerID * VP1DetInfo::triggerIDHelper() { return Imp::cachedRetrieve(Imp::m_triggerIDHelper,"TriggerID",VP1JobConfigInfo::hasTriggerGeometry()); } const PreshowerID * VP1DetInfo::preshowerIDHelper() { return Imp::cachedRetrieve(Imp::m_preshowerIDHelper,"PreshowerID",VP1JobConfigInfo::hasPreshowerGeometry()); } @@ -154,6 +170,12 @@ bool VP1DetInfo::isUnsafe( const Identifier& id ) { if ( !idhelper || !id.is_valid() ) return true; + if (idhelper->is_neutrino(id)) + { + if (!VP1JobConfigInfo::hasEmulsionGeometry() && idhelper->is_emulsion(id)) + return true; + } + if (idhelper->is_scint(id)) { if (!VP1JobConfigInfo::hasVetoGeometry() && idhelper->is_veto(id)) return true; diff --git a/graphics/VTI12/VTI12Utils/src/VP1JobConfigInfo.cxx b/graphics/VTI12/VTI12Utils/src/VP1JobConfigInfo.cxx index 0449af39..03a305c6 100644 --- a/graphics/VTI12/VTI12Utils/src/VP1JobConfigInfo.cxx +++ b/graphics/VTI12/VTI12Utils/src/VP1JobConfigInfo.cxx @@ -35,6 +35,7 @@ public: static GeoPVConstLink geoModelWorld; static bool hasGeoModelExperiment; + static bool hasEmulsionGeometry; static bool hasVetoGeometry; static bool hasTriggerGeometry; static bool hasPreshowerGeometry; @@ -49,6 +50,7 @@ GeoPVConstLink VP1JobConfigInfo::Imp::geoModelWorld; // init default values bool VP1JobConfigInfo::Imp::initialised = false; bool VP1JobConfigInfo::Imp::hasGeoModelExperiment = false; +bool VP1JobConfigInfo::Imp::hasEmulsionGeometry = false; bool VP1JobConfigInfo::Imp::hasVetoGeometry = false; bool VP1JobConfigInfo::Imp::hasTriggerGeometry = false; bool VP1JobConfigInfo::Imp::hasPreshowerGeometry = false; @@ -60,6 +62,7 @@ bool VP1JobConfigInfo::Imp::hasCavernInfraGeometry = false; void VP1JobConfigInfo::Imp::turnOffAll() { hasGeoModelExperiment = false; + hasEmulsionGeometry = false; hasVetoGeometry = false; hasTriggerGeometry = false; hasPreshowerGeometry = false; @@ -84,6 +87,7 @@ void VP1JobConfigInfo::Imp::ensureInit() if (VP1Msg::verbose()) { VP1Msg::messageVerbose("VTI12JobConfigInfo => Found job configuration:"); VP1Msg::messageVerbose("VTI12JobConfigInfo => hasGeoModelExperiment = "+QString(hasGeoModelExperiment?"On":"Off")); + VP1Msg::messageVerbose("VTI12JobConfigInfo => hasEmulsionGeometry = "+QString(hasEmulsionGeometry?"On":"Off")); VP1Msg::messageVerbose("VTI12JobConfigInfo => hasVetoGeometry = "+QString(hasVetoGeometry?"On":"Off")); VP1Msg::messageVerbose("VTI12JobConfigInfo => hasTriggerGeometry = "+QString(hasTriggerGeometry?"On":"Off")); VP1Msg::messageVerbose("VTI12JobConfigInfo => hasPreshowerGeometry = "+QString(hasPreshowerGeometry?"On":"Off")); @@ -97,6 +101,7 @@ void VP1JobConfigInfo::Imp::ensureInit() //____________________________________________________________________ bool VP1JobConfigInfo::hasGeoModelExperiment() { if (!Imp::initialised) Imp::ensureInit(); return Imp::hasGeoModelExperiment; } +bool VP1JobConfigInfo::hasEmulsionGeometry() { if (!Imp::initialised) Imp::ensureInit(); return Imp::hasEmulsionGeometry; } bool VP1JobConfigInfo::hasVetoGeometry() { if (!Imp::initialised) Imp::ensureInit(); return Imp::hasVetoGeometry; } bool VP1JobConfigInfo::hasTriggerGeometry() { if (!Imp::initialised) Imp::ensureInit(); return Imp::hasTriggerGeometry; } bool VP1JobConfigInfo::hasPreshowerGeometry() { if (!Imp::initialised) Imp::ensureInit(); return Imp::hasPreshowerGeometry; } @@ -152,6 +157,7 @@ bool VP1JobConfigInfo::Imp::actualInit( StoreGateSvc* detStore ) while (!av.atEnd()) { std::string name = av.getName(); VP1Msg::message( QString { name.c_str() } ); + if ( !hasEmulsionGeometry && name=="Emulsion") hasEmulsionGeometry = true; if ( !hasVetoGeometry && name=="Veto") hasVetoGeometry = true; if ( !hasTriggerGeometry && name=="Trigger") hasTriggerGeometry = true; if ( !hasPreshowerGeometry && name=="Preshower") hasPreshowerGeometry = true; -- GitLab