From db731c79ac00419f10e40b9c7c642f5d301fb3c5 Mon Sep 17 00:00:00 2001 From: jmcarcell Date: Mon, 11 Dec 2023 18:49:08 +0100 Subject: [PATCH 01/21] Change LCIO::LCIO to LCIO::lcio --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 384999510..d467551ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,8 +85,8 @@ add_library(lcgeo ALIAS k4geo) target_include_directories(${PackageName} PRIVATE ${PROJECT_SOURCE_DIR}/detector/include ) target_include_directories(${PackageName}G4 PRIVATE ${PROJECT_SOURCE_DIR}/detector/include ) -target_link_libraries(${PackageName} DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers ROOT::Core LCIO::LCIO detectorSegmentations) -target_link_libraries(${PackageName}G4 DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers DD4hep::DDG4 ROOT::Core ${Geant4_LIBRARIES} LCIO::LCIO) +target_link_libraries(${PackageName} DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers ROOT::Core LCIO::lcio detectorSegmentations) +target_link_libraries(${PackageName}G4 DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers DD4hep::DDG4 ROOT::Core ${Geant4_LIBRARIES} LCIO::lcio) #Create this_package.sh file, and install dd4hep_instantiate_package(${PackageName}) From 444e6d18f7bd1acf75196f7f6981e92234638d82 Mon Sep 17 00:00:00 2001 From: jmcarcell Date: Mon, 29 Jan 2024 08:50:29 +0100 Subject: [PATCH 02/21] Add a key4hep build workflow; previous commit: Change LCIO::LCIO to LCIO::lcio --- .github/workflows/key4hep-build.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/key4hep-build.yaml diff --git a/.github/workflows/key4hep-build.yaml b/.github/workflows/key4hep-build.yaml new file mode 100644 index 000000000..deeea38c4 --- /dev/null +++ b/.github/workflows/key4hep-build.yaml @@ -0,0 +1,20 @@ +name: Key4hep build + +on: + push: + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + build_type: ["release", "nightly"] + image: ["alma9", "ubuntu22", "centos7"] + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: key4hep/key4hep-actions/key4hep-build@main + with: + build_type: ${{ matrix.build_type }} + image: ${{ matrix.image }} From a2d22ce5b7ebb6ce66c1a0bcf2907e7d2be6bf5b Mon Sep 17 00:00:00 2001 From: jmcarcell Date: Mon, 5 Feb 2024 14:31:05 +0100 Subject: [PATCH 03/21] Change key4hep-build workflow triggers; previous commit: Add a key4hep build workflow; previous commit: Change LCIO::LCIO to LCIO::lcio --- .github/workflows/key4hep-build.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/key4hep-build.yaml b/.github/workflows/key4hep-build.yaml index deeea38c4..3f9007f09 100644 --- a/.github/workflows/key4hep-build.yaml +++ b/.github/workflows/key4hep-build.yaml @@ -2,6 +2,9 @@ name: Key4hep build on: push: + branches: + - main + pull_request: workflow_dispatch: jobs: @@ -13,7 +16,7 @@ jobs: fail-fast: false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: key4hep/key4hep-actions/key4hep-build@main with: build_type: ${{ matrix.build_type }} From 953441c383999da140c901fd305ab51c1c34e7fa Mon Sep 17 00:00:00 2001 From: BrieucF Date: Tue, 9 Jan 2024 19:01:47 +0100 Subject: [PATCH 04/21] [ALLEGRO] File and variable renaming plus propagation of overlap fix --- ..._DectDimensions.xml => DectDimensions.xml} | 0 ...ectEmptyMaster.xml => DectEmptyMaster.xml} | 0 ...d.xml => ECalBarrel_thetamodulemerged.xml} | 16 +++-- ...lBarrel_thetamodulemerged_calibration.xml} | 25 ++++---- ...ECalBarrel_thetamodulemerged_upstream.xml} | 29 +++++----- ..._coneCryo.xml => ECalEndcaps_coneCryo.xml} | 0 ...rel_TileCal.xml => HCalBarrel_TileCal.xml} | 0 ...xml => HCalEndcaps_ThreeParts_TileCal.xml} | 0 .../ALLEGRO_o1_v02/SimplifiedDriftChamber.xml | 58 ------------------- 9 files changed, 37 insertions(+), 91 deletions(-) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_DectDimensions.xml => DectDimensions.xml} (100%) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_DectEmptyMaster.xml => DectEmptyMaster.xml} (100%) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_ECalBarrel_thetamodulemerged.xml => ECalBarrel_thetamodulemerged.xml} (93%) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_ECalBarrel_thetamodulemerged_calibration.xml => ECalBarrel_thetamodulemerged_calibration.xml} (92%) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_ECalBarrel_thetamodulemerged_upstream.xml => ECalBarrel_thetamodulemerged_upstream.xml} (90%) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_EcalEndcaps_coneCryo.xml => ECalEndcaps_coneCryo.xml} (100%) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_HCalBarrel_TileCal.xml => HCalBarrel_TileCal.xml} (100%) rename FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/{FCCee_HCalEndcaps_ThreeParts_TileCal.xml => HCalEndcaps_ThreeParts_TileCal.xml} (100%) delete mode 100644 FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/SimplifiedDriftChamber.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_DectDimensions.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectDimensions.xml similarity index 100% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_DectDimensions.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectDimensions.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_DectEmptyMaster.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectEmptyMaster.xml similarity index 100% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_DectEmptyMaster.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectEmptyMaster.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged.xml similarity index 93% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged.xml index 2a0beb3e8..9cf284bf0 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged.xml @@ -23,8 +23,8 @@ - - + + @@ -42,24 +42,22 @@ - - + + - - + + - - @@ -119,7 +117,7 @@ - + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged_calibration.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_calibration.xml similarity index 92% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged_calibration.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_calibration.xml index be8770709..d69ba26f9 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged_calibration.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_calibration.xml @@ -15,11 +15,11 @@ - - + + - + @@ -34,19 +34,22 @@ - - + + - - + + - - + + + + + @@ -102,7 +105,7 @@ - + @@ -133,4 +136,4 @@ - \ No newline at end of file + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged_upstream.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_upstream.xml similarity index 90% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged_upstream.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_upstream.xml index 8c96a5939..ee39e57a5 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_ECalBarrel_thetamodulemerged_upstream.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_upstream.xml @@ -15,17 +15,17 @@ - - + + - + - + @@ -34,19 +34,22 @@ - - + + - - + + - - + + + + + @@ -75,7 +78,7 @@ - + system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10 @@ -102,7 +105,7 @@ - + @@ -133,4 +136,4 @@ - \ No newline at end of file + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_EcalEndcaps_coneCryo.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalEndcaps_coneCryo.xml similarity index 100% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_EcalEndcaps_coneCryo.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalEndcaps_coneCryo.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_HCalBarrel_TileCal.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/HCalBarrel_TileCal.xml similarity index 100% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_HCalBarrel_TileCal.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/HCalBarrel_TileCal.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_HCalEndcaps_ThreeParts_TileCal.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/HCalEndcaps_ThreeParts_TileCal.xml similarity index 100% rename from FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/FCCee_HCalEndcaps_ThreeParts_TileCal.xml rename to FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/HCalEndcaps_ThreeParts_TileCal.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/SimplifiedDriftChamber.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/SimplifiedDriftChamber.xml deleted file mode 100644 index 9d13d0176..000000000 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/SimplifiedDriftChamber.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - A simplified implementation of the drift chamber for the FCCee-IDEA concept - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${GlobalTrackerReadoutID_DCH} - - - - - - - - Dimensions for the drift chamber - - - - - - - From 17fc2fb68c148263657fbb261dab6ee40e77d026 Mon Sep 17 00:00:00 2001 From: BrieucF Date: Tue, 9 Jan 2024 19:03:29 +0100 Subject: [PATCH 05/21] [ALLEGRO] Replacing the simplified drift chamber by the detailed one --- .../compact/ALLEGRO_o1_v02/ALLEGRO_o1_v02.xml | 12 +- .../compact/ALLEGRO_o1_v02/DectDimensions.xml | 6 +- .../compact/ALLEGRO_o1_v02/DriftChamber.xml | 110 +++++++++++++++++ .../compact/ALLEGRO_o1_v02/materials.xml | 116 +++++++++++++++++- FCCee/ALLEGRO/compact/README.md | 4 +- 5 files changed, 232 insertions(+), 16 deletions(-) create mode 100644 FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DriftChamber.xml diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ALLEGRO_o1_v02.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ALLEGRO_o1_v02.xml index ff4266dd9..bf4b652fe 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ALLEGRO_o1_v02.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ALLEGRO_o1_v02.xml @@ -28,7 +28,7 @@ - + @@ -36,11 +36,11 @@ - - - - - + + + + + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectDimensions.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectDimensions.xml index 439e20cdd..237223204 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectDimensions.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectDimensions.xml @@ -84,9 +84,9 @@ - - - + + + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DriftChamber.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DriftChamber.xml new file mode 100644 index 000000000..b24fa784f --- /dev/null +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DriftChamber.xml @@ -0,0 +1,110 @@ + + + + Detector description for the IDEA Drift Chamber. To understand the free parameters below, look e.g. at https://indico.cern.ch/event/932973/contributions/4041314/attachments/2139657/3664808/primavera_FCCworkshop_2020.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:4,superLayer:5,layer:5,phi:11,hitorigin:3,stereo:1,layerInCell:2 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/materials.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/materials.xml index a899266c3..7fe008147 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/materials.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/materials.xml @@ -225,14 +225,118 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

