From 09987132f17bc06862354114da0daa904497c2f0 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado <114166109+atolosadelgado@users.noreply.github.com> Date: Wed, 15 May 2024 14:34:16 +0200 Subject: [PATCH] Lightweight implementation of IDEA drift chamber (#330) * New implementation of DCH, based on excel spreadsheet * refactor fill of DCH database * remove legacy comment * compact file added * new parameters added * Twisted tube as layer envelope ready to be replaced by hyperboloid * layer shape is now hyperboloid * interlayer spacing for geometry safety is reduced to 1 nm overlap test passes * segmentation in phi works overlap tests pass * Stereo (twist) angle sign is now taken into account * DCH materials detailed in a dedicated XML file Detector constructor takes material from DCH material file * Sense wire added overlap tests pass * staggering in phi placement of cells for alternating layers * thickness of wires added to XML file * Central field wire added overlap tests pass * update geometry tree comment added todo note * field wires 123 placed properly overlap test passes * field wires 45 in place overlap test passes :) * stagering of cells changed from 0.5 to 0.25 phi aperture * vessel and gas mat/vis given via XML * wire configuration now via XML overlap test pass * setup wire thickness in the XML * old commented block deleted overlap tests pass * increase version number, keep option 1 * increase version number, keep option 1 * remove old file * superlayer bitfield added * fix bug, bitfield superlayer number is now calculated properly * bitfield superlayer starts now at zero, not one * rename DCH XML file * lcgeo test added: DCH o1 v02 overlap test * tracker README expanded * Start new version of IDEA detector * refactor DCH_info class. static members removed * refactor inner and outer radius variable names, suffix _z0 removed * comment added * Missing units... Good catch by Brieuc :) * variable name for guard wire radii are renamed for clarity * IDEA compact README updated * Add note that is based on the geometry version "IDEA231026" * comments about wires added * Central field wire, side field wire, sense wire have independent material definition * pi * Replace retrieving of global parameters from dsc with Setters * Protection against neg. parameters added in Fill_DCH_info_database fcn * Replace retrieving of global parameters from dsc with Setters * Replace retrieving of global parameters from dsc with Setters * Replace retrieving of global parameters from dsc with Setters DCH_info is now independent of the dsc file * remove condition for debuging * refactor, use method to calculate the superlayer * dummy space where the extension lives refactored, to be changed for dd4hep::rec:: * refactor constexpr PI and TWOPI * operator << added to class DCH_info * class DCH_info renamed into DCH_info_struct, placed within dd4hep::rec:: the corresponding DetectorData wraper is called now DCH_info * data extension added * data extension changed from local object to pointer so the destructor is not invoked twice * separate data extension class from detector constructor ready to be upstreamed to DD4hep * comment fixed, thanks Andre! * refactor DCH_info, prefix dch_ removed from members * refactor aliases for length/angle * use alias for super/layer numbering * add region and limitset to DCH * Vessel and gas geometry parameters completely moved to DectDimensions file * Staggering in phi confirmed by expert * aesthetics * Fix typo of variable that set radius of outer ring of guard wires Guard wires are not yet implemented, but data is stored in data extension * readout bitfield changed; now layer bitfield corresponds to layer within the superlayer * refactor global variables in XML * comments added * remove reference to excel table from DCH_info documentation * inner and outer R walls are redefined * radial walls ready, bulk material of endcap to be implemented... * endcap bulk material defined to be equivalent to 5%X0 * rename DCH o2 to v2 consistently * rename vessel endcap parameters * wire material is now a mix of coating+core * comment fix * debugGeometry tag added to DCH detector constructor used in overlap test * update readme * build wires of DCH for IDEA v3 * add a test of the whole IDEA_o1_v03 please * remove legacy file * make inline only functions not defined within the class-type functions defined within the class are marked as inline by default * comment fix * fix readme * formated as CLD readme * enable other subdetectors * comment typo fixed * IDEA o1 v03 main compact file is now mirrored from latest v02 * add the following compact files to the IDEA_o1_v03 folder: Solenoid_o1_v01.xml, EndPlateAbsorber_o1_v01.xml * Add detector dimensions * use DDRec/include/DCH_info.h * IDEA v3 material compact file updated * exclude this new detector in case data extension header file is missing * Andre fix: cmake macro CHECK_INCLUDE_FILE_CXX now checks for data extension header file --- CMakeLists.txt | 11 + .../BeamInstrumentation_o1_v01.xml | 36 + .../compact/IDEA_o1_v03/Beampipe_o4_v05.xml | 158 ++++ .../DectDimensions_IDEA_o1_v02.xml | 273 ++++++ .../IDEA_o1_v03/DriftChamber_o1_v02.xml | 165 ++++ .../IDEA_o1_v03/EndPlateAbsorber_o1_v01.xml | 21 + .../IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml | 87 ++ .../compact/IDEA_o1_v03/LumiCal_o1_v01.xml | 192 ++++ .../compact/IDEA_o1_v03/Solenoid_o1_v01.xml | 50 + .../IDEA_o1_v03/Vertex_IDEA_o1_v01.xml | 726 ++++++++++++++ .../compact/IDEA_o1_v03/elements_o1_v01.xml | 884 ++++++++++++++++++ .../compact/IDEA_o1_v03/materials_o1_v02.xml | 398 ++++++++ FCCee/IDEA/compact/README.md | 18 +- detector/tracker/DriftChamber_o1_v02.cpp | 517 ++++++++++ detector/tracker/README.md | 16 + lcgeoTests/CMakeLists.txt | 19 + lcgeoTests/compact/DCH_standalone_o1_v02.xml | 195 ++++ 17 files changed, 3764 insertions(+), 2 deletions(-) create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/BeamInstrumentation_o1_v01.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/Beampipe_o4_v05.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v02.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/DriftChamber_o1_v02.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/EndPlateAbsorber_o1_v01.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/LumiCal_o1_v01.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/Solenoid_o1_v01.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/Vertex_IDEA_o1_v01.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/elements_o1_v01.xml create mode 100644 FCCee/IDEA/compact/IDEA_o1_v03/materials_o1_v02.xml create mode 100644 detector/tracker/DriftChamber_o1_v02.cpp create mode 100644 lcgeoTests/compact/DCH_standalone_o1_v02.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index d1441d0b2..a5fc00744 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,17 @@ if(NOT K4GEO_USE_LCIO) message(STATUS "Use of LCIO is DISABLED, some detectors that depend on LCIO will not be built: ${lcio_sources}") endif() +include(CheckIncludeFileCXX) +set(CMAKE_REQUIRED_LIBRARIES DD4hep::DDRec) +CHECK_INCLUDE_FILE_CXX(DDRec/DCH_info.h DCH_INFO_H_EXIST) +set(CMAKE_REQUIRED_LIBRARIES) +set(FILES_DEPENDINGON_DCH_INFO_H "DriftChamber_o1_v02.cpp" ) + +if(NOT DCH_INFO_H_EXIST) + list(FILTER sources EXCLUDE REGEX "${FILES_DEPENDINGON_DCH_INFO_H}") + message(WARNING "Subdetector ${FILES_DEPENDINGON_DCH_INFO_H} will not be built because header file ${DCH_INFO_H} was not found") +endif() + file(GLOB G4sources ./plugins/TPCSDAction.cpp ./plugins/CaloPreShowerSDAction.cpp diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/BeamInstrumentation_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v03/BeamInstrumentation_o1_v01.xml new file mode 100644 index 000000000..49647b2b8 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/BeamInstrumentation_o1_v01.xml @@ -0,0 +1,36 @@ + + + + COmpensating and screening solenoids for FCCee + + + + + Beampipe Instrumentation + + + + + + +
+ + + + + + + + +
+ +
+ + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/Beampipe_o4_v05.xml b/FCCee/IDEA/compact/IDEA_o1_v03/Beampipe_o4_v05.xml new file mode 100644 index 000000000..73283b2f5 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/Beampipe_o4_v05.xml @@ -0,0 +1,158 @@ + + + + A beampipe for FCCee detector based on CLD + + + + + + + + + + + + + + + + + + + + + Part of beampipe made of AlBeMet162 and Paraffin flow + + + + + + + +
+
+
+
+ + + + + + + + + + + + Golden foil in the inner part of the Be beampipe + +
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ +
+ + + + + +Synch Radiation mask inside the beam-pipe, at z = 2.1 m + + + +
+ +
+ +
+ + + +Full Cone Tungsten Shield + + + + Beampipe Shield (APS: WHAT????? +18 cm (??plus??) as solenoid is now closer to IP) +
+ + + + +Asymmetric Tungsten Shield no Rotation + + + + +
+ + was 370. Add 0.1*mm so that rmax1 is larger than rmin1 +
+ + one degree less, to fit lumical window +
+ +
+ + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v02.xml b/FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v02.xml new file mode 100644 index 000000000..35ecaf11d --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/DectDimensions_IDEA_o1_v02.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/DriftChamber_o1_v02.xml b/FCCee/IDEA/compact/IDEA_o1_v03/DriftChamber_o1_v02.xml new file mode 100644 index 000000000..b7f781561 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/DriftChamber_o1_v02.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:5,superlayer:5,layer:4,nphi:11,stereosign:-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/EndPlateAbsorber_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v03/EndPlateAbsorber_o1_v01.xml new file mode 100644 index 000000000..55acb6c6d --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/EndPlateAbsorber_o1_v01.xml @@ -0,0 +1,21 @@ + + + + + Endcap plate absorber to mimic the material budget from the solenoid (0.75 X0) present only in the barrel and start the showers. + + + + + + + + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml b/FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml new file mode 100644 index 000000000..f6075a08d --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml @@ -0,0 +1,87 @@ + + + + + + + + Version o1_v03 of the IDEA detector + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/LumiCal_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v03/LumiCal_o1_v01.xml new file mode 100644 index 000000000..2c19e5772 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/LumiCal_o1_v01.xml @@ -0,0 +1,192 @@ + + + + LumiCal for FCCee detector + + + + + + + + + + + system:8,barrel:3,layer:8,slice:8,r:32:-16,phi:-16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/Solenoid_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v03/Solenoid_o1_v01.xml new file mode 100644 index 000000000..7287662e0 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/Solenoid_o1_v01.xml @@ -0,0 +1,50 @@ + + + + This is a solenoid place holder. It has the right spacial extent and overall accounts for the 0.75 X0 but its internals should be revised by ultra-thin magnet designers --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/Vertex_IDEA_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v03/Vertex_IDEA_o1_v01.xml new file mode 100644 index 000000000..c38d19da7 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/Vertex_IDEA_o1_v01.xml @@ -0,0 +1,726 @@ + + + + + A Vertex Detector for the FCC-ee IDEA detector concept, based on the engineered design by Fabrizio Palla and Filippo Bosi (INFN Pisa) + + Vertex detector + + + + + + + + + + + + + Vertex Assembly + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${GlobalTrackerReadoutID} + + + ${GlobalTrackerReadoutID_OB} + + + ${GlobalTrackerReadoutID_Disk} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Vertex Detector Disks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/elements_o1_v01.xml b/FCCee/IDEA/compact/IDEA_o1_v03/elements_o1_v01.xml new file mode 100644 index 000000000..f35eb3454 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/elements_o1_v01.xml @@ -0,0 +1,884 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FCCee/IDEA/compact/IDEA_o1_v03/materials_o1_v02.xml b/FCCee/IDEA/compact/IDEA_o1_v03/materials_o1_v02.xml new file mode 100644 index 000000000..cdf85f605 --- /dev/null +++ b/FCCee/IDEA/compact/IDEA_o1_v03/materials_o1_v02.xml @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CMS ECAL https://gitlab.cern.ch/geant4/geant4/-/blob/master/examples/advanced/composite_calorimeter/dataglobal/material.cms#L183 + + + + + + + + + + + + + + + + 0.98810714*2.7 + 0.011892860*10.49 + + field wire center: 50 um Al (core), 0.3 um Ag (coating) + + + + + 0.98516708*2.7 + 0.014832922*10.49 + + field wires top/bottom: 40 um Al (core), 0.3 um Ag (coating) + + + + + 0.97066175*19.28+0.029338250*19.3 + + sense wire: 20 um W (core), 0.3 um Au (coating) + + + + + + + + diff --git a/FCCee/IDEA/compact/README.md b/FCCee/IDEA/compact/README.md index 17ba793c0..fc2eb6045 100644 --- a/FCCee/IDEA/compact/README.md +++ b/FCCee/IDEA/compact/README.md @@ -1,4 +1,18 @@ IDEA ==== -IDEA_o1_v01: IDEA version picked from the latest version in FCCDetectors repo -IDEA_o1_v02: Based on o1_v01 but with a detailed description of the vertex detector and the drift chamber, a place holder solenoid and the endplate absorber. Missing: SiWrapper, calorimeter, detailed muons system (coming soon). + +IDEA_o1_v01 +------------ + +IDEA version picked from the latest version in FCCDetectors repo + +IDEA_o1_v02 +------------ + +Based on o1_v01 but with a detailed description of the vertex detector and the drift chamber, a place holder solenoid and the endplate absorber. Missing: SiWrapper, calorimeter, detailed muons system (coming soon). + +IDEA_o1_v03 +------------ + +Based on o1_v02 but replacing the drift chamber (o1, v01) for the lightweight implementation based on twisted tubes (o1, v02). Production threshold and step limit physics have to be tuned + diff --git a/detector/tracker/DriftChamber_o1_v02.cpp b/detector/tracker/DriftChamber_o1_v02.cpp new file mode 100644 index 000000000..87c54e0fd --- /dev/null +++ b/detector/tracker/DriftChamber_o1_v02.cpp @@ -0,0 +1,517 @@ +//---------------------------------- +// DCH detector v2 +//---------------------------------- + +/*! + * \brief Detector constructor of DCH v2 + * \details This code creates full geometry of IDEA DCH subdetector + * \author Alvaro Tolosa-Delgado alvaro.tolosa.delgado@cern.ch + * \author Brieuc Francois brieuc.francois@cern.ch + * \version 2 + * \date 2024 + * \pre DD4hep compiled with Geant4+Qt + */ + + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/Shapes.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Detector.h" + +#include "DDRec/DCH_info.h" + +namespace DCH_v2 { + +using DCH_length_t = dd4hep::rec::DCH_info_struct::DCH_length_t; +using DCH_angle_t = dd4hep::rec::DCH_info_struct::DCH_angle_t; +using DCH_layer = dd4hep::rec::DCH_info_struct::DCH_layer; + +/// Function to build DCH +static dd4hep::Ref_t create_DCH_o1_v02(dd4hep::Detector &desc, dd4hep::xml::Handle_t handle, dd4hep::SensitiveDetector sens) +{ + dd4hep::xml::DetElement detElem = handle; + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + dd4hep::DetElement det(detName, detID); + sens.setType("tracker"); + + // initialize empty DCH_info object + // data extension mechanism requires it to be a raw pointer + dd4hep::rec::DCH_info * DCH_i = new dd4hep::rec::DCH_info(); + // fill DCH_i with information from the XML file + { + // DCH outer geometry dimensions + DCH_i->Set_rin ( desc.constantAsDouble("DCH_gas_inner_cyl_R") ); + DCH_i->Set_rout ( desc.constantAsDouble("DCH_gas_outer_cyl_R") ); + DCH_i->Set_lhalf( desc.constantAsDouble("DCH_gas_Lhalf") ); + + // guard wires position, fix position + DCH_i->Set_guard_rin_at_z0 ( desc.constantAsDouble("DCH_guard_inner_r_at_z0" ) ); + DCH_i->Set_guard_rout_at_zL2( desc.constantAsDouble("DCH_guard_outer_r_at_zL2") ); + + DCH_angle_t dch_alpha = desc.constantAsDouble("DCH_alpha"); + DCH_i->Set_twist_angle( 2*dch_alpha ); + + DCH_i->Set_nsuperlayers(desc.constantAsLong("DCH_nsuperlayers")); + DCH_i->Set_nlayersPerSuperlayer(desc.constantAsLong("DCH_nlayersPerSuperlayer")); + + DCH_i->Set_ncell0(desc.constantAsLong("DCH_ncell")); + DCH_i->Set_ncell_increment(desc.constantAsLong("DCH_ncell_increment")); + DCH_i->Set_ncell_per_sector(desc.constantAsLong("DCH_ncell_per_sector")); + + DCH_i->Set_first_width ( desc.constantAsDouble("DCH_first_width") ); + DCH_i->Set_first_sense_r( desc.constantAsDouble("DCH_first_sense_r") ); + + bool buildLayers = detElem.attr(_Unicode(buildLayers)); + if(buildLayers){ + DCH_i->BuildLayerDatabase(); + // safety check just in case something went wrong... + if( DCH_i->IsDatabaseEmpty() ) + throw std::runtime_error("Empty database"); + } + + bool printExcelTable = detElem.attr(_Unicode(printExcelTable)); + if(printExcelTable) + DCH_i->Show_DCH_info_database(std::cout); + } + + bool debugGeometry = detElem.hasChild(_Unicode(debugGeometry)); + auto gasElem = detElem.child("gas"); + auto gasvolMat = desc.material(gasElem.attr(_Unicode(material))); + auto gasvolVis = desc.visAttributes(gasElem.attr(_Unicode(vis))); + + auto vesselElem = detElem.child("vessel"); + auto vesselSkinVis = desc.visAttributes(vesselElem.attr(_Unicode(visSkin))); + auto vesselBulkVis = desc.visAttributes(vesselElem.attr(_Unicode(visBulk))); + auto vessel_mainMaterial = desc.material(vesselElem.attr(_Unicode(mainMaterial))); + auto vessel_fillmaterial_outerR = desc.material(vesselElem.attr(_Unicode(fillmaterial_outerR))); + auto vessel_fillmaterial_endcap = desc.material(vesselElem.attr(_Unicode(fillmaterial_endcap))); + DCH_length_t vessel_fillmaterial_fraction_outerR = vesselElem.attr(_Unicode(fillmaterial_fraction_outerR)) ; + DCH_length_t vessel_fillmaterial_fraction_endcap = vesselElem.attr(_Unicode(fillmaterial_fraction_endcap)) ; + + if( 0 > vessel_fillmaterial_fraction_outerR || 1 < vessel_fillmaterial_fraction_outerR ) + throw std::runtime_error("vessel_fillmaterial_fraction_outerR must be between 0 and 1"); + if( 0 > vessel_fillmaterial_fraction_endcap || 1 < vessel_fillmaterial_fraction_endcap ) + throw std::runtime_error("vessel_fillmaterial_fraction_z must be between 0 and 1"); + + auto wiresElem = detElem.child("wires"); + auto wiresVis = desc.visAttributes(wiresElem.attr(_Unicode(vis))); + bool buildSenseWires = wiresElem.attr(_Unicode(buildSenseWires)); + bool buildFieldWires = wiresElem.attr(_Unicode(buildFieldWires)); + + DCH_length_t dch_SWire_thickness = wiresElem.attr(_Unicode(SWire_thickness)) ; + DCH_length_t dch_FSideWire_thickness = wiresElem.attr(_Unicode(FSideWire_thickness)) ; + DCH_length_t dch_FCentralWire_thickness = wiresElem.attr(_Unicode(FCentralWire_thickness)) ; + + auto dch_SWire_material = desc.material(wiresElem.attr(_Unicode(SWire_material)) ) ; + auto dch_FSideWire_material = desc.material(wiresElem.attr(_Unicode(FSideWire_material)) ) ; + auto dch_FCentralWire_material = desc.material(wiresElem.attr(_Unicode(FCentralWire_material)) ) ; + + /* Geometry tree: + * Gas (tube) -> Layer_1 (hyp) -> cell_1 (twisted tube) + * -> cell_... (twisted tube) + * -> Layer_... (hyp) -> cell_1 (twisted tube) + * -> cell_... (twisted tube) + * -> Inner radius vessel wall + * -> Outer radius vessel wall -> fill made of foam + * -> Endcap disk vessel wall -> fill made of kapton + * + * Layers represent a segmentation in radius + * Sectors represent a segmentation in phi + * Each cell corresponds to a Detector Element + * Vessel wall has to be defined as 3 volumes to account for independent thickness and materials + */ + + DCH_length_t safety_r_interspace = 1 * dd4hep::nm; + DCH_length_t safety_z_interspace = 1 * dd4hep::nm; + DCH_length_t safety_phi_interspace = 1e-6 * dd4hep::rad; + + DCH_length_t vessel_thickness_innerR = desc.constantAsDouble("DCH_vessel_thickness_innerR"); + DCH_length_t vessel_thickness_outerR = desc.constantAsDouble("DCH_vessel_thickness_outerR"); + DCH_length_t vessel_endcapdisk_zmin = desc.constantAsDouble("DCH_vessel_disk_zmin"); + DCH_length_t vessel_endcapdisk_zmax = desc.constantAsDouble("DCH_vessel_disk_zmax"); + + // if( 0 > vessel_thickness_z ) + // throw std::runtime_error("vessel_thickness_z must be positive"); + if( 0 > vessel_thickness_innerR ) + throw std::runtime_error("vessel_thickness_innerR must be positive"); + if( 0 > vessel_thickness_outerR ) + throw std::runtime_error("vessel_thickness_outerR must be positive"); + + // // // // // // // // // // // // // // // + // // // // // MAIN VOLUME // // // // // // + // // // // // // // // // // // // // // // + dd4hep::Tube gas_s( DCH_i->rin - vessel_thickness_innerR, + DCH_i->rout + vessel_thickness_outerR, + vessel_endcapdisk_zmax ); + dd4hep::Volume gas_v (detName+"_gas", gas_s, gasvolMat ); + gas_v.setVisAttributes( gasvolVis ); + gas_v.setRegion ( desc, detElem.regionStr() ); + gas_v.setLimitSet( desc, detElem.limitsStr() ); + + DCH_length_t vessel_innerR_start = DCH_i->rin - vessel_thickness_innerR + safety_r_interspace; + DCH_length_t vessel_innerR_end = DCH_i->rin ; + DCH_length_t vessel_outerR_start = DCH_i->rout; + DCH_length_t vessel_outerR_end = DCH_i->rout + vessel_thickness_outerR - safety_r_interspace; + DCH_length_t vessel_R_zhalf = vessel_endcapdisk_zmax - safety_z_interspace; + // // // // // // // // // // // // // // // + // // // // // INNER R WALL // // // // // + // // // // // // // // // // // // // // // + dd4hep::Tube vessel_innerR_s( vessel_innerR_start, + vessel_innerR_end , + vessel_R_zhalf + ); + dd4hep::Volume vessel_innerR_v (detName+"_vessel_innerR", vessel_innerR_s, vessel_mainMaterial ); + vessel_innerR_v.setVisAttributes( vesselSkinVis ); + gas_v.placeVolume(vessel_innerR_v); + // // // // // // // // // // // // // // // + // // // // // OUTER R WALL // // // // // + // // // // // // // // // // // // // // // + dd4hep::Tube vessel_outerR_s( vessel_outerR_start, + vessel_outerR_end , + vessel_R_zhalf + ); + dd4hep::Volume vessel_outerR_v (detName+"_vessel_outerR", vessel_outerR_s, vessel_mainMaterial ); + vessel_outerR_v.setVisAttributes( vesselSkinVis ); + + // if thickness fraction of bulk material is defined, build the bulk material + if(0 < vessel_fillmaterial_fraction_outerR) + { + double f = vessel_fillmaterial_fraction_outerR; + DCH_length_t fillmaterial_thickness = f * (vessel_outerR_end - vessel_outerR_start); + DCH_length_t rstart = vessel_outerR_start + 0.5*(1-f)*fillmaterial_thickness; + DCH_length_t rend = vessel_outerR_end - 0.5*(1-f)*fillmaterial_thickness; + dd4hep::Tube vessel_fillmat_outerR_s( rstart, + rend , + vessel_R_zhalf - safety_z_interspace + ); + dd4hep::Volume vessel_fillmat_outerR_v (detName+"_vessel_fillmat_outerR", + vessel_fillmat_outerR_s, + vessel_fillmaterial_outerR + ); + vessel_fillmat_outerR_v.setVisAttributes( vesselBulkVis ); + vessel_outerR_v.placeVolume(vessel_fillmat_outerR_v); + } + gas_v.placeVolume(vessel_outerR_v); + + // // // // // // // // // // // // // // // + // // // // // ENDCAP WALL // // // // // + // // // // // // // // // // // // // // // + DCH_length_t vessel_endcap_thickness = vessel_endcapdisk_zmax - vessel_endcapdisk_zmin - 2*safety_z_interspace; + DCH_length_t vessel_endcap_zpos = 0.5*(vessel_endcapdisk_zmax + vessel_endcapdisk_zmin); + DCH_length_t vessel_endcap_rstart = vessel_innerR_end + safety_r_interspace; + DCH_length_t vessel_endcap_rend = vessel_outerR_start - safety_r_interspace; + dd4hep::Tube vessel_endcap_s( vessel_endcap_rstart, + vessel_endcap_rend, + 0.5*vessel_endcap_thickness + ); + dd4hep::Volume vessel_endcap_v (detName+"_vessel_endcap", vessel_endcap_s, vessel_mainMaterial ); + vessel_endcap_v.setVisAttributes( vesselSkinVis ); + + // if thickness fraction of bulk material is defined, build the bulk material + if(0 < vessel_fillmaterial_fraction_endcap) + { + double f = vessel_fillmaterial_fraction_endcap; + DCH_length_t fillmaterial_thickness = f * vessel_endcap_thickness; + dd4hep::Tube vessel_fillmat_endcap_s( vessel_endcap_rstart + safety_r_interspace, + vessel_endcap_rend - safety_r_interspace , + 0.5*fillmaterial_thickness + ); + dd4hep::Volume vessel_fillmat_endcap_v (detName+"_vessel_fillmat_endcap", + vessel_fillmat_endcap_s, + vessel_fillmaterial_endcap + ); + vessel_fillmat_endcap_v.setVisAttributes( vesselBulkVis ); + vessel_endcap_v.placeVolume(vessel_fillmat_endcap_v); + } + // place endcap wall at +/- z + gas_v.placeVolume(vessel_endcap_v, dd4hep::Position(0,0, vessel_endcap_zpos)); + gas_v.placeVolume(vessel_endcap_v, dd4hep::Position(0,0,-vessel_endcap_zpos)); + + // // // // // // // // // // // // // // // + // // // // // DCH layers // // // // // + // // // // // // // // // // // // // // // + for(const auto& [ilayer, l] : DCH_i->database ) + { + + // // // // // // // // // // // // // // // // // // // // / + // // // // // INITIALIZATION OF THE LAYER // // // // // // + // // // // // // // // // // // // // // // // // // // // + // Hyperboloid parameters: + /// inner radius at z=0 + DCH_length_t rin = l.radius_fdw_z0+safety_r_interspace; + /// inner stereoangle, calculated from rin(z=0) + DCH_angle_t stin = DCH_i->stereoangle_z0(rin); + /// outer radius at z=0 + DCH_length_t rout = l.radius_fuw_z0-safety_r_interspace; + /// outer stereoangle, calculated from rout(z=0) + DCH_angle_t stout = DCH_i->stereoangle_z0(rout); + /// half-length + DCH_length_t dz = DCH_i->Lhalf + safety_z_interspace; + + dd4hep::Hyperboloid layer_s(rin, stin, rout, stout, dz); + + + std::string layer_name = detName+"_layer"+std::to_string(ilayer); + dd4hep::Volume layer_v ( layer_name , layer_s, gasvolMat ); + layer_v.setVisAttributes( desc.visAttributes( Form("dch_layer_vis%d", ilayer%22) ) ); + auto layer_pv = gas_v.placeVolume(layer_v); + // ilayer is a counter that runs from 1 to 112 (nsuperlayers * nlayersPerSuperlayer) + // it seems more convenient to store the layer number within the superlayer + // ilayerWithinSuperlayer runs from 0 to 7 (nlayersPerSuperlayer-1) + int ilayerWithinSuperlayer = (ilayer-1) % DCH_i->nlayersPerSuperlayer; + layer_pv.addPhysVolID("layer", ilayerWithinSuperlayer ); + // add superlayer bitfield + int nsuperlayer_minus_1 = DCH_i->Get_nsuperlayer_minus_1(ilayer); + layer_pv.addPhysVolID("superlayer", nsuperlayer_minus_1 ); + + dd4hep::DetElement layer_DE(det,layer_name+"DE", ilayer); + layer_DE.setPlacement(layer_pv); + + // // // // // // // // // // // // // // // // // // // // + // // // // // SEGMENTATION OF THE LAYER // // // // // // + // // // // // INTO CELLS (TWISTED TUBES) // // // // // // + // // // // // // // // // // // // // // // // // // // // + + // ncells in this layer = 2x number of wires + int ncells = l.nwires/2; + DCH_angle_t phi_step = (TMath::TwoPi()/ncells)*dd4hep::rad; + + // unitary cell (Twisted tube) is repeated for each layer l.nwires/2 times + // Twisted tube parameters + DCH_angle_t cell_twistangle = l.StereoSign() * DCH_i->twist_angle; + DCH_length_t cell_rin_z0 = l.radius_fdw_z0 + 2*safety_r_interspace; + DCH_length_t cell_rout_z0 = l.radius_fuw_z0 - 2*safety_r_interspace; + DCH_length_t cell_rin_zLhalf = DCH_i->Radius_zLhalf(cell_rin_z0); + DCH_length_t cell_rout_zLhalf = DCH_i->Radius_zLhalf(cell_rout_z0); + DCH_length_t cell_dz = DCH_i->Lhalf; + DCH_angle_t cell_phi_width = phi_step - safety_phi_interspace; + dd4hep::TwistedTube cell_s( cell_twistangle, cell_rin_zLhalf, cell_rout_zLhalf, cell_dz, 1, cell_phi_width); + + // initialize cell volume + std::string cell_name = detName+"_layer"+std::to_string(ilayer)+"_cell"; + dd4hep::Volume cell_v (cell_name, cell_s, gasvolMat ); + cell_v.setSensitiveDetector(sens); + cell_v.setVisAttributes( desc.visAttributes( "dch_no_vis_nodaughters" ) ); + + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF WIRES // // // // // // // + // // // // // // // // // // // // // // // // // // // // + { + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF SENSE WIRES // // // // // + // // // // // // // // // // // // // // // // // // // // + // average radius to position sense wire + DCH_length_t cell_rave_z0 = 0.5*(cell_rin_z0+cell_rout_z0); + DCH_length_t cell_swire_radius = dch_SWire_thickness/2; + DCH_length_t swlength = 0.5*DCH_i->WireLength(ilayer,cell_rave_z0) + - cell_swire_radius*cos(DCH_i->stereoangle_z0(cell_rave_z0)) + - safety_z_interspace; + if(buildSenseWires) + { + dd4hep::Tube swire_s(0., dch_SWire_thickness, swlength); + dd4hep::Volume swire_v(cell_name+"_swire", swire_s, dch_SWire_material); + swire_v.setVisAttributes( wiresVis ); + // Change sign of stereo angle to place properly the wire inside the twisted tube + dd4hep::RotationX stereoTr( (-1.)*l.StereoSign()*DCH_i->stereoangle_z0(cell_rave_z0) ); + dd4hep::Transform3D swireTr ( stereoTr * dd4hep::Translation3D(cell_rave_z0,0.,0.) ); + cell_v.placeVolume(swire_v,swireTr); + } + if(buildFieldWires) + { + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF FIELD WIRES // // // // // + // // // // // // // // // // // // // // // // // // // // + // + // The following sketch represents the crossection of a DCH cell, where + // O symbol = Field wires, the number in parenthesis is used as ID + // X symbol = sense wire + // + // ^ radius + // + // O(1)---O(4)---O(6) radius_z0 = l.radius_fuw_z0 == (++l).radius_fdw_z0 + // + // O(2) X O(7) radius_z0 = average(l.radius_fuw_z0, l.radius_fdw_z0) + // + // O(3)---O(5)---O(8) radius_z0 = l.radius_fdw_z0 == (--l).radius_fuw_z0 + // + // --> phi axis + // + // In the previous sketch, the wires are shared among several cells. + // Since we are using an actual shape to contain each cell, + // it is not feasible. + // + // As a workaround, we introduce an offset in phi and radially to the cell center, + // in such a manner that the wires are fully contained in one cell. + // The following code implements the following sketch: + // + // O(1)---O(4)--- radius_z0 = l.radius_fuw_z0 - wire_thickness/2 + // + // O(2) X radius_z0 = average(l.radius_fuw_z0, l.radius_fdw_z0) + // + // O(3)---O(5)--- radius_z0 = l.radius_fdw_z0 + wire_thickness/2 + // + // phi_offset(n) = atan( wire_thickness/2 / radius_z0 ) + // + // notice that the field wires are offcentered with respect to the sense wire + // by about 20um/1cm ~ 0.1 mrad, which is not expected to have any impact + + /// encapsulate the calculation of the phi offset into a function + /// since it will be different for each field wire + /// it includes the safety phi distance + auto fwire_phi_offset = [&](DCH_length_t radial_distance, DCH_length_t wire_radius)->DCH_angle_t + { + return atan(wire_radius/radial_distance)*dd4hep::rad + safety_phi_interspace; + }; + + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF F WIRE 2 // // // // // // + // // // // // // REQUIRES OFFSET OF PHI // // // // // // + // // // // // // // // // // // // // // // // // // // // + { + DCH_length_t fwire_radius = dch_FCentralWire_thickness/2; + DCH_length_t fwire_r_z0 = cell_rave_z0; + DCH_angle_t fwire_stereo = (-1.)*l.StereoSign()*DCH_i->stereoangle_z0(fwire_r_z0); + DCH_angle_t fwire_phi = -cell_phi_width/2 + fwire_phi_offset( fwire_r_z0, fwire_radius); + DCH_length_t fwire_length = 0.5*DCH_i->WireLength(ilayer, fwire_r_z0) + - fwire_radius*cos(DCH_i->stereoangle_z0(fwire_r_z0)) + - safety_z_interspace; + + dd4hep::Tube fwire_s(0., fwire_radius, fwire_length); + dd4hep::Volume fwire_v(cell_name+"_f2wire", fwire_s, dch_FCentralWire_material ); + fwire_v.setVisAttributes( wiresVis ); + // Change sign of stereo angle to place properly the wire inside the twisted tube + dd4hep::RotationX fwireStereoTr( fwire_stereo ); + dd4hep::RotationZ fwirePhoTr( fwire_phi ); + dd4hep::Transform3D fwireTr ( fwirePhoTr * fwireStereoTr * dd4hep::Translation3D(fwire_r_z0,0.,0.) ); + cell_v.placeVolume(fwire_v,fwireTr); + } + + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF F WIRE 1 // // // // // + // // // // // // REQUIRES OFFSET OF PHI & R // // // // // + // // // // // // // // // // // // // // // // // // // // + { + DCH_length_t fwire_radius = dch_FSideWire_thickness/2; + // decrease radial distance, move it closer to the sense wire + DCH_length_t fwire_r_z0 = cell_rout_z0 - fwire_radius; + DCH_angle_t fwire_stereo = (-1.)*l.StereoSign()*DCH_i->stereoangle_z0(fwire_r_z0); + DCH_angle_t fwire_phi = -cell_phi_width/2 + fwire_phi_offset( fwire_r_z0, fwire_radius); + DCH_length_t fwire_length = 0.5*DCH_i->WireLength(ilayer, fwire_r_z0) + - fwire_radius*cos(DCH_i->stereoangle_z0(fwire_r_z0)) + - safety_z_interspace; + + dd4hep::Tube fwire_s(0., fwire_radius, fwire_length); + dd4hep::Volume fwire_v(cell_name+"_f1wire", fwire_s, dch_FSideWire_material ); + fwire_v.setVisAttributes( wiresVis ); + // Change sign of stereo angle to place properly the wire inside the twisted tube + dd4hep::RotationX fwireStereoTr( fwire_stereo ); + dd4hep::RotationZ fwirePhoTr( fwire_phi ); + dd4hep::Transform3D fwireTr ( fwirePhoTr * fwireStereoTr * dd4hep::Translation3D(fwire_r_z0,0.,0.) ); + cell_v.placeVolume(fwire_v,fwireTr); + } + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF F WIRE 3 // // // // // + // // // // // // REQUIRES OFFSET OF PHI & R // // // // // + // // // // // // // // // // // // // // // // // // // // + { + DCH_length_t fwire_radius = dch_FSideWire_thickness/2; + // increase radial distance, move it closer to the sense wire + DCH_length_t fwire_r_z0 = cell_rin_z0 + fwire_radius; + DCH_angle_t fwire_stereo = (-1.)*l.StereoSign()*DCH_i->stereoangle_z0(fwire_r_z0); + DCH_angle_t fwire_phi = -cell_phi_width/2 + fwire_phi_offset( fwire_r_z0, fwire_radius); + DCH_length_t fwire_length = 0.5*DCH_i->WireLength(ilayer, fwire_r_z0) + - fwire_radius*cos(DCH_i->stereoangle_z0(fwire_r_z0)) + - safety_z_interspace; + + dd4hep::Tube fwire_s(0., fwire_radius, fwire_length); + dd4hep::Volume fwire_v(cell_name+"_f3wire", fwire_s, dch_FSideWire_material ); + fwire_v.setVisAttributes( wiresVis ); + // Change sign of stereo angle to place properly the wire inside the twisted tube + dd4hep::RotationX fwireStereoTr( fwire_stereo ); + dd4hep::RotationZ fwirePhoTr( fwire_phi ); + dd4hep::Transform3D fwireTr ( fwirePhoTr * fwireStereoTr * dd4hep::Translation3D(fwire_r_z0,0.,0.) ); + cell_v.placeVolume(fwire_v,fwireTr); + } + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF F WIRE 5 // // // // // + // // // // // // REQUIRES OFFSET OF R // // // // // + // // // // // // // // // // // // // // // // // // // // + { + DCH_length_t fwire_radius = dch_FSideWire_thickness/2; + // increase radial distance, move it closer to the sense wire + DCH_length_t fwire_r_z0 = cell_rin_z0 + fwire_radius; + DCH_angle_t fwire_stereo = (-1.)*l.StereoSign()*DCH_i->stereoangle_z0(fwire_r_z0); + DCH_length_t fwire_length = 0.5*DCH_i->WireLength(ilayer, fwire_r_z0) + - fwire_radius*cos(DCH_i->stereoangle_z0(fwire_r_z0)) + - safety_z_interspace; + + dd4hep::Tube fwire_s(0., fwire_radius, fwire_length); + dd4hep::Volume fwire_v(cell_name+"_f5wire", fwire_s, dch_FSideWire_material ); + fwire_v.setVisAttributes( wiresVis ); + // Change sign of stereo angle to place properly the wire inside the twisted tube + dd4hep::RotationX fwireStereoTr( fwire_stereo ); + dd4hep::Transform3D fwireTr ( fwireStereoTr * dd4hep::Translation3D(fwire_r_z0,0.,0.) ); + cell_v.placeVolume(fwire_v,fwireTr); + } + // // // // // // // // // // // // // // // // // // // // + // // // // // // POSITIONING OF F WIRE 4 // // // // // + // // // // // // REQUIRES OFFSET OF R // // // // // + // // // // // // // // // // // // // // // // // // // // + { + DCH_length_t fwire_radius = dch_FSideWire_thickness/2; + // increase radial distance, move it closer to the sense wire + DCH_length_t fwire_r_z0 = cell_rout_z0 - fwire_radius; + DCH_angle_t fwire_stereo = (-1.)*l.StereoSign()*DCH_i->stereoangle_z0(fwire_r_z0); + DCH_length_t fwire_length = 0.5*DCH_i->WireLength(ilayer, fwire_r_z0) + - fwire_radius*cos(DCH_i->stereoangle_z0(fwire_r_z0)) + - safety_z_interspace; + + dd4hep::Tube fwire_s(0., fwire_radius, fwire_length); + dd4hep::Volume fwire_v(cell_name+"_f4wire", fwire_s, dch_FSideWire_material ); + fwire_v.setVisAttributes( wiresVis ); + // Change sign of stereo angle to place properly the wire inside the twisted tube + dd4hep::RotationX fwireStereoTr( fwire_stereo ); + dd4hep::Transform3D fwireTr ( fwireStereoTr * dd4hep::Translation3D(fwire_r_z0,0.,0.) ); + cell_v.placeVolume(fwire_v,fwireTr); + } + }// end building field wires + }/// end building wires + int maxphi = ncells; + if(debugGeometry) + maxphi=3; + for(int nphi = 0; nphi < maxphi; ++nphi) + { + // TODO: check if staggering is just + 0.25*cell_phi_width*(ilayer%2); + // phi positioning, adding offset for odd ilayers + DCH_angle_t cell_phi_angle = phi_step * nphi + 0.25*cell_phi_width*(ilayer%2); + // conversion of RotationZ into Transform3D using constructor) + dd4hep::Transform3D cellTr { dd4hep::RotationZ(cell_phi_angle) }; + auto cell_pv = layer_v.placeVolume(cell_v, cellTr); + cell_pv.addPhysVolID("nphi", nphi); + cell_pv.addPhysVolID("stereosign", l.StereoSign() ); + + dd4hep::DetElement cell_DE(layer_DE,cell_name+std::to_string(nphi)+"DE", nphi); + cell_DE.setPlacement(cell_pv); + } + + + } + + // Place our mother volume in the world + dd4hep::Volume wVol = desc.pickMotherVolume(det); + dd4hep::PlacedVolume vessel_pv = wVol.placeVolume(gas_v); + // Associate the wall to the detector element. + det.setPlacement(vessel_pv); + // Assign the system ID to our mother volume + vessel_pv.addPhysVolID("system", detID); + det.addExtension(DCH_i); + + return det; + +} + +}; // end DCH_v2 namespace + + +DECLARE_DETELEMENT(DriftChamber_o1_v02_T, DCH_v2::create_DCH_o1_v02) diff --git a/detector/tracker/README.md b/detector/tracker/README.md index 3fbe421fc..d2e213cfe 100644 --- a/detector/tracker/README.md +++ b/detector/tracker/README.md @@ -30,3 +30,19 @@ What to improve: - better automation in the C++ to rely less on user defined parameters from the xml - better variable naming (started already but could still be improved) - make sense out of the many layer radiuses defined + + +### o1_v02 +Reimplementation of the drift chamber concept, based on a fully detailed spreadsheet. The improvements with respect the previous implementation are the following: +- The standalone simulation consumes 400MB of memory, out of which the geometry represents 150MB. +- The DCH is built out of few global parameters, thanks to the prescription given in the spreadsheet +- C++ guidelines are followed +- ASCII drawing is included to make sense of positioning of wires inside the cells +- The cell shape corresponds to a twisted tube, which is missing in ROOT, but DD4hep provides a workaround +- Because of the previous point, this subdetector can not be used by any ROOT-based application, and the shape parameters can be accessed only by DD4hep/Geant4 +- Visualization of the full DCH is possible with Geant4+Qt, but not with ROOT-based applications +- The optional tag `` build only 3 sectors of each layer, it must be used only when checking for overlaps. +- Endcap services. A dummy plate with 5% X0 is used to account for such services. +- Vessel wall is a sandwich of Carbon fiber and PE foam. The thickness of the fill material is given as a fraction of the total thickness of the wall. It is adjusted to provide 1.2%X0 radially and 5%X0 longitudinally. +- Material of field and sense wire is averaged for the sake of speedup. +- Guard wires are not implemented yet. diff --git a/lcgeoTests/CMakeLists.txt b/lcgeoTests/CMakeLists.txt index 59dac77fa..93cd303a8 100644 --- a/lcgeoTests/CMakeLists.txt +++ b/lcgeoTests/CMakeLists.txt @@ -86,6 +86,15 @@ 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 360) +#-------------------------------------------------- +# test for IDEA o1 v03 +if(DCH_INFO_H_EXIST) +SET( test_name "test_IDEA_o1_v03" ) +ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test_${PackageName}.sh" + ddsim --compactFile=${CMAKE_CURRENT_SOURCE_DIR}/../FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml --runType=batch -G -N=1 --outputFile=testIDEA_o1_v03.slcio ) +SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Exception;EXCEPTION;ERROR;Error" TIMEOUT 700) +endif() + #-------------------------------------------------- # test for ALLEGRO o1 v02 SET( test_name "test_ALLEGRO_o1_v02" ) @@ -114,6 +123,16 @@ ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test_${PackageName}.sh SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Exception;EXCEPTION;ERROR;Error" ) set_tests_properties( t_${test_name} PROPERTIES TIMEOUT 360) +#-------------------------------------------------- +# test for DCH o1 v02 +if(DCH_INFO_H_EXIST) +SET( test_name "test_DCH_o1_v02_overlap" ) +ADD_TEST( t_${test_name} "${CMAKE_INSTALL_PREFIX}/bin/run_test_${PackageName}.sh" + ddsim --compactFile=${CMAKE_CURRENT_SOURCE_DIR}/compact/DCH_standalone_o1_v02.xml --runType run --part.userParticleHandler= --macroFile=${CMAKE_CURRENT_SOURCE_DIR}/../utils/overlap.mac ) +SET_TESTS_PROPERTIES( t_${test_name} PROPERTIES FAIL_REGULAR_EXPRESSION "Exception;EXCEPTION;ERROR;Error" ) +set_tests_properties( t_${test_name} PROPERTIES TIMEOUT 60) +endif() + #-------------------------------------------------- ADD_EXECUTABLE( TestSensThickness src/TestSensThickness.cpp ) diff --git a/lcgeoTests/compact/DCH_standalone_o1_v02.xml b/lcgeoTests/compact/DCH_standalone_o1_v02.xml new file mode 100644 index 000000000..93a3ec357 --- /dev/null +++ b/lcgeoTests/compact/DCH_standalone_o1_v02.xml @@ -0,0 +1,195 @@ + + + + The compact format of the DCH subdetector, built from XLSX spreadsheet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:5,superlayer:5,layer:4,nphi:11,stereosign:-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +