diff --git a/Detector/DetCEPCv4/CMakeLists.txt b/Detector/DetCEPCv4/CMakeLists.txt index e969df42e033b2bff74f08dd13c729fb0eec31f9..69bcc73e14484665c6ec628ae20e3fce63c765f3 100644 --- a/Detector/DetCEPCv4/CMakeLists.txt +++ b/Detector/DetCEPCv4/CMakeLists.txt @@ -32,6 +32,9 @@ set(DetCEPCv4_src src/calorimeter/SEcal05_Barrel.cpp src/calorimeter/SEcal05_Endcaps.cpp src/calorimeter/SEcal05_ECRing.cpp + src/calorimeter/SHcalRpc01_Barrel.cpp + src/calorimeter/SHcalRpc01_Endcaps.cpp + src/calorimeter/SHcalRpc01_EndcapRing.cpp src/other/BoxSupport_o1_v01_geo.cpp src/other/TubeSupport_o1_v01_geo.cpp ) diff --git a/Detector/DetCEPCv4/compact/CepC_v4.xml b/Detector/DetCEPCv4/compact/CepC_v4.xml index 393a40e9002e23cdfb6975e88e1117b53441becb..e79cadaaacf1d655295a6016560bcbc03f901bca 100644 --- a/Detector/DetCEPCv4/compact/CepC_v4.xml +++ b/Detector/DetCEPCv4/compact/CepC_v4.xml @@ -34,6 +34,15 @@ <!-- Readout slice in hcal for reconstruction --> <constant name="Hcal_readout_segmentation_slice" value="3"/> </define> + <materials> + <material name="RPC2ECRMix" state="solid"> + <D unit="g/cm3" value="Hcal_mix_density"/> + <composite n="Hcal_airgap_fraction" ref="Air"/> + <composite n="Hcal_graphite_fraction" ref="graphite"/> + <composite n="Hcal_mylar_fraction" ref="mylar"/> + <composite n="Hcal_g10_fraction" ref="g10"/> + </material> + </materials> <limits> <limitset name="cal_limits"> <limit name="step_length_max" particles="*" value="cal_steplimit_val" unit="cal_steplimit_unit" /> @@ -46,19 +55,19 @@ </limitset> </limits> <include ref="display.xml"/> - <include ref="Beampipe_o1_v01_01.xml"/> - <!--include ref="vxd07.xml"/> - <include ref="ftd_simple_staggered_02.xml"/> - <include ref="sit_simple_pixel_sensors_01.xml"/> + <!--include ref="Beampipe_o1_v01_01.xml"/> + <include ref="vxd07.xml"/> + <include ref="ftd_cepc.xml"/> + <include ref="sit_simple_planar_sensors_01.xml"/> <include ref="tpc10_01.xml"/> - <include ref="set_simple_planar_sensors_01.xml"/--> + <include ref="set_simple_planar_sensors_01.xml"/> <include ref="SEcal05_siw_Barrel.xml"/> <include ref="SEcal05_siw_Endcaps.xml"/> - <include ref="SEcal05_siw_ECRing.xml"/> - <!--include ref="Hcal_Barrel_SD_v01.xml"/> - <include ref="Hcal_Endcaps_SD_v01.xml"/> - <include ref="Hcal_EndcapRing_SD_v01.xml"/> - <include ref="Yoke05_Barrel.xml"/> + <include ref="SEcal05_siw_ECRing.xml"/--> + <include ref="SHcalRpc01_Barrel_01.xml"/> + <include ref="SHcalRpc01_Endcaps_01.xml"/> + <include ref="SHcalRpc01_EndcapRing_01.xml"/> + <!--include ref="Yoke05_Barrel.xml"/> <include ref="Yoke05_Endcaps.xml"/> <include ref="LumiCal.xml"/--> diff --git a/Detector/DetCEPCv4/compact/Hcal_Barrel_SD_v01.xml b/Detector/DetCEPCv4/compact/Hcal_Barrel_SD_v01.xml deleted file mode 100644 index bfee3f1b9cea39cc91b3e3938af66e2f45344d65..0000000000000000000000000000000000000000 --- a/Detector/DetCEPCv4/compact/Hcal_Barrel_SD_v01.xml +++ /dev/null @@ -1,47 +0,0 @@ -<lccdd> - - <detectors> - <detector name="HcalBarrel" type="Hcal_Barrel_SD_v01" id="ILDDetID_HCAL" readout="HCalBarrelRPCHits" vis="GreenVis" insideTrackingVolume="false" > - <comment>Hadron Calorimeter Barrel</comment> - - <envelope vis="ILD_HCALVis"> - <shape type="BooleanShape" operation="Subtraction" material="Air" > - <shape type="Cone" z="Hcal_half_length + env_safety/2" rmin1="0.0" rmax1="Hcal_outer_radius + env_safety" rmin2="0.0" rmax2="Hcal_outer_radius + env_safety"/> - <shape type="PolyhedraRegular" numsides="Hcal_inner_symmetry" rmin="0.0" - rmax="Hcal_inner_radius - env_safety" dz="2*(Hcal_half_length + env_safety)"/> - </shape> - <rotation x="0" y="0" z="90*deg-180*deg/Hcal_inner_symmetry"/> - </envelope> - <type_flags type=" DetType_CALORIMETER + DetType_BARREL + DetType_HADRONIC " /> - - <staves material = "Steel304L" vis="BlueVis"/> - - <!-- The layer structure reference in the following paper--> - <!-- ??? --> - <layer repeat="HcalBarrelSD_nlayers" vis="SeeThrough"> - <slice material = "Steel304L" thickness = "HcalSD_radiator_thickness" vis="BlueVis" /> - <slice material = "Air" thickness = "HcalSD_airgap_thickness" vis="WhiteVis" /> - <slice material = "Steel304L" thickness = "HcalSD_steel_casette_thickness" vis="BlueVis" /> - <slice material = "epoxy" thickness = "HcalSD_electronics_mask_thickness" vis="GreenVis" /> - <slice material = "PCB" thickness = "HcalSD_PCB_thickness" vis="CyanVis" /> - <slice material = "mylar" thickness = "HcalSD_mylar_anode_thickness" vis="MagentaVis" /> - <slice material = "graphite" thickness = "HcalSD_graphite_anode_thickness" vis="Invisible" /> - <slice material = "FloatGlass" thickness = "HcalSD_glass_anode_thickness" vis="RedVis" /> - <slice material = "RPCGAS2" thickness = "HcalSD_sensitive_gas_gap" sensitive = "yes" vis="YellowVis" /> - <slice material = "FloatGlass" thickness = "HcalSD_glass_cathode_thickness" vis="RedVis" /> - <slice material = "graphite" thickness = "HcalSD_graphite_cathode_thickness" vis="Invisible" /> - <slice material = "mylar" thickness = "HcalSD_mylar_cathode_thickness" vis="MagentaVis" /> - <slice material = "Steel304L" thickness = "HcalSD_steel_casette_thickness" vis="BlueVis" /> - <slice material = "Air" thickness = "HcalSD_airgap_thickness" vis="WhiteVis" /> - </layer> - </detector> - </detectors> - - <readouts> - <readout name="HCalBarrelRPCHits"> - <segmentation type="CartesianGridXY" grid_size_x="HcalSD_cells_size" grid_size_y="HcalSD_cells_size"/> - <id>system:5,module:3,stave:3,tower:5,layer:6,slice:4,x:32:-16,y:-16</id> - </readout> - </readouts> - -</lccdd> diff --git a/Detector/DetCEPCv4/compact/Hcal_EndcapRing_SD_v01.xml b/Detector/DetCEPCv4/compact/Hcal_EndcapRing_SD_v01.xml deleted file mode 100644 index ee89545a0187d2cc8e87318e770aa9e7f408800d..0000000000000000000000000000000000000000 --- a/Detector/DetCEPCv4/compact/Hcal_EndcapRing_SD_v01.xml +++ /dev/null @@ -1,56 +0,0 @@ -<lccdd> - - <detectors> - <detector name="HcalRing" type="Hcal_EndcapRing_SD_v01" id="ILDDetID_HCAL_RING" readout="HCalECRingRPCHits" vis="SeeThrough" insideTrackingVolume="false" > - <comment>Hadron Calorimeter EndcapRing</comment> - - <envelope vis="ILD_HCALVis"> - <shape type="BooleanShape" operation="Subtraction" material="Air"> - <shape type="BooleanShape" operation="Intersection" material="Air"> - <shape type="Box" dx="HcalEndcapRing_outer_radius + 2.0*env_safety" dy="HcalEndcapRing_outer_radius + 2.0*env_safety" - dz="HcalEndcapRing_max_z + 2.0*env_safety"/> <!--Box defined the coordinate system--> - <shape type="PolyhedraRegular" numsides="HcalEndcapRingSD_inner_symmetry" rmin="HcalEndcapRing_inner_radius - env_safety" - rmax="HcalEndcapRing_outer_radius + env_safety" dz="2.0*HcalEndcapRing_max_z + env_safety" material="Air"/> - <rotation x="0" y="0" z="90*deg-180*deg/HcalEndcapRingSD_inner_symmetry"/> - </shape> - - <shape type="Box" dx="HcalEndcapRing_outer_radius + 2.0*env_safety" dy="HcalEndcapRing_outer_radius + 2.0*env_safety" - dz="HcalEndcapRing_min_z - env_safety"/> - </shape> - </envelope> - - <type_flags type=" DetType_CALORIMETER + DetType_ENDCAP + DetType_HADRONIC + DetType_AUXILIARY " /> - - <!-- absorber material - --> - <staves material = "Steel304L" vis="GreenVis"/> - <material name="Steel304L"/> - - <layer repeat="HcalEndcapRingSD_nlayers" vis="SeeThrough"> - <slice material = "Steel304L" thickness = "HcalSD_radiator_thickness" vis="BlueVis" /> - <slice material = "Air" thickness = "HcalSD_airgap_thickness" vis="WhiteVis" /> - <slice material = "Steel304L" thickness = "HcalSD_steel_casette_thickness" vis="BlueVis" /> - <slice material = "epoxy" thickness = "HcalSD_electronics_mask_thickness" vis="GreenVis" /> - <slice material = "PCB" thickness = "HcalSD_PCB_thickness" vis="CyanVis" /> - <slice material = "mylar" thickness = "HcalSD_mylar_anode_thickness" vis="MagentaVis" /> - <slice material = "graphite" thickness = "HcalSD_graphite_anode_thickness" vis="Invisible" /> - <slice material = "FloatGlass" thickness = "HcalSD_glass_anode_thickness" vis="RedVis" /> - <slice material = "RPCGAS2" thickness = "HcalSD_sensitive_gas_gap" sensitive = "yes" vis="YellowVis" /> - <slice material = "FloatGlass" thickness = "HcalSD_glass_cathode_thickness" vis="RedVis" /> - <slice material = "graphite" thickness = "HcalSD_graphite_cathode_thickness" vis="Invisible" /> - <slice material = "mylar" thickness = "HcalSD_mylar_cathode_thickness" vis="MagentaVis" /> - <slice material = "Steel304L" thickness = "HcalSD_steel_casette_thickness" vis="BlueVis" /> - <slice material = "Air" thickness = "HcalSD_airgap_thickness" vis="WhiteVis" /> - </layer> - </detector> - </detectors> - - <readouts> - <readout name="HCalECRingRPCHits"> - <segmentation type="CartesianGridXY" grid_size_x="HcalSD_cells_size" grid_size_y="HcalSD_cells_size"/> - <id>system:5,module:3,stave:4,tower:3,layer:6,x:32:-16,y:-16</id> - </readout> - </readouts> - -</lccdd> - diff --git a/Detector/DetCEPCv4/compact/Hcal_Endcaps_SD_v01.xml b/Detector/DetCEPCv4/compact/Hcal_Endcaps_SD_v01.xml deleted file mode 100644 index 3b77b0fa6104dd0cd1e60b439d185ed6eb9af23c..0000000000000000000000000000000000000000 --- a/Detector/DetCEPCv4/compact/Hcal_Endcaps_SD_v01.xml +++ /dev/null @@ -1,53 +0,0 @@ -<lccdd> - -<detectors> -<detector id="ILDDetID_HCAL_ENDCAP" name="HcalEndcap" type="Hcal_Endcaps_SD_v01" readout="HCalEndcapRPCHits" vis="SeeThrough" calorimeterType="HAD_ENDCAP"> - <comment>Hadron Calorimeter Endcap</comment> - - - <envelope vis="ILD_HCALVis"> - <shape type="BooleanShape" operation="Subtraction" material="Air"><!--2. create center box hole --> - <shape type="BooleanShape" operation="Subtraction" material="Air"><!--1. create Endcaps envelope --> - <shape type="Tube" rmin="0.0" rmax="HcalEndcap_outer_radius + env_safety" dz="HcalEndcap_max_z + env_safety"/> - <shape type="Tube" rmin="0.0" rmax="HcalEndcap_outer_radius + 2.0*env_safety" dz="HcalEndcap_min_z - env_safety"/> - </shape> - <shape type="Box" dx="HcalEndcap_inner_radius - env_safety" dy="HcalEndcap_inner_radius - env_safety" - dz="HcalEndcap_max_z + 2.0*env_safety"/> - </shape> - <rotation x="0" y="0" z="0"/> - </envelope> - - <type_flags type=" DetType_CALORIMETER + DetType_ENDCAP + DetType_HADRONIC " /> - <material name="Steel304L"/><!-- radiator and the thickness has been defined in the main xml file--> - <staves material = "Steel235" vis="SeeThrough"/> - - - <!-- slice: from inner to outer --> - <layer repeat="HcalEndcapSD_nlayers" vis="SeeThrough"> - <slice material = "Steel304L" thickness = "HcalSD_radiator_thickness" vis="BlueVis" /> - <slice material = "Air" thickness = "HcalSD_airgap_thickness" vis="WhiteVis" /> - <slice material = "Steel304L" thickness = "HcalSD_steel_casette_thickness" vis="BlueVis" /> - <slice material = "epoxy" thickness = "HcalSD_electronics_mask_thickness" vis="GreenVis" /> - <slice material = "PCB" thickness = "HcalSD_PCB_thickness" vis="CyanVis" /> - <slice material = "mylar" thickness = "HcalSD_mylar_anode_thickness" vis="MagentaVis"/> - <slice material = "graphite" thickness = "HcalSD_graphite_anode_thickness" vis="Invisible" /> - <slice material = "FloatGlass" thickness = "HcalSD_glass_anode_thickness" vis="RedVis" /> - <slice material = "RPCGAS2" thickness = "HcalSD_sensitive_gas_gap" sensitive = "yes" vis="YellowVis" /> - <slice material = "FloatGlass" thickness = "HcalSD_glass_cathode_thickness" vis="RedVis" /> - <slice material = "graphite" thickness = "HcalSD_graphite_cathode_thickness" vis="Invisible" /> - <slice material = "mylar" thickness = "HcalSD_mylar_cathode_thickness" vis="MagentaVis"/> - <slice material = "Steel304L" thickness = "HcalSD_steel_casette_thickness" vis="BlueVis" /> - <slice material = "Air" thickness = "HcalSD_airgap_thickness" vis="WhiteVis" /> - </layer> - -</detector> -</detectors> - -<readouts> - <readout name="HCalEndcapRPCHits"> - <segmentation type="CartesianGridXY" grid_size_x="HcalSD_cells_size" grid_size_y="HcalSD_cells_size" offset_x="HcalSD_cells_size/2.0" offset_y="HcalSD_cells_size/2.0" /> - <id>system:5,module:3,stave:3,tower:5,layer:6,x:32:-16,y:-16</id> - </readout> -</readouts> - -</lccdd> diff --git a/Detector/DetCEPCv4/compact/SHcalRpc01_Barrel_01.xml b/Detector/DetCEPCv4/compact/SHcalRpc01_Barrel_01.xml new file mode 100644 index 0000000000000000000000000000000000000000..8ea02125f3e24158e985c8f2dc9ac455b84c013f --- /dev/null +++ b/Detector/DetCEPCv4/compact/SHcalRpc01_Barrel_01.xml @@ -0,0 +1,41 @@ +<lccdd> + <detectors> + <detector name="HcalBarrel" type="SHcalRpc01_Barrel" id="ILDDetID_HCAL" readout="HcalBarrelCollection" vis="GreenVis" insideTrackingVolume="false" > + <comment>Hadron Calorimeter Barrel</comment> + <envelope vis="ILD_HCALVis"> + <shape type="BooleanShape" operation="Subtraction" material="Air" > + <shape type="Cone" z="Hcal_half_length + env_safety/2" rmin1="0.0" rmax1="Hcal_outer_radius + env_safety" rmin2="0.0" rmax2="Hcal_outer_radius + env_safety"/> + <shape type="PolyhedraRegular" numsides="Hcal_inner_symmetry" rmin="0.0" + rmax="Hcal_inner_radius - env_safety" dz="2*(Hcal_half_length + env_safety)"/> + <rotation x="0" y="0" z="-180*deg/Hcal_inner_symmetry"/> + </shape> + <!--rotation x="0" y="0" z="90*deg-180*deg/Hcal_inner_symmetry"/--> + </envelope> + <type_flags type=" DetType_CALORIMETER + DetType_BARREL + DetType_HADRONIC " /> + + <staves material="stainless_steel" vis="BlueVis"/> + + <layer repeat="Hcal_nlayers" vis="SeeThrough"> + <slice material="stainless_steel" thickness="Hcal_radiator_thickness" vis="BlueVis" /> + <slice material="Air" thickness="Hcal_airgap_thickness" vis="WhiteVis" /> + <slice material="mylar" thickness="Hcal_mylar_cathode_thickness" vis="MagentaVis" /> + <slice material="graphite" thickness="Hcal_graphite_cathode_thickness" vis="Invisible" /> + <slice material="FloatGlass" thickness="Hcal_glass_cathode_thickness" vis="RedVis" /> + <slice material="RPCGAS2" thickness="Hcal_sensitive_gas_gap" sensitive = "yes" vis="YellowVis" edge_material="PEEK-GF30" spacer_material="Nylon"/> + <slice material="FloatGlass" thickness="Hcal_glass_anode_thickness" vis="RedVis" /> + <slice material="graphite" thickness="Hcal_graphite_anode_thickness" vis="Invisible" /> + <slice material="mylar" thickness="Hcal_mylar_anode_thickness" vis="MagentaVis" /> + <slice material="g10" thickness="Hcal_PCB_thickness" vis="CyanVis" /> + <slice material="g10" thickness="Hcal_electronics_mask_thickness" vis="GreenVis" /> + </layer> + </detector> + </detectors> + + <readouts> + <readout name="HcalBarrelCollection"> + <segmentation type="CartesianGridXY" grid_size_x="Hcal_cells_size" grid_size_y="Hcal_cells_size"/> + <id>system:5,module:3,stave:3,tower:5,layer:6,slice:4,x:32:-16,y:-16</id> + </readout> + </readouts> + +</lccdd> diff --git a/Detector/DetCEPCv4/compact/SHcalRpc01_EndcapRing_01.xml b/Detector/DetCEPCv4/compact/SHcalRpc01_EndcapRing_01.xml new file mode 100644 index 0000000000000000000000000000000000000000..824b932c8276357fe5373d57c78780f462aca381 --- /dev/null +++ b/Detector/DetCEPCv4/compact/SHcalRpc01_EndcapRing_01.xml @@ -0,0 +1,41 @@ +<lccdd> + <detectors> + <detector name="HcalRing" type="SHcalRpc01_EndcapRing" id="ILDDetID_HCAL_RING" readout="HcalEndcapRingCollection" vis="SeeThrough" insideTrackingVolume="false" > + <comment>Hadron Calorimeter EndcapRing</comment> + <envelope vis="ILD_HCALVis"> + <!--shape type="Assembly"/--> + <shape type="BooleanShape" operation="Subtraction" material="Air"> + <shape type="BooleanShape" operation="Intersection" material="Air"> + <shape type="Box" dx="HcalEndcapRing_outer_radius + 2.0*env_safety" dy="HcalEndcapRing_outer_radius + 2.0*env_safety" + dz="HcalEndcapRing_max_z + 2.0*env_safety"/> + <shape type="PolyhedraRegular" numsides="Hcal_ring_inner_symmetry" rmin="HcalEndcapRing_inner_radius - env_safety" + rmax="HcalEndcapRing_outer_radius + env_safety" dz="2.0*HcalEndcapRing_max_z + env_safety" material="Air"/> + <rotation x="0" y="0" z="90*deg-180*deg/Hcal_ring_inner_symmetry"/> + </shape> + <shape type="Box" dx="HcalEndcapRing_outer_radius + 2.0*env_safety" dy="HcalEndcapRing_outer_radius + 2.0*env_safety" + dz="HcalEndcapRing_min_z - env_safety"/> + </shape> + </envelope> + + <type_flags type=" DetType_CALORIMETER + DetType_ENDCAP + DetType_HADRONIC + DetType_AUXILIARY " /> + <staves material="stainless_steel" vis="GreenVis"/> + + <layer repeat="HcalEndcapRing_nlayers" vis="SeeThrough"> + <slice material="stainless_steel" thickness="Hcal_radiator_thickness" vis="BlueVis"/> + <slice material="FloatGlass" thickness="Hcal_glass_cathode_thickness" vis="RedVis"/> + <slice material="RPCGAS2" thickness="Hcal_sensitive_gas_gap" sensitive = "yes" vis="YellowVis"/> + <slice material="FloatGlass" thickness="Hcal_glass_anode_thickness" vis="RedVis"/> + <slice material="RPC2ECRMix" thickness="Hcal_mix_thickness" vis="CyanVis"/> + </layer> + </detector> + </detectors> + + <readouts> + <readout name="HcalEndcapRingCollection"> + <segmentation type="CartesianGridXY" grid_size_x="Hcal_cells_size" grid_size_y="Hcal_cells_size"/> + <id>system:5,module:3,stave:4,tower:3,layer:6,x:32:-16,y:-16</id> + </readout> + </readouts> + +</lccdd> + diff --git a/Detector/DetCEPCv4/compact/SHcalRpc01_Endcaps_01.xml b/Detector/DetCEPCv4/compact/SHcalRpc01_Endcaps_01.xml new file mode 100644 index 0000000000000000000000000000000000000000..677a23dd3dcdb7f207f11089a0144e0846f00a84 --- /dev/null +++ b/Detector/DetCEPCv4/compact/SHcalRpc01_Endcaps_01.xml @@ -0,0 +1,38 @@ +<lccdd> + <detectors> + <detector id="ILDDetID_HCAL_ENDCAP" name="HcalEndcap" type="SHcalRpc01_Endcaps" readout="HcalEndcapsCollection" vis="SeeThrough" calorimeterType="HAD_ENDCAP"> + <comment>Hadron Calorimeter Endcap</comment> + <envelope vis="ILD_HCALVis"> + <shape type="BooleanShape" operation="Subtraction" material="Air"> + <shape type="BooleanShape" operation="Subtraction" material="Air"> + <shape type="Tube" rmin="0.0" rmax="HcalEndcap_outer_radius + env_safety" dz="HcalEndcap_max_z + env_safety"/> + <shape type="Tube" rmin="0.0" rmax="HcalEndcap_outer_radius + 2.0*env_safety" dz="HcalEndcap_min_z - env_safety"/> + </shape> + <shape type="Box" dx="HcalEndcap_inner_radius - env_safety" dy="HcalEndcap_inner_radius - env_safety" dz="HcalEndcap_max_z + 2.0*env_safety"/> + </shape> + <rotation x="0" y="0" z="0"/> + </envelope> + + <type_flags type="DetType_CALORIMETER + DetType_ENDCAP + DetType_HADRONIC " /> + + <staves material="stainless_steel" vis="SeeThrough"/> + + <layer repeat="Hcal_endcap_nlayers" vis="SeeThrough"> + <slice material="stainless_steel" thickness="Hcal_radiator_thickness" vis="BlueVis"/> + <slice material="FloatGlass" thickness="Hcal_glass_cathode_thickness" vis="RedVis"/> + <slice material="RPCGAS2" thickness="Hcal_sensitive_gas_gap" sensitive = "yes" vis="YellowVis"/> + <slice material="FloatGlass" thickness="Hcal_glass_anode_thickness" vis="RedVis"/> + <slice material="RPC2ECRMix" thickness="Hcal_mix_thickness" vis="CyanVis"/> + </layer> + + </detector> + </detectors> + + <readouts> + <readout name="HcalEndcapsCollection"> + <segmentation type="CartesianGridXY" grid_size_x="Hcal_cells_size" grid_size_y="Hcal_cells_size" offset_x="Hcal_cells_size/2.0" offset_y="Hcal_cells_size/2.0" /> + <id>system:5,module:3,stave:3,tower:5,layer:6,x:32:-16,y:-16</id> + </readout> + </readouts> + +</lccdd> diff --git a/Detector/DetCEPCv4/compact/envelope_defs.xml b/Detector/DetCEPCv4/compact/envelope_defs.xml index 920b90ee0c9091fa21b1fd4a3d5225de3defafef..5b900a1b04eb2078bbab7e3eca2d67e4a1474bef 100644 --- a/Detector/DetCEPCv4/compact/envelope_defs.xml +++ b/Detector/DetCEPCv4/compact/envelope_defs.xml @@ -93,7 +93,8 @@ <constant name="Ecal_symmetry" value="Ecal_Hcal_symmetry"/> <constant name="Hcal_inner_radius" value="Ecal_outer_radius+Hcal_Ecal_gap"/> - <constant name="Hcal_outer_radius" value="(Hcal_inner_radius+Hcal_barrel_thickness)/cos(pi/Hcal_outer_symmetry)"/> <!-- cos(pi/16) --> + <!--constant name="Hcal_outer_radius" value="(Hcal_inner_radius+Hcal_barrel_thickness)/cos(pi/Hcal_outer_symmetry)"/--> <!-- cos(pi/16) --> + <constant name="Hcal_outer_radius" value="3144.43*mm"/> <constant name="Hcal_half_length" value="TPC_Ecal_Hcal_barrel_halfZ"/> <constant name="Hcal_inner_symmetry" value="Ecal_Hcal_symmetry"/> diff --git a/Detector/DetCEPCv4/compact/hcal_defs.xml b/Detector/DetCEPCv4/compact/hcal_defs.xml index 12f7ba31c749056b80cd53abd81378c13773c787..c9d72eae8ed9263a480936e222fed1ab76508715 100644 --- a/Detector/DetCEPCv4/compact/hcal_defs.xml +++ b/Detector/DetCEPCv4/compact/hcal_defs.xml @@ -1,85 +1,49 @@ <define> - - <constant name="Hcal_radiator_thickness" value="20.0*mm"/> - <constant name="Hcal_chamber_thickness" value="6.73*mm"/> - <constant name="Hcal_back_plate_thickness" value="15*mm"/> - <constant name="Hcal_lateral_structure_thickness" value="10*mm"/> - <constant name="Hcal_stave_gaps" value="3*mm"/> - <constant name="Hcal_modules_gap" value="0.001*mm"/> - <constant name="Hcal_layer_air_gap" value="2*mm"/> - <constant name="Hcal_middle_stave_gaps" value="10*mm"/> + <constant name="Hcal_airgap_thickness" value="1*mm"/> + <constant name="Hcal_mylar_cathode_thickness" value="0.18*mm"/> + <constant name="Hcal_graphite_cathode_thickness" value="0.05*mm"/> + <constant name="Hcal_glass_cathode_thickness" value="1.1*mm"/> + <constant name="Hcal_sensitive_gas_gap" value="1.2*mm"/> + <constant name="Hcal_glass_anode_thickness" value="0.7*mm"/> + <constant name="Hcal_graphite_anode_thickness" value="0.05*mm"/> + <constant name="Hcal_mylar_anode_thickness" value="0.05*mm"/> + <constant name="Hcal_PCB_thickness" value="0.8*mm"/> + <constant name="Hcal_electronics_mask_thickness" value="1.6*mm"/> + <constant name="Hcal_nlayers" value="40"/> - <constant name="Hcal_fiber_gap" value="1.5*mm"/> - <constant name="Hcal_Cu_thickness" value="0.1*mm"/> - <constant name="Hcal_PCB_thickness" value="0.7*mm"/> - <constant name="Hcal_scintillator_thickness" value="3.0*mm"/> + <constant name="Hcal_endcap_nlayers" value="Hcal_nlayers"/> + <constant name="Hcal_ring_nlayers" value="7"/> <constant name="Hcal_cells_size" value="10*mm"/> - <constant name="Hcal_endcap_lateral_structure_thickness" value="5.0*mm"/> - <constant name="Hcal_endcap_layer_air_gap" value="2.5*mm"/> - <constant name="Hcal_endcap_nlayers" value="40"/> <!-- needed for ring only? --> - - <!-- fg: - copy extra parameters for SDHcal from ILD_o2_v01 here - maybe they should all be renamed to SDHCal_ for clarity ? - TK: Yes, here are they ... HcalSD_ - --> - <constant name="HcalSD_cells_size" value="10.406*mm"/> - <constant name="HcalSD_pad_separation" value="0.406*mm"/> - <constant name="HcalSD_radiator_thickness" value="15.0*mm"/> - <constant name="HcalSD_sensitive_gas_gap" value="1.2*mm"/> - <constant name="HcalSD_graphite_cathode_thickness" value="0.05*mm"/> - <constant name="HcalSD_graphite_anode_thickness" value="0.05*mm"/> - <constant name="HcalSD_glass_cathode_thickness" value="1.1*mm"/> - <constant name="HcalSD_glass_anode_thickness" value="0.7*mm"/> - <constant name="HcalSD_g10_thickness" value="1.4*mm"/> - <constant name="HcalSD_mylar_anode_thickness" value="0.05*mm"/> - <constant name="HcalSD_mylar_cathode_thickness" value="0.175*mm"/> - <constant name="HcalSD_mylar_thickness" value="0.2*mm"/> - <constant name="HcalSD_PCB_thickness" value="1.2*mm"/> - <constant name="HcalSD_electronics_mask_thickness" value="1.6*mm"/> - <constant name="HcalSD_steel_casette_thickness" value="2.5*mm"/> - <constant name="HcalSD_airgap_thickness" value="0.5*mm"/> - <constant name="HcalSD_back_plate_thickness" value="10*mm"/> - <constant name="HcalSD_barrel_end_module_type" value="1"/> - <constant name="HcalSD_stave_gaps" value="10*mm"/> - <constant name="HcalSD_lateral_structure_thickness" value="10*mm"/> - <constant name="HcalSD_layer_air_gap" value="2*mm"/> - <constant name="HcalSD_endcap_lateral_structure_thickness" value="5.0*mm"/> - - <constant name="HcalSD_module_wall_thickness" value="10*mm"/> - - <constant name="HcalBarrelSD_nlayers" value="40"/> - <constant name="HcalSD_MinNumCellsInTransvPlane" value="1"/> - <constant name="HcalBarrelSD_number_modules" value="5"/> - <constant name="HcalEndcap_symmetry" value="Hcal_outer_symmetry"/> - <constant name="HcalEndcapRingSD_inner_symmetry" value="Ecal_Hcal_symmetry"/> - <constant name="HcalEndcapRingSD_outer_symmetry" value="HcalEndcap_symmetry"/> - <constant name="HcalEndcapRingSD_nlayers" value="7"/> - <constant name="HcalEndcapSD_nlayers" value="40"/> - - <constant name="HcalSD_gasInlet_length" value="3.0*mm"/> - <constant name="HcalSD_modules_gap" value="20*mm"/> - <constant name="HcalSD_spacer_separation" value="100*mm"/> - <constant name="HcalSD_spacer_thickness" value="8*mm"/> - <constant name="HcalSD_gasInlet_innerRadius" value="0.4*mm"/> - <constant name="HcalSD_gasInlet_outerRadius" value="0.5*mm"/> - - - - <!-- translations --> - <constant name="Hcal_endcap_zmin" value="HcalEndcap_min_z"/> - - <!-- used for "hybrid" readout segmentation --> - <constant name="AHCal_cell_size" value="3.0*cm"/> - <constant name="SDHCal_cell_size" value="1.0*cm"/> - - <!-- TODO move these two element at the correct place --> - <!-- TODO create the additional detectors for the different options for l/s4 and l/s5 --> - <!-- TODO merge the two variables to only one for both barrel and endcap --> - <!-- barrel and endcvap constructors use the slices in reversed order ! --> - <!-- <constant name="Hcal_readout_segmentation_slice_barrel" value="3"/> --> - <!-- <constant name="Hcal_readout_segmentation_slice_endcap" value="3"/> --> - + <constant name="Hcal_gas_edge_width" value="1*mm"/> + <constant name="Hcal_MinNumCellsInTransvPlane" value="11"/> + <constant name="Hcal_barrel_number_modules" value="5"/> + <constant name="Hcal_chamber_thickness" value="6.73*mm"/> + <constant name="Hcal_back_plate_thickness" value="15*mm"/> + <constant name="Hcal_lateral_structure_thickness" value="10*mm"/> + <constant name="Hcal_stave_gaps" value="0*mm"/> + <constant name="Hcal_modules_gap" value="2*mm"/> + + <constant name="Hcal_pad_separation" value="0*mm"/> + <constant name="Hcal_gasInlet_length" value="3.0*mm"/> + <constant name="Hcal_spacer_separation" value="100*mm"/> + <constant name="Hcal_spacer_thickness" value="8*mm"/> + <constant name="Hcal_gasInlet_inner_radius" value="0.4*mm"/> + <constant name="Hcal_gasInlet_outer_radius" value="0.5*mm"/> + + <constant name="Hcal_endcap_outer_symmetry" value="Hcal_outer_symmetry"/> + <constant name="Hcal_ring_inner_symmetry" value="Ecal_Hcal_symmetry"/> + <constant name="Hcal_ring_outer_symmetry" value="Hcal_endcap_outer_symmetry"/> + + <constant name="Hcal_graphite_thickness" value="Hcal_graphite_cathode_thickness+Hcal_graphite_anode_thickness"/> + <constant name="Hcal_mylar_thickness" value="Hcal_mylar_cathode_thickness+Hcal_mylar_anode_thickness"/> + <constant name="Hcal_g10_thickness" value="Hcal_PCB_thickness+Hcal_electronics_mask_thickness"/> + <constant name="Hcal_mix_thickness" value="Hcal_airgap_thickness+Hcal_graphite_thickness+Hcal_mylar_thickness+Hcal_g10_thickness"/> + <constant name="Hcal_mix_density" value="Hcal_airgap_thickness/Hcal_mix_thickness*0.00120479 + Hcal_graphite_thickness/Hcal_mix_thickness*2.21 + + Hcal_mylar_thickness/Hcal_mix_thickness*1.4 + Hcal_g10_thickness/Hcal_mix_thickness*1.7"/> + <constant name="Hcal_airgap_fraction" value="Hcal_airgap_thickness/Hcal_mix_thickness*0.00120479/Hcal_mix_density"/> + <constant name="Hcal_graphite_fraction" value="Hcal_graphite_thickness/Hcal_mix_thickness*2.21/Hcal_mix_density"/> + <constant name="Hcal_mylar_fraction" value="Hcal_mylar_thickness/Hcal_mix_thickness*1.4/Hcal_mix_density"/> + <constant name="Hcal_g10_fraction" value="Hcal_g10_thickness/Hcal_mix_thickness*1.7/Hcal_mix_density"/> </define> diff --git a/Detector/DetCEPCv4/compact/top_defs.xml b/Detector/DetCEPCv4/compact/top_defs.xml index bb0f6ac7ea7b05ac8455fcfec6f7d061415a141c..6b09c8a30df471c5354ff6227666c350894fe20d 100644 --- a/Detector/DetCEPCv4/compact/top_defs.xml +++ b/Detector/DetCEPCv4/compact/top_defs.xml @@ -58,16 +58,17 @@ <constant name="Ecal_EC_Ring_gap" value="10*mm"/> <!-- HCAL --> - <constant name="Hcal_barrel_thickness" value="1272.3*mm"/> + <constant name="Hcal_barrel_thickness" value="1086.43*mm"/> <constant name="Hcal_Coil_additional_gap" value="29.5*mm"/> <!--constant name="Hcal_outer_symmetry" value="16"/--> <constant name="Hcal_outer_symmetry" value="8"/> <constant name="Hcal_endcap_center_box_size" value="700.0*mm"/> <constant name="Hcal_endcap_zmin" value="2650*mm" /> - <constant name="Hcal_endcap_thickness" value="1287.0*mm"/> + <constant name="Hcal_endcap_thickness" value="1084.2*mm"/> <constant name="Hcal_radial_ring_inner_gap" value="50*mm"/> - <constant name="Hcal_endcap_cryostat_gap" value="170*mm"/> + <constant name="Hcal_endcap_cryostat_gap" value="0*mm"/> + <constant name="Hcal_endcap_ecal_gap" value="15*mm"/> <!-- coil --> <constant name="Coil_extra_size" value="1522*mm"/> diff --git a/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_Barrel.cpp b/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_Barrel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9801a0a17418f93b03e46f8ea259be8f80e6ad6c --- /dev/null +++ b/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_Barrel.cpp @@ -0,0 +1,333 @@ +//==================================================================== +// SHcalRpc01 - Implementation from ILCSoft's Mokka version +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetType.h" + +#include "DDRec/Surface.h" +#include "DDRec/DetectorData.h" +#include "XML/Utilities.h" + +using namespace std; + +using dd4hep::Ref_t; +using dd4hep::BUILD_ENVELOPE; +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::SensitiveDetector; +using dd4hep::Segmentation; +using dd4hep::Readout; +using dd4hep::Material; +using dd4hep::Volume; +using dd4hep::PlacedVolume; +using dd4hep::Position; +using dd4hep::RotationZYX; +using dd4hep::Transform3D; +using dd4hep::Box; +using dd4hep::Tube; +using dd4hep::PolyhedraRegular; +using dd4hep::SubtractionSolid; +using dd4hep::_toString; +using dd4hep::pi; +using dd4hep::rec::LayeredCalorimeterData; + +/** Construction of SHcalRpc01 detector, ported from Mokka driver SHcalRpc01.cc + * + * Mokka History: + * - first implementation from ILCSoft + * - http://cepcgit.ihep.ac.cn/cepcsoft/MokkaC + */ +static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens) { + cout << "--------------------------" << endl; + cout << "creating SHcalRpc01_Barrel" << endl; + cout << "--------------------------" << endl; + + xml_det_t x_det = element; + string name = x_det.nameStr(); + int det_id = x_det.id(); + DetElement det(name, det_id); + + Volume envelope = dd4hep::xml::createPlacedEnvelope(theDetector, element , det ) ; + + dd4hep::xml::setDetectorTypeFlag(element, det) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return det ; + + xml_comp_t x_staves = x_det.staves(); + string Hcal_radiator_material = x_staves.materialStr(); + Material stavesMaterial = theDetector.material(Hcal_radiator_material); + Material air = theDetector.air(); + + sens.setType("calorimeter"); + + Readout readout = sens.readout(); + Segmentation seg = readout.segmentation(); + + std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); + double cell_sizeX = cellSizeVector[0]; + double cell_sizeZ = cellSizeVector[1]; + + double Hcal_inner_radius = theDetector.constant<double>("Hcal_inner_radius"); + double Hcal_outer_radius_set = theDetector.constant<double>("Hcal_outer_radius"); + double Hcal_half_length = theDetector.constant<double>("Hcal_half_length"); + int Hcal_inner_symmetry = theDetector.constant<int>("Hcal_inner_symmetry"); + int Hcal_outer_symmetry = 0; + double Hcal_lateral_plate_thickness = theDetector.constant<double>("Hcal_lateral_structure_thickness"); + double Hcal_modules_gap = theDetector.constant<double>("Hcal_modules_gap"); + int Hcal_nlayers = theDetector.constant<int>("Hcal_nlayers"); + double TPC_outer_radius = theDetector.constant<double>("TPC_outer_radius"); + double Ecal_outer_radius = theDetector.constant<double>("Ecal_outer_radius"); + int Hcal_barrel_number_modules = theDetector.constant<int>("Hcal_barrel_number_modules"); + + double hPrime = Ecal_outer_radius + theDetector.constant<double>("Hcal_Ecal_gap"); + Hcal_inner_radius = hPrime / cos(pi/8.); + + double Hcal_normal_dim_z = (2*Hcal_half_length - (Hcal_barrel_number_modules-1)*Hcal_modules_gap)/Hcal_barrel_number_modules; + + xml_coll_t c(x_det,_U(layer)); + xml_comp_t x_layer = c; + + double Hcal_radiator_thickness = 0; + double layerThickness = 0.0; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + layerThickness += x_slice.thickness(); + if(x_slice.materialStr()==Hcal_radiator_material) Hcal_radiator_thickness = x_slice.thickness(); + } + cout << " layer_thickness (from slices) = " << layerThickness << " and radiator_thickness = " << Hcal_radiator_thickness << endl; + double Hcal_chamber_thickness = layerThickness - Hcal_radiator_thickness; + + int MinNumCellsInTransvPlane = theDetector.constant<int>("Hcal_MinNumCellsInTransvPlane"); + double RPC_EdgeWidth = theDetector.constant<double>("Hcal_gas_edge_width"); + double RPCGazInletInnerRadius = theDetector.constant<double>("Hcal_gasInlet_inner_radius"); + double RPCGazInletOuterRadius = theDetector.constant<double>("Hcal_gasInlet_outer_radius"); + double RPCGazInletLength = theDetector.constant<double>("Hcal_gasInlet_length"); + double RPC_PadSeparation = theDetector.constant<double>("Hcal_pad_separation"); + double Hcal_spacer_thickness = theDetector.constant<double>("Hcal_spacer_thickness"); + double Hcal_spacer_separation = theDetector.constant<double>("Hcal_spacer_separation"); + + //========== fill data for reconstruction ============================ + LayeredCalorimeterData* caloData = new LayeredCalorimeterData ; + caloData->layoutType = LayeredCalorimeterData::BarrelLayout ; + caloData->inner_symmetry = Hcal_inner_symmetry ; + caloData->outer_symmetry = Hcal_outer_symmetry ; + caloData->phi0 = 0 ; // fg: also hardcoded below + + // general calculated parameters + double AngleRatio=0.76536686;//"k" + double d_InnerOctoSize=AngleRatio*Hcal_inner_radius;//"d" + double LMin = 2*RPC_EdgeWidth+cell_sizeX*MinNumCellsInTransvPlane+(MinNumCellsInTransvPlane+1)*RPC_PadSeparation; + + double Ynl = 0.5*d_InnerOctoSize - Hcal_nlayers*layerThickness; + double Hcal_outer_radius = sqrt((LMin-Ynl)*(LMin-Ynl) + (hPrime + Hcal_nlayers*layerThickness)*(hPrime + Hcal_nlayers*layerThickness)); + if(Hcal_outer_radius!=Hcal_outer_radius_set){ + cout << "calculated Hcal_outer_radius != input, will impact HcalEndcap and HcalEndcapRing. Hcal_outer_radius = " << Hcal_outer_radius + << " but set as " << Hcal_outer_radius_set << " difference = " << Hcal_outer_radius-Hcal_outer_radius_set << endl; + } + + /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in cm. + caloData->extent[0] = Hcal_inner_radius ; + caloData->extent[1] = Hcal_outer_radius ; + caloData->extent[2] = 0. ; // Barrel zmin is "0" by default. + caloData->extent[3] = Hcal_half_length ; + + double Hcal_total_dim_y = Hcal_outer_radius - hPrime; + + // the y_dim1_for_z kept as the original value in TDR + double Hcal_regular_chamber_dim_z = Hcal_normal_dim_z - 2 *(Hcal_lateral_plate_thickness); + //int N_cells_z = static_cast <int> ( (Hcal_regular_chamber_dim_z - 2*RPC_EdgeWidth - RPC_PadSeparation) / (Hcal_cell_dim_x + RPC_PadSeparation) ); + // Hcal_cell_dim_z=(Hcal_regular_chamber_dim_z-RPC_PadSeparation )/N_cells_z + // - RPC_PadSeparation; + Tube solidCaloTube(0, Hcal_outer_radius, Hcal_half_length); + + PolyhedraRegular solidOctogon(8, 0, hPrime, 4*Hcal_half_length); + RotationZYX rotOctogon(dd4hep::twopi/16,0,0); + SubtractionSolid solidCalo(solidCaloTube, solidOctogon, rotOctogon); + Volume logicCalo(name+"_radiator", solidCalo, stavesMaterial); + logicCalo.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + PlacedVolume calo_pv = envelope.placeVolume(logicCalo, Position(0,0,0)); + DetElement calo(det, "envelope", det_id); + calo.setPlacement(calo_pv); + + for(int layer_id=1; layer_id<=Hcal_nlayers; layer_id++){ + double yn = sqrt(Hcal_outer_radius*Hcal_outer_radius - (hPrime + layer_id*layerThickness)*(hPrime + layer_id*layerThickness)); + double Yn = 0.5*d_InnerOctoSize - layer_id*layerThickness; + + double halfX = Hcal_chamber_thickness/2.; + double halfZ = (yn+Yn)/2.; + + LayeredCalorimeterData::Layer caloLayer ; + caloLayer.cellSize0 = cell_sizeX; + caloLayer.cellSize1 = cell_sizeZ; + + //double halfY = Hcal_normal_dim_z / 2.; + double halfY = Hcal_regular_chamber_dim_z / 2.; + + double localXPos = hPrime + Hcal_radiator_thickness + Hcal_chamber_thickness/2. + (layer_id-1)*layerThickness; + double localYPos = -Yn + 0.5*(Yn + yn); + Box chamberSolid(halfX, halfY, halfZ); + string chamberLogical_name = name+_toString(layer_id,"_layer%d"); + Volume chamberLogical(chamberLogical_name, chamberSolid, air); + chamberLogical.setAttributes(theDetector, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr()); + + string layer_name = name+_toString(layer_id,"_layer%d"); + + double nRadiationLengths=0.; + double nInteractionLengths=0.; + double thickness_sum=0; + + nRadiationLengths = Hcal_radiator_thickness/(stavesMaterial.radLength()); + nInteractionLengths = Hcal_radiator_thickness/(stavesMaterial.intLength()); + + double slice_pos_z = -halfX; + int slice_number = 0; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + if(x_slice.materialStr()==Hcal_radiator_material) continue; + string slice_name = layer_name + _toString(slice_number,"_slice%d"); + double slice_thickness = x_slice.thickness(); + Material slice_material = theDetector.material(x_slice.materialStr()); + if(layer_id==1) cout<<" Layer_slice: "<< slice_name<<" slice_thickness: "<< slice_thickness<< endl; + + slice_pos_z += slice_thickness/2.; + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + + // Slice volume & box + Box sliceSolid(slice_thickness/2., halfY, halfZ); + Volume sliceVol(slice_name, sliceSolid, slice_material); + + if ( x_slice.isSensitive() ) { + sliceVol.setSensitiveDetector(sens); + if(RPC_EdgeWidth>0){ + double RPC_GazInlet_In_Y = halfY - RPC_EdgeWidth - RPCGazInletOuterRadius; + double RPC_GazInlet_In_Z = halfZ - RPC_EdgeWidth/2; + double RPC_GazInlet_Out_Y = -RPC_GazInlet_In_Y; + double RPC_GazInlet_Out_Z = RPC_GazInlet_In_Z; + + string mateialName = x_slice.attr<string>(_Unicode(edge_material)); + Material edge_material = theDetector.material(mateialName); + Box solidRPCEdge1(slice_thickness/2.,halfY, halfZ); + Box solidRPCEdge2(slice_thickness/2.,halfY-RPC_EdgeWidth, halfZ-RPC_EdgeWidth); + SubtractionSolid solidRPCEdge(solidRPCEdge1, solidRPCEdge2, Position(0,0,0)); + Volume logicRPCEdge(slice_name+"_edge", solidRPCEdge, edge_material); + logicRPCEdge.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + sliceVol.placeVolume(logicRPCEdge); + + Tube solidRPCGazInlet(RPCGazInletInnerRadius,RPCGazInletOuterRadius,RPC_EdgeWidth/*RPCGazInletLength*//2); + Volume logicRPCGazInlet(slice_name+"_GazInlet", solidRPCGazInlet, edge_material); + logicRPCGazInlet.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + logicRPCEdge.placeVolume(logicRPCGazInlet, Position(0,RPC_GazInlet_In_Y,RPC_GazInlet_In_Z)); + logicRPCEdge.placeVolume(logicRPCGazInlet, Position(0,RPC_GazInlet_Out_Y,RPC_GazInlet_Out_Z)); + + Tube solidRPCGazInsideInlet(0,RPCGazInletInnerRadius,RPC_EdgeWidth/*RPCGazInletLength*//2); + Volume logicRPCGazInsideInlet(slice_name+"_GazInsideInlet", solidRPCGazInsideInlet, slice_material); + logicRPCGazInsideInlet.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),"SeeThrough"); + logicRPCEdge.placeVolume(logicRPCGazInsideInlet, Position(0,RPC_GazInlet_In_Y,RPC_GazInlet_In_Z)); + logicRPCEdge.placeVolume(logicRPCGazInsideInlet, Position(0,RPC_GazInlet_Out_Y,RPC_GazInlet_Out_Z)); + } + if(Hcal_spacer_thickness>0){ + Tube solidRPCSpacer(0,Hcal_spacer_thickness/2,slice_thickness/2); + Material space_material = theDetector.material(x_slice.attr<string>(_Unicode(spacer_material))); + Volume logicRPCSpacer(slice_name+"_spacer", solidRPCSpacer, space_material); + logicRPCSpacer.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + RotationZYX rotSpacer(0, pi/2., 0); + + double gap_hZ = halfZ-RPC_EdgeWidth; + double gap_hY = halfY-RPC_EdgeWidth; + int y_number_of_separations = (int)(2*gap_hY/Hcal_spacer_separation); + int z_number_of_separations = (int)(2*gap_hZ/Hcal_spacer_separation); + double y_lateral_space = (2*gap_hY - y_number_of_separations*Hcal_spacer_separation)/2; + double z_lateral_space = (2*gap_hZ - z_number_of_separations*Hcal_spacer_separation)/2; + if(y_lateral_space < Hcal_spacer_thickness/2.){ + y_number_of_separations = (int)((2*gap_hY-Hcal_spacer_thickness)/Hcal_spacer_separation); + y_lateral_space = (2*gap_hY - y_number_of_separations*Hcal_spacer_separation)/2; + } + if(z_lateral_space < Hcal_spacer_thickness/2.){ + z_number_of_separations = (int)((2*gap_hZ-Hcal_spacer_thickness)/Hcal_spacer_separation); + z_lateral_space = (2*gap_hZ - z_number_of_separations*Hcal_spacer_separation)/2; + } + for(int y_counter = 0; y_counter <=y_number_of_separations; y_counter++){ + double SpacerY = gap_hY - y_lateral_space - y_counter*Hcal_spacer_separation; + for(int z_counter = 0; z_counter <=z_number_of_separations; z_counter++){ + double SpacerZ = gap_hZ - z_lateral_space - z_counter*Hcal_spacer_separation; + PlacedVolume space_pv = sliceVol.placeVolume(logicRPCSpacer, Transform3D(rotSpacer, Position(0,SpacerY,SpacerZ))); + } + } + } + + caloLayer.inner_nRadiationLengths = nRadiationLengths; + caloLayer.inner_nInteractionLengths = nInteractionLengths; + caloLayer.inner_thickness = thickness_sum; + if(layer_id==1) cout<<"Hcal_Barrel: inner_thickness= "<<thickness_sum<<endl; + //Store readout gasgap thickness + caloLayer.sensitive_thickness = slice_thickness; + //Reset counters to measure "outside" quantitites + nRadiationLengths=0.; + nInteractionLengths=0.; + thickness_sum = 0.; + + sliceVol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),"SeeThrough"); + } + else{ + sliceVol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + } + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + + // slice PlacedVolume + PlacedVolume slice_phv = chamberLogical.placeVolume(sliceVol,Position(slice_pos_z,0,0)); + if ( x_slice.isSensitive() ) { + int slice_id = (layer_id > Hcal_nlayers)? 1:-1; + slice_phv.addPhysVolID("layer",layer_id).addPhysVolID("slice",slice_id); + } + DetElement sliceDetE(layer_name,_toString(slice_number,"slice%d"),x_det.id()); + sliceDetE.setPlacement(slice_phv); + // Increment x position for next slice. + slice_pos_z += slice_thickness/2.; + // Increment slice number. + ++slice_number; + } + caloLayer.outer_nRadiationLengths = nRadiationLengths; + caloLayer.outer_nInteractionLengths = nInteractionLengths; + caloLayer.outer_thickness = thickness_sum; + if(layer_id==1) cout << "Hcal_Barrel: outer_thickness= " << thickness_sum << endl; + + double chamber_y_offset = -(-Hcal_total_dim_y/2. + (layer_id-1)*layerThickness + layerThickness/2.); + + caloLayer.distance = Hcal_inner_radius + Hcal_total_dim_y/2.0 + chamber_y_offset ; + caloLayer.absorberThickness = Hcal_radiator_thickness ; + + caloData->layers.push_back( caloLayer ) ; + + double stave_phi_offset, module_z_offset; + + stave_phi_offset = pi*0.5; + for(int stave_id = 1; stave_id <= 8; stave_id++){ + double phirot = stave_phi_offset+(stave_id-1)*pi/4.; + + RotationZYX rot(0, phirot, pi*0.5); + RotationZYX rotInverse(0,-phirot, -pi*0.5); + for(int module_id = 1; module_id <= Hcal_barrel_number_modules; module_id++){ + module_z_offset = - Hcal_half_length + Hcal_normal_dim_z/2. + (module_id-1)*(Hcal_normal_dim_z+Hcal_modules_gap); + + Position localPos(localXPos,-module_z_offset,localYPos); + Position newPos = rotInverse*localPos; + Transform3D tran3D(rot, newPos); + PlacedVolume pv = logicCalo.placeVolume(chamberLogical, tran3D); + pv.addPhysVolID("stave",stave_id).addPhysVolID("module",module_id).addPhysVolID("layer",layer_id); + DetElement layer(calo, name+_toString(stave_id,"_stave%d")+_toString(module_id,"_module%d")+_toString(layer_id,"_layer%d"), det_id); + layer.setPlacement(pv); + } + } + } + + det.addExtension< LayeredCalorimeterData >( caloData ) ; + + return det; +} + +DECLARE_DETELEMENT(SHcalRpc01_Barrel, create_detector) diff --git a/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_EndcapRing.cpp b/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_EndcapRing.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a9978cc85833ad6807f55cbaae2fd9d74d3656d --- /dev/null +++ b/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_EndcapRing.cpp @@ -0,0 +1,266 @@ +//==================================================================== +// SHcalRpc01 - Implementation from ILCSoft's Mokka version +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetType.h" + +#include "DDRec/Surface.h" +#include "DDRec/DetectorData.h" +#include "XML/Utilities.h" + +using namespace std; + +using dd4hep::Ref_t; +using dd4hep::BUILD_ENVELOPE; +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::SensitiveDetector; +using dd4hep::Segmentation; +using dd4hep::Readout; +using dd4hep::Material; +using dd4hep::Volume; +using dd4hep::PlacedVolume; +using dd4hep::Position; +using dd4hep::RotationZYX; +using dd4hep::Transform3D; +using dd4hep::Box; +using dd4hep::Tube; +using dd4hep::PolyhedraRegular; +using dd4hep::SubtractionSolid; +using dd4hep::IntersectionSolid; +using dd4hep::_toString; +using dd4hep::pi; +using dd4hep::rec::LayeredCalorimeterData; + +/** Construction of SHcalRpc01 detector, ported from Mokka driver SHcalRpc01.cc + * + * Mokka History: + * - first implementation from ILCSoft + * - http://cepcgit.ihep.ac.cn/cepcsoft/MokkaC + */ +static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens) { + cout << "------------------------------" << endl; + cout << "creating SHcalRpc01_EndcapRing" << endl; + cout << "------------------------------" << endl; + + xml_det_t x_det = element; + string name = x_det.nameStr(); + + int det_id = x_det.id(); + DetElement det(name, det_id) ; + + xml_comp_t x_staves = x_det.staves(); + string Hcal_radiator_material = x_staves.materialStr(); + Material stavesMaterial = theDetector.material(Hcal_radiator_material); + Material air = theDetector.air(); + + Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, element , det ) ; + + dd4hep::xml::setDetectorTypeFlag( element, det ) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return det ; + + sens.setType("calorimeter"); + + DetElement module(det,"module0",det_id); + DetElement layer(module, "stave_layer", det_id); + DetElement slice(layer, "slice", det_id); + + Readout readout = sens.readout(); + Segmentation seg = readout.segmentation(); + + std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); + double cell_sizeX = cellSizeVector[0]; + double cell_sizeY = cellSizeVector[1]; + + double Hcal_outer_radius = theDetector.constant<double>("Hcal_outer_radius"); + int Hcal_endcap_outer_symmetry = theDetector.constant<int>("Hcal_endcap_outer_symmetry"); + double Hcal_stave_gaps = theDetector.constant<double>("Hcal_stave_gaps"); + int Hcal_nlayers = theDetector.constant<int>("Hcal_endcap_nlayers"); + double Hcal_start_z = theDetector.constant<double>("Hcal_endcap_zmin"); + double Hcal_lateral_plate_thickness = theDetector.constant<double>("Hcal_lateral_structure_thickness"); + double Ecal_endcap_zmin = theDetector.constant<double>("Ecal_endcap_zmin"); + double Hcal_endcap_ecal_gap = theDetector.constant<double>("Hcal_endcap_ecal_gap"); + double Ecal_endcap_outer_radius = theDetector.constant<double>("EcalEndcap_outer_radius"); + double Hcal_radial_ring_inner_gap = theDetector.constant<double>("Hcal_radial_ring_inner_gap"); + + xml_coll_t c(x_det,_U(layer)); + xml_comp_t x_layer = c; + + double Hcal_radiator_thickness = 0; + double layerThickness = 0.0; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + layerThickness += x_slice.thickness(); + if(x_slice.materialStr()==Hcal_radiator_material) Hcal_radiator_thickness = x_slice.thickness(); + } + cout << " layer_thickness (from slices) = " << layerThickness << " and radiator_thickness = " << Hcal_radiator_thickness << endl; + double Hcal_chamber_thickness = layerThickness - Hcal_radiator_thickness; + + int numSide = Hcal_endcap_outer_symmetry; + double Hcal_endcap_rmax = Hcal_outer_radius * cos(pi/numSide); + + LayeredCalorimeterData* caloData = new LayeredCalorimeterData ; + caloData->layoutType = LayeredCalorimeterData::EndcapLayout ; + caloData->inner_symmetry = numSide; + caloData->outer_symmetry = numSide; + caloData->phi0 = 0; + + double start_z = Ecal_endcap_zmin; + double SpaceForLayers = Hcal_start_z - Hcal_endcap_ecal_gap - Ecal_endcap_zmin - 2*Hcal_lateral_plate_thickness; + int MaxNumberOfLayers = (int)(SpaceForLayers / (Hcal_chamber_thickness + Hcal_radiator_thickness)); + double stop_z = start_z + MaxNumberOfLayers*layerThickness + 2*Hcal_lateral_plate_thickness; + + double pRMax = Hcal_endcap_rmax; + double pDz = (stop_z - start_z)/2.; + double pRMin = Ecal_endcap_outer_radius + Hcal_radial_ring_inner_gap; + + cout << "Rings will have " << MaxNumberOfLayers << " layers." << endl; + cout << " Z: " << start_z << " -> " << stop_z << endl; + cout << " R: " << pRMin << " -> " << pRMax << endl; + + caloData->extent[0] = pRMin; + caloData->extent[1] = pRMax; + caloData->extent[2] = start_z; + caloData->extent[3] = stop_z; + + PolyhedraRegular EndCapRingSolidPoly(numSide, -pi/numSide, pRMin, pRMax, 2*pDz); + Volume EndCapRingLogical(name+"_radiator", EndCapRingSolidPoly, stavesMaterial); + EndCapRingLogical.setAttributes(theDetector,x_staves.regionStr(),x_staves.limitsStr(),x_staves.visStr()); + + int number_of_chambers = Hcal_nlayers; + if(MaxNumberOfLayers < number_of_chambers) number_of_chambers = MaxNumberOfLayers; + + double rInner = pRMin + Hcal_lateral_plate_thickness; + double rOuter = pRMax - Hcal_lateral_plate_thickness; + + PolyhedraRegular EndCapRingChamberPoly(numSide, -pi/numSide, rInner, rOuter, Hcal_chamber_thickness); + Box IntersectionStaveBox(rOuter/2., rOuter/2., Hcal_chamber_thickness/2); + Position IntersectPos(rOuter/2. + Hcal_stave_gaps/2., rOuter/2. + Hcal_stave_gaps/2., 0.); + IntersectionSolid EndCapRingStaveSolid(EndCapRingChamberPoly, IntersectionStaveBox, IntersectPos); + Volume EndCapRingChamberLogical(name+"_chamber", EndCapRingStaveSolid, air); + EndCapRingChamberLogical.setAttributes(theDetector,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + + double nRadiationLengthsInside=0.; + double nInteractionLengthsInside=0.; + double inner_thickness=0; + double sensitive_thickness=0; + double nRadiationLengths=0.; + double nInteractionLengths=0.; + double thickness_sum=0; + + double slice_pos_z = -Hcal_chamber_thickness/2.; + int slice_number = 0; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + string slice_name = name + _toString(slice_number,"_slice%d"); + double slice_thickness = x_slice.thickness(); + Material slice_material = theDetector.material(x_slice.materialStr()); + cout<<" Layer_slice: " << slice_name << " slice_thickness: " << slice_thickness<< endl; + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + if(x_slice.materialStr()==Hcal_radiator_material) continue; + + slice_pos_z += slice_thickness/2.; + + PolyhedraRegular slicePoly(numSide, -pi/numSide, rInner, rOuter, slice_thickness); + IntersectionSolid sliceStaveSolid(slicePoly, IntersectionStaveBox, IntersectPos); + Volume sliceVol(name + _toString(slice_number,"_slice%d"), sliceStaveSolid, slice_material); + sliceVol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + if(x_slice.isSensitive()){ + sliceVol.setSensitiveDetector(sens); + nRadiationLengthsInside = nRadiationLengths; + nInteractionLengthsInside = nInteractionLengths; + inner_thickness = thickness_sum; + sensitive_thickness = slice_thickness; + + nRadiationLengths=0.; + nInteractionLengths=0.; + thickness_sum = 0.; + } + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + // slice PlacedVolume + PlacedVolume slice_phv = EndCapRingChamberLogical.placeVolume(sliceVol,Position(0,0,slice_pos_z)); + //DetElement slice(layer_name,_toString(slice_number,"slice%d"),x_det.id()); + slice.setPlacement(slice_phv); + // Increment x position for next slice. + slice_pos_z += slice_thickness/2.; + // Increment slice number. + ++slice_number; + } + + // chamber placements + for(int stave_id = 1; stave_id <= 4; stave_id++){ + double angle = pi/2.*(stave_id-1); + RotationZYX lrot(angle,0,0); + for (int layer_id = 1; layer_id <= number_of_chambers; layer_id++){ + double Zoff = -pDz + (layer_id-1)*layerThickness + Hcal_radiator_thickness + Hcal_chamber_thickness/2.; + Position l_pos(0., 0., Zoff); + Position l_new = lrot*l_pos; + Transform3D ltran3D(lrot,l_new); + PlacedVolume layer_phv = EndCapRingLogical.placeVolume(EndCapRingChamberLogical, ltran3D); + layer_phv.addPhysVolID("layer",layer_id); + layer_phv.addPhysVolID("stave",stave_id); + + //string l_name = _toString(layer_id,"layer%d"); + //string stave_name = _toString(stave_id,"stave%d"); + //DetElement layer(module_det, l_name+stave_name, det_id); + layer.setPlacement(layer_phv); + + if(stave_id==1&&layer_id==1){ + cout << "Hcal_EndcapRing: inner_thickness= " << inner_thickness << endl; + cout << "Hcal_EndcapRing: outer_thickness= " << thickness_sum << endl; + } + LayeredCalorimeterData::Layer caloLayer ; + caloLayer.cellSize0 = cell_sizeX; + caloLayer.cellSize1 = cell_sizeY; + caloLayer.inner_nRadiationLengths = nRadiationLengthsInside; + caloLayer.inner_nInteractionLengths = nInteractionLengthsInside; + caloLayer.inner_thickness = inner_thickness; + caloLayer.sensitive_thickness = sensitive_thickness; + caloLayer.outer_nRadiationLengths = nRadiationLengths; + caloLayer.outer_nInteractionLengths = nInteractionLengths; + caloLayer.outer_thickness = thickness_sum; + + caloLayer.distance = start_z + (layer_id-1)*layerThickness; + caloLayer.absorberThickness = Hcal_radiator_thickness ; + + caloData->layers.push_back( caloLayer ) ; + } + } + + // Placements + double endcap_z_offset = start_z + pDz; + for(int side = 0; side <= 1; side++){ + int module_id = (side==0) ? 0 : 6; + double this_module_z_offset = (side==0) ? endcap_z_offset : -endcap_z_offset; + // use reflect volume for z<0, therefore, same rotation + // segmentation violation happen if EndCapRingLogical.reflect(), back to rotate Y + // double this_module_rotY = (side==0) ? 0.0 : 0.0; + double this_module_rotY = (side==0) ? 0.0 : pi; + //double this_module_rotZ = (side==0) ? pi/8. : pi/8; + RotationZYX rot(0,this_module_rotY,0); + Transform3D tran3D(rot,Position(0,0,this_module_z_offset)); + + PlacedVolume module_phv; + //if(side==0) module_phv = envelope.placeVolume(EndCapRingLogical, tran3D); + //else module_phv = envelope.placeVolume(EndCapRingLogical.reflect(), tran3D); + module_phv = envelope.placeVolume(EndCapRingLogical, tran3D); + + module_phv.addPhysVolID("module", module_id); + //DetElement sd = (module_id==0) ? module_det : module_det.clone(_toString(side,"module%d")); + module.setPlacement(module_phv); + } + + det.addExtension<LayeredCalorimeterData>(caloData) ; + + return det; +} + +DECLARE_DETELEMENT(SHcalRpc01_EndcapRing, create_detector) diff --git a/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_Endcaps.cpp b/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_Endcaps.cpp new file mode 100644 index 0000000000000000000000000000000000000000..abe42b6588278d3ba043656bd109f89922693527 --- /dev/null +++ b/Detector/DetCEPCv4/src/calorimeter/SHcalRpc01_Endcaps.cpp @@ -0,0 +1,269 @@ +//==================================================================== +// SHcalRpc01 - Implementation from ILCSoft's Mokka version +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetType.h" + +#include "DDRec/Surface.h" +#include "DDRec/DetectorData.h" +#include "XML/Utilities.h" + +using namespace std; + +using dd4hep::Ref_t; +using dd4hep::BUILD_ENVELOPE; +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::SensitiveDetector; +using dd4hep::Segmentation; +using dd4hep::Readout; +using dd4hep::Material; +using dd4hep::Volume; +using dd4hep::PlacedVolume; +using dd4hep::Position; +using dd4hep::RotationZYX; +using dd4hep::Transform3D; +using dd4hep::Box; +using dd4hep::Tube; +using dd4hep::PolyhedraRegular; +using dd4hep::SubtractionSolid; +using dd4hep::IntersectionSolid; +using dd4hep::_toString; +using dd4hep::pi; +using dd4hep::rec::LayeredCalorimeterData; + +/** Construction of SHcalRpc01 detector, ported from Mokka driver SHcalRpc01.cc + * + * Mokka History: + * - first implementation from ILCSoft + * - http://cepcgit.ihep.ac.cn/cepcsoft/MokkaC + */ +static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens) { + cout << "--------------------------" << endl; + cout << "creating SHcalRpc01_Endcap" << endl; + cout << "--------------------------" << endl; + + xml_det_t x_det = element; + string name = x_det.nameStr(); + + int det_id = x_det.id(); + DetElement det(name, det_id) ; + + xml_comp_t x_staves = x_det.staves(); + string Hcal_radiator_material = x_staves.materialStr(); + Material stavesMaterial = theDetector.material(Hcal_radiator_material); + Material air = theDetector.air(); + + Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, element , det ) ; + + dd4hep::xml::setDetectorTypeFlag( element, det ) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return det ; + + sens.setType("calorimeter"); + + DetElement module(det,"module0",det_id); + DetElement layer(module, "stave_layer", det_id); + DetElement slice(layer, "slice", det_id); + + Readout readout = sens.readout(); + Segmentation seg = readout.segmentation(); + + std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); + double cell_sizeX = cellSizeVector[0]; + double cell_sizeY = cellSizeVector[1]; + + //double Hcal_inner_radius = theDetector.constant<double>("Hcal_inner_radius"); + double Hcal_outer_radius = theDetector.constant<double>("Hcal_outer_radius"); + //double Hcal_half_length = theDetector.constant<double>("Hcal_half_length"); + int Hcal_endcap_outer_symmetry = theDetector.constant<int>("Hcal_endcap_outer_symmetry"); + //double Hcal_cells_size = theDetector.constant<double>("Hcal_cells_size"); + double Hcal_stave_gaps = theDetector.constant<double>("Hcal_stave_gaps"); + int Hcal_nlayers = theDetector.constant<int>("Hcal_endcap_nlayers"); + double Hcal_start_z = theDetector.constant<double>("Hcal_endcap_zmin"); + double Hcal_back_plate_thickness = theDetector.constant<double>("Hcal_back_plate_thickness"); + double Hcal_lateral_plate_thickness = theDetector.constant<double>("Hcal_lateral_structure_thickness"); + double Hcal_endcap_center_box_size = theDetector.constant<double>("Hcal_endcap_center_box_size"); + + xml_coll_t c(x_det,_U(layer)); + xml_comp_t x_layer = c; + + double Hcal_radiator_thickness = 0; + double layerThickness = 0.0; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + layerThickness += x_slice.thickness(); + if(x_slice.materialStr()==Hcal_radiator_material) Hcal_radiator_thickness = x_slice.thickness(); + } + cout << " layer_thickness (from slices) = " << layerThickness << " and radiator_thickness = " << Hcal_radiator_thickness << endl; + double Hcal_chamber_thickness = layerThickness - Hcal_radiator_thickness; + + int numSide = Hcal_endcap_outer_symmetry; + double Hcal_endcap_thickness = Hcal_nlayers*layerThickness + Hcal_back_plate_thickness; + double Hcal_endcap_rmax = Hcal_outer_radius * cos(pi/numSide); + + LayeredCalorimeterData* caloData = new LayeredCalorimeterData; + caloData->layoutType = LayeredCalorimeterData::EndcapLayout; + caloData->inner_symmetry = 4; + caloData->outer_symmetry = Hcal_endcap_outer_symmetry; + caloData->phi0 = 0; + + caloData->extent[0] = Hcal_endcap_center_box_size/2.; + caloData->extent[1] = Hcal_outer_radius; + caloData->extent[2] = Hcal_start_z; + caloData->extent[3] = Hcal_start_z+Hcal_endcap_thickness; + + double pRMax = Hcal_endcap_rmax; + double pDz = Hcal_endcap_thickness/2.; + double pRMin = Hcal_endcap_center_box_size/2.; + + PolyhedraRegular EndCapSolidPoly(numSide, -pi/numSide, 0., pRMax, 2*pDz); + Box hcalECInnerHole(pRMin, pRMin, pDz); + SubtractionSolid solidHCalEC(EndCapSolidPoly,hcalECInnerHole); + Volume EndCapLogical(name+"_radiator", solidHCalEC, stavesMaterial); + EndCapLogical.setAttributes(theDetector,x_staves.regionStr(),x_staves.limitsStr(),x_staves.visStr()); + + int number_of_chambers = Hcal_nlayers; + int possible_number_of_chambers = (int) (floor(abs(Hcal_endcap_thickness-Hcal_back_plate_thickness) / (Hcal_chamber_thickness + Hcal_radiator_thickness))); + if(possible_number_of_chambers < number_of_chambers) number_of_chambers = possible_number_of_chambers; + + double rInner = 0.; + double rOuter= Hcal_endcap_rmax - Hcal_lateral_plate_thickness; + + PolyhedraRegular EndCapChamberPoly(numSide, -pi/numSide, rInner, rOuter, Hcal_chamber_thickness); + Box hcalECChamberInnerHole(pRMin + Hcal_lateral_plate_thickness, pRMin + Hcal_lateral_plate_thickness, Hcal_chamber_thickness/2); + SubtractionSolid EndCapChamberSolid(EndCapChamberPoly, hcalECChamberInnerHole); + Box IntersectionStaveBox(rOuter/2., rOuter/2., Hcal_chamber_thickness/2); + Position pos(rOuter/2. + Hcal_stave_gaps/2., rOuter/2. + Hcal_stave_gaps/2., 0.); + Position IntersectPos = pos; + IntersectionSolid EndCapStaveSolid(EndCapChamberSolid, IntersectionStaveBox, IntersectPos); + Volume EndCapChamberLogical(name+"_chamber", EndCapStaveSolid, air); + EndCapChamberLogical.setAttributes(theDetector,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); + + double nRadiationLengthsInside=0.; + double nInteractionLengthsInside=0.; + double inner_thickness=0; + double sensitive_thickness=0; + double nRadiationLengths=0.; + double nInteractionLengths=0.; + double thickness_sum=0; + + double slice_pos_z = -Hcal_chamber_thickness/2.; + int slice_number = 0; + for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { + xml_comp_t x_slice = k; + string slice_name = name + _toString(slice_number,"_slice%d"); + double slice_thickness = x_slice.thickness(); + Material slice_material = theDetector.material(x_slice.materialStr()); + cout<<" Layer_slice: " << slice_name << " slice_thickness: " << slice_thickness<< endl; + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + if(x_slice.materialStr()==Hcal_radiator_material) continue; + + slice_pos_z += slice_thickness/2.; + + PolyhedraRegular slicePoly(numSide, -pi/numSide, rInner, rOuter, slice_thickness); + SubtractionSolid sliceSolid(slicePoly, hcalECChamberInnerHole); + IntersectionSolid sliceStaveSolid(sliceSolid, IntersectionStaveBox, IntersectPos); + + Volume sliceVol(name + _toString(slice_number,"_slice%d"), sliceStaveSolid, slice_material); + sliceVol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); + if(x_slice.isSensitive()){ + sliceVol.setSensitiveDetector(sens); + nRadiationLengthsInside = nRadiationLengths; + nInteractionLengthsInside = nInteractionLengths; + inner_thickness = thickness_sum; + sensitive_thickness = slice_thickness; + + nRadiationLengths=0.; + nInteractionLengths=0.; + thickness_sum = 0.; + } + + nRadiationLengths += slice_thickness/(2.*slice_material.radLength()); + nInteractionLengths += slice_thickness/(2.*slice_material.intLength()); + thickness_sum += slice_thickness/2; + // slice PlacedVolume + PlacedVolume slice_phv = EndCapChamberLogical.placeVolume(sliceVol,Position(0,0,slice_pos_z)); + //DetElement slice(layer_name,_toString(slice_number,"slice%d"),x_det.id()); + slice.setPlacement(slice_phv); + // Increment x position for next slice. + slice_pos_z += slice_thickness/2.; + // Increment slice number. + ++slice_number; + } + + if(possible_number_of_chambers < number_of_chambers) number_of_chambers = possible_number_of_chambers; + // chamber placements + for(int stave_id = 1; stave_id <= 4; stave_id++){ + double angle = pi/2.*(stave_id-1); + //RotationZ lrotz(angle); + RotationZYX lrot(angle,0,0); + for (int layer_id = 1; layer_id <= number_of_chambers; layer_id++){ + double Zoff = -Hcal_endcap_thickness/2. + (layer_id-1) *(Hcal_chamber_thickness + Hcal_radiator_thickness) + Hcal_radiator_thickness + Hcal_chamber_thickness/2.; + Position l_pos(0., 0., Zoff); + Position l_new = lrot*l_pos; + Transform3D ltran3D(lrot,l_new); + PlacedVolume layer_phv = EndCapLogical.placeVolume(EndCapChamberLogical, ltran3D); + layer_phv.addPhysVolID("layer",layer_id); + layer_phv.addPhysVolID("stave",stave_id); + + //string l_name = _toString(layer_id,"layer%d"); + //string stave_name = _toString(stave_id,"stave%d"); + //DetElement layer(module_det, l_name+stave_name, det_id); + layer.setPlacement(layer_phv); + + if(stave_id==1&&layer_id==1){ + cout << "Hcal_Endcap: inner_thickness= " << inner_thickness << endl; + cout << "Hcal_Endcap: outer_thickness= " << thickness_sum << endl; + } + LayeredCalorimeterData::Layer caloLayer ; + caloLayer.cellSize0 = cell_sizeX; + caloLayer.cellSize1 = cell_sizeY; + caloLayer.inner_nRadiationLengths = nRadiationLengthsInside; + caloLayer.inner_nInteractionLengths = nInteractionLengthsInside; + caloLayer.inner_thickness = inner_thickness; + caloLayer.sensitive_thickness = sensitive_thickness; + caloLayer.outer_nRadiationLengths = nRadiationLengths; + caloLayer.outer_nInteractionLengths = nInteractionLengths; + caloLayer.outer_thickness = thickness_sum; + + caloLayer.distance = Hcal_start_z + (layer_id-1)*layerThickness; + caloLayer.absorberThickness = Hcal_radiator_thickness ; + + caloData->layers.push_back( caloLayer ) ; + } + } + + // Placements + double endcap_z_offset = Hcal_start_z + Hcal_endcap_thickness/2.; + for(int side = 0; side <= 1; side++){ + int module_id = (side==0) ? 0 : 6; + double this_module_z_offset = (side==0) ? endcap_z_offset : -endcap_z_offset; + // use reflect volume for z<0, therefore, same rotation + // segmentation violation happen if EndCapRingLogical.reflect(), back to rotate Y + // double this_module_rotY = (side==0) ? 0.0 : 0.0; + double this_module_rotY = (side==0) ? 0.0 : pi; + //double this_module_rotZ = (side==0) ? pi/8. : pi/8; + RotationZYX rot(0,this_module_rotY,0); + Transform3D tran3D(rot,Position(0,0,this_module_z_offset)); + + PlacedVolume module_phv; + //if(side==0) module_phv = envelope.placeVolume(EndCapRingLogical, tran3D); + //else module_phv = envelope.placeVolume(EndCapRingLogical.reflect(), tran3D); + module_phv = envelope.placeVolume(EndCapLogical, tran3D); + + module_phv.addPhysVolID("module", module_id); + //DetElement sd = (module_id==0) ? module_det : module_det.clone(_toString(side,"module%d")); + module.setPlacement(module_phv); + } + + det.addExtension<LayeredCalorimeterData>(caloData) ; + + return det; +} + +DECLARE_DETELEMENT(SHcalRpc01_Endcaps, create_detector)