diff --git a/FCCee/ALLEGRO/compact/README.md b/FCCee/ALLEGRO/compact/README.md index 9a6ded62d..aecc08265 100644 --- a/FCCee/ALLEGRO/compact/README.md +++ b/FCCee/ALLEGRO/compact/README.md @@ -2,4 +2,6 @@ ALLEGRO ======================== ALLEGRO_o1_v01: it is a liquid Noble gas based detector. This version picked from the latest version in FCCDetectors repo. -ALLEGRO_o1_v02: evolves from o1_v01, replacing the barrel ECAL. This version has a constant cell size in theta for the ECAL barrel (instead of eta as in o1_v01) and now it is possible to have a different number of cells merged for each longitudinal layer. +ALLEGRO_o1_v02: evolves from o1_v01, replacing the barrel ECAL and adding a detailed version drift chamber. +This version has a constant cell size in theta for the ECAL barrel (instead of eta as in o1_v01) and now it is possible to have a different number of cells merged for each longitudinal layer. +Known caveat: the drift chamber has a larger z extent than in the IDEA detector but the wire spacing was not re-optimized. It is ok software-wise but the currently implemented design is not fully compliant with R&D considerations, will need a new drift chamber layout from the detector concept team. From 1fbfaab282c4b92138592765eb638e4439dd1ae8 Mon Sep 17 00:00:00 2001 From: BrieucF Date: Tue, 9 Jan 2024 19:19:56 +0100 Subject: [PATCH 06/21] [TESTS] Add a test for ALLEGRO_o1_v02 --- lcgeoTests/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lcgeoTests/CMakeLists.txt b/lcgeoTests/CMakeLists.txt index 635a52c7c..909fbdee6 100644 --- a/lcgeoTests/CMakeLists.txt +++ b/lcgeoTests/CMakeLists.txt @@ -86,6 +86,13 @@ ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test_${PackageName}.sh ddsim --compactFile=${CMAKE_CURRENT_SOURCE_DIR}/../FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v02.xml --runType=batch -G -N=1 --outputFile=testIDEA_o1_v02.slcio ) SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Exception;EXCEPTION;ERROR;Error" TIMEOUT 240) +#-------------------------------------------------- +# test for ALLEGRO o1 v02 +SET( test_name "test_ALLEGRO_o1_v02" ) +ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test_${PackageName}.sh" + ddsim --compactFile=${CMAKE_CURRENT_SOURCE_DIR}/../FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ALLEGRO_o1_v02.xml --runType=batch -G -N=1 --outputFile=testALLEGRO_o1_v02.root ) +SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Exception;EXCEPTION;ERROR;Error" ) + #-------------------------------------------------- # test for ARC o1 v01 SET( test_name "test_ARC_o1_v01_run" ) From 42c73b0108e5c00d56c92819716e0984b1c9b670 Mon Sep 17 00:00:00 2001 From: Juraj Smiesko Date: Mon, 11 Dec 2023 12:50:08 +0100 Subject: [PATCH 07/21] Printing "Found:...." in downstream projects --- cmake/k4geoConfig.cmake.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/k4geoConfig.cmake.in b/cmake/k4geoConfig.cmake.in index eb98cb140..6b2985f6d 100644 --- a/cmake/k4geoConfig.cmake.in +++ b/cmake/k4geoConfig.cmake.in @@ -12,3 +12,6 @@ find_dependency(ROOT REQUIRED COMPONENTS Geom GenVector) find_dependency(LCIO REQUIRED) include(${k4geo_CMAKE_DIR}/k4geoConfig-targets.cmake) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(k4geo DEFAULT_MSG CMAKE_CURRENT_LIST_FILE) From f6c17622a0c99806b2790551503a3cab45d0d962 Mon Sep 17 00:00:00 2001 From: Andre Sailer Date: Tue, 6 Feb 2024 11:21:14 +0100 Subject: [PATCH 08/21] ALLEGRO: EcalBarrel CaloData: caloDim.dZ is already the half length --- .../ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp index dece89dde..d0abe7645 100644 --- a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp +++ b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp @@ -568,7 +568,7 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, caloData->extent[0] = Rmin; caloData->extent[1] = Rmax; // or r_max ? caloData->extent[2] = 0.; // NN: for barrel detectors this is 0 - caloData->extent[3] = caloDim.dz()/2; + caloData->extent[3] = caloDim.dz(); // Set type flags dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); From 36bd6babd8e8ad847f6be517951c5f79facc467b Mon Sep 17 00:00:00 2001 From: Andre Sailer Date: Wed, 14 Feb 2024 17:08:00 +0100 Subject: [PATCH 09/21] CMake: add shim for LCIO::lcio --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d467551ae..73bd2a448 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,15 @@ message ( STATUS "ROOT_VERSION: ${ROOT_VERSION}" ) find_package( Geant4 REQUIRED ) find_package( LCIO REQUIRED) +# Shim for older LCIO versions +if(NOT TARGET LCIO::lcio) + add_library(LCIO::lcio INTERFACE IMPORTED GLOBAL) + set_target_properties(LCIO::lcio + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LCIO_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${LCIO_LIBRARIES}" + ) +endif() add_subdirectory(detectorSegmentations) add_subdirectory(detectorCommon) From 9889d01ba16f5eac9eed65c7f469eacacc856aca Mon Sep 17 00:00:00 2001 From: Andre Sailer Date: Fri, 16 Feb 2024 11:36:27 +0100 Subject: [PATCH 10/21] LinearSortingPolicy: ignore unavailable extension error and adapt treatment for it --- plugins/LinearSortingPolicy.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/LinearSortingPolicy.cpp b/plugins/LinearSortingPolicy.cpp index 41ca7d9e4..dde46cf9a 100644 --- a/plugins/LinearSortingPolicy.cpp +++ b/plugins/LinearSortingPolicy.cpp @@ -91,9 +91,13 @@ namespace { dd4hep::rec::DoubleParameters* para = nullptr; try { // use existing map, or create a new one - para = ddsurf->detElement().extension(); + para = ddsurf->detElement().extension(false); + if(not para) { + para = new dd4hep::rec::DoubleParameters; + ddsurf->detElement().addExtension(para); + } para->doubleParameters["SortingPolicy"] = rValue; - } catch(...){ + } catch(...) { para = new dd4hep::rec::DoubleParameters; para->doubleParameters["SortingPolicy"] = rValue; ddsurf->detElement().addExtension(para); From 92ffe4a35347524eaa351932daab774f7d067102 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori <39376142+giovannimarchiori@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:04:34 +0100 Subject: [PATCH 11/21] Update some ALLEGRO xml config files (#318) --- FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectEmptyMaster.xml | 6 +++--- .../ECalBarrel_thetamodulemerged_calibration.xml | 6 +++++- .../ECalBarrel_thetamodulemerged_upstream.xml | 8 ++++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectEmptyMaster.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectEmptyMaster.xml index a5ad3e23b..263dcce4d 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectEmptyMaster.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/DectEmptyMaster.xml @@ -6,8 +6,8 @@ - - + + - + diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_calibration.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_calibration.xml index d69ba26f9..027f20800 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_calibration.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_calibration.xml @@ -102,6 +102,10 @@ + + + + @@ -136,4 +140,4 @@ - + \ No newline at end of file diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_upstream.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_upstream.xml index ee39e57a5..962746659 100644 --- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_upstream.xml +++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v02/ECalBarrel_thetamodulemerged_upstream.xml @@ -25,7 +25,7 @@ - + @@ -78,7 +78,7 @@ - + system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10 @@ -102,6 +102,10 @@ + + + + From acfef0114df55991c0858f88b35af895193aba3e Mon Sep 17 00:00:00 2001 From: Brieuc Francois Date: Thu, 22 Feb 2024 22:23:54 +0100 Subject: [PATCH 12/21] Increase timeOut for IDEA test (#323) --- lcgeoTests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lcgeoTests/CMakeLists.txt b/lcgeoTests/CMakeLists.txt index 909fbdee6..5df4cfc31 100644 --- a/lcgeoTests/CMakeLists.txt +++ b/lcgeoTests/CMakeLists.txt @@ -84,7 +84,7 @@ SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Except SET( test_name "test_IDEA_o1_v02" ) ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test_${PackageName}.sh" ddsim --compactFile=${CMAKE_CURRENT_SOURCE_DIR}/../FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v02.xml --runType=batch -G -N=1 --outputFile=testIDEA_o1_v02.slcio ) -SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Exception;EXCEPTION;ERROR;Error" TIMEOUT 240) +SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Exception;EXCEPTION;ERROR;Error" TIMEOUT 360) #-------------------------------------------------- # test for ALLEGRO o1 v02 From c5cced6b647a49d1abbabdde79f4e4d43b1db899 Mon Sep 17 00:00:00 2001 From: jmcarcell Date: Fri, 23 Feb 2024 08:01:46 +0100 Subject: [PATCH 13/21] Bump version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73bd2a448..5e2c52bc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project(${PackageName}) # project version SET( ${PackageName}_VERSION_MAJOR 0 ) -SET( ${PackageName}_VERSION_MINOR 19 ) +SET( ${PackageName}_VERSION_MINOR 20 ) SET( ${PackageName}_VERSION_PATCH 0 ) SET( ${PackageName}_VERSION "${${PackageName}_VERSION_MAJOR}.${${PackageName}_VERSION_MINOR}" ) From 7c3d24111af17c336a6c26cade61788ff1740f1d Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller <22276694+jmcarcell@users.noreply.github.com> Date: Fri, 23 Feb 2024 08:02:48 +0100 Subject: [PATCH 14/21] Release Notes for v00-20-00 --- doc/ReleaseNotes.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/doc/ReleaseNotes.md b/doc/ReleaseNotes.md index 872c6ddd6..94ec37b5d 100644 --- a/doc/ReleaseNotes.md +++ b/doc/ReleaseNotes.md @@ -1,3 +1,47 @@ +# v00-20-00 + +* 2024-02-22 BrieucF ([PR#323](https://github.com/key4hep/k4geo/pull/323)) + - Increase IDEA test timeout + +* 2024-02-21 Giovanni Marchiori ([PR#318](https://github.com/key4hep/k4geo/pull/318)) + * ALLEGRO: Update some xml config files + +* 2024-02-16 Andre Sailer ([PR#320](https://github.com/key4hep/k4geo/pull/320)) + - CMake: Add shim for older LCIO versions that do not have LCIO::lcio yet + - LinearSortingPolicy: adapt check for existing extension to silence error message from DD4hep + +* 2024-02-09 Andre Sailer ([PR#317](https://github.com/key4hep/k4geo/pull/317)) + - ALLEGRO: EcalBarrel: fix the length of the Z extent for the calorimeter data extension for reconstruction + +* 2024-02-06 BrieucF ([PR#315](https://github.com/key4hep/k4geo/pull/315)) + - [ALLEGRO_o1_v02] Replace the simplified drift chamber with the detailed one + - [TESTS] Add a test for ALLEGRO_o1_v02 + - [ALLEGRO_o1_v02] File and variable renaming plus propagation of overlap fix to upstream and calibration xml's + +* 2024-02-06 Juraj Smiesko ([PR#309](https://github.com/key4hep/k4geo/pull/309)) + - CMake: Add printing of "Found k4geo" message in downstream projects picking up k4geoConfig.cmake + +* 2024-01-18 jmcarcell ([PR#310](https://github.com/key4hep/k4geo/pull/310)) + - Change LCIO::LCIO to LCIO::lcio. The target provided by LCIO is LCIO::lcio; DD4hep provides LCIO::LCIO so building without DD4hep and using LCIO::LCIO doesn't seem to work. + +* 2024-01-09 Jana ([PR#308](https://github.com/key4hep/k4geo/pull/308)) + - fixing the overlaps in ALLEGRO Ecal barrel geometry by increasing the LAr bath volume. + +* 2023-12-18 Swathi Sasikumar ([PR#312](https://github.com/key4hep/k4geo/pull/312)) + - CLD_o4_v05: The name of the inclined calorimeter was given as `EmCaloBarrelInclined` before. This is now changed to the latest naming convention as `ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01` + - ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01: The units for cell sizes has been added to the CaloLayerData ensure that they are given correctly and not mistaken due to confusion in units. now they are represented in mm. + +* 2023-12-14 BrieucF ([PR#307](https://github.com/key4hep/k4geo/pull/307)) + - Added DriftChamber_o1_v01, a first version of the detailed IDEA drift chamber to enable further technical developments (digitization, tracking, PFlow, ...) + +* 2023-12-13 Giovanni Marchiori ([PR#304](https://github.com/key4hep/k4geo/pull/304)) + - Code changes related to k4geo migration of FCC segmentation classes and related utilities + - Also moves HCal readout for Allegro from eta-based to theta-based + - Basically a rebasing of https://github.com/key4hep/k4geo/pull/296 after https://github.com/key4hep/k4geo/pull/298 was merged + +* 2023-12-12 BrieucF ([PR#311](https://github.com/key4hep/k4geo/pull/311)) + - Changed the sensitive detector type of the ALLEGO simplified drift chamber to be able to run with ddsim + # v00-19-00 * 2023-11-22 alvarotd ([PR#289](https://github.com/key4hep/k4geo/pull/289)) From 032f294a5b04871c4eb6ad0300a4d6ee09b32324 Mon Sep 17 00:00:00 2001 From: jmcarcell Date: Sun, 25 Feb 2024 09:25:07 +0100 Subject: [PATCH 15/21] Update the key4hep-build workflow; previous commit: Release Notes for v00-20-00 --- .github/workflows/key4hep-build.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/key4hep-build.yaml b/.github/workflows/key4hep-build.yaml index 3f9007f09..5ba768a48 100644 --- a/.github/workflows/key4hep-build.yaml +++ b/.github/workflows/key4hep-build.yaml @@ -6,6 +6,9 @@ on: - main pull_request: workflow_dispatch: + schedule: + - cron: '17 5 * * *' + jobs: build: From bda060c72afb560b5ebe8c1f206efc71d74e771c Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller <22276694+jmcarcell@users.noreply.github.com> Date: Sun, 25 Feb 2024 19:20:35 +0100 Subject: [PATCH 16/21] Remove the old key4hep build workflow (#324) --- .github/workflows/key4hep.yml | 43 ----------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 .github/workflows/key4hep.yml diff --git a/.github/workflows/key4hep.yml b/.github/workflows/key4hep.yml deleted file mode 100644 index e41729bd8..000000000 --- a/.github/workflows/key4hep.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: key4hep-stack - -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - SETUP: ['/cvmfs/sw.hsf.org/key4hep/setup.sh', '/cvmfs/sw-nightlies.hsf.org/key4hep/setup.sh'] - steps: - - uses: actions/checkout@v3 - - uses: cvmfs-contrib/github-action-cvmfs@v3 - - name: Start container - run: | - docker run -it --name CI_container -v ${GITHUB_WORKSPACE}:/Package -v /cvmfs:/cvmfs:shared -d ghcr.io/aidasoft/centos7:latest /bin/bash - - name: CMake Configure - run: | - docker exec CI_container /bin/bash -c 'cd Package;\ - mkdir -p build install;\ - source ${{ matrix.SETUP }};\ - cd build;\ - cmake -DCMAKE_INSTALL_PREFIX=../install -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_FLAGS=" -fdiagnostics-color=always " -G Ninja ..;' - - name: Compile - run: | - docker exec CI_container /bin/bash -c 'cd ./Package;\ - source ${{ matrix.SETUP }};\ - cd build;\ - ninja -k0;' - - name: Install - run: | - docker exec CI_container /bin/bash -c 'cd ./Package;\ - source ${{ matrix.SETUP }};\ - cd build;\ - ninja -k0 install;' - - name: Test - run: | - docker exec CI_container /bin/bash -c 'cd ./Package;\ - source ${{ matrix.SETUP }};\ - cd build;\ - ninja -k0 && ctest --output-on-failure;' - From e6ca6638659534d6927e2882a340fe739f6f1516 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller <22276694+jmcarcell@users.noreply.github.com> Date: Sun, 25 Feb 2024 20:40:54 +0100 Subject: [PATCH 17/21] Clean up unused variables (#302) --- ...l_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp | 6 ++---- detector/calorimeter/ECalBarrel_o2_v01_geo.cpp | 10 ---------- detector/calorimeter/ECalEndcap_o1_v01_geo.cpp | 2 -- .../calorimeter/GenericCalBarrel_o1_v01_geo.cpp | 10 ---------- detector/calorimeter/HCalBarrel_o1_v01_geo.cpp | 12 +----------- .../HCalThreePartsEndcap_o1_v01_geo.cpp | 7 ------- detector/calorimeter/HCalTileBarrel_o1_v01_geo.cpp | 3 --- detector/calorimeter/SECalEndcap_o1_v01_geo.cpp | 2 -- detector/calorimeter/SEcal05_ECRing.cpp | 2 +- .../calorimeter/SteppedMuonBarrel_o2_v02_geo.cpp | 9 --------- detector/calorimeter/YokeBarrel_o1_v01_geo.cpp | 12 +----------- detector/calorimeter/YokeEndcap_o1_v01_geo.cpp | 12 +----------- .../tracker/VertexBarrel_detailed_o1_v01_geo.cpp | 14 +++++++------- .../tracker/VertexEndcap_detailed_o1_v01_geo.cpp | 7 ++----- 14 files changed, 15 insertions(+), 93 deletions(-) diff --git a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp index d0abe7645..2f3777384 100644 --- a/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp +++ b/detector/calorimeter/ECalBarrel_NobleLiquid_InclinedTrapezoids_o1_v01_geo.cpp @@ -574,15 +574,13 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, dd4hep::xml::setDetectorTypeFlag(xmlDetElem, caloDetElem); dd4hep::rec::MaterialManager matMgr(envelopeVol); dd4hep::rec::LayeredCalorimeterData::Layer caloLayer; - double nRadiationLengths = 0.; - double nInteractionLengths = 0.; double rad_first = Rmin; double rad_last = 0; double scale_fact = dR / (-Rmin * cos(angle) + sqrt(pow(Rmax, 2) - pow(Rmin * sin(angle), 2))); // since the layer height is given along the electrode and not along the radius it needs to be scaled to get the values of layer height radially std::cout << "Scaling factor " << scale_fact << std::endl; - for (auto il = 0; il < layerHeight.size(); il++) { + for (size_t il = 0; il < layerHeight.size(); il++) { double thickness_sen = 0.; double absorberThickness = 0.; @@ -600,7 +598,7 @@ static dd4hep::detail::Ref_t createECalBarrelInclined(dd4hep::Detector& aLcdd, const double value_of_lambda = layerHeight[il] / nInteractionLengths; std::string str1("LAr"); - for (auto imat = 0; imat < materials.size(); imat++) { + for (size_t imat = 0; imat < materials.size(); imat++) { std::string str2(materials.at(imat).first.name()); if (str1.compare(str2) == 0){ diff --git a/detector/calorimeter/ECalBarrel_o2_v01_geo.cpp b/detector/calorimeter/ECalBarrel_o2_v01_geo.cpp index 2cce0befa..c05626be8 100644 --- a/detector/calorimeter/ECalBarrel_o2_v01_geo.cpp +++ b/detector/calorimeter/ECalBarrel_o2_v01_geo.cpp @@ -71,8 +71,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s string det_type = x_det.typeStr(); Material air = theDetector.air(); double totalThickness = layering.totalThickness(); - int totalRepeat = 0; - int totalSlices = 0; double gap = xml_dim_t(x_det).gap(); int nsides = dim.numsides(); @@ -107,14 +105,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s caloData->gap1 = 0.; //FIXME caloData->gap2 = 0.; //FIXME - - for (xml_coll_t c(x_det, _U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - totalRepeat += repeat; - totalSlices += x_layer.numChildren(_U(slice)); - } - // --- create an envelope volume and position it into the world --------------------- Volume envelopeVol = dd4hep::xml::createPlacedEnvelope(theDetector, e , sdet) ; diff --git a/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp b/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp index d78650fd6..f27941378 100644 --- a/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp +++ b/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp @@ -184,7 +184,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s // Loop over the sets of layer elements in the detector double check_thick = 0.0; int l_num = 1; - int l_set = 0; for(xml_coll_t li(x_det,_U(layer)); li; ++li) { xml_comp_t x_layer = li; @@ -281,7 +280,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s // Increment layer number ++l_num; } - l_set++; } std::cout << "Total slice thickness check " << check_thick << " cm" << std::endl; diff --git a/detector/calorimeter/GenericCalBarrel_o1_v01_geo.cpp b/detector/calorimeter/GenericCalBarrel_o1_v01_geo.cpp index 3b199f76c..77a718c61 100644 --- a/detector/calorimeter/GenericCalBarrel_o1_v01_geo.cpp +++ b/detector/calorimeter/GenericCalBarrel_o1_v01_geo.cpp @@ -74,8 +74,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s string det_type = x_det.typeStr(); Material air = theDetector.air(); double totalThickness = layering.totalThickness(); - int totalRepeat = 0; - int totalSlices = 0; double gap = xml_dim_t(x_det).gap(); int nsides = dim.numsides(); @@ -110,14 +108,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s caloData->gap1 = 0.; //FIXME caloData->gap2 = 0.; //FIXME - - for (xml_coll_t c(x_det, _U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - totalRepeat += repeat; - totalSlices += x_layer.numChildren(_U(slice)); - } - // --- create an envelope volume and position it into the world --------------------- Volume envelopeVol = dd4hep::xml::createPlacedEnvelope( theDetector, e , sdet ) ; diff --git a/detector/calorimeter/HCalBarrel_o1_v01_geo.cpp b/detector/calorimeter/HCalBarrel_o1_v01_geo.cpp index dbee8243b..060606e5b 100644 --- a/detector/calorimeter/HCalBarrel_o1_v01_geo.cpp +++ b/detector/calorimeter/HCalBarrel_o1_v01_geo.cpp @@ -22,7 +22,7 @@ using dd4hep::Layer; using dd4hep::Layering; using dd4hep::Material; using dd4hep::PlacedVolume; -using dd4hep::PolyhedraRegular; +// using dd4hep::PolyhedraRegular; using dd4hep::Position; using dd4hep::Readout; using dd4hep::Ref_t; @@ -70,8 +70,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s string det_type = x_det.typeStr(); Material air = theDetector.air(); double totalThickness = layering.totalThickness(); - int totalRepeat = 0; - int totalSlices = 0; double gap = xml_dim_t(x_det).gap(); int nsides = dim.numsides(); @@ -106,14 +104,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s caloData->gap1 = 0.; //FIXME caloData->gap2 = 0.; //FIXME - - for (xml_coll_t c(x_det, _U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - totalRepeat += repeat; - totalSlices += x_layer.numChildren(_U(slice)); - } - // --- create an envelope volume and position it into the world --------------------- Volume envelopeVol = dd4hep::xml::createPlacedEnvelope( theDetector, e , sdet ) ; diff --git a/detector/calorimeter/HCalThreePartsEndcap_o1_v01_geo.cpp b/detector/calorimeter/HCalThreePartsEndcap_o1_v01_geo.cpp index e02d4bfea..34544c2e2 100644 --- a/detector/calorimeter/HCalThreePartsEndcap_o1_v01_geo.cpp +++ b/detector/calorimeter/HCalThreePartsEndcap_o1_v01_geo.cpp @@ -5,7 +5,6 @@ #define endmsg std::endl #define lLog std::cout namespace MSG { -const std::string ERROR = " Error: "; const std::string DEBUG = " Debug: "; const std::string INFO = " Info: "; } @@ -216,7 +215,6 @@ void buildEC(dd4hep::Detector& aLcdd, dd4hep::SensitiveDetector& aSensDet, dd4he layerVolume.setVisAttributes(aLcdd.invisible()); unsigned int idxSubMod = 0; - unsigned int idxActMod = 0; dd4hep::Position moduleOffset1 (0,0,sign * extBarrelOffset1); @@ -248,7 +246,6 @@ void buildEC(dd4hep::Detector& aLcdd, dd4hep::SensitiveDetector& aSensDet, dd4he if (xComp.isSensitive()) { tileVol.setSensitiveDetector(sensDet); tilesPerLayer.push_back(placedTileVol); - idxActMod++; } tileZOffset += xComp.thickness(); } @@ -290,7 +287,6 @@ void buildEC(dd4hep::Detector& aLcdd, dd4hep::SensitiveDetector& aSensDet, dd4he layerVolume.setVisAttributes(aLcdd.invisible()); unsigned int idxSubMod = 0; - unsigned int idxActMod = 0; double tileZOffset = - 0.5* dzSequence; @@ -311,7 +307,6 @@ void buildEC(dd4hep::Detector& aLcdd, dd4hep::SensitiveDetector& aSensDet, dd4he if (xComp.isSensitive()) { tileVol.setSensitiveDetector(sensDet); tilesPerLayer.push_back(placedTileVol); - idxActMod++; } tileZOffset += xComp.thickness(); } @@ -361,7 +356,6 @@ void buildEC(dd4hep::Detector& aLcdd, dd4hep::SensitiveDetector& aSensDet, dd4he layerVolume.setVisAttributes(aLcdd.invisible()); unsigned int idxSubMod = 0; - unsigned int idxActMod = 0; double tileZOffset = - 0.5* dzSequence; @@ -382,7 +376,6 @@ void buildEC(dd4hep::Detector& aLcdd, dd4hep::SensitiveDetector& aSensDet, dd4he if (xComp.isSensitive()) { tileVol.setSensitiveDetector(sensDet); tilesPerLayer.push_back(placedTileVol); - idxActMod++; } tileZOffset += xComp.thickness(); } diff --git a/detector/calorimeter/HCalTileBarrel_o1_v01_geo.cpp b/detector/calorimeter/HCalTileBarrel_o1_v01_geo.cpp index e6d67caa8..89be7154d 100644 --- a/detector/calorimeter/HCalTileBarrel_o1_v01_geo.cpp +++ b/detector/calorimeter/HCalTileBarrel_o1_v01_geo.cpp @@ -12,7 +12,6 @@ using dd4hep::PlacedVolume; #define endmsg std::endl #define lLog std::cout namespace MSG { -const std::string ERROR = " Error: "; const std::string DEBUG = " Debug: "; const std::string INFO = " Info: "; } @@ -168,7 +167,6 @@ static dd4hep::Ref_t createHCal(dd4hep::Detector& lcdd, xml_det_t xmlDet, dd4hep layerVolume.setVisAttributes(lcdd.invisible()); unsigned int idxSubMod = 0; - unsigned int idxActMod = 0; dd4hep::PlacedVolume placedLayerVolume = envelopeVolume.placeVolume(layerVolume); @@ -192,7 +190,6 @@ static dd4hep::Ref_t createHCal(dd4hep::Detector& lcdd, xml_det_t xmlDet, dd4hep if (xComp.isSensitive()) { tileVol.setSensitiveDetector(sensDet); tilesPerLayer.push_back(placedTileVol); - idxActMod++; } tileZOffset += xComp.thickness(); } diff --git a/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp b/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp index 338282826..bf16d0348 100644 --- a/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp +++ b/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp @@ -193,7 +193,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s // Loop over the sets of layer elements in the detector double check_thick = 0.0; int l_num = 1; - int l_set = 0; for(xml_coll_t li(x_det,_U(layer)); li; ++li) { xml_comp_t x_layer = li; @@ -289,7 +288,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s // Increment layer number ++l_num; } - l_set++; } std::cout << "Total slice thickness check " << check_thick << " cm" << std::endl; diff --git a/detector/calorimeter/SEcal05_ECRing.cpp b/detector/calorimeter/SEcal05_ECRing.cpp index aee2e0b16..186ad7605 100644 --- a/detector/calorimeter/SEcal05_ECRing.cpp +++ b/detector/calorimeter/SEcal05_ECRing.cpp @@ -210,7 +210,7 @@ static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDete // //==================================================================== - int Number_of_Si_Layers_in_Barrel = 0; + int Number_of_Si_Layers_in_Barrel [[maybe_unused]] = 0; #ifdef VERBOSE std::cout << " Ecal total number of Silicon layers = " << Number_of_Si_Layers_in_Barrel << std::endl; diff --git a/detector/calorimeter/SteppedMuonBarrel_o2_v02_geo.cpp b/detector/calorimeter/SteppedMuonBarrel_o2_v02_geo.cpp index 11df5cee7..0d8e42da6 100644 --- a/detector/calorimeter/SteppedMuonBarrel_o2_v02_geo.cpp +++ b/detector/calorimeter/SteppedMuonBarrel_o2_v02_geo.cpp @@ -52,8 +52,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s string det_type = x_det.typeStr(); Material air = theDetector.air(); double totalThickness = layering.totalThickness(); - int totalRepeat = 0; - int totalSlices = 0; double gap = xml_dim_t(x_det).gap(); int nsides = dim.numsides(); @@ -93,13 +91,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s caloData->gap1 = 0.; //FIXME caloData->gap2 = 0.; //FIXME - for (xml_coll_t c(x_det, _U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - totalRepeat += repeat; - totalSlices += x_layer.numChildren(_U(slice)); - } - // CHECK THIS! // --- create an envelope volume and position it into the world --------------------- diff --git a/detector/calorimeter/YokeBarrel_o1_v01_geo.cpp b/detector/calorimeter/YokeBarrel_o1_v01_geo.cpp index 673a5dd63..5be170b91 100644 --- a/detector/calorimeter/YokeBarrel_o1_v01_geo.cpp +++ b/detector/calorimeter/YokeBarrel_o1_v01_geo.cpp @@ -22,7 +22,7 @@ using dd4hep::Layer; using dd4hep::Layering; using dd4hep::Material; using dd4hep::PlacedVolume; -using dd4hep::PolyhedraRegular; +// using dd4hep::PolyhedraRegular; using dd4hep::Position; using dd4hep::Readout; using dd4hep::Ref_t; @@ -70,8 +70,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s string det_type = x_det.typeStr(); Material air = theDetector.air(); double totalThickness = layering.totalThickness(); - int totalRepeat = 0; - int totalSlices = 0; double gap = xml_dim_t(x_det).gap(); int numSides = dim.numsides(); double detZ = dim.z(); @@ -98,14 +96,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s caloData->gap1 = 0.; //FIXME caloData->gap2 = 0.; //FIXME - - for (xml_coll_t c(x_det, _U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - totalRepeat += repeat; - totalSlices += x_layer.numChildren(_U(slice)); - } - // --- create an envelope volume and position it into the world --------------------- Volume envelopeVol = dd4hep::xml::createPlacedEnvelope( theDetector, e , sdet ) ; diff --git a/detector/calorimeter/YokeEndcap_o1_v01_geo.cpp b/detector/calorimeter/YokeEndcap_o1_v01_geo.cpp index 169ee3082..2f957424c 100644 --- a/detector/calorimeter/YokeEndcap_o1_v01_geo.cpp +++ b/detector/calorimeter/YokeEndcap_o1_v01_geo.cpp @@ -20,7 +20,6 @@ using dd4hep::RotationZYX; using dd4hep::Segmentation; using dd4hep::SensitiveDetector; using dd4hep::Transform3D; -using dd4hep::Tube; using dd4hep::Volume; using dd4hep::_toString; @@ -114,7 +113,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s double sliceZ = -l_thick/2; double totalAbsorberThickness=0.; - double th_i(0.), th_o(-1.) ; for(xml_coll_t s(x_layer,_U(slice)); s; ++s) { xml_comp_t x_slice = s; string s_name = _toString(s_num,"slice%d"); @@ -132,15 +130,7 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s s_phv.addPhysVolID("submodule",sensor_num); sensor_num++; - th_i += s_thick / 2. ; - th_o = s_thick / 2. ; - } else { - if( th_o < 0. ){ - th_i += s_thick; - } else { - th_o += s_thick; - } - } + } if( x_slice.isRadiator() ==true) totalAbsorberThickness+= s_thick; diff --git a/detector/tracker/VertexBarrel_detailed_o1_v01_geo.cpp b/detector/tracker/VertexBarrel_detailed_o1_v01_geo.cpp index 9ade326c0..cc9704eb5 100644 --- a/detector/tracker/VertexBarrel_detailed_o1_v01_geo.cpp +++ b/detector/tracker/VertexBarrel_detailed_o1_v01_geo.cpp @@ -43,10 +43,10 @@ using dd4hep::Translation3D; using dd4hep::Trapezoid; using dd4hep::Volume; using dd4hep::_toString; -using dd4hep::rec::Vector3D; -using dd4hep::rec::SurfaceType; +// using dd4hep::rec::Vector3D; +// using dd4hep::rec::SurfaceType; using dd4hep::rec::VolPlane; -using dd4hep::rec::volSurfaceList; +// using dd4hep::rec::volSurfaceList; static Ref_t create_element(Detector& theDetector, xml_h e, SensitiveDetector sens) { @@ -55,7 +55,7 @@ static Ref_t create_element(Detector& theDetector, xml_h e, SensitiveDetector se std::string det_name = x_det.nameStr(); DetElement sdet( det_name, x_det.id() ) ; - PlacedVolume pv; + // PlacedVolume pv; // put the whole detector into an assembly // - should be replaced by an envelope volume ... @@ -182,7 +182,8 @@ static Ref_t create_element(Detector& theDetector, xml_h e, SensitiveDetector se m.sensor_thickness = xml_comp_t(c_sensor).thickness(); xml_coll_t c_component = xml_coll_t(c_sensor,_U(component)); - int iSensitive, iPassive = 0; + // Is iSensitive being used later with this default value in a call to _toString? + int iSensitive = 0, iPassive = 0; for(c_component.reset(); c_component; ++c_component){ xml_comp_t component = c_component; m.sensor_sensitives.push_back(component.isSensitive()); @@ -341,7 +342,7 @@ static Ref_t create_element(Detector& theDetector, xml_h e, SensitiveDetector se // passivesDE.setPlacement(pv); // Place all sensor parts - int iSensitive = 0, iPassive = 0; + int iSensitive = 0; for(int i=0; i Date: Mon, 26 Feb 2024 08:02:49 +0100 Subject: [PATCH 18/21] Update the key4hep-build workflow; previous commit: Clean up unused variables (#302) --- .github/workflows/downstream-build.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/downstream-build.yaml b/.github/workflows/downstream-build.yaml index e763bb47a..df5bac57d 100644 --- a/.github/workflows/downstream-build.yaml +++ b/.github/workflows/downstream-build.yaml @@ -5,11 +5,10 @@ on: workflow_dispatch: jobs: - test: + downstream-build: runs-on: ubuntu-latest strategy: fail-fast: false steps: - - uses: actions/checkout@v3 - - uses: cvmfs-contrib/github-action-cvmfs@v3 + - uses: actions/checkout@v4 - uses: key4hep/key4hep-actions/downstream-build@main From 1122f7de9537e58612d5bef62a4369b2ceff774c Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 6 Mar 2024 11:00:27 +0100 Subject: [PATCH 19/21] Make LCIO an optional dependency (#328) --- CMakeLists.txt | 55 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e2c52bc7..d1441d0b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,20 +51,20 @@ find_package ( ROOT REQUIRED COMPONENTS Geom GenVector) message ( STATUS "ROOT_VERSION: ${ROOT_VERSION}" ) find_package( Geant4 REQUIRED ) -find_package( LCIO REQUIRED) -# Shim for older LCIO versions -if(NOT TARGET LCIO::lcio) - add_library(LCIO::lcio INTERFACE IMPORTED GLOBAL) - set_target_properties(LCIO::lcio - PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${LCIO_INCLUDE_DIRS}" - INTERFACE_LINK_LIBRARIES "${LCIO_LIBRARIES}" - ) +OPTION(K4GEO_USE_LCIO "Enable or disable the use of LCIO, which is needed for some detector constructors and plugins" ON) +if(K4GEO_USE_LCIO) + find_package(LCIO REQUIRED) + # Shim for older LCIO versions + if(NOT TARGET LCIO::lcio) + add_library(LCIO::lcio INTERFACE IMPORTED GLOBAL) + set_target_properties(LCIO::lcio + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LCIO_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${LCIO_LIBRARIES}" + ) + endif() endif() -add_subdirectory(detectorSegmentations) -add_subdirectory(detectorCommon) - file(GLOB sources ./detector/tracker/*.cpp ./detector/calorimeter/*.cpp @@ -76,6 +76,25 @@ file(GLOB sources ./detector/PID/ARC_geo_o1_v01.cpp ) +if(NOT K4GEO_USE_LCIO) + set(lcio_sources # in ./detector/tracker + TrackerEndcap_o2_v05_geo.cpp + SiTrackerEndcap_o2_v02ext_geo.cpp + TrackerBarrel_o1_v03_geo.cpp + TrackerBarrel_o1_v04_geo.cpp + TrackerBarrel_o1_v05_geo.cpp + TrackerEndcap_o1_v05_geo.cpp + TrackerEndcap_o2_v06_geo.cpp + VertexBarrel_detailed_o1_v01_geo.cpp + VertexEndcap_o1_v05_geo.cpp + ZPlanarTracker_geo.cpp + ) + foreach(lcio_source ${lcio_sources}) + list(FILTER sources EXCLUDE REGEX "${lcio_source}") + endforeach() + message(STATUS "Use of LCIO is DISABLED, some detectors that depend on LCIO will not be built: ${lcio_sources}") +endif() + file(GLOB G4sources ./plugins/TPCSDAction.cpp ./plugins/CaloPreShowerSDAction.cpp @@ -94,12 +113,20 @@ add_library(lcgeo ALIAS k4geo) target_include_directories(${PackageName} PRIVATE ${PROJECT_SOURCE_DIR}/detector/include ) target_include_directories(${PackageName}G4 PRIVATE ${PROJECT_SOURCE_DIR}/detector/include ) -target_link_libraries(${PackageName} DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers ROOT::Core LCIO::lcio detectorSegmentations) -target_link_libraries(${PackageName}G4 DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers DD4hep::DDG4 ROOT::Core ${Geant4_LIBRARIES} LCIO::lcio) +target_link_libraries(${PackageName} DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers ROOT::Core detectorSegmentations) +target_link_libraries(${PackageName}G4 DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers DD4hep::DDG4 ROOT::Core ${Geant4_LIBRARIES}) + +if(K4GEO_USE_LCIO) + target_link_libraries(${PackageName} LCIO::lcio) + target_link_libraries(${PackageName}G4 LCIO::lcio) +endif() #Create this_package.sh file, and install dd4hep_instantiate_package(${PackageName}) +add_subdirectory(detectorSegmentations) +add_subdirectory(detectorCommon) + # Destination directories are hardcoded because GNUdirectories are not included install(TARGETS ${PackageName} ${PackageName}G4 EXPORT ${PROJECT_NAME}Targets From 0a96366afde5b730879c9076bbcd1b17779e83b5 Mon Sep 17 00:00:00 2001 From: Sungwon Kim Date: Thu, 7 Mar 2024 16:21:34 +0900 Subject: [PATCH 20/21] Update branch with latest k4geo & Split FiberDRC xml files --- CMakeLists.txt | 7 +- .../DectDimensions_IDEA_o1_v01.xml | 62 +- .../FiberDualReadoutCalo_o1_v01.xml | 653 ++++++++++++++++++ .../IDEA/compact/IDEA_o1_v02/IDEA_o1_v02.xml | 3 + .../compact/IDEA_o1_v02/materials_o1_v01.xml | 52 ++ .../dual-readout/include/DRconstructor.h | 77 +++ .../dual-readout/src/DRconstructor.cpp | 444 ++++++++++++ .../src/FiberDualReadoutCalo_o1_v01.cpp | 75 ++ .../DRparamBarrel_k4geo.h | 27 + .../detectorSegmentations/DRparamBase_k4geo.h | 99 +++ .../DRparamEndcap_k4geo.h | 27 + .../GridDRcaloHandle_k4geo.h | 90 +++ .../detectorSegmentations/GridDRcalo_k4geo.h | 109 +++ .../src/DRparamBarrel_k4geo.cpp | 98 +++ .../src/DRparamBase_k4geo.cpp | 100 +++ .../src/DRparamEndcap_k4geo.cpp | 98 +++ .../src/GridDRcaloHandle_k4geo.cpp | 4 + .../src/GridDRcalo_k4geo.cpp | 232 +++++++ .../src/plugins/SegmentationFactories.cpp | 3 +- 19 files changed, 2219 insertions(+), 41 deletions(-) create mode 100644 FCCee/IDEA/compact/IDEA_o1_v02/FiberDualReadoutCalo_o1_v01.xml create mode 100644 detector/calorimeter/dual-readout/include/DRconstructor.h create mode 100644 detector/calorimeter/dual-readout/src/DRconstructor.cpp create mode 100644 detector/calorimeter/dual-readout/src/FiberDualReadoutCalo_o1_v01.cpp create mode 100644 detectorSegmentations/include/detectorSegmentations/DRparamBarrel_k4geo.h create mode 100644 detectorSegmentations/include/detectorSegmentations/DRparamBase_k4geo.h create mode 100644 detectorSegmentations/include/detectorSegmentations/DRparamEndcap_k4geo.h create mode 100644 detectorSegmentations/include/detectorSegmentations/GridDRcaloHandle_k4geo.h create mode 100644 detectorSegmentations/include/detectorSegmentations/GridDRcalo_k4geo.h create mode 100644 detectorSegmentations/src/DRparamBarrel_k4geo.cpp create mode 100644 detectorSegmentations/src/DRparamBase_k4geo.cpp create mode 100644 detectorSegmentations/src/DRparamEndcap_k4geo.cpp create mode 100644 detectorSegmentations/src/GridDRcaloHandle_k4geo.cpp create mode 100644 detectorSegmentations/src/GridDRcalo_k4geo.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d1441d0b2..ce36ed619 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ endif() file(GLOB sources ./detector/tracker/*.cpp ./detector/calorimeter/*.cpp + ./detector/calorimeter/dual-readout/src/*.cpp ./detector/fcal/*.cpp ./detector/other/*.cpp ./detector/CaloTB/*.cpp @@ -98,6 +99,7 @@ endif() file(GLOB G4sources ./plugins/TPCSDAction.cpp ./plugins/CaloPreShowerSDAction.cpp + ./plugins/FiberDRcaloSDAction.cpp ) if(DD4HEP_USE_PYROOT) @@ -113,8 +115,11 @@ add_library(lcgeo ALIAS k4geo) target_include_directories(${PackageName} PRIVATE ${PROJECT_SOURCE_DIR}/detector/include ) target_include_directories(${PackageName}G4 PRIVATE ${PROJECT_SOURCE_DIR}/detector/include ) +target_include_directories(${PackageName} PRIVATE ${PROJECT_SOURCE_DIR}/detector/calorimeter/dual-readout/include ) +target_include_directories(${PackageName}G4 PRIVATE ${PROJECT_SOURCE_DIR}/detector/calorimeter/dual-readout/include ) + target_link_libraries(${PackageName} DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers ROOT::Core detectorSegmentations) -target_link_libraries(${PackageName}G4 DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers DD4hep::DDG4 ROOT::Core ${Geant4_LIBRARIES}) +target_link_libraries(${PackageName}G4 DD4hep::DDCore DD4hep::DDRec DD4hep::DDParsers DD4hep::DDG4 ROOT::Core ${Geant4_LIBRARIES} detectorSegmentations) if(K4GEO_USE_LCIO) target_link_libraries(${PackageName} LCIO::lcio) diff --git a/FCCee/IDEA/compact/IDEA_o1_v02/DectDimensions_IDEA_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v02/DectDimensions_IDEA_o1_v01.xml index 27a5bb4fc..225b3a740 100644 --- a/FCCee/IDEA/compact/IDEA_o1_v02/DectDimensions_IDEA_o1_v01.xml +++ b/FCCee/IDEA/compact/IDEA_o1_v02/DectDimensions_IDEA_o1_v01.xml @@ -53,6 +53,9 @@ + + + @@ -92,45 +95,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -206,6 +170,15 @@ + + + + + + + + + @@ -222,6 +195,8 @@ + + @@ -254,6 +229,15 @@ + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v02/FiberDualReadoutCalo_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v02/FiberDualReadoutCalo_o1_v01.xml new file mode 100644 index 000000000..c1bb2c80e --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v02/FiberDualReadoutCalo_o1_v01.xml @@ -0,0 +1,653 @@ + + + + + + + + + The compact format for the dual-readout calorimeter (for FCCee IDEA) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:5,eta:-8,phi:9,x:32:-11,y:-9,c:1,module:2 + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v02.xml b/FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v02.xml index 5ea3592ad..569610739 100644 --- a/FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v02.xml +++ b/FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v02.xml @@ -47,6 +47,9 @@ + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v02/materials_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v02/materials_o1_v01.xml index f68afa8b4..22a1a3f98 100644 --- a/FCCee/IDEA/compact/IDEA_o1_v02/materials_o1_v01.xml +++ b/FCCee/IDEA/compact/IDEA_o1_v02/materials_o1_v01.xml @@ -459,4 +459,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/detector/calorimeter/dual-readout/include/DRconstructor.h b/detector/calorimeter/dual-readout/include/DRconstructor.h new file mode 100644 index 000000000..99b0f3a53 --- /dev/null +++ b/detector/calorimeter/dual-readout/include/DRconstructor.h @@ -0,0 +1,77 @@ +#ifndef DRconstructor_h +#define DRconstructor_h 1 + +#include "detectorSegmentations/DRparamBarrel_k4geo.h" +#include "detectorSegmentations/GridDRcaloHandle_k4geo.h" + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/OpticalSurfaces.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Detector.h" + +namespace ddDRcalo { + class DRconstructor { + public: + DRconstructor(xml_det_t& x_det); + ~DRconstructor() {} + + void setExpHall(dd4hep::Assembly* experimentalHall) { fExperimentalHall = experimentalHall; } + void setDRparamBarrel(dd4hep::DDSegmentation::DRparamBarrel_k4geo* paramBarrel) { fParamBarrel = paramBarrel; } + void setDRparamEndcap(dd4hep::DDSegmentation::DRparamEndcap_k4geo* paramEndcap) { fParamEndcap = paramEndcap; } + void setDescription(dd4hep::Detector* description) { fDescription = description; } + void setDetElement(dd4hep::DetElement* drDet) { fDetElement = drDet; } + void setSipmSurf(dd4hep::OpticalSurface* sipmSurf) { fSipmSurf = sipmSurf; } + void setMirrorSurf(dd4hep::OpticalSurface* mirrorSurf) { fMirrorSurf = mirrorSurf; } + void setSensDet(dd4hep::SensitiveDetector* sensDet) { + fSensDet = sensDet; + fSegmentation = dynamic_cast( sensDet->readout().segmentation().segmentation() ); + } + + void construct(); + + private: + void implementTowers(xml_comp_t& x_theta, dd4hep::DDSegmentation::DRparamBase_k4geo* param); + void placeAssembly(xml_comp_t& x_theta, xml_comp_t& x_wafer, dd4hep::DDSegmentation::DRparamBase_k4geo* param, + dd4hep::Trap& assemblyEnvelop, dd4hep::Volume& towerVol, dd4hep::Volume& sipmLayerVol, dd4hep::Volume& sipmWaferVol, + int towerNo, int nPhi, bool isRHS=true); + void implementFibers(xml_comp_t& x_theta, dd4hep::Volume& towerVol, dd4hep::Trap& trap, dd4hep::DDSegmentation::DRparamBase_k4geo* param, int towerNo); + void implementFiber(dd4hep::Volume& towerVol, dd4hep::Trap& trap, dd4hep::Position pos, int col, int row, + dd4hep::Tube& fiberEnv, dd4hep::Tube& fiber, dd4hep::Tube& fiberC, dd4hep::Tube& fiberS, + dd4hep::Volume& capC, dd4hep::Volume& capS); + void implementSipms(dd4hep::Volume& sipmLayerVol, dd4hep::Trap& trap); + double calculateDistAtZ(TGeoTrap* rootTrap, dd4hep::Position& pos, double* norm, double z); + float calculateFiberLen(TGeoTrap* rootTrap, dd4hep::Position& pos, double* norm, double z1, double diff, double towerHeight); + dd4hep::Box calculateFullBox(TGeoTrap* rootTrap, int& rmin, int& rmax, int& cmin, int& cmax, double dz); + bool checkContained(TGeoTrap* rootTrap, dd4hep::Position& pos, double z, bool throwExcept=false); + void getNormals(TGeoTrap* rootTrap, int numxBl2, double z, double* norm1, double* norm2, double* norm3, double* norm4); + void placeUnitBox(dd4hep::Volume& fullBox, dd4hep::Volume& unitBox, int rmin, int rmax, int cmin, int cmax, bool& isEvenRow, bool& isEvenCol); + + xml_det_t fX_det; + xml_comp_t fX_barrel; + xml_comp_t fX_endcap; + xml_comp_t fX_sipmDim; + xml_comp_t fX_struct; + xml_comp_t fX_dim; + xml_comp_t fX_cladC; + xml_comp_t fX_coreC; + xml_comp_t fX_coreS; + xml_comp_t fX_hole; + xml_comp_t fX_dark; + xml_comp_t fX_mirror; + dd4hep::Assembly* fExperimentalHall; + dd4hep::Detector* fDescription; + dd4hep::DDSegmentation::DRparamBarrel_k4geo* fParamBarrel; + dd4hep::DDSegmentation::DRparamEndcap_k4geo* fParamEndcap; + dd4hep::DetElement* fDetElement; + dd4hep::SensitiveDetector* fSensDet; + dd4hep::OpticalSurface* fSipmSurf; + dd4hep::OpticalSurface* fMirrorSurf; + dd4hep::DDSegmentation::GridDRcalo_k4geo* fSegmentation; + + bool fVis; + int fNumx, fNumy; + std::vector< std::pair > fFiberCoords; + }; +} + +#endif diff --git a/detector/calorimeter/dual-readout/src/DRconstructor.cpp b/detector/calorimeter/dual-readout/src/DRconstructor.cpp new file mode 100644 index 000000000..603032e4a --- /dev/null +++ b/detector/calorimeter/dual-readout/src/DRconstructor.cpp @@ -0,0 +1,444 @@ +#include "DRconstructor.h" + +ddDRcalo::DRconstructor::DRconstructor(xml_det_t& x_det) +: fX_det(x_det), + // no default initializer for xml_comp_t + fX_barrel( x_det.child( _Unicode(barrel) ) ), + fX_endcap( x_det.child( _Unicode(endcap) ) ), + fX_sipmDim( x_det.child( _Unicode(sipmDim) ) ), + fX_struct( x_det.child( _Unicode(structure) ) ), + fX_dim( fX_struct.child( _Unicode(dim) ) ), + fX_cladC( fX_struct.child( _Unicode(cladC) ) ), + fX_coreC( fX_struct.child( _Unicode(coreC) ) ), + fX_coreS( fX_struct.child( _Unicode(coreS) ) ), + fX_hole( fX_struct.child( _Unicode(hole) ) ), + fX_dark( fX_struct.child( _Unicode(dark) ) ), + fX_mirror( fX_struct.child( _Unicode(mirror) ) ) { + fExperimentalHall = nullptr; + fParamBarrel = nullptr; + fDescription = nullptr; + fDetElement = nullptr; + fSensDet = nullptr; + fSipmSurf = nullptr; + fMirrorSurf = nullptr; + fSegmentation = nullptr; + fVis = false; + fNumx = 0; + fNumy = 0; + fFiberCoords.reserve(100000); +} + +void ddDRcalo::DRconstructor::construct() { + // set vis on/off + fVis = fDescription->visAttributes(fX_det.visStr()).showDaughters(); + + implementTowers(fX_barrel, fParamBarrel); + implementTowers(fX_endcap, fParamEndcap); +} + +void ddDRcalo::DRconstructor::implementTowers(xml_comp_t& x_theta, dd4hep::DDSegmentation::DRparamBase_k4geo* param) { + double currentTheta = x_theta.theta(); + int towerNo = x_theta.start(); + for (xml_coll_t x_dThetaColl(x_theta,_U(deltatheta)); x_dThetaColl; ++x_dThetaColl, ++towerNo ) { + xml_comp_t x_deltaTheta = x_dThetaColl; + // debug + std::cout << "towerNo : " << towerNo << std::endl; + + // always use RHS for the reference + param->SetIsRHS(true); + param->SetDeltaTheta(x_deltaTheta.deltatheta()); + + double currentToC = currentTheta + x_deltaTheta.deltatheta()/2.; + currentTheta += x_deltaTheta.deltatheta(); + param->SetThetaOfCenter(currentToC); + param->init(); + + dd4hep::Trap assemblyEnvelop( (x_theta.height()+param->GetSipmHeight())/2., 0., 0., param->GetH1(), param->GetBl1(), param->GetTl1(), 0., + param->GetH2sipm(), param->GetBl2sipm(), param->GetTl2sipm(), 0. ); + + dd4hep::Trap tower( x_theta.height()/2., 0., 0., param->GetH1(), param->GetBl1(), param->GetTl1(), 0., + param->GetH2(), param->GetBl2(), param->GetTl2(), 0. ); + + dd4hep::Volume towerVol( "tower", tower, fDescription->material(x_theta.materialStr()) ); + towerVol.setVisAttributes(*fDescription, x_theta.visStr()); + + implementFibers(x_theta, towerVol, tower, param, towerNo); + + xml_comp_t x_wafer ( fX_sipmDim.child( _Unicode(sipmWafer) ) ); + + // Assume the top surface is nearly rectangular shape + dd4hep::Trap sipmLayer( (param->GetSipmHeight()-x_wafer.height())/2., 0., 0., param->GetH2(), param->GetBl2(), param->GetTl2(), 0., + param->GetH2(), param->GetBl2(), param->GetTl2(), 0. ); + dd4hep::Volume sipmLayerVol( "sipmLayer", sipmLayer, fDescription->material(fX_sipmDim.materialStr()) ); + if (fVis) sipmLayerVol.setVisAttributes(*fDescription, fX_sipmDim.visStr()); + + // Photosensitive wafer + dd4hep::Trap sipmWaferBox( x_wafer.height()/2., 0., 0., param->GetH2(), param->GetBl2(), param->GetTl2(), 0., + param->GetH2(), param->GetBl2(), param->GetTl2(), 0. ); + dd4hep::Volume sipmWaferVol( "sipmWafer", sipmWaferBox, fDescription->material(x_wafer.materialStr()) ); + if (fVis) sipmWaferVol.setVisAttributes(*fDescription, x_wafer.visStr()); + dd4hep::SkinSurface(*fDescription, *fDetElement, "SiPMSurf_Tower"+std::to_string(towerNo), *fSipmSurf, sipmWaferVol); + + if (x_wafer.isSensitive()) { + sipmWaferVol.setSensitiveDetector(*fSensDet); + } + + implementSipms(sipmLayerVol, tower); + + for (int nPhi = 0; nPhi < x_theta.nphi(); nPhi++) { + placeAssembly(x_theta,x_wafer,param,assemblyEnvelop,towerVol,sipmLayerVol,sipmWaferVol,towerNo,nPhi); + + if ( fX_det.reflect() ) + placeAssembly(x_theta,x_wafer,param,assemblyEnvelop,towerVol,sipmLayerVol,sipmWaferVol,towerNo,nPhi,false); + } + } + + param->filled(); + param->SetTotTowerNum( towerNo - x_theta.start() ); +} + +void ddDRcalo::DRconstructor::placeAssembly(xml_comp_t& x_theta, xml_comp_t& x_wafer, dd4hep::DDSegmentation::DRparamBase_k4geo* param, + dd4hep::Trap& assemblyEnvelop, dd4hep::Volume& towerVol, dd4hep::Volume& sipmLayerVol, dd4hep::Volume& sipmWaferVol, + int towerNo, int nPhi, bool isRHS) { + param->SetIsRHS(isRHS); + int towerNoLR = param->signedTowerNo(towerNo); + auto towerId64 = fSegmentation->setVolumeID( towerNoLR, nPhi ); + int towerId32 = fSegmentation->getFirst32bits(towerId64); + + // copy number of assemblyVolume is unpredictable, use dummy volume to make use of copy number of afterwards + dd4hep::Volume assemblyEnvelopVol( std::string("assembly") + (isRHS ? "" : "_refl") , assemblyEnvelop, fDescription->material("Vacuum") ); + fExperimentalHall->placeVolume( assemblyEnvelopVol, param->GetAssembleTransform3D(nPhi) ); + + assemblyEnvelopVol.placeVolume( towerVol, towerId32, dd4hep::Position(0.,0.,-param->GetSipmHeight()/2.) ); + + assemblyEnvelopVol.placeVolume( sipmLayerVol, towerId32, dd4hep::Position(0.,0.,(x_theta.height()-x_wafer.height())/2.) ); + + dd4hep::PlacedVolume sipmWaferPhys = assemblyEnvelopVol.placeVolume( sipmWaferVol, towerId32, dd4hep::Position(0.,0.,(x_theta.height()+param->GetSipmHeight()-x_wafer.height())/2.) ); + sipmWaferPhys.addPhysVolID("eta", towerNoLR); + sipmWaferPhys.addPhysVolID("phi", nPhi); + sipmWaferPhys.addPhysVolID("module", 0); + + return; +} + +void ddDRcalo::DRconstructor::implementFibers(xml_comp_t& x_theta, dd4hep::Volume& towerVol, dd4hep::Trap& trap, dd4hep::DDSegmentation::DRparamBase_k4geo* param, int towerNo) { + dd4hep::Tube fiberEnv = dd4hep::Tube(0.,fX_cladC.rmax(),x_theta.height()/2.); + dd4hep::Tube fiber = dd4hep::Tube(0.,fX_cladC.rmax(),x_theta.height()/2.-fX_mirror.height()/2.); + dd4hep::Tube fiberC = dd4hep::Tube(0.,fX_coreC.rmin(),x_theta.height()/2.-fX_mirror.height()/2.); + dd4hep::Tube fiberS = dd4hep::Tube(0.,fX_coreS.rmin(),x_theta.height()/2.-fX_mirror.height()/2.); + + dd4hep::Tube cap = dd4hep::Tube(0.,fX_coreC.rmax(),fX_mirror.height()/2.); + dd4hep::Volume capC = dd4hep::Volume("capC", cap, fDescription->material(fX_mirror.materialStr())); + dd4hep::Volume capS = dd4hep::Volume("capS", cap, fDescription->material(fX_dark.materialStr())); + dd4hep::SkinSurface(*fDescription, *fDetElement, "MirrorSurf_Tower"+std::to_string(towerNo), *fMirrorSurf, capC); + if (fVis) capC.setVisAttributes(*fDescription, fX_mirror.visStr()); + if (fVis) capS.setVisAttributes(*fDescription, fX_dark.visStr()); + + auto rootTrap = trap.access(); + + float sipmSize = fX_dim.dx(); + float gridSize = fX_dim.distance(); + float towerHeight = x_theta.height(); + + float diff = fX_cladC.rmax(); // can be arbitrary small number + float z1 = towerHeight/2.-2*diff; // can be arbitrary number slightly smaller than towerHeight/2-diff + + fNumx = static_cast( std::floor( ( param->GetTl2()*2. - sipmSize )/gridSize ) ) + 1; // in phi direction + fNumy = static_cast( std::floor( ( param->GetH2()*2. - sipmSize )/gridSize ) ) + 1; // in eta direction + int numxBl2 = static_cast( std::floor( ( param->GetBl2()*2. - sipmSize )/gridSize ) ) + 1; // only used for estimating normals + + // full length fibers + int rmin = 0, rmax = 0, cmin = 0, cmax = 0; + dd4hep::Box fullBox = calculateFullBox(rootTrap,rmin,rmax,cmin,cmax,rootTrap->GetDz()); + dd4hep::Volume fullBoxVol("fullBox",fullBox,fDescription->material(x_theta.materialStr())); + fullBoxVol.setVisAttributes(*fDescription, x_theta.visStr()); + + dd4hep::Box unitBox = dd4hep::Box(gridSize,gridSize,x_theta.height()/2.); + dd4hep::Volume unitBoxVol("unitBox",unitBox,fDescription->material(x_theta.materialStr())); + + if (fVis) + unitBoxVol.setVisAttributes(*fDescription, x_theta.visStr()); + + implementFiber(unitBoxVol, trap, dd4hep::Position(-gridSize/2.,-gridSize/2.,0.), cmin, rmin, fiberEnv, fiber, fiberC, fiberS, capC, capS); + implementFiber(unitBoxVol, trap, dd4hep::Position(gridSize/2.,-gridSize/2.,0.), cmin+1, rmin, fiberEnv, fiber, fiberC, fiberS, capC, capS); + implementFiber(unitBoxVol, trap, dd4hep::Position(-gridSize/2.,gridSize/2.,0.), cmin, rmin+1, fiberEnv, fiber, fiberC, fiberS, capC, capS); + implementFiber(unitBoxVol, trap, dd4hep::Position(gridSize/2.,gridSize/2.,0.), cmin+1, rmin+1, fiberEnv, fiber, fiberC, fiberS, capC, capS); + + bool isEvenRow = false, isEvenCol = false; + placeUnitBox(fullBoxVol,unitBoxVol,rmin,rmax,cmin,cmax,isEvenRow,isEvenCol); + towerVol.placeVolume(fullBoxVol); + + // get normals to each side + double norm1[3] = {0.,0.,0.}, norm2[3] = {0.,0.,0.}, norm3[3] = {0.,0.,0.}, norm4[3] = {0.,0.,0.}; + getNormals(rootTrap,numxBl2,z1,norm1,norm2,norm3,norm4); + + for (int row = 0; row < fNumy; row++) { + for (int column = 0; column < fNumx; column++) { + auto localPosition = fSegmentation->localPosition(fNumx,fNumy,column,row); + dd4hep::Position pos = dd4hep::Position(localPosition); + + if ( row >= rmin && row <= rmax && column >= cmin && column <= cmax ) { + if ( ( !isEvenRow && row==rmax ) || ( !isEvenCol && column==cmax ) ) { + double pos_[3] = {pos.x(),pos.y(),-fullBox.z()+TGeoShape::Tolerance()}; + bool check = fullBox.access()->Contains(pos_); + + if (check) { + implementFiber(fullBoxVol, trap, pos, column, row, fiberEnv, fiber, fiberC, fiberS, capC, capS); + fFiberCoords.push_back( std::make_pair(column,row) ); + } + } + } else { + // outside tower + if (!checkContained(rootTrap,pos,z1)) continue; + + double* normX = nullptr; + double* normY = nullptr; + + // select two closest orthogonal sides + if (column > fNumx/2) normX = norm2; + else normX = norm4; + + if (row > fNumy/2) normY = norm3; + else normY = norm1; + + // compare and choose the shortest fiber length + float cand1 = calculateFiberLen(rootTrap, pos, normX, z1, diff, towerHeight); + float cand2 = calculateFiberLen(rootTrap, pos, normY, z1, diff, towerHeight); + float fiberLen = std::min(cand1,cand2); + + // not enough space to place fiber + if ( fiberLen < 0. ) continue; + + // trim fiber length in the case calculated length is longer than tower height + if (fiberLen > towerHeight) fiberLen = towerHeight; + float centerZ = towerHeight/2. - fiberLen/2.; + + // final check + if ( checkContained(rootTrap,pos,towerHeight/2.-fiberLen) ) { + dd4hep::Position centerPos( pos.x(),pos.y(),centerZ ); + + dd4hep::Tube shortFiberEnv = dd4hep::Tube(0.,fX_cladC.rmax(),fiberLen/2.); + dd4hep::Tube shortFiber = dd4hep::Tube(0.,fX_cladC.rmax(),fiberLen/2.-fX_mirror.height()/2.); + dd4hep::Tube shortFiberC = dd4hep::Tube(0.,fX_coreC.rmin(),fiberLen/2.-fX_mirror.height()/2.); + dd4hep::Tube shortFiberS = dd4hep::Tube(0.,fX_coreS.rmin(),fiberLen/2.-fX_mirror.height()/2.); + + implementFiber(towerVol, trap, centerPos, column, row, shortFiberEnv, shortFiber, shortFiberC, shortFiberS, capC, capS); + fFiberCoords.push_back( std::make_pair(column,row) ); + } + } + } + } +} + +void ddDRcalo::DRconstructor::implementFiber(dd4hep::Volume& towerVol, dd4hep::Trap& trap, dd4hep::Position pos, int col, int row, + dd4hep::Tube& fiberEnv, dd4hep::Tube& fiber, dd4hep::Tube& fiberC, dd4hep::Tube& fiberS, + dd4hep::Volume& capC, dd4hep::Volume& capS) { + // punch air hole + if ( fX_hole.gap() && pos.z() > TGeoShape::Tolerance() ) { + dd4hep::Tube airHoleTube = dd4hep::Tube(0.,fX_cladC.rmax(),pos.z()); + dd4hep::Position airPos( pos.x(), pos.y(), -fiberEnv.dZ() ); + dd4hep::IntersectionSolid airHole = dd4hep::IntersectionSolid(trap,airHoleTube,airPos); + dd4hep::Volume airHoleVol("airHole", airHole, fDescription->material(fX_hole.materialStr())); + towerVol.placeVolume(airHoleVol); + } + + dd4hep::Volume fiberEnvVol("fiberEnv", fiberEnv, fDescription->material(fX_hole.materialStr())); + towerVol.placeVolume( fiberEnvVol, pos ); + + if ( fSegmentation->IsCerenkov(col,row) ) { //c fiber + dd4hep::Volume cladVol("cladC", fiber, fDescription->material(fX_cladC.materialStr())); + fiberEnvVol.placeVolume( cladVol, dd4hep::Position(0.,0.,fX_mirror.height()/2.) ); + if (fVis) cladVol.setVisAttributes(*fDescription, fX_cladC.visStr()); // high CPU consumption! + + dd4hep::Volume coreVol("coreC", fiberC, fDescription->material(fX_coreC.materialStr())); + if (fVis) coreVol.setVisAttributes(*fDescription, fX_coreC.visStr()); + cladVol.placeVolume( coreVol ); + fiberEnvVol.placeVolume( capC, dd4hep::Position(0.,0.,fX_mirror.height()/2.-fiberEnv.dZ()) ); + + coreVol.setRegion(*fDescription, fX_det.regionStr()); + cladVol.setRegion(*fDescription, fX_det.regionStr()); + } else { // s fiber + dd4hep::Volume cladVol("cladS", fiber, fDescription->material(fX_coreC.materialStr())); + fiberEnvVol.placeVolume( cladVol, dd4hep::Position(0.,0.,fX_mirror.height()/2.) ); + if (fVis) cladVol.setVisAttributes(*fDescription, fX_coreC.visStr()); + + dd4hep::Volume coreVol("coreS", fiberS, fDescription->material(fX_coreS.materialStr())); + if (fVis) coreVol.setVisAttributes(*fDescription, fX_coreS.visStr()); + cladVol.placeVolume( coreVol ); + fiberEnvVol.placeVolume( capS, dd4hep::Position(0.,0.,fX_mirror.height()/2.-fiberEnv.dZ()) ); + + coreVol.setRegion(*fDescription, fX_det.regionStr()); + cladVol.setRegion(*fDescription, fX_det.regionStr()); + } +} + +void ddDRcalo::DRconstructor::implementSipms(dd4hep::Volume& sipmLayerVol, dd4hep::Trap& trap) { + xml_comp_t x_glass ( fX_sipmDim.child( _Unicode(sipmGlass) ) ); + xml_comp_t x_wafer ( fX_sipmDim.child( _Unicode(sipmWafer) ) ); + + float sipmSize = fX_dim.dx(); + double windowHeight = fX_sipmDim.height() - x_wafer.height(); + + int rmin = 0, rmax = 0, cmin = 0, cmax = 0; + auto rootTrap = trap.access(); + dd4hep::Box sipmFullBox = calculateFullBox(rootTrap,rmin,rmax,cmin,cmax,windowHeight/2.); + dd4hep::Volume sipmFullBoxVol("sipmFullBox",sipmFullBox,fDescription->material(fX_sipmDim.materialStr())); + + float gridSize = fX_dim.distance(); + dd4hep::Box sipmUnitBox = dd4hep::Box(gridSize,gridSize,windowHeight/2.); + dd4hep::Volume sipmUnitBoxVol("sipmUnitBox",sipmUnitBox,fDescription->material(fX_sipmDim.materialStr())); + + // Glass box + dd4hep::Box sipmEnvelop(sipmSize/2., sipmSize/2., windowHeight/2.); + dd4hep::Volume sipmEnvelopVol( "sipmEnvelop", sipmEnvelop, fDescription->material(x_glass.materialStr()) ); + + if (fVis) { + sipmFullBoxVol.setVisAttributes(*fDescription, fX_sipmDim.visStr()); + sipmUnitBoxVol.setVisAttributes(*fDescription, fX_sipmDim.visStr()); + sipmEnvelopVol.setVisAttributes(*fDescription, fX_sipmDim.visStr()); + } + + sipmUnitBoxVol.placeVolume( sipmEnvelopVol, dd4hep::Position(-gridSize/2.,-gridSize/2.,0.) ); + sipmUnitBoxVol.placeVolume( sipmEnvelopVol, dd4hep::Position(gridSize/2.,-gridSize/2.,0.) ); + sipmUnitBoxVol.placeVolume( sipmEnvelopVol, dd4hep::Position(-gridSize/2.,gridSize/2.,0.) ); + sipmUnitBoxVol.placeVolume( sipmEnvelopVol, dd4hep::Position(gridSize/2.,gridSize/2.,0.) ); + + bool isEvenRow = false, isEvenCol = false; + placeUnitBox(sipmFullBoxVol,sipmUnitBoxVol,rmin,rmax,cmin,cmax,isEvenRow,isEvenCol); + sipmLayerVol.placeVolume(sipmFullBoxVol); + + for (unsigned iFiber = 0; iFiber < fFiberCoords.size(); iFiber++) { + int column = fFiberCoords.at(iFiber).first; + int row = fFiberCoords.at(iFiber).second; + auto localPosition = fSegmentation->localPosition(fNumx,fNumy,column,row); + + if ( row >= rmin && row <= rmax && column >= cmin && column <= cmax ) { + if ( ( !isEvenRow && row==rmax ) || ( !isEvenCol && column==cmax ) ) { + dd4hep::Position pos = dd4hep::Position(localPosition.x(),localPosition.y(),0.); + sipmFullBoxVol.placeVolume( sipmEnvelopVol, pos ); + } + } else { + dd4hep::Position pos = dd4hep::Position(localPosition.x(),localPosition.y(),0.); + sipmLayerVol.placeVolume( sipmEnvelopVol, pos ); + } + } + + // clear fiber coordinate vector + fFiberCoords.clear(); +} + +double ddDRcalo::DRconstructor::calculateDistAtZ(TGeoTrap* rootTrap, dd4hep::Position& pos, double* norm, double z) { + double pos_[3] = {pos.x(),pos.y(),z}; + + return rootTrap->DistFromInside(pos_,norm); +} + +float ddDRcalo::DRconstructor::calculateFiberLen(TGeoTrap* rootTrap, dd4hep::Position& pos, double* norm, double z1, double diff, double towerHeight) { + float z2 = z1+diff; + float y1 = calculateDistAtZ(rootTrap,pos,norm,z1); + float y2 = calculateDistAtZ(rootTrap,pos,norm,z2); + float ymin = std::min(y1,y2); + + // return if the distance is smaller than fiber diameter + if ( ymin < 2.*fX_cladC.rmax() ) return -1.; + + // find the point where the fiber reaches a side of the tower + float slope = (y2-y1)/diff; + float y0 = (y1*z2-y2*z1)/diff; + float z = (fX_cladC.rmax()-y0)/slope; + float fiberLen = towerHeight/2. - z; + + return fiberLen; +} + +bool ddDRcalo::DRconstructor::checkContained(TGeoTrap* rootTrap, dd4hep::Position& pos, double z, bool throwExcept) { + double pos_[3] = {pos.x(),pos.y(),z}; + bool check = rootTrap->Contains(pos_); + + if ( throwExcept && !check ) throw std::runtime_error("Fiber must be in the tower!"); + return check; +} + +void ddDRcalo::DRconstructor::getNormals(TGeoTrap* rootTrap, int numxBl2, double z, double* norm1, double* norm2, double* norm3, double* norm4) { + dd4hep::Position pos1 = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,fNumx/2,0) ); + dd4hep::Position pos2 = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,fNumx/2+numxBl2/2-1,fNumy/2) ); + dd4hep::Position pos3 = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,fNumx/2,fNumy-1) ); + dd4hep::Position pos4 = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,fNumx/2-numxBl2/2+1,fNumy/2) ); + double pos1_[3] = {pos1.x(),pos1.y(),z}; + double pos2_[3] = {pos2.x(),pos2.y(),z}; + double pos3_[3] = {pos3.x(),pos3.y(),z}; + double pos4_[3] = {pos4.x(),pos4.y(),z}; + double dir[3] = {0.,0.,0.}; + + rootTrap->ComputeNormal(pos1_,dir,norm1); + rootTrap->ComputeNormal(pos2_,dir,norm2); + rootTrap->ComputeNormal(pos3_,dir,norm3); + rootTrap->ComputeNormal(pos4_,dir,norm4); + norm1[2] = 0.; // check horizontal distance only + norm2[2] = 0.; + norm3[2] = 0.; + norm4[2] = 0.; +} + +dd4hep::Box ddDRcalo::DRconstructor::calculateFullBox(TGeoTrap* rootTrap, int& rmin, int& rmax, int& cmin, int& cmax, double dz) { + float gridSize = fX_dim.distance(); + double zmin = -rootTrap->GetDz() + TGeoShape::Tolerance(); + float xmin = 0., xmax = 0., ymin = 0., ymax = 0.; + + for (int row = 0; row < fNumy; row++) { // bottom-up + auto localPosition = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,fNumx/2,row) ); + auto pos = localPosition + dd4hep::Position(0.,-gridSize/2.,0.); + if ( checkContained(rootTrap,pos,zmin) ) { + ymin = pos.y(); + rmin = row; + break; + } + } + + for (int row = fNumy-1; row !=0 ; row--) { // top-down + auto localPosition = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,fNumx/2,row) ); + auto pos = localPosition + dd4hep::Position(0.,gridSize/2.,0.); + if ( checkContained(rootTrap,pos,zmin) ) { + ymax = pos.y(); + rmax = row; + break; + } + } + + for (int col = 0; col < fNumx; col++) { // left-right + auto localPosition = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,col,rmin) ); + auto pos = localPosition + dd4hep::Position(-gridSize/2.,-gridSize/2.,0.); + if ( checkContained(rootTrap,pos,zmin) ) { + xmin = pos.x(); + cmin = col; + break; + } + } + + for (int col = fNumx-1; col!=0; col--) { // right-left + auto localPosition = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,col,rmin) ); + auto pos = localPosition + dd4hep::Position(gridSize/2.,-gridSize/2.,0.); + if ( checkContained(rootTrap,pos,zmin) ) { + xmax = pos.x(); + cmax = col; + break; + } + } + + return dd4hep::Box( (xmax-xmin)/2., (ymax-ymin)/2., dz ); +} + +void ddDRcalo::DRconstructor::placeUnitBox(dd4hep::Volume& fullBox, dd4hep::Volume& unitBox, int rmin, int rmax, int cmin, int cmax, bool& isEvenRow, bool& isEvenCol) { + for (int row = rmin; row < rmax; row+=2) { + for (int col = cmin; col < cmax; col+=2) { + auto pos0 = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,col,row) ); + auto pos3 = dd4hep::Position( fSegmentation->localPosition(fNumx,fNumy,col+1,row+1) ); + fullBox.placeVolume(unitBox,(pos0+pos3)/2.); + } + } + + isEvenRow = (rmax-rmin+1)%2==0; + isEvenCol = (cmax-cmin+1)%2==0; + + return; +} diff --git a/detector/calorimeter/dual-readout/src/FiberDualReadoutCalo_o1_v01.cpp b/detector/calorimeter/dual-readout/src/FiberDualReadoutCalo_o1_v01.cpp new file mode 100644 index 000000000..79b66def7 --- /dev/null +++ b/detector/calorimeter/dual-readout/src/FiberDualReadoutCalo_o1_v01.cpp @@ -0,0 +1,75 @@ +#include "detectorSegmentations/DRparamBarrel_k4geo.h" +#include "detectorSegmentations/DRparamEndcap_k4geo.h" +#include "detectorSegmentations/GridDRcaloHandle_k4geo.h" + +#include "DRconstructor.h" + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/OpticalSurfaces.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Detector.h" + +namespace ddDRcalo { + static dd4hep::Ref_t create_detector( dd4hep::Detector &description, xml_h xmlElement, dd4hep::SensitiveDetector sensDet ) { + // Get the detector description from the xml-tree + xml_det_t x_det = xmlElement; + std::string name = x_det.nameStr(); + // Create the detector element + dd4hep::DetElement drDet( name, x_det.id() ); + // set the sensitive detector type to the DD4hep calorimeter + dd4hep::xml::Dimension sensDetType = xmlElement.child(_Unicode(sensitive)); + sensDet.setType(sensDetType.typeStr()); + // Get the world volume + dd4hep::Assembly experimentalHall("hall"); + // Get the dimensions defined in the xml-tree + xml_comp_t x_barrel ( x_det.child( _Unicode(barrel) ) ); + xml_comp_t x_endcap ( x_det.child( _Unicode(endcap) ) ); + xml_comp_t x_structure ( x_det.child( _Unicode(structure) ) ); + xml_comp_t x_dim ( x_structure.child( _Unicode(dim) ) ); + xml_comp_t x_sipmDim ( x_det.child( _Unicode(sipmDim) ) ); + + dd4hep::OpticalSurfaceManager surfMgr = description.surfaceManager(); + dd4hep::OpticalSurface sipmSurfProp = surfMgr.opticalSurface("/world/"+name+"#SiPMSurf"); + dd4hep::OpticalSurface mirrorSurfProp = surfMgr.opticalSurface("/world/"+name+"#MirrorSurf"); + surfMgr.opticalSurface("/world/"+name+"#FilterSurf"); // actual filtering applied in the stepping action + + auto segmentation = dynamic_cast( sensDet.readout().segmentation().segmentation() ); + segmentation->setGridSize( x_dim.distance() ); + segmentation->setSipmSize( x_dim.dx() ); + + auto paramBarrel = segmentation->paramBarrel(); + paramBarrel->SetInnerX(x_barrel.rmin()); + paramBarrel->SetTowerH(x_barrel.height()); + paramBarrel->SetNumZRot(x_barrel.nphi()); + paramBarrel->SetSipmHeight(x_sipmDim.height()); + + auto paramEndcap = segmentation->paramEndcap(); + paramEndcap->SetInnerX(x_endcap.rmin()); + paramEndcap->SetTowerH(x_endcap.height()); + paramEndcap->SetNumZRot(x_endcap.nphi()); + paramEndcap->SetSipmHeight(x_sipmDim.height()); + + auto constructor = DRconstructor(x_det); + constructor.setExpHall(&experimentalHall); + constructor.setDRparamBarrel(paramBarrel); + constructor.setDRparamEndcap(paramEndcap); + constructor.setDescription(&description); + constructor.setDetElement(&drDet); + constructor.setSipmSurf(&sipmSurfProp); + constructor.setMirrorSurf(&mirrorSurfProp); + constructor.setSensDet(&sensDet); + constructor.construct(); // right + + dd4hep::Volume worldVol = description.pickMotherVolume(drDet); + dd4hep::PlacedVolume hallPlace = worldVol.placeVolume(experimentalHall); + hallPlace.addPhysVolID("system",x_det.id()); + // connect placed volume and physical volume + drDet.setPlacement( hallPlace ); + + paramBarrel->finalized(); + paramEndcap->finalized(); + + return drDet; + } +} // namespace detector +DECLARE_DETELEMENT(FiberDualReadoutCalo_o1_v01, ddDRcalo::create_detector) // factory method \ No newline at end of file diff --git a/detectorSegmentations/include/detectorSegmentations/DRparamBarrel_k4geo.h b/detectorSegmentations/include/detectorSegmentations/DRparamBarrel_k4geo.h new file mode 100644 index 000000000..47b2bb6af --- /dev/null +++ b/detectorSegmentations/include/detectorSegmentations/DRparamBarrel_k4geo.h @@ -0,0 +1,27 @@ +#ifndef DETSEGMENTATION_DRPARAMBARREL_H +#define DETSEGMENTATION_DRPARAMBARREL_H + +#include "detectorSegmentations/DRparamBase_k4geo.h" + +#include "TVector3.h" +#include "DD4hep/DetFactoryHelper.h" + +#include +#include + +namespace dd4hep { +namespace DDSegmentation { + class DRparamBarrel_k4geo : public DRparamBase_k4geo { + public: + DRparamBarrel_k4geo(); + virtual ~DRparamBarrel_k4geo(); + + virtual void SetDeltaThetaByTowerNo(int signedTowerNo, int) override; + virtual void SetThetaOfCenterByTowerNo(int signedTowerNo, int) override; + + virtual void init() override; + }; +} +} + +#endif diff --git a/detectorSegmentations/include/detectorSegmentations/DRparamBase_k4geo.h b/detectorSegmentations/include/detectorSegmentations/DRparamBase_k4geo.h new file mode 100644 index 000000000..c072eabb5 --- /dev/null +++ b/detectorSegmentations/include/detectorSegmentations/DRparamBase_k4geo.h @@ -0,0 +1,99 @@ +#ifndef DETSEGMENTATION_DRPARAMBASE_H +#define DETSEGMENTATION_DRPARAMBASE_H + +#include "TVector3.h" +#include "DD4hep/DetFactoryHelper.h" + +#include +#include + +namespace dd4hep { +namespace DDSegmentation { + class DRparamBase_k4geo { + public: + DRparamBase_k4geo(); + virtual ~DRparamBase_k4geo(); + + void SetIsRHS(bool isRHS) { fIsRHS = isRHS; } + void SetInnerX(double innerX) { fInnerX = innerX; } + void SetTowerH(double towerH) { fTowerH = towerH; } + void SetNumZRot(int num) { fNumZRot = num; fPhiZRot = 2*M_PI/(double)num; } + void SetDeltaTheta(double theta) { fDeltaTheta = theta; } + void SetThetaOfCenter(double theta) { fThetaOfCenter = theta; } + void SetSipmHeight(double SipmHeight) { fSipmHeight = SipmHeight; } + + bool GetIsRHS() { return fIsRHS; } + double GetCurrentInnerR() { return fCurrentInnerR; } + double GetTowerH() { return fTowerH; } + double GetSipmHeight() { return fSipmHeight; } + double GetH1() { return fCurrentInnerHalf; } + double GetBl1() { return fV3.X()*std::tan(fPhiZRot/2.); } + double GetTl1() { return fV1.X()*std::tan(fPhiZRot/2.); } + double GetH2() { return fCurrentOuterHalf; } + double GetBl2() { return fV4.X()*std::tan(fPhiZRot/2.); } + double GetTl2() { return fV2.X()*std::tan(fPhiZRot/2.); } + + double GetH2sipm() { return fCurrentOuterHalfSipm; } + double GetBl2sipm() { return fV4sipm.X()*std::tan(fPhiZRot/2.); } + double GetTl2sipm() { return fV2sipm.X()*std::tan(fPhiZRot/2.); } + + dd4hep::RotationZYX GetRotationZYX(int numPhi); + dd4hep::Position GetTowerPos(int numPhi); + dd4hep::Position GetAssemblePos(int numPhi); + dd4hep::Position GetSipmLayerPos(int numPhi); + + dd4hep::Transform3D GetTransform3D(int numPhi); + dd4hep::Transform3D GetAssembleTransform3D(int numPhi); + dd4hep::Transform3D GetSipmTransform3D(int numPhi); + + int signedTowerNo(int unsignedTowerNo) { return fIsRHS ? unsignedTowerNo : -unsignedTowerNo-1; } + int unsignedTowerNo(int signedTowerNo) { return signedTowerNo >= 0 ? signedTowerNo : -signedTowerNo-1; } + + virtual void SetDeltaThetaByTowerNo(int , int ) {} + virtual void SetThetaOfCenterByTowerNo(int , int ) {} + void SetIsRHSByTowerNo(int signedTowerNo) { fIsRHS = ( signedTowerNo >=0 ? true : false ); } + + int GetTotTowerNum() { return fTotNum; } + void SetTotTowerNum(int totNum) { fTotNum = totNum; } + + int GetCurrentTowerNum() { return fCurrentTowerNum; } + void SetCurrentTowerNum(int numEta) { fCurrentTowerNum = numEta; } + + virtual void init() {}; + void filled() { fFilled = true; } + void finalized() { fFinalized = true; } + bool IsFinalized() { return fFinalized; } + + protected: + bool fIsRHS; + double fPhiZRot; + double fInnerX; + double fTowerH; + int fNumZRot; + double fDeltaTheta; + double fThetaOfCenter; + double fCurrentInnerR; + TVector3 fCurrentCenter; + TVector3 fV1; + TVector3 fV2; + TVector3 fV3; + TVector3 fV4; + TVector3 fV2sipm; + TVector3 fV4sipm; + double fSipmHeight; + + double fCurrentInnerHalf; + double fCurrentOuterHalf; + double fCurrentOuterHalfSipm; + + int fTotNum; + int fCurrentTowerNum; + std::vector fDeltaThetaVec; + std::vector fThetaOfCenterVec; + bool fFilled; + bool fFinalized; + }; +} +} + +#endif diff --git a/detectorSegmentations/include/detectorSegmentations/DRparamEndcap_k4geo.h b/detectorSegmentations/include/detectorSegmentations/DRparamEndcap_k4geo.h new file mode 100644 index 000000000..d8fb48d4d --- /dev/null +++ b/detectorSegmentations/include/detectorSegmentations/DRparamEndcap_k4geo.h @@ -0,0 +1,27 @@ +#ifndef DETSEGMENTATION_DRPARAMENDCAP_H +#define DETSEGMENTATION_DRPARAMENDCAP_H + +#include "detectorSegmentations/DRparamBase_k4geo.h" + +#include "TVector3.h" +#include "DD4hep/DetFactoryHelper.h" + +#include +#include + +namespace dd4hep { +namespace DDSegmentation { + class DRparamEndcap_k4geo : public DRparamBase_k4geo { + public: + DRparamEndcap_k4geo(); + virtual ~DRparamEndcap_k4geo(); + + virtual void SetDeltaThetaByTowerNo(int signedTowerNo, int BEtrans) override; + virtual void SetThetaOfCenterByTowerNo(int signedTowerNo, int BEtrans) override; + + virtual void init() override; + }; +} +} + +#endif diff --git a/detectorSegmentations/include/detectorSegmentations/GridDRcaloHandle_k4geo.h b/detectorSegmentations/include/detectorSegmentations/GridDRcaloHandle_k4geo.h new file mode 100644 index 000000000..0f777c3dd --- /dev/null +++ b/detectorSegmentations/include/detectorSegmentations/GridDRcaloHandle_k4geo.h @@ -0,0 +1,90 @@ +#ifndef DD4HEP_DDCORE_GRIDDRCALO_H +#define DD4HEP_DDCORE_GRIDDRCALO_H 1 + +#include "detectorSegmentations/GridDRcalo_k4geo.h" + +#include "DD4hep/Segmentations.h" +#include "DD4hep/detail/SegmentationsInterna.h" + +namespace dd4hep { + class Segmentation; + template class SegmentationWrapper; + + typedef Handle> GridDRcaloHandle; + + class GridDRcalo_k4geo : public GridDRcaloHandle { + typedef GridDRcaloHandle::Object Object; + + public: + /// Default constructor + GridDRcalo_k4geo() = default; + /// Copy constructor + GridDRcalo_k4geo(const GridDRcalo_k4geo& e) = default; + /// Copy Constructor from segmentation base object + GridDRcalo_k4geo(const Segmentation& e) : Handle(e) {} + /// Copy constructor from handle + GridDRcalo_k4geo(const Handle& e) : Handle(e) {} + /// Copy constructor from other polymorph/equivalent handle + template + GridDRcalo_k4geo(const Handle& e) : Handle(e) {} + /// Assignment operator + GridDRcalo_k4geo& operator=(const GridDRcalo_k4geo& seg) = default; + /// Equality operator + bool operator==(const GridDRcalo_k4geo& seg) const { return m_element == seg.m_element; } + /// determine the position based on the cell ID + inline Position position(const CellID& id) const { return Position(access()->implementation->position(id)); } + inline Position localPosition(const CellID& id) const { return Position(access()->implementation->localPosition(id)); } + inline Position localPosition(int numx, int numy, int x_, int y_) const { return Position(access()->implementation->localPosition(numx,numy,x_,y_)); } + + /// determine the cell ID based on the position + inline dd4hep::CellID cellID(const Position& local, const Position& global, const VolumeID& volID) const { + return access()->implementation->cellID(local, global, volID); + } + + inline VolumeID setVolumeID(int numEta, int numPhi) const { return access()->implementation->setVolumeID(numEta,numPhi); } + inline CellID setCellID(int numEta, int numPhi, int x, int y) const { return access()->implementation->setCellID(numEta, numPhi, x, y); } + + inline void setGridSize(double grid) { access()->implementation->setGridSize(grid); } + + // Get the identifier number of a mother tower in eta or phi direction + inline int numEta(const CellID& aCellID) const { return access()->implementation->numEta(aCellID); } + inline int numPhi(const CellID& aCellID) const { return access()->implementation->numPhi(aCellID); } + + // Get the total number of SiPMs of the mother tower in x or y direction (local coordinate) + inline int numX(const CellID& aCellID) const { return access()->implementation->numX(aCellID); } + inline int numY(const CellID& aCellID) const { return access()->implementation->numY(aCellID); } + + // Get the identifier number of a SiPM in x or y direction (local coordinate) + inline int x(const CellID& aCellID) const { return access()->implementation->x(aCellID); } // approx eta direction + inline int y(const CellID& aCellID) const { return access()->implementation->y(aCellID); } // approx phi direction + + inline bool IsCerenkov(const CellID& aCellID) const { return access()->implementation->IsCerenkov(aCellID); } + inline bool IsCerenkov(int col, int row) const { return access()->implementation->IsCerenkov(col, row); } + + inline bool IsTower(const CellID& aCellID) const { return access()->implementation->IsTower(aCellID); } + inline bool IsSiPM(const CellID& aCellID) const { return access()->implementation->IsSiPM(aCellID); } + + inline int getFirst32bits(const CellID& aCellID) const { return access()->implementation->getFirst32bits(aCellID); } + inline int getLast32bits(const CellID& aCellID) const { return access()->implementation->getLast32bits(aCellID); } + + inline CellID convertFirst32to64(const int aId32) const { return access()->implementation->convertFirst32to64(aId32); } + inline CellID convertLast32to64(const int aId32) const { return access()->implementation->convertLast32to64(aId32); } + + // Methods for 32bit to 64bit en/decoder + inline int numEta(const int& aId32) const { return access()->implementation->numEta(aId32); } + inline int numPhi(const int& aId32) const { return access()->implementation->numPhi(aId32); } + + inline int numX(const int& aId32) const { return access()->implementation->numX(aId32); } + inline int numY(const int& aId32) const { return access()->implementation->numY(aId32); } + + inline int x(const int& aId32) const { return access()->implementation->x(aId32); } + inline int y(const int& aId32) const { return access()->implementation->y(aId32); } + + inline bool IsCerenkov(const int& aId32) const { return access()->implementation->IsCerenkov(aId32); } + + inline bool IsTower(const int& aId32) const { return access()->implementation->IsTower(aId32); } + inline bool IsSiPM(const int& aId32) const { return access()->implementation->IsSiPM(aId32); } + }; +} + +#endif diff --git a/detectorSegmentations/include/detectorSegmentations/GridDRcalo_k4geo.h b/detectorSegmentations/include/detectorSegmentations/GridDRcalo_k4geo.h new file mode 100644 index 000000000..4df5e4f41 --- /dev/null +++ b/detectorSegmentations/include/detectorSegmentations/GridDRcalo_k4geo.h @@ -0,0 +1,109 @@ +#ifndef DETSEGMENTATION_GRIDDRCALO_H +#define DETSEGMENTATION_GRIDDRCALO_H + +#include "detectorSegmentations/DRparamBarrel_k4geo.h" +#include "detectorSegmentations/DRparamEndcap_k4geo.h" + +#include "DDSegmentation/Segmentation.h" + +namespace dd4hep { +namespace DDSegmentation { +class GridDRcalo_k4geo : public Segmentation { +public: + /// default constructor using an arbitrary type + GridDRcalo_k4geo(const std::string& aCellEncoding); + /// Default constructor used by derived classes passing an existing decoder + GridDRcalo_k4geo(const BitFieldCoder* decoder); + /// destructor + virtual ~GridDRcalo_k4geo() override; + + // Determine the global(local) position based on the cell ID. + virtual Vector3D position(const CellID& aCellID) const; + Vector3D localPosition(const CellID& aCellID) const; + Vector3D localPosition(int numx, int numy, int x_, int y_) const; + + virtual CellID cellID(const Vector3D& aLocalPosition, const Vector3D& aGlobalPosition, + const VolumeID& aVolumeID) const; + + VolumeID setVolumeID(int numEta, int numPhi) const; + CellID setCellID(int numEta, int numPhi, int x, int y) const; + + void setGridSize(double grid) { fGridSize = grid; } + void setSipmSize(double sipm) { fSipmSize = sipm; } + + // Get the identifier number of a mother tower in eta or phi direction + int numEta(const CellID& aCellID) const; + int numPhi(const CellID& aCellID) const; + + // Get the total number of SiPMs of the mother tower in x or y direction (local coordinate) + int numX(const CellID& aCellID) const; + int numY(const CellID& aCellID) const; + + // Get the identifier number of a SiPM in x or y direction (local coordinate) + int x(const CellID& aCellID) const; // approx eta direction + int y(const CellID& aCellID) const; // approx phi direction + + bool IsCerenkov(const CellID& aCellID) const; + bool IsCerenkov(int col, int row) const; + + bool IsTower(const CellID& aCellID) const; + bool IsSiPM(const CellID& aCellID) const; + + int getFirst32bits(const CellID& aCellID) const { return (int)aCellID; } + int getLast32bits(const CellID& aCellID) const; + CellID convertFirst32to64(const int aId32) const { return (CellID)aId32; } + CellID convertLast32to64(const int aId32) const; + + // Methods for 32bit to 64bit en/decoder + int numEta(const int& aId32) const { return numEta( convertFirst32to64(aId32) ); } + int numPhi(const int& aId32) const { return numPhi( convertFirst32to64(aId32) ); } + + int numX(const int& aId32) const { return numX( convertFirst32to64(aId32) ); } + int numY(const int& aId32) const { return numY( convertFirst32to64(aId32) ); } + + int x(const int& aId32) const { return x( convertLast32to64(aId32) ); } + int y(const int& aId32) const { return y( convertLast32to64(aId32) ); } + + bool IsCerenkov(const int& aId32) const { return IsCerenkov( convertLast32to64(aId32) ); } + + bool IsTower(const int& aId32) const { return IsTower( convertLast32to64(aId32) ); } + bool IsSiPM(const int& aId32) const { return IsSiPM( convertLast32to64(aId32) ); } + + inline const std::string& fieldNameNumEta() const { return fNumEtaId; } + inline const std::string& fieldNameNumPhi() const { return fNumPhiId; } + inline const std::string& fieldNameX() const { return fXId; } + inline const std::string& fieldNameY() const { return fYId; } + inline const std::string& fieldNameIsCerenkov() const { return fIsCerenkovId; } + inline const std::string& fieldNameModule() const { return fModule; } + + inline void setFieldNameNumEta(const std::string& fieldName) { fNumEtaId = fieldName; } + inline void setFieldNameNumPhi(const std::string& fieldName) { fNumPhiId = fieldName; } + inline void setFieldNameX(const std::string& fieldName) { fXId = fieldName; } + inline void setFieldNameY(const std::string& fieldName) { fYId = fieldName; } + inline void setFieldNameIsCerenkov(const std::string& fieldName) { fIsCerenkovId = fieldName; } + inline void setFieldNameModule(const std::string& fieldName) { fModule = fieldName; } + + DRparamBarrel_k4geo* paramBarrel() { return fParamBarrel; } + DRparamEndcap_k4geo* paramEndcap() { return fParamEndcap; } + + DRparamBase_k4geo* setParamBase(int noEta) const; + +protected: + std::string fNumEtaId; + std::string fNumPhiId; + std::string fXId; + std::string fYId; + std::string fIsCerenkovId; + std::string fModule; + + double fGridSize; + double fSipmSize; + +private: + DRparamBarrel_k4geo* fParamBarrel; + DRparamEndcap_k4geo* fParamEndcap; +}; +} +} + +#endif diff --git a/detectorSegmentations/src/DRparamBarrel_k4geo.cpp b/detectorSegmentations/src/DRparamBarrel_k4geo.cpp new file mode 100644 index 000000000..7d5f617e0 --- /dev/null +++ b/detectorSegmentations/src/DRparamBarrel_k4geo.cpp @@ -0,0 +1,98 @@ +#include "detectorSegmentations/DRparamBarrel_k4geo.h" + +#include "Math/GenVector/RotationZYX.h" + +#include + +namespace dd4hep { +namespace DDSegmentation { + +DRparamBarrel_k4geo::DRparamBarrel_k4geo() { + fIsRHS = 0; + fPhiZRot = 0.; + fInnerX = 0.; + fTowerH = 0.; + fNumZRot = 0; + fDeltaTheta = 0.; + fThetaOfCenter = 0.; + fCurrentInnerR = 0.; + fPhiZRot = 0; + fCurrentCenter = TVector3(); + fV1 = TVector3(); + fV2 = TVector3(); + fV3 = TVector3(); + fV4 = TVector3(); + fSipmHeight = 0.; + fCurrentInnerHalf = 0.; + fCurrentOuterHalf = 0.; + fFilled = false; + fFinalized = false; +} + +DRparamBarrel_k4geo::~DRparamBarrel_k4geo() {} + +void DRparamBarrel_k4geo::init() { + fCurrentInnerR = fInnerX/std::cos(fThetaOfCenter); + double trnsLength = fTowerH/2.+fCurrentInnerR; + fCurrentCenter = TVector3(std::cos(fThetaOfCenter)*trnsLength,0.,std::sin(fThetaOfCenter)*trnsLength); + + fCurrentInnerHalf = fCurrentInnerR*std::tan(fDeltaTheta/2.); + fCurrentOuterHalf = (fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.); + fCurrentOuterHalfSipm = (fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.); + + fV1 = TVector3( + std::cos(fThetaOfCenter)*fCurrentInnerR+std::sin(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*fCurrentInnerR-std::cos(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.) + ); + + fV2 = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)+std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)-std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.) + ); + + fV3 = TVector3( + std::cos(fThetaOfCenter)*fCurrentInnerR-std::sin(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*fCurrentInnerR+std::cos(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.) + ); + + fV4 = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)-std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)+std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.) + ); + + fV2sipm = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)+std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)-std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.) + ); + + fV4sipm = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)-std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)+std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.) + ); + + if (!fFilled) { + fDeltaThetaVec.push_back(fDeltaTheta); + fThetaOfCenterVec.push_back(fThetaOfCenter); + } +} + +void DRparamBarrel_k4geo::SetDeltaThetaByTowerNo(int signedTowerNo, int) { + if (!fFilled) throw std::runtime_error("Attempt to set by tower num while barrel parameter is not filled!"); + + fDeltaTheta = fDeltaThetaVec.at( unsignedTowerNo(signedTowerNo) ); +} + +void DRparamBarrel_k4geo::SetThetaOfCenterByTowerNo(int signedTowerNo, int) { + if (!fFilled) throw std::runtime_error("Attempt to set by tower num while barrel parameter is not filled!"); + + fThetaOfCenter = fThetaOfCenterVec.at( unsignedTowerNo(signedTowerNo) ); +} + +} +} diff --git a/detectorSegmentations/src/DRparamBase_k4geo.cpp b/detectorSegmentations/src/DRparamBase_k4geo.cpp new file mode 100644 index 000000000..e5912f025 --- /dev/null +++ b/detectorSegmentations/src/DRparamBase_k4geo.cpp @@ -0,0 +1,100 @@ +#include "detectorSegmentations/DRparamBase_k4geo.h" + +#include "Math/GenVector/RotationZYX.h" + +#include + +namespace dd4hep { +namespace DDSegmentation { + +DRparamBase_k4geo::DRparamBase_k4geo() { + fIsRHS = 0; + fPhiZRot = 0.; + fInnerX = 0.; + fTowerH = 0.; + fNumZRot = 0; + fDeltaTheta = 0.; + fThetaOfCenter = 0.; + fCurrentInnerR = 0.; + fPhiZRot = 0; + fCurrentCenter = TVector3(); + fV1 = TVector3(); + fV2 = TVector3(); + fV3 = TVector3(); + fV4 = TVector3(); + fSipmHeight = 0.; + fCurrentInnerHalf = 0.; + fCurrentOuterHalf = 0.; + fCurrentTowerNum = 0; + fFilled = false; + fFinalized = false; +} + +DRparamBase_k4geo::~DRparamBase_k4geo() {} + +dd4hep::RotationZYX DRparamBase_k4geo::GetRotationZYX(int numPhi) { + double numPhi_ = (double)numPhi; + double xRot = fIsRHS ? -fThetaOfCenter : fThetaOfCenter; + double zRot = fIsRHS ? -M_PI/2. : M_PI/2.; + dd4hep::RotationZYX rot = dd4hep::RotationZYX(zRot, M_PI/2.+xRot, 0.); + ROOT::Math::RotationZ rotZ = ROOT::Math::RotationZ(numPhi_*fPhiZRot); + rot = rotZ*rot; + + return rot; +} + +dd4hep::Position DRparamBase_k4geo::GetTowerPos(int numPhi) { + double numPhi_ = (double)numPhi; + double x = std::cos(numPhi_*fPhiZRot)*fCurrentCenter.X(); + double y = std::sin(numPhi_*fPhiZRot)*fCurrentCenter.X(); + double z = fIsRHS ? fCurrentCenter.Z() : -fCurrentCenter.Z(); + dd4hep::Position pos = dd4hep::Position(x,y,z); + + return pos; +} + +dd4hep::Position DRparamBase_k4geo::GetAssemblePos(int numPhi) { + double numPhi_ = (double)numPhi; + double x = std::cos(numPhi_*fPhiZRot)*fCurrentCenter.X()*(fCurrentCenter.Mag()+fSipmHeight/2.)/fCurrentCenter.Mag(); + double y = std::sin(numPhi_*fPhiZRot)*fCurrentCenter.X()*(fCurrentCenter.Mag()+fSipmHeight/2.)/fCurrentCenter.Mag(); + double z_abs = fCurrentCenter.Z()*(fCurrentCenter.Mag()+fSipmHeight/2.)/fCurrentCenter.Mag(); + double z = fIsRHS ? z_abs : -z_abs; + dd4hep::Position pos = dd4hep::Position(x,y,z); + + return pos; +} + +dd4hep::Position DRparamBase_k4geo::GetSipmLayerPos(int numPhi) { + double numPhi_ = (double)numPhi; + double x = std::cos(numPhi_*fPhiZRot)*fCurrentCenter.X()*(fCurrentCenter.Mag()+fTowerH/2.+fSipmHeight/2.)/fCurrentCenter.Mag(); + double y = std::sin(numPhi_*fPhiZRot)*fCurrentCenter.X()*(fCurrentCenter.Mag()+fTowerH/2.+fSipmHeight/2.)/fCurrentCenter.Mag(); + double z_abs = fCurrentCenter.Z()*(fCurrentCenter.Mag()+fTowerH/2.+fSipmHeight/2.)/fCurrentCenter.Mag(); + double z = fIsRHS ? z_abs : -z_abs; + dd4hep::Position pos = dd4hep::Position(x,y,z); + + return pos; +} + +dd4hep::Transform3D DRparamBase_k4geo::GetTransform3D(int numPhi) { + auto rot = GetRotationZYX(numPhi); + auto pos = GetTowerPos(numPhi); + + return dd4hep::Transform3D(rot,pos); +} + +dd4hep::Transform3D DRparamBase_k4geo::GetAssembleTransform3D(int numPhi) { + auto rot = GetRotationZYX(numPhi); + auto pos = GetAssemblePos(numPhi); + + return dd4hep::Transform3D(rot,pos); +} + +dd4hep::Transform3D DRparamBase_k4geo::GetSipmTransform3D(int numPhi) { + auto rot = GetRotationZYX(numPhi); + auto pos = GetSipmLayerPos(numPhi); + + return dd4hep::Transform3D(rot,pos); +} + +} +} diff --git a/detectorSegmentations/src/DRparamEndcap_k4geo.cpp b/detectorSegmentations/src/DRparamEndcap_k4geo.cpp new file mode 100644 index 000000000..d8b9e2b0d --- /dev/null +++ b/detectorSegmentations/src/DRparamEndcap_k4geo.cpp @@ -0,0 +1,98 @@ +#include "detectorSegmentations/DRparamEndcap_k4geo.h" + +#include "Math/GenVector/RotationZYX.h" + +#include + +namespace dd4hep { +namespace DDSegmentation { + +DRparamEndcap_k4geo::DRparamEndcap_k4geo() { + fIsRHS = 0; + fPhiZRot = 0.; + fInnerX = 0.; + fTowerH = 0.; + fNumZRot = 0; + fDeltaTheta = 0.; + fThetaOfCenter = 0.; + fCurrentInnerR = 0.; + fPhiZRot = 0; + fCurrentCenter = TVector3(); + fV1 = TVector3(); + fV2 = TVector3(); + fV3 = TVector3(); + fV4 = TVector3(); + fSipmHeight = 0.; + fCurrentInnerHalf = 0.; + fCurrentOuterHalf = 0.; + fFilled = false; + fFinalized = false; +} + +DRparamEndcap_k4geo::~DRparamEndcap_k4geo() {} + +void DRparamEndcap_k4geo::init() { + fCurrentInnerR = fInnerX/std::sin(fThetaOfCenter); + double trnsLength = fTowerH/2.+fCurrentInnerR; + fCurrentCenter = TVector3(std::cos(fThetaOfCenter)*trnsLength,0.,std::sin(fThetaOfCenter)*trnsLength); + + fCurrentInnerHalf = fCurrentInnerR*std::tan(fDeltaTheta/2.); + fCurrentOuterHalf = (fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.); + fCurrentOuterHalfSipm = (fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.); + + fV1 = TVector3( + std::cos(fThetaOfCenter)*fCurrentInnerR+std::sin(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*fCurrentInnerR-std::cos(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.) + ); + + fV2 = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)+std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)-std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.) + ); + + fV3 = TVector3( + std::cos(fThetaOfCenter)*fCurrentInnerR-std::sin(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*fCurrentInnerR+std::cos(fThetaOfCenter)*fCurrentInnerR*std::tan(fDeltaTheta/2.) + ); + + fV4 = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)-std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH)+std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH)*std::tan(fDeltaTheta/2.) + ); + + fV2sipm = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)+std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)-std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.) + ); + + fV4sipm = TVector3( + std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)-std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.), + 0., + std::sin(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)+std::cos(fThetaOfCenter)*(fCurrentInnerR+fTowerH+fSipmHeight)*std::tan(fDeltaTheta/2.) + ); + + if (!fFilled) { + fDeltaThetaVec.push_back(fDeltaTheta); + fThetaOfCenterVec.push_back(fThetaOfCenter); + } +} + +void DRparamEndcap_k4geo::SetDeltaThetaByTowerNo(int signedTowerNo, int BEtrans) { + if (!fFilled) throw std::runtime_error("Attempt to set by tower num while endcap parameter is not filled!"); + + fDeltaTheta = fDeltaThetaVec.at( unsignedTowerNo(signedTowerNo) - unsignedTowerNo(BEtrans) ); +} + +void DRparamEndcap_k4geo::SetThetaOfCenterByTowerNo(int signedTowerNo, int BEtrans) { + if (!fFilled) throw std::runtime_error("Attempt to set by tower num while endcap parameter is not filled!"); + + fThetaOfCenter = fThetaOfCenterVec.at( unsignedTowerNo(signedTowerNo) - unsignedTowerNo(BEtrans) ); +} + +} +} diff --git a/detectorSegmentations/src/GridDRcaloHandle_k4geo.cpp b/detectorSegmentations/src/GridDRcaloHandle_k4geo.cpp new file mode 100644 index 000000000..88bc40586 --- /dev/null +++ b/detectorSegmentations/src/GridDRcaloHandle_k4geo.cpp @@ -0,0 +1,4 @@ +#include "detectorSegmentations/GridDRcaloHandle_k4geo.h" +#include "DD4hep/detail/Handle.inl" + +DD4HEP_INSTANTIATE_HANDLE_UNNAMED(dd4hep::DDSegmentation::GridDRcalo_k4geo); diff --git a/detectorSegmentations/src/GridDRcalo_k4geo.cpp b/detectorSegmentations/src/GridDRcalo_k4geo.cpp new file mode 100644 index 000000000..069de02be --- /dev/null +++ b/detectorSegmentations/src/GridDRcalo_k4geo.cpp @@ -0,0 +1,232 @@ +#include "detectorSegmentations/GridDRcalo_k4geo.h" + +#include +#include +#include + +namespace dd4hep { +namespace DDSegmentation { + +/// default constructor using an encoding string +GridDRcalo_k4geo::GridDRcalo_k4geo(const std::string& cellEncoding) : Segmentation(cellEncoding) { + // define type and description + _type = "GridDRcalo_k4geo"; + _description = "DRcalo segmentation based on the tower / (Cerenkov or Scintillation) fiber / SiPM hierarchy"; + + // register all necessary parameters + registerIdentifier("identifier_eta", "Cell ID identifier for numEta", fNumEtaId, "eta"); + registerIdentifier("identifier_phi", "Cell ID identifier for numPhi", fNumPhiId, "phi"); + registerIdentifier("identifier_x", "Cell ID identifier for x", fXId, "x"); + registerIdentifier("identifier_y", "Cell ID identifier for y", fYId, "y"); + registerIdentifier("identifier_IsCerenkov", "Cell ID identifier for IsCerenkov", fIsCerenkovId, "c"); + registerIdentifier("identifier_module", "Cell ID identifier for module", fModule, "module"); + + fParamBarrel = new DRparamBarrel_k4geo(); + fParamEndcap = new DRparamEndcap_k4geo(); +} + +GridDRcalo_k4geo::GridDRcalo_k4geo(const BitFieldCoder* decoder) : Segmentation(decoder) { + // define type and description + _type = "GridDRcalo_k4geo"; + _description = "DRcalo segmentation based on the tower / (Cerenkov or Scintillation) fiber / SiPM hierarchy"; + + // register all necessary parameters + registerIdentifier("identifier_eta", "Cell ID identifier for numEta", fNumEtaId, "eta"); + registerIdentifier("identifier_phi", "Cell ID identifier for numPhi", fNumPhiId, "phi"); + registerIdentifier("identifier_x", "Cell ID identifier for x", fXId, "x"); + registerIdentifier("identifier_y", "Cell ID identifier for y", fYId, "y"); + registerIdentifier("identifier_IsCerenkov", "Cell ID identifier for IsCerenkov", fIsCerenkovId, "c"); + registerIdentifier("identifier_module", "Cell ID identifier for module", fModule, "module"); + + fParamBarrel = new DRparamBarrel_k4geo(); + fParamEndcap = new DRparamEndcap_k4geo(); +} + +GridDRcalo_k4geo::~GridDRcalo_k4geo() { + if (fParamBarrel) delete fParamBarrel; + if (fParamEndcap) delete fParamEndcap; +} + +Vector3D GridDRcalo_k4geo::position(const CellID& cID) const { + int noEta = numEta(cID); + int noPhi = numPhi(cID); + + DRparamBase_k4geo* paramBase = setParamBase(noEta); + + auto transformA = paramBase->GetSipmTransform3D(noPhi); + dd4hep::Position localPos = dd4hep::Position(0.,0.,0.); + if ( IsSiPM(cID) ) localPos = dd4hep::Position( localPosition(cID) ); + + dd4hep::RotationZYX rot = dd4hep::RotationZYX(M_PI, 0., 0.); // AdHoc rotation, potentially bug + dd4hep::Transform3D transformB = dd4hep::Transform3D(rot,localPos); + auto total = transformA*transformB; + + dd4hep::Position translation = dd4hep::Position(0.,0.,0.); + total.GetTranslation(translation); + + return Vector3D(translation.x(),translation.y(),translation.z()); +} + +Vector3D GridDRcalo_k4geo::localPosition(const CellID& cID) const { + int numx = numX(cID); + int numy = numY(cID); + int x_ = x(cID); + int y_ = y(cID); + + return localPosition(numx,numy,x_,y_); +} + +Vector3D GridDRcalo_k4geo::localPosition(int numx, int numy, int x_, int y_) const { + float ptX = -fGridSize*static_cast(numx/2) + static_cast(x_)*fGridSize + ( numx%2==0 ? fGridSize/2. : 0. ); + float ptY = -fGridSize*static_cast(numy/2) + static_cast(y_)*fGridSize + ( numy%2==0 ? fGridSize/2. : 0. ); + + return Vector3D(ptX,ptY,0.); +} + +/// determine the cell ID based on the position +CellID GridDRcalo_k4geo::cellID(const Vector3D& localPosition, const Vector3D& /*globalPosition*/, const VolumeID& vID) const { + int numx = numX(vID); + int numy = numY(vID); + + auto localX = localPosition.x(); + auto localY = localPosition.y(); + + int x = std::floor( ( localX + ( numx%2==0 ? 0. : fGridSize/2. ) ) / fGridSize ) + numx/2; + int y = std::floor( ( localY + ( numy%2==0 ? 0. : fGridSize/2. ) ) / fGridSize ) + numy/2; + + return setCellID( numEta(vID), numPhi(vID), x, y ); +} + +VolumeID GridDRcalo_k4geo::setVolumeID(int numEta, int numPhi) const { + VolumeID numEtaId = static_cast(numEta); + VolumeID numPhiId = static_cast(numPhi); + VolumeID vID = 0; + _decoder->set(vID, fNumEtaId, numEtaId); + _decoder->set(vID, fNumPhiId, numPhiId); + + VolumeID module = 0; // Tower, SiPM layer attached to the tower, etc. + _decoder->set(vID, fModule, module); + + return vID; +} + +CellID GridDRcalo_k4geo::setCellID(int numEta, int numPhi, int x, int y) const { + VolumeID numEtaId = static_cast(numEta); + VolumeID numPhiId = static_cast(numPhi); + VolumeID xId = static_cast(x); + VolumeID yId = static_cast(y); + VolumeID vID = 0; + _decoder->set(vID, fNumEtaId, numEtaId); + _decoder->set(vID, fNumPhiId, numPhiId); + _decoder->set(vID, fXId, xId); + _decoder->set(vID, fYId, yId); + + VolumeID module = 1; // Fiber, SiPM, etc. + _decoder->set(vID, fModule, module); + + VolumeID isCeren = IsCerenkov(x,y) ? 1 : 0; + _decoder->set(vID, fIsCerenkovId, isCeren); + + return vID; +} + +// Get the identifier number of a mother tower in eta or phi direction +int GridDRcalo_k4geo::numEta(const CellID& aCellID) const { + VolumeID numEta = static_cast(_decoder->get(aCellID, fNumEtaId)); + return static_cast(numEta); +} + +int GridDRcalo_k4geo::numPhi(const CellID& aCellID) const { + VolumeID numPhi = static_cast(_decoder->get(aCellID, fNumPhiId)); + return static_cast(numPhi); +} + +// Get the total number of SiPMs of the mother tower in x or y direction (local coordinate) +int GridDRcalo_k4geo::numX(const CellID& aCellID) const { + int noEta = numEta(aCellID); + + DRparamBase_k4geo* paramBase = setParamBase(noEta); + + int noX = static_cast( std::floor( ( paramBase->GetTl2()*2. - fSipmSize )/fGridSize ) ) + 1; // in phi direction + + return noX; +} + +int GridDRcalo_k4geo::numY(const CellID& aCellID) const { + int noEta = numEta(aCellID); + + DRparamBase_k4geo* paramBase = setParamBase(noEta); + + int noY = static_cast( std::floor( ( paramBase->GetH2()*2. - fSipmSize )/fGridSize ) ) + 1; // in eta direction + + return noY; +} + +// Get the identifier number of a SiPM in x or y direction (local coordinate) +int GridDRcalo_k4geo::x(const CellID& aCellID) const { // approx eta direction + VolumeID x = static_cast(_decoder->get(aCellID, fXId)); + return static_cast(x); +} +int GridDRcalo_k4geo::y(const CellID& aCellID) const { // approx phi direction + VolumeID y = static_cast(_decoder->get(aCellID, fYId)); + return static_cast(y); +} + +bool GridDRcalo_k4geo::IsCerenkov(const CellID& aCellID) const { + VolumeID isCeren = static_cast(_decoder->get(aCellID, fIsCerenkovId)); + return static_cast(isCeren); +} + +bool GridDRcalo_k4geo::IsCerenkov(int col, int row) const { + bool isCeren = false; + if ( col%2 == 1 ) { isCeren = !isCeren; } + if ( row%2 == 1 ) { isCeren = !isCeren; } + return isCeren; +} + +bool GridDRcalo_k4geo::IsTower(const CellID& aCellID) const { + VolumeID module = static_cast(_decoder->get(aCellID, fModule)); + return module==0; +} + +bool GridDRcalo_k4geo::IsSiPM(const CellID& aCellID) const { + VolumeID module = static_cast(_decoder->get(aCellID, fModule)); + return module==1; +} + +int GridDRcalo_k4geo::getLast32bits(const CellID& aCellID) const { + CellID aId64 = aCellID >> sizeof(int)*CHAR_BIT; + int aId32 = (int)aId64; + + return aId32; +} + +CellID GridDRcalo_k4geo::convertLast32to64(const int aId32) const { + CellID aId64 = (CellID)aId32; + aId64 <<= sizeof(int)*CHAR_BIT; + + return aId64; +} + +DRparamBase_k4geo* GridDRcalo_k4geo::setParamBase(int noEta) const { + DRparamBase_k4geo* paramBase = nullptr; + + if ( fParamEndcap->unsignedTowerNo(noEta) >= fParamBarrel->GetTotTowerNum() ) paramBase = static_cast(fParamEndcap); + else paramBase = static_cast(fParamBarrel); + + if ( paramBase->GetCurrentTowerNum()==noEta ) return paramBase; + + // This should not be called while building detector geometry + if (!paramBase->IsFinalized()) throw std::runtime_error("GridDRcalo_k4geo::position should not be called while building detector geometry!"); + + paramBase->SetDeltaThetaByTowerNo(noEta, fParamBarrel->GetTotTowerNum()); + paramBase->SetThetaOfCenterByTowerNo(noEta, fParamBarrel->GetTotTowerNum()); + paramBase->SetIsRHSByTowerNo(noEta); + paramBase->SetCurrentTowerNum(noEta); + paramBase->init(); + + return paramBase; +} + +} +} diff --git a/detectorSegmentations/src/plugins/SegmentationFactories.cpp b/detectorSegmentations/src/plugins/SegmentationFactories.cpp index 4dd15369a..4a5f78fb7 100644 --- a/detectorSegmentations/src/plugins/SegmentationFactories.cpp +++ b/detectorSegmentations/src/plugins/SegmentationFactories.cpp @@ -29,4 +29,5 @@ DECLARE_SEGMENTATION(GridRPhiEta_k4geo, create_segmentation) - +#include "detectorSegmentations/GridDRcalo_k4geo.h" +DECLARE_SEGMENTATION(GridDRcalo_k4geo, create_segmentation) From df5d7829515ddd167d8aa2eaed311b6b37f3ecc6 Mon Sep 17 00:00:00 2001 From: Sungwon Kim Date: Thu, 7 Mar 2024 16:23:36 +0900 Subject: [PATCH 21/21] remove debugging cout --- detector/calorimeter/dual-readout/src/DRconstructor.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/detector/calorimeter/dual-readout/src/DRconstructor.cpp b/detector/calorimeter/dual-readout/src/DRconstructor.cpp index 603032e4a..752bc5d29 100644 --- a/detector/calorimeter/dual-readout/src/DRconstructor.cpp +++ b/detector/calorimeter/dual-readout/src/DRconstructor.cpp @@ -41,8 +41,6 @@ void ddDRcalo::DRconstructor::implementTowers(xml_comp_t& x_theta, dd4hep::DDSeg int towerNo = x_theta.start(); for (xml_coll_t x_dThetaColl(x_theta,_U(deltatheta)); x_dThetaColl; ++x_dThetaColl, ++towerNo ) { xml_comp_t x_deltaTheta = x_dThetaColl; - // debug - std::cout << "towerNo : " << towerNo << std::endl; // always use RHS for the reference param->SetIsRHS(true);