diff --git a/CMakeLists.txt b/CMakeLists.txt
index aedbe21b4..08c8bf3d3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,6 +37,7 @@ ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
option(BUILD_TESTING "Enable and build tests" ON)
option(INSTALL_COMPACT_FILES "Copy compact files to install area" OFF)
+option(INSTALL_BEAMPIPE_STL_FILES "Download CAD files for building the detailed beampipe" OFF)
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -68,6 +69,7 @@ endif()
file(GLOB sources
./detector/tracker/*.cpp
./detector/calorimeter/*.cpp
+ ./detector/calorimeter/dual-readout/src/*.cpp
./detector/fcal/*.cpp
./detector/muonSystem/*.cpp
./detector/other/*.cpp
@@ -107,9 +109,15 @@ if(NOT DCH_INFO_H_EXIST)
message(WARNING "Subdetector ${FILES_DEPENDINGON_DCH_INFO_H} will not be built because header file DDRec/DCH_info.h was not found")
endif()
+find_package(EDM4HEP)
file(GLOB G4sources
./plugins/TPCSDAction.cpp
./plugins/CaloPreShowerSDAction.cpp
+ ./plugins/FiberDRCaloSDAction.h
+ ./plugins/FiberDRCaloSDAction.cpp
+ ./plugins/Geant4Output2EDM4hep_DRC.cpp
+ ./plugins/DRCaloFastSimModel.cpp
+ ./plugins/DRCaloFastSimModel.h
)
if(DD4HEP_USE_PYROOT)
@@ -125,8 +133,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 EDM4HEP::edm4hep EDM4HEP::edm4hepDict podio::podio podio::podioDict podio::podioRootIO ${Geant4_LIBRARIES})
if(K4GEO_USE_LCIO)
target_link_libraries(${PackageName} LCIO::lcio)
@@ -184,3 +195,47 @@ write_basic_package_version_file(
install(FILES ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}/k4geoConfig.cmake
${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}/k4geoConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_CMAKEDIR} )
+
+if(INSTALL_BEAMPIPE_STL_FILES)
+
+ set(STL_FILES
+ "AlBeMet162_30042024.stl"
+ "Copper_pipe_28092023.stl"
+ "Gold_19042024.stl"
+ "Paraffine_19042024.stl"
+ "Tungsten_mask_02102023.stl"
+ "Water_30042024.stl"
+ )
+ # Set main FCC url
+ set(FCC_URL "https://fccsw.web.cern.ch/fccsw/filesForSimDigiReco")
+ set(STL_PATH "MDI_o1_v01/stl_files/Pipe_240430")
+
+ # Set the output directory where the file will be placed
+ set(OUTPUT_DIR "${PROJECT_SOURCE_DIR}/FCCee/MDI/compact/${STL_PATH}")
+ file(MAKE_DIRECTORY ${OUTPUT_DIR})
+
+ foreach(STL_FILE ${STL_FILES})
+ set(FULL_URL "${FCC_URL}/MDI/${STL_PATH}/${STL_FILE}")
+ message(DEBUG "Downloading file ${FULL_URL}")
+ set(OUTPUT_FILE "${OUTPUT_DIR}/${STL_FILE}")
+
+ if(EXISTS "${OUTPUT_FILE}")
+ message(STATUS "File ${STL_FILE} already exists. Skipping download.")
+ else()
+ # Download the file
+ file(DOWNLOAD ${FULL_URL} ${OUTPUT_FILE}
+ SHOW_PROGRESS
+ STATUS download_status)
+
+ list(GET download_status 0 status_code)
+ if(NOT status_code EQUAL 0)
+ list(GET download_status 1 error_message)
+ message(FATAL_ERROR "Failed to download file: ${error_message}")
+ endif()
+ endif()
+ endforeach()
+
+ file(MAKE_DIRECTORY share/k4geo/FCCee)
+ INSTALL(DIRECTORY ${OUTPUT_DIR} DESTINATION share/k4geo/FCCee/MDI/compact/MDI_o1_v01/stl_files )
+
+endif()
diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml
index 4858ee905..7606b7f23 100644
--- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml
+++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml
@@ -34,6 +34,8 @@
+
@@ -42,9 +44,9 @@
-
-
+
+
diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/DectDimensions.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/DectDimensions.xml
index c09dbea21..d100e0a0f 100644
--- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/DectDimensions.xml
+++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/DectDimensions.xml
@@ -103,6 +103,7 @@
+
diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged.xml
index 7a978c8d9..5b7dc11fa 100644
--- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged.xml
+++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged.xml
@@ -88,13 +88,13 @@
-
+
system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10
-
+
system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10
diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_calibration.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_calibration.xml
index e3e45f658..c8c79f253 100644
--- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_calibration.xml
+++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_calibration.xml
@@ -80,13 +80,13 @@
-
+
system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10
-
+
system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10
diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_upstream.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_upstream.xml
index 31ea25fa0..b4e05e073 100644
--- a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_upstream.xml
+++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalBarrel_thetamodulemerged_upstream.xml
@@ -80,13 +80,13 @@
-
+
system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10
-
+
system:4,cryo:1,type:3,subtype:3,layer:8,module:11,theta:10
@@ -154,4 +154,4 @@
-
\ No newline at end of file
+
diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalEndcaps_Turbine.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalEndcaps_Turbine.xml
new file mode 100644
index 000000000..547053962
--- /dev/null
+++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalEndcaps_Turbine.xml
@@ -0,0 +1,133 @@
+
+
+
+
+
+ Liquid argon EM calorimeter endcap design.
+ Electromagnetic part (EMEC) includes lead+steel absorber.
+ Turbine geometry.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ offset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ system:4,cryo:1,type:3,subtype:3,side:-2,wheel:3,layer:8,module:17,rho:8,z:8
+
+
+ -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalEndcaps_Turbine_calibration.xml b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalEndcaps_Turbine_calibration.xml
new file mode 100644
index 000000000..3d07d3671
--- /dev/null
+++ b/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ECalEndcaps_Turbine_calibration.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ Liquid argon EM calorimeter endcap design.
+ Electromagnetic part (EMEC) includes lead+steel absorber.
+ Turbine geometry.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ offset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ system:4,cryo:1,type:3,subtype:3,side:-2,wheel:3,layer:8,module:17,rho:8,z:8
+
+
+ -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FCCee/ALLEGRO/compact/README.md b/FCCee/ALLEGRO/compact/README.md
index 2d8dd9f66..6225008c8 100644
--- a/FCCee/ALLEGRO/compact/README.md
+++ b/FCCee/ALLEGRO/compact/README.md
@@ -8,4 +8,5 @@ Known caveat: the drift chamber has a larger z extent than in the IDEA detector
ALLEGRO_o1_v03: with respect to v02 it features an ECal barrel with 11 layers and cell corners projective along phi.
The vertex detector and drift chamber are now taken directly from IDEA_o1_v03, this effectively updates both the vertex detector (which was taken from an old CLD version) and the drift chamber (which was corresponding to IDEA_o1_v02/DriftChamber_o1_v01.xml). The z-extent of the drift chamber is now unchanged w.r.t. the IDEA detector (2 m) since it requires optimization anyway.
-Magnetic fields (solenoid + MDI) have been added.
\ No newline at end of file
+Magnetic fields (solenoid + MDI) have been added.
+Added "turbine-style" endcap ecal, and invoke this in the top-level xml (replacing the coneCyro geometry).
diff --git a/FCCee/CLD/compact/CLD_o2_v06/CLD_o2_v06.xml b/FCCee/CLD/compact/CLD_o2_v06/CLD_o2_v06.xml
index 853cd02d4..4599dc34d 100644
--- a/FCCee/CLD/compact/CLD_o2_v06/CLD_o2_v06.xml
+++ b/FCCee/CLD/compact/CLD_o2_v06/CLD_o2_v06.xml
@@ -2,12 +2,12 @@
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd">
-
+ version="6">
The compact format for the FCCee Detector design
diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v03.xml b/FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v03.xml
index cf080fa0c..e662f7a58 100644
--- a/FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v03.xml
+++ b/FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v03.xml
@@ -53,7 +53,10 @@
-
+
+
+
+
@@ -107,45 +110,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -217,6 +181,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -231,6 +209,7 @@
+
@@ -247,6 +226,8 @@
+
+
@@ -279,6 +260,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/FiberDualReadoutCalo_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v03/FiberDualReadoutCalo_o1_v01.xml
new file mode 100644
index 000000000..8961ffac4
--- /dev/null
+++ b/FCCee/IDEA/compact/IDEA_o1_v03/FiberDualReadoutCalo_o1_v01.xml
@@ -0,0 +1,698 @@
+
+
+
+
+
+
+
+ The compact format for the dual-readout calorimeter (for FCCee IDEA)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ system:5,assembly:1,eta:-8,phi:9,x:32:-11,y:-9,c:1,module:2
+
+
+
+
diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml b/FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml
index 66a5c49bd..949c55eb7 100644
--- a/FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml
+++ b/FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml
@@ -37,7 +37,10 @@
+
+
@@ -57,6 +60,10 @@
+
+
+
+
diff --git a/FCCee/IDEA/compact/README.md b/FCCee/IDEA/compact/README.md
index 192d63f55..fed6cf941 100644
--- a/FCCee/IDEA/compact/README.md
+++ b/FCCee/IDEA/compact/README.md
@@ -14,4 +14,9 @@ Based on o1_v01 but with a detailed description of the vertex detector, drift ch
IDEA_o1_v03
------------
-Based on o1_v02 but replacing the drift chamber (o1, v01) for the lightweight implementation based on twisted tubes (o1, v02). NB: production threshold and step limit physics have to be tuned for the drift chamber. July 2024: Added a detailed version of the muon system.
+Based on o1_v02 but replacing the drift chamber (o1, v01) for the lightweight implementation based on twisted tubes (o1,
+v02). NB: production threshold and step limit physics have to be tuned for the drift chamber.
+
+July 2024: Added a detailed version of the muon system.
+
+The monolithic fiber dual-readout calorimeter (o1, v01) is added to the directory, but commented in the main file IDEA_o1_v03.xml for the sake of speed. Please remove the comments to include this calorimeter in the full IDEA detector.
diff --git a/FCCee/MDI/compact/MDI_o1_v01/Beampipe_CADimport_o1_v02.xml b/FCCee/MDI/compact/MDI_o1_v01/Beampipe_CADimport_o1_v02.xml
index c4a3132f6..21df662c8 100644
--- a/FCCee/MDI/compact/MDI_o1_v01/Beampipe_CADimport_o1_v02.xml
+++ b/FCCee/MDI/compact/MDI_o1_v01/Beampipe_CADimport_o1_v02.xml
@@ -19,7 +19,7 @@
-
@@ -31,7 +31,7 @@
-
@@ -44,7 +44,7 @@
-
@@ -57,7 +57,7 @@
-
@@ -69,7 +69,7 @@
-
@@ -81,7 +81,7 @@
-
diff --git a/FCCee/MDI/compact/README.md b/FCCee/MDI/compact/README.md
index 0b177c6d5..13222dae2 100644
--- a/FCCee/MDI/compact/README.md
+++ b/FCCee/MDI/compact/README.md
@@ -5,9 +5,10 @@ aciarma - 08/07/24
-- BeamInstrumentation_o1_v01.xml : compensating and screening solenoids
-- HOMAbsorber.xml : old model of the HOM absorbers. Not needed anymore with new low impedance beam pipe.
-- MDI_o1_v01 (STL FILES NOT IN THIS REPO!!! WILL BE ADDED LATER)
+- MDI_o1_v01
-- Beampipe_CADimport_o1_v02.xml : import CAD models for engineered beam pipe (by F. Fransesini/INFN-LNF)
-These .stl files are hosted [here](https://fccsw.web.cern.ch/fccsw/filesForSimDigiReco/MDI/MDI_o1_v01/)
+These .stl files are hosted [here](https://fccsw.web.cern.ch/fccsw/filesForSimDigiReco/MDI/MDI_o1_v01/).
+The CMake option `INSTALL_BEAMPIPE_STL_FILES=ON` downloads these STL.
-- stl_files/Pipe_240430
├── AlBeMet162_30042024.stl : central and elliptoconical chambers, with cooling manifolds
├── Copper_pipe_28092023.stl : low impedance beam pipe separation region
@@ -15,4 +16,4 @@ These .stl files are hosted [here](https://fccsw.web.cern.ch/fccsw/filesForSimDi
├── Paraffine_19042024.stl : cooling for central chamber
├── Tungsten_mask_02102023.stl : SR masks 2.1m upstream
└── Water_30042024.stl : cooling for elliptoconical chambers
--- BeamInstrumentation_o1_v01.xml : compensating and screening solenoids
\ No newline at end of file
+-- BeamInstrumentation_o1_v01.xml : compensating and screening solenoids
diff --git a/ILD/compact/ILD_l5_v11/InnerTrackerILD_o1_v01_00.xml b/ILD/compact/ILD_l5_v11/InnerTrackerILD_o1_v01_00.xml
index 1d5142850..8f1df743f 100644
--- a/ILD/compact/ILD_l5_v11/InnerTrackerILD_o1_v01_00.xml
+++ b/ILD/compact/ILD_l5_v11/InnerTrackerILD_o1_v01_00.xml
@@ -120,13 +120,8 @@ adapted by DJeans to fit into ILD model at FCCee
-
-
diff --git a/detector/CaloTB/CaloPrototype_v01.cpp b/detector/CaloTB/CaloPrototype_v01.cpp
index 47fc83585..18816b815 100644
--- a/detector/CaloTB/CaloPrototype_v01.cpp
+++ b/detector/CaloTB/CaloPrototype_v01.cpp
@@ -8,11 +8,7 @@
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
-#include "DDRec/DetectorData.h"
-#include "LcgeoExceptions.h"
-#include
-#include
using namespace std;
diff --git a/detector/CaloTB/CaloPrototype_v02.cpp b/detector/CaloTB/CaloPrototype_v02.cpp
index d443f2803..d1bc40ee0 100644
--- a/detector/CaloTB/CaloPrototype_v02.cpp
+++ b/detector/CaloTB/CaloPrototype_v02.cpp
@@ -8,12 +8,8 @@
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
-#include "DDRec/DetectorData.h"
#include "DDSegmentation/TiledLayerGridXY.h"
-#include "LcgeoExceptions.h"
-#include
-#include
using namespace std;
diff --git a/detector/CaloTB/CaloPrototype_v03.cpp b/detector/CaloTB/CaloPrototype_v03.cpp
index 6484accc1..360487aea 100644
--- a/detector/CaloTB/CaloPrototype_v03.cpp
+++ b/detector/CaloTB/CaloPrototype_v03.cpp
@@ -10,7 +10,6 @@
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
-#include "LcgeoExceptions.h"
#include
diff --git a/detector/CaloTB/TBecal4d.cpp b/detector/CaloTB/TBecal4d.cpp
index 5765ec086..168aa00ac 100644
--- a/detector/CaloTB/TBecal4d.cpp
+++ b/detector/CaloTB/TBecal4d.cpp
@@ -8,11 +8,7 @@
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
-#include "DDRec/DetectorData.h"
-#include "DDSegmentation/TiledLayerGridXY.h"
-#include "LcgeoExceptions.h"
-#include
#include
using namespace std;
diff --git a/detector/CaloTB/TBhcal4d.cpp b/detector/CaloTB/TBhcal4d.cpp
index 2d2e8c6cb..39c462717 100644
--- a/detector/CaloTB/TBhcal4d.cpp
+++ b/detector/CaloTB/TBhcal4d.cpp
@@ -8,11 +8,7 @@
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
-#include "DDRec/DetectorData.h"
-#include "DDSegmentation/TiledLayerGridXY.h"
-#include "LcgeoExceptions.h"
-#include
#include
using namespace std;
diff --git a/detector/calorimeter/ECalBarrel_o1_v01_geo.cpp b/detector/calorimeter/ECalBarrel_o1_v01_geo.cpp
index f8b8266a7..eb9da2a67 100644
--- a/detector/calorimeter/ECalBarrel_o1_v01_geo.cpp
+++ b/detector/calorimeter/ECalBarrel_o1_v01_geo.cpp
@@ -12,9 +12,7 @@
//=========================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/Segmentation.h"
diff --git a/detector/calorimeter/ECalBarrel_o1_v02_geo.cpp b/detector/calorimeter/ECalBarrel_o1_v02_geo.cpp
index 1274bb77d..6fc9f3422 100644
--- a/detector/calorimeter/ECalBarrel_o1_v02_geo.cpp
+++ b/detector/calorimeter/ECalBarrel_o1_v02_geo.cpp
@@ -15,9 +15,7 @@
#define VERBOSE_LEVEL 2
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/Segmentation.h"
diff --git a/detector/calorimeter/ECalBarrel_o1_v03_geo.cpp b/detector/calorimeter/ECalBarrel_o1_v03_geo.cpp
index aaa8540ca..97b154e6f 100644
--- a/detector/calorimeter/ECalBarrel_o1_v03_geo.cpp
+++ b/detector/calorimeter/ECalBarrel_o1_v03_geo.cpp
@@ -16,9 +16,7 @@
#define VERBOSE_LEVEL 0
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/Segmentation.h"
diff --git a/detector/calorimeter/ECalBarrel_o2_v03_geo.cpp b/detector/calorimeter/ECalBarrel_o2_v03_geo.cpp
index 20e24f26d..14e12c102 100644
--- a/detector/calorimeter/ECalBarrel_o2_v03_geo.cpp
+++ b/detector/calorimeter/ECalBarrel_o2_v03_geo.cpp
@@ -16,9 +16,7 @@
#define VERBOSE_LEVEL 0
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/Segmentation.h"
diff --git a/detector/calorimeter/ECalBarrel_o2_v04_geo.cpp b/detector/calorimeter/ECalBarrel_o2_v04_geo.cpp
index 40d57f439..024cd9c9a 100644
--- a/detector/calorimeter/ECalBarrel_o2_v04_geo.cpp
+++ b/detector/calorimeter/ECalBarrel_o2_v04_geo.cpp
@@ -17,9 +17,7 @@
#define VERBOSE_LEVEL 0
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/Segmentation.h"
diff --git a/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp b/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp
new file mode 100644
index 000000000..51d79a656
--- /dev/null
+++ b/detector/calorimeter/ECalEndcap_Turbine_o1_v01_geo.cpp
@@ -0,0 +1,670 @@
+#include "DD4hep/DetFactoryHelper.h"
+#include "TMatrixT.h"
+
+// todo: remove gaudi logging and properly capture output
+#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: ";
+}
+
+namespace det {
+
+ unsigned ECalEndCapElementCounter = 0;
+
+ unsigned ECalEndcapNumCalibLayers;
+
+ double tForArcLength(double s, double bladeangle, double delZ, double r) {
+
+ // some intermediate constants
+ double zpos = delZ/2.;
+ double zp = zpos/TMath::Tan(bladeangle);
+ double b = zp/(TMath::Sqrt(r*r-zp*zp));
+ double c = (TMath::Tan(s/r) +b)/(1.-b*TMath::Tan(s/r));
+ double d = c*c*r*r/(1+c*c);
+ return (TMath::Sqrt(d)-zp)*TMath::Sin(bladeangle);
+
+ // try approximating the arclength as dx. Less accurate, but that
+ // approximation is used in calculating the LAr gap, so maybe this
+ // will make it more consistent?
+ //return s*TMath::Sin(bladeangle);
+
+ }
+
+ // return position of the inner edge of a blade
+ double getZmin(double r, double bladeangle, double delZ) {
+ // r: distance from the beamline
+ // bladeangle: angle of turbine blades wrt xy plane, in radians
+ // delZ: z extent of the blades
+ return TMath::Sqrt(r*r - ((delZ/2)/TMath::Tan(bladeangle))*((delZ/2)/TMath::Tan(bladeangle)));
+ }
+
+ dd4hep::Solid buildOneBlade(double thickness_inner,
+ double thickness_outer,
+ double width,
+ double ro, double ri,
+ double bladeangle,
+ double delZ)
+ {
+
+ dd4hep::Solid shapeBeforeSubtraction;
+
+ // set max and min extent of the blade (along the z axis in the body frame)
+ double zmax = ro;
+ double zmin = getZmin(ri, bladeangle, delZ);
+
+ dd4hep::Trd2 tmp1(thickness_inner/2., thickness_outer/2., width/2., width/2., (zmax-zmin)/2. );
+ shapeBeforeSubtraction = tmp1;
+
+ dd4hep::Tube allowedTube(ri, ro, delZ);
+
+ return dd4hep::IntersectionSolid (shapeBeforeSubtraction, allowedTube, dd4hep::Transform3D(dd4hep::RotationZYX( 0, TMath::Pi()/2.-bladeangle, TMath::Pi()/2.),dd4hep::Position(0,0, -(zmin+zmax)/2.)));
+
+ }
+
+ void buildWheel(dd4hep::Detector& aLcdd,
+ dd4hep::SensitiveDetector& aSensDet,
+ dd4hep::Volume& aEnvelope,
+ dd4hep::xml::Handle_t& aXmlElement,
+ dd4hep::DetElement& bathDetElem,
+ float ri, float ro, float delZ,
+ unsigned iWheel) {
+
+
+ dd4hep::xml::DetElement calorimeterElem = aXmlElement.child(_Unicode(calorimeter));
+ dd4hep::xml::DetElement genericBladeElem = calorimeterElem.child(_Unicode(turbineBlade));
+ dd4hep::xml::DetElement absBladeElem = genericBladeElem.child(_Unicode(absorberBlade));
+ dd4hep::xml::DetElement claddingElem = genericBladeElem.child(_Unicode(cladding));
+ dd4hep::xml::DetElement glueElem = genericBladeElem.child(_Unicode(glue));
+ dd4hep::xml::DetElement electrodeBladeElem = genericBladeElem.child(_Unicode(electrodeBlade));
+ dd4hep::xml::DetElement nobleLiquidElem = genericBladeElem.child(_Unicode(nobleLiquidGap));
+
+ float BladeAngle = genericBladeElem.attr(_Unicode(angle));
+ bool decreaseAnglePerWheel = genericBladeElem.attr(_Unicode(decreaseAnglePerWheel));
+ lLog << MSG::DEBUG << "Making wheel with inner, outer radii " << ri << ", " << ro << std:: endl;
+ lLog << MSG::DEBUG << "Blade angle is " << BladeAngle << "; decrease angle per wheel? " << decreaseAnglePerWheel << endmsg;
+ dd4hep::xml::Dimension dim(aXmlElement.child(_Unicode(dimensions)));
+ double grmin = dim.rmin1();
+ lLog << MSG::DEBUG << "delZ is " << delZ << endmsg;
+ if (decreaseAnglePerWheel) {
+ float tubeFracCovered = delZ/(2*grmin*TMath::Tan(BladeAngle));
+ BladeAngle = TMath::ATan(delZ/(2*ri*tubeFracCovered));
+ }
+
+ if (TMath::Abs(TMath::Tan(BladeAngle)) < delZ/(2.*ri)) {
+ lLog << MSG::ERROR << "The requested blade angle is too small for the given delZ and ri values. Please adjust to at least " << TMath::ATan(delZ/(2.*ri))*180./TMath::Pi() << " degrees!" << endmsg;
+ return;
+ }
+
+ Float_t xRange = delZ/(TMath::Sin(BladeAngle));
+
+ double delrPhiNoGap;
+
+ float GlueThick = glueElem.attr(_Unicode(thickness));
+ float CladdingThick = claddingElem.attr(_Unicode(thickness));
+ float AbsThickMin = absBladeElem.attr(_Unicode(thickness))-(GlueThick+CladdingThick);
+ if (AbsThickMin < 0.) {
+ lLog << MSG::ERROR << "Error: requested absorber thickness is negative after accounting for glue and cladding thickness" << endmsg;
+ }
+ float ElectrodeThick = electrodeBladeElem.attr(_Unicode(thickness));
+ float LArgapi = nobleLiquidElem.attr(_Unicode(gap));
+
+ bool sameNUnitCells = genericBladeElem.attr(_Unicode(sameNUnitCells));
+ auto nUnitCellsStrArr = genericBladeElem.attr(_Unicode(nUnitCells));
+ char* nUnitCellsCStr = strtok(const_cast(nUnitCellsStrArr.c_str()), " ");
+ int nUnitCells = 0;
+ if (!sameNUnitCells) {
+ for (unsigned i = 0; i < iWheel; i++) {
+ nUnitCellsCStr = strtok(NULL, " ");
+ }
+ std::string nUnitCellsStr = nUnitCellsCStr;
+ nUnitCells = std::stoi(nUnitCellsStr);
+ }
+ int nUnitCellsLeastCommonMultiple = genericBladeElem.attr(_Unicode(nUnitCellsLeastCommonMultiple));
+
+ bool scaleBladeThickness = absBladeElem.attr(_Unicode(scaleThickness));
+ float bladeThicknessScaleFactor = absBladeElem.attr(_Unicode(thicknessScaleFactor));
+
+ lLog << MSG::DEBUG << "nUnitCells: " << nUnitCells << endmsg;
+
+ float AbsThicki = AbsThickMin;
+ // make volumes for the noble liquid, electrode, and absorber blades
+ float AbsThicko;
+ if (scaleBladeThickness) {
+ AbsThicko = AbsThicki + bladeThicknessScaleFactor*((ro/ri)-1.)*AbsThicki;
+ } else {
+ AbsThicko = AbsThicki;
+ }
+
+ // Calculate gap thickness at inner layer
+ double circ = 2*TMath::Pi()*ri;
+ double x2 =(AbsThickMin+(GlueThick+CladdingThick)+ElectrodeThick)/TMath::Sin(BladeAngle);
+ double y2 = TMath::Sqrt(ri*ri-x2*x2);
+ double rPhi1 = ri*TMath::Pi()/2.;
+ double rPhi2 = ri*TMath::ATan(y2/x2);
+ delrPhiNoGap = TMath::Abs(rPhi1-rPhi2);
+ double leftoverS = (circ - nUnitCells*delrPhiNoGap);
+ double delrPhiGapOnly = leftoverS/(2*nUnitCells);
+ LArgapi = delrPhiGapOnly*TMath::Sin(BladeAngle);
+ lLog << MSG::DEBUG << "LArGap at inner radius is " << LArgapi << endmsg;
+
+ // now find gap at outer radius
+ circ = 2*TMath::Pi()*ro;
+ x2 = (AbsThicko+GlueThick+CladdingThick+ElectrodeThick)/TMath::Sin(BladeAngle);
+ y2 = TMath::Sqrt(ro*ro-x2*x2);
+ rPhi1 = ro*TMath::Pi()/2.;
+ rPhi2 = ro*TMath::ATan(y2/x2);
+ delrPhiNoGap = TMath::Abs(rPhi1-rPhi2);
+ leftoverS = (circ - nUnitCells*delrPhiNoGap);
+ delrPhiGapOnly = leftoverS/(2*nUnitCells);
+ float LArgapo = delrPhiGapOnly*TMath::Sin(BladeAngle);
+ // LArgapo *= 2.;
+
+ float riLayer = ri;
+
+ std::vector claddingLayerVols;
+ std::vector glueLayerVols;
+ std::vector absBladeLayerVols;
+ std::vector LArTotalLayerVols;
+ std::vector electrodeBladeLayerVols;
+
+
+ dd4hep::Solid passiveShape = buildOneBlade(AbsThicki+GlueThick+CladdingThick, AbsThicko+GlueThick+CladdingThick, xRange, ro, ri, BladeAngle, delZ );
+ dd4hep::Volume passiveVol("passive", passiveShape, aLcdd.material("Air"));
+
+ dd4hep::Solid activeShape = buildOneBlade(ElectrodeThick+LArgapi*2, ElectrodeThick+LArgapo*2, xRange, ro, ri, BladeAngle, delZ);
+ dd4hep::Volume activeVol("active", activeShape, aLcdd.material("Air"));
+
+ unsigned numNonActiveLayers = 1;
+ // check that either all non-active volumes are set to sensitive (for
+ // sampling fraction calculations) or none are (for normal running)
+ bool allNonActiveSensitive = ( claddingElem.isSensitive() &&
+ glueElem.isSensitive() &&
+ absBladeElem.isSensitive() &&
+ electrodeBladeElem.isSensitive() );
+ bool allNonActiveNotSensitive = ( !claddingElem.isSensitive() &&
+ !glueElem.isSensitive() &&
+ !absBladeElem.isSensitive() &&
+ !electrodeBladeElem.isSensitive() );
+ if (allNonActiveSensitive) {
+ numNonActiveLayers = ECalEndcapNumCalibLayers;
+ } else if (allNonActiveNotSensitive) {
+ numNonActiveLayers = 1;
+ } else {
+ lLog << MSG::ERROR << "Some non-active layers are sensitive and others are not -- this is likely a misconfiguration";
+ }
+
+ float delrNonActive = (ro-ri)/numNonActiveLayers;
+ float delrActive = (ro-ri)/ECalEndcapNumCalibLayers;
+
+ for (unsigned iLayer = 0; iLayer < numNonActiveLayers; iLayer++) {
+ float roLayer = riLayer + delrNonActive;
+ lLog << MSG::INFO << "Making layer in inner, outer radii " << riLayer << " " << roLayer << endmsg;
+
+ if (scaleBladeThickness) {
+ AbsThicko = AbsThicki + bladeThicknessScaleFactor*((roLayer/riLayer)-1.)*AbsThicki;
+ } else {
+ AbsThicko = AbsThicki;
+ }
+ lLog << MSG::DEBUG << "Inner and outer absorber thicknesses " << AbsThicki << " " << AbsThicko << endmsg;
+ dd4hep::Solid claddingLayer = buildOneBlade(AbsThicki+GlueThick+CladdingThick, AbsThicko+GlueThick+CladdingThick, xRange, roLayer, riLayer, BladeAngle, delZ );
+
+ dd4hep::Solid glueLayer = buildOneBlade(AbsThicki+GlueThick, AbsThicko+GlueThick, xRange, roLayer, riLayer, BladeAngle, delZ );
+
+ // dd4hep::SubtractionSolid claddingLayer(absGlueCladdingLayer, absGlueLayer);
+ dd4hep::Solid absBladeLayer = buildOneBlade(AbsThicki, AbsThicko, xRange, roLayer, riLayer, BladeAngle, delZ );
+
+ // dd4hep::SubtractionSolid glueLayer(absGlueLayer, absBladeLayer);
+ dd4hep::Volume claddingLayerVol("claddingLayer", claddingLayer, aLcdd.material(claddingElem.materialStr()));
+ if (claddingElem.isSensitive()) {
+ claddingLayerVol.setSensitiveDetector(aSensDet);
+ }
+ claddingLayerVols.push_back(claddingLayerVol);
+
+ dd4hep::Volume glueLayerVol("glueLayer", glueLayer, aLcdd.material(glueElem.materialStr()));
+ if (glueElem.isSensitive()) {
+ glueLayerVol.setSensitiveDetector(aSensDet);
+ }
+ glueLayerVols.push_back(glueLayerVol);
+
+ dd4hep::Volume absBladeLayerVol("absBladeLayer", absBladeLayer, aLcdd.material(absBladeElem.materialStr()));
+ if (absBladeElem.isSensitive()) {
+ absBladeLayerVol.setSensitiveDetector(aSensDet);
+ }
+ absBladeLayerVols.push_back(absBladeLayerVol);
+
+ riLayer = roLayer;
+ AbsThicki = AbsThicko;
+ }
+
+ riLayer = ri;
+
+ AbsThicki = AbsThickMin;
+
+ for (unsigned iLayer = 0; iLayer < ECalEndcapNumCalibLayers; iLayer++) {
+
+ float roLayer = riLayer + delrActive;
+
+ if (scaleBladeThickness) {
+ AbsThicko = AbsThicki + bladeThicknessScaleFactor*((roLayer/riLayer)-1.)*AbsThicki;
+ } else {
+ AbsThicko = AbsThicki;
+ }
+
+
+ // now find gap at outer layer
+ circ = 2*TMath::Pi()*roLayer;
+ x2 = (AbsThicko+GlueThick+CladdingThick+ElectrodeThick)/TMath::Sin(BladeAngle);
+ y2 = TMath::Sqrt(roLayer*roLayer-x2*x2);
+ rPhi1 = roLayer*TMath::Pi()/2.;
+ rPhi2 = roLayer*TMath::ATan(y2/x2);
+ delrPhiNoGap = TMath::Abs(rPhi1-rPhi2);
+ leftoverS = (circ - nUnitCells*delrPhiNoGap);
+ delrPhiGapOnly = leftoverS/(2*nUnitCells);
+ LArgapo = delrPhiGapOnly*TMath::Sin(BladeAngle);
+ lLog << MSG::DEBUG << "Outer LAr gap is " << LArgapo << endmsg ;
+ lLog << MSG::INFO << "Inner and outer thicknesses of noble liquid volume " << ElectrodeThick+LArgapi*2 << " " << ElectrodeThick+LArgapo*2 << endmsg;
+
+ dd4hep::Solid electrodeBladeAndGapLayer = buildOneBlade(ElectrodeThick+LArgapi*2, ElectrodeThick+LArgapo*2, xRange, roLayer, riLayer, BladeAngle, delZ);
+
+ dd4hep::Solid electrodeBladeLayer = buildOneBlade(ElectrodeThick, ElectrodeThick, xRange, roLayer, riLayer, BladeAngle, delZ);
+
+ dd4hep::Volume electrodeBladeLayerVol("electrodeBladeLayer", electrodeBladeLayer, aLcdd.material(electrodeBladeElem.materialStr()));
+ if (electrodeBladeElem.isSensitive()) {
+ electrodeBladeLayerVol.setSensitiveDetector(aSensDet);
+ }
+ electrodeBladeLayerVols.push_back(electrodeBladeLayerVol);
+
+ // dd4hep::SubtractionSolid LArShapeTotalLayer(electrodeBladeAndGapLayer, electrodeBladeLayer);
+ dd4hep::Volume LArTotalLayerVol("LArTotalLayerVol", electrodeBladeAndGapLayer, aLcdd.material(nobleLiquidElem.materialStr()));
+
+ if ( nobleLiquidElem.isSensitive() ) {
+ LArTotalLayerVol.setSensitiveDetector(aSensDet);
+ }
+ LArTotalLayerVols.push_back(LArTotalLayerVol);
+
+ riLayer = roLayer;
+ LArgapi = LArgapo;
+ AbsThicki = AbsThicko;
+ }
+ lLog << MSG::INFO << "ECal endcap materials: nobleLiquid: " << nobleLiquidElem.materialStr() << " absorber: " << absBladeElem.materialStr() << " electrode: " << electrodeBladeElem.materialStr() << endmsg;
+
+ int nUnitCellsToDraw = nUnitCells;
+ // nUnitCellsToDraw = 2;
+
+ lLog << MSG::INFO << "Number of unit cells "<< nUnitCells << endmsg;
+
+ // place all components of the absorber blade inside passive volume
+
+ unsigned iLayer = 0;
+
+ riLayer = ri;
+
+ for (auto absBladeLayerVol: absBladeLayerVols) {
+
+ float roLayer = riLayer+delrNonActive;
+
+ dd4hep::Position posLayer(0,0,(riLayer-ri+roLayer-ro)/2.);
+ dd4hep::PlacedVolume absBladeVol_pv = glueLayerVols[iLayer].placeVolume(absBladeLayerVol, posLayer);
+
+ absBladeVol_pv.addPhysVolID("subtype", 0); // 0 = absorber, 1 = glue, 2 = cladding
+ lLog << MSG::DEBUG << "Blade layer, rho is " << iLayer << " " << absBladeVol_pv.position().Rho() << " " << roLayer/2. << endmsg;
+ absBladeVol_pv.addPhysVolID("layer", iWheel*numNonActiveLayers+iLayer);
+
+ riLayer = roLayer;
+ iLayer++;
+ }
+
+ riLayer = ri;
+ iLayer =0;
+
+ for (auto glueLayerVol: glueLayerVols) {
+
+ float roLayer = riLayer+delrNonActive;
+
+ dd4hep::Position posLayer(0,0,(riLayer-ri+roLayer-ro)/2.);
+ dd4hep::PlacedVolume glueVol_pv = claddingLayerVols[iLayer].placeVolume(glueLayerVol, posLayer);
+
+
+ glueVol_pv.addPhysVolID("subtype", 1); // 0 = absorber, 1 = glue, 2 = cladding
+ glueVol_pv.addPhysVolID("layer", iWheel*numNonActiveLayers+iLayer);
+
+ // dd4hep::DetElement glueDetElem(passiveDetElem, "glue_",ECalEndCapElementCounter++);
+ // glueDetElem.setPlacement(glueVol_pv);
+
+ riLayer = roLayer;
+ iLayer++;
+ }
+
+ riLayer = ri;
+ iLayer =0;
+
+ double zminri = getZmin(ri, BladeAngle, delZ);
+
+ for (auto claddingLayerVol: claddingLayerVols) {
+
+ float roLayer = riLayer+delrNonActive;
+
+ double zminLayer = getZmin(riLayer, BladeAngle, delZ);
+
+ dd4hep::Position posLayer(0,0,(zminLayer-zminri+roLayer-ro)/2.);
+ dd4hep::PlacedVolume claddingVol_pv = passiveVol.placeVolume(claddingLayerVol, posLayer);
+
+ claddingVol_pv.addPhysVolID("subtype", 2); // 0 = absorber, 1 = glue, 2 = cladding
+ claddingVol_pv.addPhysVolID("layer", iWheel*numNonActiveLayers+iLayer);
+
+ // dd4hep::DetElement claddingDetElem(passiveDetElem, "cladding_", ECalEndCapElementCounter++);
+ // claddingDetElem.setPlacement(claddingVol_pv);
+
+ riLayer = roLayer;
+ iLayer++;
+ }
+
+
+ riLayer = ri;
+ iLayer = 0;
+
+ for (auto electrodeBladeLayerVol: electrodeBladeLayerVols) {
+
+ float roLayer = riLayer+delrActive;
+
+ dd4hep::PlacedVolume electrodeBladeVol_pv = LArTotalLayerVols[iLayer].placeVolume(electrodeBladeLayerVol);
+ electrodeBladeVol_pv.addPhysVolID("layer", iWheel*numNonActiveLayers+iLayer);
+
+ riLayer = roLayer;
+ iLayer++;
+ }
+
+ riLayer = ri;
+ iLayer = 0;
+
+ for (auto LArTotalLayerVol: LArTotalLayerVols) {
+
+ float roLayer = riLayer+delrActive;
+
+ double zminLayer = getZmin(riLayer, BladeAngle, delZ);
+
+ dd4hep::Position posLayer(0,0,(zminLayer-zminri+roLayer-ro)/2.);
+ std::cout << "for active, riLayer, ri, roLayer, ro = " << riLayer << " " << ri << " " << roLayer << " " << ro << std::endl;
+
+ dd4hep::PlacedVolume LArVol_pv(activeVol.placeVolume(LArTotalLayerVol, posLayer));
+ lLog << MSG::DEBUG << "LAr layer: " << iLayer << endmsg;
+ LArVol_pv.addPhysVolID("layer", iWheel*ECalEndcapNumCalibLayers+iLayer);
+
+ riLayer = roLayer;
+ iLayer++;
+ }
+
+ for (int iUnitCell = 0; iUnitCell < nUnitCellsToDraw; iUnitCell++) {
+
+ int modIndex = iUnitCell-nUnitCellsToDraw/2;
+ if (modIndex < 0) modIndex += nUnitCells;
+ float phi = (iUnitCell-nUnitCellsToDraw/2)*2*TMath::Pi()/nUnitCells;
+ float delPhi = 2*TMath::Pi()/nUnitCells;
+
+ lLog << MSG::DEBUG << "Placing blade, ro, ri = " << ro << " " << ri << endmsg;
+ TGeoRotation tgr;
+ tgr.RotateZ(BladeAngle*180/TMath::Pi());
+ tgr.RotateX(-phi*180/TMath::Pi());
+ tgr.RotateY(90);
+
+ const Double_t *rotMatPtr;
+
+ rotMatPtr = tgr.GetRotationMatrix();
+ TMatrixT rotMat(3,3, rotMatPtr);
+ dd4hep::Rotation3D r3d;
+ r3d.SetComponents(rotMat(0,0), rotMat(0,1), rotMat(0,2),
+ rotMat(1,0), rotMat(1,1), rotMat(1,2),
+ rotMat(2,0), rotMat(2,1), rotMat(2,2));
+
+ tgr.Clear();
+ tgr.RotateZ(BladeAngle*180/TMath::Pi());
+ tgr.RotateX(-(phi+delPhi/2.)*180/TMath::Pi());
+ tgr.RotateY(90);
+
+ rotMatPtr = tgr.GetRotationMatrix();
+ TMatrixT rotMat2(3,3, rotMatPtr);
+ dd4hep::Rotation3D r3d2;
+ r3d2.SetComponents(rotMat2(0,0), rotMat2(0,1), rotMat2(0,2),
+ rotMat2(1,0), rotMat2(1,1), rotMat2(1,2),
+ rotMat2(2,0), rotMat2(2,1), rotMat2(2,2));
+
+ riLayer = ri;
+
+ float xCell = ((ro+zminri)/2.)*TMath::Cos(phi);
+ float yCell = ((ro+zminri)/2.)*TMath::Sin(phi); //ri*TMath::Sin(phi)/6.;
+ float zCell = 0.;
+
+ dd4hep::Transform3D comCell(r3d, dd4hep::Translation3D(xCell,yCell,zCell));
+
+ // place passive volume in LAr bath
+ dd4hep::PlacedVolume passivePhysVol = aEnvelope.placeVolume(passiveVol, comCell);
+ passivePhysVol.addPhysVolID("module", modIndex*nUnitCellsLeastCommonMultiple/nUnitCells);
+ passivePhysVol.addPhysVolID("wheel", iWheel);
+ passivePhysVol.addPhysVolID("type", 1); // 0 = active, 1 = passive, 2 = readout
+ dd4hep::DetElement passiveDetElem(bathDetElem, "passive_" + std::to_string(iUnitCell)+"_"+std::to_string(iWheel), ECalEndCapElementCounter++);
+ passiveDetElem.setPlacement(passivePhysVol);
+
+ // place active volume in LAr bath
+
+ xCell = ((ro+zminri)/2.)*TMath::Cos(phi+delPhi/2.);
+ yCell = ((ro+zminri)/2.)*TMath::Sin(phi+delPhi/2.); //ri*TMath::Sin(phi)/6.;
+ zCell = 0.;
+ dd4hep::Transform3D comCell2(r3d2, dd4hep::Translation3D(xCell,yCell,zCell));
+ dd4hep::PlacedVolume activePhysVol = aEnvelope.placeVolume(activeVol, comCell2);
+ activePhysVol.addPhysVolID("module", modIndex*nUnitCellsLeastCommonMultiple/nUnitCells);
+ activePhysVol.addPhysVolID("wheel", iWheel);
+ activePhysVol.addPhysVolID("type", 0); // 0 = active, 1 = passive, 2 = readout
+
+ dd4hep::DetElement activeDetElem(bathDetElem, "active_" + std::to_string(iUnitCell)+"_"+std::to_string(iWheel), ECalEndCapElementCounter++);
+ activeDetElem.setPlacement(activePhysVol);
+
+ riLayer = ri;
+ iLayer =0;
+
+
+
+ lLog << MSG::DEBUG << "LArTotalLayerVols.size = " << LArTotalLayerVols.size() << endmsg;
+
+ }
+
+ return;
+
+ }
+
+ void buildOneSide_Turbine(dd4hep::Detector& aLcdd, dd4hep::SensitiveDetector& aSensDet,
+ dd4hep::Volume& aEnvelope, dd4hep::xml::Handle_t& aXmlElement,
+ unsigned& iModule) {
+
+ dd4hep::xml::DetElement calo = aXmlElement.child(_Unicode(calorimeter));
+ dd4hep::xml::Dimension caloDim(calo.dimensions());
+
+
+ dd4hep::xml::DetElement blade = calo.child(_Unicode(turbineBlade));
+ dd4hep::xml::DetElement nobleLiquid = blade.child(_Unicode(nobleLiquidGap));
+
+ dd4hep::xml::DetElement xmlDetElem = aXmlElement;
+ std::string nameDet = xmlDetElem.nameStr();
+ dd4hep::DetElement caloDetElem(nameDet, xmlDetElem.id());
+
+ dd4hep::xml::Dimension dim(aXmlElement.child(_Unicode(dimensions)));
+
+ //build cryostat
+// Retrieve cryostat data
+ dd4hep::xml::DetElement cryostat = calo.child(_Unicode(cryostat));
+ dd4hep::xml::Dimension cryoDim(cryostat.dimensions());
+ double cryoThicknessFront = cryoDim.rmin2() - cryoDim.rmin1();
+
+ dd4hep::xml::DetElement cryoFront = cryostat.child(_Unicode(front));
+ dd4hep::xml::DetElement cryoBack = cryostat.child(_Unicode(back));
+ dd4hep::xml::DetElement cryoSide = cryostat.child(_Unicode(side));
+ bool cryoFrontSensitive = cryoFront.isSensitive();
+ bool cryoBackSensitive = cryoBack.isSensitive();
+ bool cryoSideSensitive = cryoSide.isSensitive();
+
+ double bathRmin = caloDim.rmin(); // - margin for inclination
+ double bathRmax = caloDim.rmax(); // + margin for inclination
+ double bathDelZ = caloDim.dz();
+ dd4hep::Tube bathOuterShape(bathRmin, bathRmax, bathDelZ); // make it 4 volumes + 5th for detector envelope
+ dd4hep::Tube bathAndServicesOuterShape(cryoDim.rmin2(), cryoDim.rmax1(), caloDim.dz()); // make it 4 volumes + 5th for detector envelope
+
+ lLog << MSG::INFO << "Cryostat front thickness is " << cryoDim.rmin2() << endmsg;
+ if (cryoThicknessFront > 0) {
+ // 1. Create cryostat
+ dd4hep::Tube cryoFrontShape(cryoDim.rmin1(), cryoDim.rmin2(), cryoDim.dz());
+ dd4hep::Tube cryoBackShape(cryoDim.rmax1(), cryoDim.rmax2(), cryoDim.dz());
+ dd4hep::Tube cryoSideOuterShape(cryoDim.rmin2(), cryoDim.rmax1(), cryoDim.dz());
+ dd4hep::SubtractionSolid cryoSideShape(cryoSideOuterShape, bathAndServicesOuterShape);
+ lLog << MSG::INFO << "ECAL endcap cryostat: front: rmin (cm) = " << cryoDim.rmin1() << " rmax (cm) = " << cryoDim.rmin2() << " dz (cm) = " << cryoDim.dz() << endmsg;
+ lLog << MSG::INFO << "ECAL encdap cryostat: back: rmin (cm) = " << cryoDim.rmax1() << " rmax (cm) = " << cryoDim.rmax2() << " dz (cm) = " << cryoDim.dz() << endmsg;
+ lLog << MSG::INFO << "ECAL endcap cryostat: side: rmin (cm) = " << cryoDim.rmin2() << " rmax (cm) = " << cryoDim.rmax1() << " dz (cm) = " << cryoDim.dz() - caloDim.dz() << endmsg;
+ lLog << MSG::INFO << "Cryostat is made out of " << cryostat.materialStr() << endmsg;
+
+ dd4hep::Volume cryoFrontVol(cryostat.nameStr()+"_front", cryoFrontShape, aLcdd.material(cryostat.materialStr()));
+ dd4hep::Volume cryoBackVol(cryostat.nameStr()+"_back", cryoBackShape, aLcdd.material(cryostat.materialStr()));
+ dd4hep::Volume cryoSideVol(cryostat.nameStr()+"_side", cryoSideShape, aLcdd.material(cryostat.materialStr()));
+ dd4hep::PlacedVolume cryoFrontPhysVol = aEnvelope.placeVolume(cryoFrontVol);
+ dd4hep::PlacedVolume cryoBackPhysVol = aEnvelope.placeVolume(cryoBackVol);
+ dd4hep::PlacedVolume cryoSidePhysVol = aEnvelope.placeVolume(cryoSideVol);
+ unsigned sidetype = 0x4; // probably not needed anymore...
+ if (cryoFrontSensitive) {
+ cryoFrontVol.setSensitiveDetector(aSensDet);
+ cryoFrontPhysVol.addPhysVolID("cryo", 1);
+ cryoFrontPhysVol.addPhysVolID("type", sidetype+1);
+ lLog << MSG::INFO << "Cryostat front volume set as sensitive" << endmsg;
+ }
+ if (cryoBackSensitive) {
+ cryoBackVol.setSensitiveDetector(aSensDet);
+ cryoBackPhysVol.addPhysVolID("cryo", 1);
+ cryoBackPhysVol.addPhysVolID("type", sidetype+2);
+ lLog << MSG::INFO << "Cryostat back volume set as sensitive" << endmsg;
+ }
+ if (cryoSideSensitive) {
+ cryoSideVol.setSensitiveDetector(aSensDet);
+ cryoSidePhysVol.addPhysVolID("cryo", 1);
+ cryoSidePhysVol.addPhysVolID("type", sidetype+3);
+ lLog << MSG::INFO << "Cryostat front volume set as sensitive" << endmsg;
+ }
+ dd4hep::DetElement cryoFrontDetElem(caloDetElem, "cryo_front", 0);
+ cryoFrontDetElem.setPlacement(cryoFrontPhysVol);
+ dd4hep::DetElement cryoBackDetElem(caloDetElem, "cryo_back", 0);
+ cryoBackDetElem.setPlacement(cryoBackPhysVol);
+ dd4hep::DetElement cryoSideDetElem(caloDetElem, "cryo_side", 0);
+ cryoSideDetElem.setPlacement(cryoSidePhysVol);
+ }
+
+ // 2. Create noble liquid bath
+ std::string nobleLiquidMaterial = nobleLiquid.materialStr();
+ dd4hep::Volume bathVol(nobleLiquidMaterial + "_bath", bathOuterShape, aLcdd.material(nobleLiquidMaterial));
+ lLog << MSG::INFO << "ECAL endcap bath: material = " << nobleLiquidMaterial << " rmin (cm) = " << bathRmin
+ << " rmax (cm) = " << bathRmax << " dz (cm) = " << caloDim.dz() << " thickness in front of ECal (cm) = " << caloDim.rmin() - cryoDim.rmin2()
+ << " thickness behind ECal (cm) = " << cryoDim.rmax1() - caloDim.rmax() << endmsg;
+ dd4hep::DetElement bathDetElem(caloDetElem, "bath", 1);
+
+ // 3. Create detector structure
+ double length = dim.dz() * 2.;
+ double zOffsetEnvelope = -length / 2.;
+
+ dd4hep::xml::DetElement supportTubeElem = calo.child(_Unicode(supportTube));
+ unsigned nWheels = supportTubeElem.attr(_Unicode(nWheels));
+ lLog << MSG::INFO << "Will build " << nWheels << " wheels" << endmsg;
+ double rmin = bathRmin;
+ double rmax = bathRmax;
+ float radiusRatio = pow(rmax/rmin, 1./nWheels);
+ double ro = rmin*radiusRatio;
+ double ri = rmin;
+
+ float supportTubeThickness=supportTubeElem.thickness();
+
+ for (unsigned iWheel = 0; iWheel < nWheels; iWheel++) {
+
+ dd4hep::Tube supportTube(ro, ro+supportTubeThickness, bathDelZ );
+
+ dd4hep::Volume supportTubeVol("supportTube", supportTube, aLcdd.material(supportTubeElem.materialStr()));
+ if (supportTubeElem.isSensitive()) {
+ supportTubeVol.setSensitiveDetector(aSensDet);
+ }
+ dd4hep::PlacedVolume supportTube_pv = bathVol.placeVolume(supportTubeVol, dd4hep::Position(0,0,zOffsetEnvelope + dim.dz() ));
+ supportTube_pv.addPhysVolID("cryo", 1);
+ // supportTube_pv.addPhysVolID("side",sign);
+ supportTube_pv.addPhysVolID("wheel", iWheel);
+ dd4hep::DetElement supportTubeDetElem(bathDetElem, "supportTube_"+std::to_string(iWheel), 0);
+ supportTubeDetElem.setPlacement(supportTube_pv);
+
+
+ buildWheel(aLcdd, aSensDet, bathVol, aXmlElement, bathDetElem, ri+supportTubeThickness, ro, bathDelZ*2, iWheel);
+ ri = ro;
+ ro *= radiusRatio;
+ if (ro > rmax) ro = rmax;
+ }
+
+
+ dd4hep::PlacedVolume bathPhysVol = aEnvelope.placeVolume(bathVol);
+ bathDetElem.setPlacement(bathPhysVol);
+
+ lLog << MSG::DEBUG << "Total number of modules: " << iModule << endmsg;
+
+ return;
+}
+
+
+
+ static dd4hep::Ref_t
+createECalEndcapTurbine(dd4hep::Detector& aLcdd, dd4hep::xml::Handle_t aXmlElement, dd4hep::SensitiveDetector aSensDet) {
+
+ dd4hep::xml::DetElement xmlDetElem = aXmlElement;
+ std::string nameDet = xmlDetElem.nameStr();
+ int idDet = xmlDetElem.id();
+ dd4hep::xml::Dimension dim(xmlDetElem.dimensions());
+ dd4hep::DetElement caloDetElem(nameDet, idDet);
+ dd4hep::xml::Dimension sdType = xmlDetElem.child(_U(sensitive));
+ aSensDet.setType(sdType.typeStr());
+
+ ECalEndcapNumCalibLayers = aLcdd.constant("ECalEndcapNumCalibLayers");
+
+
+ // Create air envelope for one endcap (will be copied to make both endcaps)
+ dd4hep::Tube endcapShape( dim.rmin1(), dim.rmax1(), dim.dz());
+
+ dd4hep::Volume envelopeVol(nameDet + "_vol", endcapShape, aLcdd.material("Air"));
+
+
+ // dd4hep::DetElement caloPositiveDetElem(caloDetElem, "positive", 0);
+ // dd4hep::DetElement caloNegativeDetElem(caloDetElem, "negative", 0);
+
+ lLog << MSG::DEBUG << "Placing dector on the positive side: (cm) " << dim.z_offset() << " with min, max radii " << dim.rmin1() << " " << dim.rmax1() << endmsg;
+ unsigned iModule = 0;
+ buildOneSide_Turbine(aLcdd, aSensDet, envelopeVol, aXmlElement, iModule);
+ // lLog << MSG::DEBUG << "Placing dector on the negative side: (cm) " << -dim.z_offset() << " with min, max radii " << dim.rmin1() << " " << dim.rmax() << endmsg;
+ // buildOneSide_Turbine(aLcdd, aSensDet, envelopeNegativeVol, aXmlElement, -1, iModule);
+
+ dd4hep::Assembly endcapsAssembly("ECalEndcaps_turbine");
+
+ // Place the envelope
+ dd4hep::Transform3D envelopePositiveVolume_tr(dd4hep::RotationZYX( 0 ,0,0), dd4hep::Translation3D(0, 0, dim.z_offset()));
+ dd4hep::PlacedVolume envelopePositivePhysVol = endcapsAssembly.placeVolume(envelopeVol, envelopePositiveVolume_tr);
+ envelopePositivePhysVol.addPhysVolID("side", 1);
+
+ dd4hep::DetElement caloPositiveDetElem(caloDetElem, "positive", 0);
+ caloPositiveDetElem.setPlacement(envelopePositivePhysVol);
+
+ // make another placement for the negative z endcap
+ dd4hep::Transform3D envelopeNegativeVolume_tr(dd4hep::RotationZYX( 0 ,0,180*dd4hep::deg), dd4hep::Translation3D(0, 0, -dim.z_offset()));
+ dd4hep::PlacedVolume envelopeNegativePhysVol =
+ endcapsAssembly.placeVolume(envelopeVol, envelopeNegativeVolume_tr);
+ envelopeNegativePhysVol.addPhysVolID("side", -1);
+
+ dd4hep::DetElement caloNegativeDetElem(caloDetElem, "negative", 0);
+ caloNegativeDetElem.setPlacement(envelopeNegativePhysVol);
+
+ dd4hep::Volume motherVol = aLcdd.pickMotherVolume(caloDetElem);
+ dd4hep::PlacedVolume envelopePhysVol = motherVol.placeVolume(endcapsAssembly);
+ caloDetElem.setPlacement(envelopePhysVol);
+ envelopePhysVol.addPhysVolID("system", idDet);
+ return caloDetElem;
+}
+} // namespace det
+
+DECLARE_DETELEMENT(ECalEndcap_Turbine_o1_v01, det::createECalEndcapTurbine)
diff --git a/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp b/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp
index f27941378..b08119890 100644
--- a/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp
+++ b/detector/calorimeter/ECalEndcap_o1_v01_geo.cpp
@@ -12,9 +12,7 @@
//=========================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "TMath.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/ECalPlug_o1_v01_geo.cpp b/detector/calorimeter/ECalPlug_o1_v01_geo.cpp
index be6b57242..ea9791421 100644
--- a/detector/calorimeter/ECalPlug_o1_v01_geo.cpp
+++ b/detector/calorimeter/ECalPlug_o1_v01_geo.cpp
@@ -12,9 +12,6 @@
//=========================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
-#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
using namespace std;
diff --git a/detector/calorimeter/Hcal_BarrelSD_v00.cpp b/detector/calorimeter/Hcal_BarrelSD_v00.cpp
index 8ee66e3e2..d64b308cc 100644
--- a/detector/calorimeter/Hcal_BarrelSD_v00.cpp
+++ b/detector/calorimeter/Hcal_BarrelSD_v00.cpp
@@ -8,10 +8,7 @@
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "XML/Layering.h"
#include "XML/Utilities.h"
-#include "DDRec/DetectorData.h"
-#include "LcgeoExceptions.h"
using namespace std;
diff --git a/detector/calorimeter/Hcal_Barrel_SD_v01.cpp b/detector/calorimeter/Hcal_Barrel_SD_v01.cpp
index 8da93799f..feb38eb70 100644
--- a/detector/calorimeter/Hcal_Barrel_SD_v01.cpp
+++ b/detector/calorimeter/Hcal_Barrel_SD_v01.cpp
@@ -5,10 +5,8 @@
// $Id: $
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "XML/Layering.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
-#include "LcgeoExceptions.h"
using namespace std;
diff --git a/detector/calorimeter/Hcal_Barrel_SD_v02.cpp b/detector/calorimeter/Hcal_Barrel_SD_v02.cpp
index f186dba6c..acc3ff518 100644
--- a/detector/calorimeter/Hcal_Barrel_SD_v02.cpp
+++ b/detector/calorimeter/Hcal_Barrel_SD_v02.cpp
@@ -5,10 +5,8 @@
// $Id: $
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "XML/Layering.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
-#include "LcgeoExceptions.h"
using namespace std;
diff --git a/detector/calorimeter/Hcal_EndcapRing_SD_v01.cpp b/detector/calorimeter/Hcal_EndcapRing_SD_v01.cpp
index 97ade488f..620ad7ac6 100644
--- a/detector/calorimeter/Hcal_EndcapRing_SD_v01.cpp
+++ b/detector/calorimeter/Hcal_EndcapRing_SD_v01.cpp
@@ -41,7 +41,6 @@
*/
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
#include "DD4hep/Shapes.h"
#include "XML/Utilities.h"
diff --git a/detector/calorimeter/Hcal_Endcaps_SD_v01.cpp b/detector/calorimeter/Hcal_Endcaps_SD_v01.cpp
index 9243c7555..203298ae7 100644
--- a/detector/calorimeter/Hcal_Endcaps_SD_v01.cpp
+++ b/detector/calorimeter/Hcal_Endcaps_SD_v01.cpp
@@ -42,7 +42,6 @@
*/
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
#include "DD4hep/Shapes.h"
#include "XML/Utilities.h"
diff --git a/detector/calorimeter/Hcal_Endcaps_SD_v02.cpp b/detector/calorimeter/Hcal_Endcaps_SD_v02.cpp
index 36bf73289..b9633d400 100644
--- a/detector/calorimeter/Hcal_Endcaps_SD_v02.cpp
+++ b/detector/calorimeter/Hcal_Endcaps_SD_v02.cpp
@@ -34,7 +34,6 @@
// ²
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/README.md b/detector/calorimeter/README.md
index 3bcd9a375..ddb6a0b1b 100644
--- a/detector/calorimeter/README.md
+++ b/detector/calorimeter/README.md
@@ -22,6 +22,13 @@ This sub-detector makes calorimeter endcaps (original and reflected). It is used
### o1_v01
Original version taken from [FCCDetectors](https://github.com/HEP-FCC/FCCDetectors/blob/70a989a6fc333610e3b1b979c3596da9c41543d8/Detector/DetFCChhCalDiscs/src/CaloEndcapDiscs_geo.cpp).
+## ECalEndcap_Turbine
+
+Sub-detector for the ecal endcaps, with the absorbers and readout boards arranged in a "turbine-like" geometry.
+
+### 01_v01
+Initial implementation. A custom segmentation that creates readout cells and constant radius and z is also included (FCCSWEndcapTurbine_k4geo).
+
## HCalTileBarrel
This sub-detector makes calorimeter barrel. It is used in ALLEGRO detector concept.
@@ -35,4 +42,8 @@ This sub-detector makes calorimeter endcaps. Each endcap is made up by three cyl
Original version taken from [FCCDetectors](https://github.com/HEP-FCC/FCCDetectors/blob/70a989a6fc333610e3b1b979c3596da9c41543d8/Detector/DetFCCeeHCalTile/src/HCalThreePartsEndcap_geo.cpp#L4).
+## dual-readout
+### o1_v01
+This sub-detector makes full 4-pi monolithic fiber dual-readout calorimeter.
+Inside the single tower (trapezoidal copper absorber), two types of optical fibers (Cherenkov and scintillation) are implemented. The readout (SiPM) is attached at the rear side of the tower. The tower is repeated in both eta and phi direction to cover both barrel and endcap region.
diff --git a/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp b/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp
index bf16d0348..8b89582c9 100644
--- a/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp
+++ b/detector/calorimeter/SECalEndcap_o1_v01_geo.cpp
@@ -10,10 +10,8 @@
//=========================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "DD4hep/DetType.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "TMath.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/SEcal04_Barrel.cpp b/detector/calorimeter/SEcal04_Barrel.cpp
index 0470d9fe7..7f139de1f 100644
--- a/detector/calorimeter/SEcal04_Barrel.cpp
+++ b/detector/calorimeter/SEcal04_Barrel.cpp
@@ -9,9 +9,7 @@
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/SEcal04_Barrel_v01.cpp b/detector/calorimeter/SEcal04_Barrel_v01.cpp
index e97aa5565..5f5ad923b 100644
--- a/detector/calorimeter/SEcal04_Barrel_v01.cpp
+++ b/detector/calorimeter/SEcal04_Barrel_v01.cpp
@@ -9,9 +9,7 @@
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/SEcal04_ECRing.cpp b/detector/calorimeter/SEcal04_ECRing.cpp
index c5e8aa414..599ebf117 100644
--- a/detector/calorimeter/SEcal04_ECRing.cpp
+++ b/detector/calorimeter/SEcal04_ECRing.cpp
@@ -37,7 +37,6 @@
*/
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/SEcal05_Barrel.cpp b/detector/calorimeter/SEcal05_Barrel.cpp
index a0329b4e2..220e73f81 100644
--- a/detector/calorimeter/SEcal05_Barrel.cpp
+++ b/detector/calorimeter/SEcal05_Barrel.cpp
@@ -9,16 +9,12 @@
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
-#include "DDSegmentation/MegatileLayerGridXY.h"
-#include "DDSegmentation/WaferGridXY.h"
#include "SEcal05_Helpers.h"
diff --git a/detector/calorimeter/SEcal05_ECRing.cpp b/detector/calorimeter/SEcal05_ECRing.cpp
index 186ad7605..69f53be00 100644
--- a/detector/calorimeter/SEcal05_ECRing.cpp
+++ b/detector/calorimeter/SEcal05_ECRing.cpp
@@ -73,7 +73,6 @@ Start ECRing ...
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/SEcal05_Endcaps.cpp b/detector/calorimeter/SEcal05_Endcaps.cpp
index a0f4c69ab..ee4bce3e2 100644
--- a/detector/calorimeter/SEcal05_Endcaps.cpp
+++ b/detector/calorimeter/SEcal05_Endcaps.cpp
@@ -40,7 +40,6 @@
#include "DD4hep/Shapes.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
-#include "DDSegmentation/WaferGridXY.h"
#include
using namespace std;
diff --git a/detector/calorimeter/SEcal05_Helpers.h b/detector/calorimeter/SEcal05_Helpers.h
index 80e8e829a..bfea1f4fe 100644
--- a/detector/calorimeter/SEcal05_Helpers.h
+++ b/detector/calorimeter/SEcal05_Helpers.h
@@ -6,9 +6,7 @@
#include "DDRec/DetectorData.h"
#include "XML/Layering.h"
-#include "XML/Utilities.h"
-#include "DD4hep/Segmentations.h"
#include "DDSegmentation/MegatileLayerGridXY.h"
diff --git a/detector/calorimeter/SEcal06_Barrel.cpp b/detector/calorimeter/SEcal06_Barrel.cpp
index 3fcd03362..587ff1dc4 100644
--- a/detector/calorimeter/SEcal06_Barrel.cpp
+++ b/detector/calorimeter/SEcal06_Barrel.cpp
@@ -9,10 +9,8 @@
//====================================================================
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/SEcal06_Helpers.cpp b/detector/calorimeter/SEcal06_Helpers.cpp
index a7b26afd7..10b2a7652 100644
--- a/detector/calorimeter/SEcal06_Helpers.cpp
+++ b/detector/calorimeter/SEcal06_Helpers.cpp
@@ -1,6 +1,5 @@
#include "SEcal06_Helpers.h"
#include "LcgeoExceptions.h"
-#include
#include "DDSegmentation/MegatileLayerGridXY.h"
#include "DDSegmentation/WaferGridXY.h"
diff --git a/detector/calorimeter/SEcal06_Helpers.h b/detector/calorimeter/SEcal06_Helpers.h
index 8ef75ac69..b6734dc85 100644
--- a/detector/calorimeter/SEcal06_Helpers.h
+++ b/detector/calorimeter/SEcal06_Helpers.h
@@ -6,7 +6,6 @@
#include "DDRec/DetectorData.h"
#include "XML/Layering.h"
-#include "XML/Utilities.h"
#include "DD4hep/Segmentations.h"
diff --git a/detector/calorimeter/SHcalSc04_Barrel_v01.cpp b/detector/calorimeter/SHcalSc04_Barrel_v01.cpp
index 9ca44f8f0..51b1251e9 100644
--- a/detector/calorimeter/SHcalSc04_Barrel_v01.cpp
+++ b/detector/calorimeter/SHcalSc04_Barrel_v01.cpp
@@ -6,7 +6,6 @@
//====================================================================
#include "DD4hep/Printout.h"
#include "DD4hep/DetFactoryHelper.h"
-#include "XML/Layering.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/TiledLayerGridXY.h"
diff --git a/detector/calorimeter/SHcalSc04_Barrel_v02.cpp b/detector/calorimeter/SHcalSc04_Barrel_v02.cpp
index 1a82893f0..2159fcef9 100644
--- a/detector/calorimeter/SHcalSc04_Barrel_v02.cpp
+++ b/detector/calorimeter/SHcalSc04_Barrel_v02.cpp
@@ -7,7 +7,6 @@
#include "DD4hep/DetFactoryHelper.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
-#include "LcgeoExceptions.h"
using namespace std;
diff --git a/detector/calorimeter/SHcalSc04_Barrel_v03.cpp b/detector/calorimeter/SHcalSc04_Barrel_v03.cpp
index 72b427b57..64ede1edf 100644
--- a/detector/calorimeter/SHcalSc04_Barrel_v03.cpp
+++ b/detector/calorimeter/SHcalSc04_Barrel_v03.cpp
@@ -9,9 +9,7 @@
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
#include "DDSegmentation/TiledLayerGridXY.h"
-#include "LcgeoExceptions.h"
-#include
#include
using namespace std;
diff --git a/detector/calorimeter/SHcalSc04_EndcapRing.cpp b/detector/calorimeter/SHcalSc04_EndcapRing.cpp
index dbf869a72..82b945de4 100644
--- a/detector/calorimeter/SHcalSc04_EndcapRing.cpp
+++ b/detector/calorimeter/SHcalSc04_EndcapRing.cpp
@@ -35,7 +35,6 @@
*/
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
#include "DD4hep/Shapes.h"
#include "XML/Utilities.h"
diff --git a/detector/calorimeter/SHcalSc04_EndcapRing_v01.cpp b/detector/calorimeter/SHcalSc04_EndcapRing_v01.cpp
index c11a7b2f5..1938c06d7 100644
--- a/detector/calorimeter/SHcalSc04_EndcapRing_v01.cpp
+++ b/detector/calorimeter/SHcalSc04_EndcapRing_v01.cpp
@@ -38,7 +38,6 @@
*/
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DetType.h"
#include "XML/Layering.h"
#include "DD4hep/Shapes.h"
#include "XML/Utilities.h"
diff --git a/detector/calorimeter/Yoke05_Barrel.cpp b/detector/calorimeter/Yoke05_Barrel.cpp
index cae888afc..8fcbb4e9a 100644
--- a/detector/calorimeter/Yoke05_Barrel.cpp
+++ b/detector/calorimeter/Yoke05_Barrel.cpp
@@ -32,7 +32,6 @@
#include "DD4hep/DetFactoryHelper.h"
#include "DD4hep/DetType.h"
#include "XML/Layering.h"
-#include "TGeoTrd2.h"
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/calorimeter/dual-readout/include/DRconstructor.h b/detector/calorimeter/dual-readout/include/DRconstructor.h
new file mode 100644
index 000000000..631576697
--- /dev/null
+++ b/detector/calorimeter/dual-readout/include/DRconstructor.h
@@ -0,0 +1,71 @@
+#ifndef DRconstructor_h
+#define DRconstructor_h 1
+
+#include "detectorSegmentations/GridDRcaloHandle_k4geo.h"
+
+#include "DD4hep/DetFactoryHelper.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 setSensDet(dd4hep::SensitiveDetector* sensDet) {
+ fSensDet = sensDet;
+ fSegmentation = dynamic_cast( sensDet->readout().segmentation().segmentation() );
+ }
+
+ void construct();
+
+ private:
+ void initiateFibers();
+ void implementTowers(xml_comp_t& x_theta, dd4hep::DDSegmentation::DRparamBase_k4geo* param, dd4hep::Volume& AssemblyBoxVol);
+ void placeAssembly(dd4hep::DDSegmentation::DRparamBase_k4geo* param, dd4hep::Volume& AssemblyBoxVol,
+ dd4hep::Volume& towerVol, 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);
+ void implementFiber(dd4hep::Volume& towerVol, dd4hep::Position pos, int col, int row, float fiberLen = 200.*dd4hep::cm);
+ 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_worldTube;
+ xml_comp_t fX_barrelTube;
+ 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::DDSegmentation::GridDRcalo_k4geo* fSegmentation;
+
+ bool fVis;
+ int fNumx, fNumy;
+ std::vector< std::pair > fFiberCoords;
+
+ std::vector< dd4hep::Tube > fFiberEnvVec;
+ std::vector< dd4hep::Tube > fFiberCoreCVec;
+ std::vector< dd4hep::Tube > fFiberCoreSVec;
+ };
+}
+
+#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..c01afa77f
--- /dev/null
+++ b/detector/calorimeter/dual-readout/src/DRconstructor.cpp
@@ -0,0 +1,382 @@
+#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_worldTube( fX_struct.child( _Unicode(worldTube) ) ),
+ fX_barrelTube( fX_struct.child( _Unicode(barrelTube) ) ) {
+ fExperimentalHall = nullptr;
+ fParamBarrel = nullptr;
+ fDescription = nullptr;
+ fDetElement = nullptr;
+ fSensDet = nullptr;
+ fSipmSurf = nullptr;
+ fSegmentation = nullptr;
+ fVis = false;
+ fNumx = 0;
+ fNumy = 0;
+ fFiberCoords.reserve(100000);
+ fFiberEnvVec.reserve(4000);
+ fFiberCoreCVec.reserve(4000);
+ fFiberCoreSVec.reserve(4000);
+}
+
+void ddDRcalo::DRconstructor::construct() {
+ // set vis on/off
+ fVis = fDescription->visAttributes(fX_det.visStr()).showDaughters();
+
+ // Tube to cover all +eta DRC geometry, Rmin = 252 - 1 mm (Rmin in endcap region), Rmax = 4500 + 1 mm, length = 4500 + 1mm
+ dd4hep::Tube WorldTube(fX_worldTube.rmin(), fX_worldTube.rmax(), fX_worldTube.height()/2. );
+ // Tube to be subtracted from Large tube, this is for barrel region, will be subtracted from z = 0 to z = 2500 -1 mm
+ // Rmin = 252 - 1 mm mm, Rmax = 2500 - 1mm, length = 2500 -1 mm
+ dd4hep::Tube BarrelTube(fX_barrelTube.rmin(), fX_barrelTube.rmax(), fX_barrelTube.height()/2.);
+ // Create World assembly tube by subtracting BarrelTube from WorldTube
+ dd4hep::SubtractionSolid AssemblyTube(WorldTube, BarrelTube, dd4hep::Position( 0, 0, -(fX_worldTube.height() - fX_barrelTube.height())/2. ));
+ dd4hep::Volume AssemblyTubeVol("AssemblyTube",AssemblyTube, fDescription->material(fX_worldTube.materialStr()) );
+ AssemblyTubeVol.setVisAttributes(*fDescription, fX_worldTube.visStr());
+ dd4hep::PlacedVolume PlacedAssemblyTubeVol = fExperimentalHall->placeVolume( AssemblyTubeVol, dd4hep::Position( 0, 0, fX_worldTube.height()/2.) );
+ PlacedAssemblyTubeVol.addPhysVolID("assembly", 0); // TODO : Have to update box ID encoding
+
+ initiateFibers();
+
+ implementTowers(fX_barrel, fParamBarrel, AssemblyTubeVol);
+ implementTowers(fX_endcap, fParamEndcap, AssemblyTubeVol);
+
+ if (fX_det.reflect()) {
+ auto refl_pos = dd4hep::Transform3D( dd4hep::RotationZYX(0., 0., M_PI), dd4hep::Position( 0, 0, -(fX_worldTube.height()/2.)) );
+ dd4hep::PlacedVolume PlacedAssemblyTubeVol_refl = fExperimentalHall->placeVolume( AssemblyTubeVol, 1, refl_pos);
+ PlacedAssemblyTubeVol_refl.addPhysVolID("assembly", 1);
+ }
+}
+
+void ddDRcalo::DRconstructor::initiateFibers() {
+ for (int idx = 1; idx <= 4000; idx++) {
+ double length = 0.05*dd4hep::cm * idx; // fiber with length interval of 0.5 mm
+
+ fFiberEnvVec.push_back( dd4hep::Tube (0., fX_cladC.rmax(), length/2. ) );
+ fFiberCoreCVec.push_back( dd4hep::Tube (0., fX_coreC.rmin(), length/2.) );
+ fFiberCoreSVec.push_back( dd4hep::Tube (0., fX_coreS.rmin(), length/2.) );
+ }
+}
+
+void ddDRcalo::DRconstructor::implementTowers(xml_comp_t& x_theta, dd4hep::DDSegmentation::DRparamBase_k4geo* param, dd4hep::Volume& AssemblyBoxVol) {
+ 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;
+
+ // 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 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);
+
+ xml_comp_t x_wafer ( fX_sipmDim.child( _Unicode(sipmWafer) ) );
+
+ // 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);
+ }
+
+ // Remove sipmLayer, clear fFiberCoords instead of implementSipms()
+ fFiberCoords.clear();
+
+ for (int nPhi = 0; nPhi < x_theta.nphi(); nPhi++) {
+ placeAssembly(param,AssemblyBoxVol,towerVol,sipmWaferVol,towerNo,nPhi);
+ }
+ }
+
+ param->filled();
+ param->SetTotTowerNum( towerNo - x_theta.start() );
+}
+
+void ddDRcalo::DRconstructor::placeAssembly(dd4hep::DDSegmentation::DRparamBase_k4geo* param, dd4hep::Volume& AssemblyBoxVol,
+ dd4hep::Volume& towerVol, 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);
+
+ dd4hep::Position towerPos = param->GetTowerPos(nPhi) + dd4hep::Position(0, 0, -(fX_worldTube.height()/2.));
+ AssemblyBoxVol.placeVolume( towerVol, towerId32, dd4hep::Transform3D( param->GetRotationZYX(nPhi), towerPos ) );
+
+ // Remove sipmLayer
+ dd4hep::Position sipmPos = param->GetSipmLayerPos(nPhi) + dd4hep::Position(0, 0, -(fX_worldTube.height()/2.));
+ dd4hep::PlacedVolume sipmWaferPhys = AssemblyBoxVol.placeVolume( sipmWaferVol, towerId32, dd4hep::Transform3D( param->GetRotationZYX(nPhi), sipmPos ) );
+ 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) {
+ 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/2. )/gridSize ) ) + 1; // in phi direction
+ fNumy = static_cast( std::floor( ( param->GetH2()*2. - sipmSize/2. )/gridSize ) ) + 1; // in eta direction
+ int numxBl2 = static_cast( std::floor( ( param->GetBl2()*2. - sipmSize/2. )/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());
+
+ // // Remove cap (mirror or black paint in front of the fiber)
+ implementFiber(unitBoxVol, dd4hep::Position(-gridSize/2.,-gridSize/2.,0.), cmin, rmin );
+ implementFiber(unitBoxVol, dd4hep::Position(gridSize/2.,-gridSize/2.,0.), cmin+1, rmin );
+ implementFiber(unitBoxVol, dd4hep::Position(-gridSize/2.,gridSize/2.,0.), cmin, rmin+1 );
+ implementFiber(unitBoxVol, dd4hep::Position(gridSize/2.,gridSize/2.,0.), cmin+1, rmin+1);
+
+
+ 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, pos, column, row);
+ 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 );
+ implementFiber(towerVol, centerPos, column, row, fiberLen);
+ fFiberCoords.push_back( std::make_pair(column,row) );
+ }
+ }
+ }
+ }
+}
+
+// Remove cap (mirror or black paint in front of the fiber)
+void ddDRcalo::DRconstructor::implementFiber(dd4hep::Volume& towerVol, dd4hep::Position pos, int col, int row, float fiberLen) {
+ // Don't implement fiber if the length required is shorter than 0.5 mm
+ if (fiberLen < 0.05*dd4hep::cm)
+ return;
+
+ int fiberIdx = int( (float) fiberLen / (float) 0.05*dd4hep::cm ) - 1; // index of fiber in fiber vectors
+ // Actual length of fiber to be implemented, quantized in 0.5 mm unit
+ float approxFiberLen = 0.05*dd4hep::cm * (fiberIdx + 1);
+ // Fix Z position of fiber since the length of fiber can differ in [0, 0.5) mm
+ dd4hep::Position fixedPos = dd4hep::Position(pos.x(), pos.y(), pos.z() + (fiberLen - approxFiberLen)/2.);
+
+ if ( fSegmentation->IsCerenkov(col,row) ) { //c fiber
+ dd4hep::Volume cladVol("cladC", fFiberEnvVec.at(fiberIdx), fDescription->material(fX_cladC.materialStr()));
+ towerVol.placeVolume( cladVol, fixedPos );
+
+ if (fVis) cladVol.setVisAttributes(*fDescription, fX_cladC.visStr()); // high CPU consumption!
+
+ dd4hep::Volume coreVol("coreC", fFiberCoreCVec.at(fiberIdx), fDescription->material(fX_coreC.materialStr()));
+ if (fVis) coreVol.setVisAttributes(*fDescription, fX_coreC.visStr());
+ cladVol.placeVolume( coreVol );
+
+ coreVol.setRegion(*fDescription, fX_det.regionStr());
+ cladVol.setRegion(*fDescription, fX_det.regionStr());
+ } else { // s fiber
+ dd4hep::Volume cladVol("cladS", fFiberEnvVec.at(fiberIdx), fDescription->material(fX_coreC.materialStr()));
+ towerVol.placeVolume( cladVol, fixedPos );
+ if (fVis) cladVol.setVisAttributes(*fDescription, fX_coreC.visStr());
+
+ dd4hep::Volume coreVol("coreS", fFiberCoreSVec.at(fiberIdx), fDescription->material(fX_coreS.materialStr()));
+ if (fVis) coreVol.setVisAttributes(*fDescription, fX_coreS.visStr());
+ cladVol.placeVolume( coreVol );
+
+ coreVol.setRegion(*fDescription, fX_det.regionStr());
+ cladVol.setRegion(*fDescription, fX_det.regionStr());
+ }
+}
+
+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..11140c0a5
--- /dev/null
+++ b/detector/calorimeter/dual-readout/src/FiberDualReadoutCalo_o1_v01.cpp
@@ -0,0 +1,72 @@
+#include "detectorSegmentations/DRparamBarrel_k4geo.h"
+#include "detectorSegmentations/DRparamEndcap_k4geo.h"
+
+#include "DRconstructor.h"
+
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/OpticalSurfaces.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");
+ 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.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
diff --git a/detector/fcal/BeamCal_o1_v01_geo.cpp b/detector/fcal/BeamCal_o1_v01_geo.cpp
index c5f660f5e..b7bef1127 100644
--- a/detector/fcal/BeamCal_o1_v01_geo.cpp
+++ b/detector/fcal/BeamCal_o1_v01_geo.cpp
@@ -1,5 +1,4 @@
#include
-#include "DD4hep/DetType.h"
#include
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/fcal/BeamCal_o1_v02_geo.cpp b/detector/fcal/BeamCal_o1_v02_geo.cpp
index 3721299b7..53196e85f 100644
--- a/detector/fcal/BeamCal_o1_v02_geo.cpp
+++ b/detector/fcal/BeamCal_o1_v02_geo.cpp
@@ -1,5 +1,4 @@
#include
-#include "DD4hep/DetType.h"
#include
#include "XML/Utilities.h"
#include "DDRec/DetectorData.h"
diff --git a/detector/muonSystem/muonSystemMuRWELL_o1_v01.cpp b/detector/muonSystem/muonSystemMuRWELL_o1_v01.cpp
index 539f6f8e6..2f4321433 100644
--- a/detector/muonSystem/muonSystemMuRWELL_o1_v01.cpp
+++ b/detector/muonSystem/muonSystemMuRWELL_o1_v01.cpp
@@ -23,10 +23,8 @@ If used with sensitive layers, the readout must contain a "slice" field
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
#include "XML/XMLElements.h"
-#include
-#include
+#include
#include
using namespace std;
@@ -526,7 +524,7 @@ static dd4hep::Ref_t createmuonSystemMuRWELL_o1_v01(dd4hep::Detector& lcdd,
dd4hep::Position detectorLayerTrans(0., 0., 0.);
dd4hep::PlacedVolume detectorLayerPhys = BarrelVolume.placeVolume(BarrelDetectorLayerVolume, dd4hep::Transform3D(dd4hep::RotationZ(0.), detectorLayerTrans));
detectorLayerPhys.addPhysVolID("layer", numBarrelLayer+1);
- dd4hep::DetElement BarrelDetectorLayerDE(BarrelDE, "MSBarrelDetectorLayerDE" + numBarrelLayer+1, numBarrelLayer+1);
+ dd4hep::DetElement BarrelDetectorLayerDE(BarrelDE, "MSBarrel_DetectorLayerDE_" + std::to_string(numBarrelLayer+1), numBarrelLayer+1);
BarrelDetectorLayerDE.setPlacement(detectorLayerPhys);
BarrelDetectorLayerVolume.setVisAttributes(lcdd.visAttributes("no_vis"));
@@ -591,7 +589,7 @@ static dd4hep::Ref_t createmuonSystemMuRWELL_o1_v01(dd4hep::Detector& lcdd,
dd4hep::Position radiatorLayerTrans(0., 0., 0.);
dd4hep::PlacedVolume radiatorLayerPhys = BarrelVolume.placeVolume(BarrelRadiatorLayerVolume, dd4hep::Transform3D(dd4hep::RotationZ(0.), radiatorLayerTrans));
- dd4hep::DetElement BarrelRadiatorLayerDE(BarrelDE, "MSBarrel_RadiatorLayerDE" + numBarrelRadiatorLayer+1, numBarrelRadiatorLayer+1);
+ dd4hep::DetElement BarrelRadiatorLayerDE(BarrelDE, "MSBarrel_RadiatorLayerDE_" + std::to_string(numBarrelRadiatorLayer+1), numBarrelRadiatorLayer+1);
BarrelRadiatorLayerDE.setPlacement(radiatorLayerPhys);
BarrelRadiatorLayerVolume.setVisAttributes(lcdd.visAttributes("no_vis"));
@@ -616,7 +614,7 @@ static dd4hep::Ref_t createmuonSystemMuRWELL_o1_v01(dd4hep::Detector& lcdd,
endcapTrans = dd4hep::Position(0., 0., endcapType * endcapOffset);
endcapPhys = detectorVolume.placeVolume(endcapVolume, dd4hep::Transform3D(dd4hep::RotationZ(0.), endcapTrans));
endcapPhys.addPhysVolID("type", endcapType);
- EndcapDE = dd4hep::DetElement(detElement, "MSEndcapDE" + endcapType , endcapType);
+ EndcapDE = dd4hep::DetElement(detElement, "MSEndcapDE_" + std::to_string(endcapType) , endcapType);
EndcapDE.setPlacement(endcapPhys);
endcapVolume.setVisAttributes(lcdd.visAttributes("no_vis"));
diff --git a/detector/other/Beampipe_o1_v01_geo.cpp b/detector/other/Beampipe_o1_v01_geo.cpp
index 676275a83..b30f77b30 100644
--- a/detector/other/Beampipe_o1_v01_geo.cpp
+++ b/detector/other/Beampipe_o1_v01_geo.cpp
@@ -9,14 +9,10 @@
#include "OtherDetectorHelpers.h"
#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/DD4hepUnits.h"
-#include "DD4hep/DetType.h"
#include "DDRec/DetectorData.h"
#include "DDRec/Surface.h"
#include "XML/Utilities.h"
-#include "XMLHandlerDB.h"
#include
-#include