diff --git a/Detector/DetCRD/CMakeLists.txt b/Detector/DetCRD/CMakeLists.txt index d1bf4f675c84d9b11a5bf957abf0c13f55615db0..836cf2bf08f9f659e4dd1411836b09769f9566dc 100644 --- a/Detector/DetCRD/CMakeLists.txt +++ b/Detector/DetCRD/CMakeLists.txt @@ -27,6 +27,8 @@ gaudi_add_module(DetCRD src/Muon/Muon_Endcap_v01.cpp src/Tracker/SiTrackerSkewRing_v01_geo.cpp src/Tracker/SiTrackerStaggeredLadder_v01_geo.cpp + src/Tracker/TPC_Simple_o1_v01.cpp + src/Tracker/TPC_ModularEndcap_o1_v01.cpp LINK ${DD4hep_COMPONENT_LIBRARIES} ) diff --git a/Detector/DetCRD/compact/CRD_common_v02/TPC_ModularEndcap_o1_v01.xml b/Detector/DetCRD/compact/CRD_common_v02/TPC_ModularEndcap_o1_v01.xml new file mode 100644 index 0000000000000000000000000000000000000000..92f9487c126759ccc7a145e4b8871581ec35777e --- /dev/null +++ b/Detector/DetCRD/compact/CRD_common_v02/TPC_ModularEndcap_o1_v01.xml @@ -0,0 +1,220 @@ +<lccdd> + <info + name ="TPC_ModularEndcap_TDR_o1_v01" + status ="developing" + version = "TPC_ModularEndcap_TDR_o1_v01" + author = "Xin She"> + <comment> The compact format for the CEPC TPC used for the TDR </comment> + </info> + + <define> + <!--from CDR baseline--> + <!--Readout pad size--> + <constant name="TPC_pad_height" value="0.5*mm" /> + <constant name="TPC_pad_width" value="0.5*mm" /> + <constant name="TPC_max_step_length" value="5*mm" /> + <constant name="TPC_sensitive_threshold_eV" value="32*eV" /> + <!--Wall/Cathode/Readout/Endplate--> + <constant name="TPC_dr_InnerWall" value="25.*mm" /> + <constant name="TPC_dr_InnerServiceArea" value="10*mm" /> + <constant name="TPC_dr_OuterServiceArea" value="23*mm" /> + <constant name="TPC_dr_OuterWall" value="25.*mm" /> + <constant name="TPC_dz_Cathode" value="0.06*mm" /> + <constant name="TPC_dz_Readout" value="3.50*mm" /> + <constant name="TPC_dz_Endplate" value="135*mm" /> + <constant name="TPC_dz_Cathode_Insulator" value="0.0275*mm" /> + <constant name="TPC_dz_Cathode_Conductor" value="0.0025*mm" /> + <constant name="TPC_dr_Cathode_Grip" value="10.*mm" /> + <constant name="TPC_dz_Cathode_Grip" value="15*mm" /> + <!-- Inermeidate variables --> + <constant name="TPC_rMin_GasVolume" value="TPC_inner_radius+TPC_dr_InnerWall"/> + <constant name="TPC_rMax_GasVolume" value="TPC_outer_radius-TPC_dr_OuterWall"/> + <constant name="TPC_dz_GasVolume" value="TPC_half_length-TPC_dz_Endplate"/> + <constant name="TPC_rMin_Sensitive" value="TPC_rMin_GasVolume+TPC_dr_InnerServiceArea"/> + <constant name="TPC_rMax_Sensitive" value="TPC_rMax_GasVolume-TPC_dr_OuterServiceArea"/> + <constant name="TPC_dz_Wall" value="2*TPC_dz_GasVolume"/> + <constant name="TPC_dz_Sensitive" value="TPC_dz_GasVolume-TPC_dz_Readout-TPC_dz_Cathode/2."/> + <constant name="TPC_numberOfPadrows" value="int((TPC_rMax_Sensitive-TPC_rMin_Sensitive)/TPC_pad_height)"/> + </define> + + <display> + <vis name="CuVis" alpha="1.0" r="0.5" g=".5" b=".5" showDaughters="true" visible="true"/> + <vis name="KaptonVis" alpha="0.8" r="1" g="0." b="0." showDaughters="true" visible="true"/> + <vis name="gasVis" alpha="0.2" r="0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="transVis" alpha="0.1" r="1.0" g="1.0" b="1.0" showDaughters="true" visible="true"/> + <vis name="readoutVis" alpha="0.8" r="1.0" g=".0" b=".0" showDaughters="true" visible="true"/> + <vis name="aramidVis" alpha="1.0" r="0.0" g="0.3" b="0.7" showDaughters="true" visible="true"/> + <vis name="epoxyVis" alpha="0.2" r="0.0" g="0.3" b="0.3" showDaughters="true" visible="true"/> + <vis name="TPCMotherVis1" alpha="0.5" r="0.96" g="0.64" b="0.90" showDaughters="true" visible="true"/> + </display> + + <detectors> + <detector name="TPC" type="TPC_ModularEndcap_o1_v01" vis="TPCVis" id="DetID_TPC" limits="tracker_limits" readout="TPCCollection" insideTrackingVolume="true"> + + <envelope vis="TPCVis"> + <shape type="Tube" rmin="TPC_inner_radius" rmax="TPC_outer_radius" dz="TPC_half_length" material="Air"/> + </envelope> + + <type_flags type="DetType_TRACKER + DetType_BARREL + DetType_GASEOUS "/> + + <component name="TPCinnerWall" type="TPCinnerWall" R_start="TPC_inner_radius" R_end="TPC_rMin_GasVolume" Z_fulllength="TPC_dz_Wall"> + <!--HoneyComb wall --> + <!--layer material="G4_Cu" thickness = "0.01*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="Aramid" thickness = "0.07*mm" vis="aramidVis" /> + <layer material="AramidHoneycomb" thickness = "23.5*mm" vis="aramidVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="Kapton" thickness = "0.0125*mm" vis="KaptonVis" /> + <layer material="Copper80P" thickness = "0.035*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="Copper80P" thickness = "0.035*mm" vis="CuVis" /> + <layer material="epoxy" thickness = "0.042*mm" vis="epoxy" /--> + <!--CF wall --> + <layer material="G4_Cu" thickness = "0.010*mm" vis="CuVis"/> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="Polyimide" thickness = "0.05*mm" vis="KaptonVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + </component> + <component name="TPCouterWall" type="TPCouterWall" R_start="TPC_rMax_GasVolume" R_end="TPC_outer_radius" Z_fulllength="TPC_dz_Wall"> + <!--HoneyComb wall --> + <!--layer material="Copper80P" thickness = "0.01*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="Copper80P" thickness = "0.03*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.07*mm" vis="KaptonVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="AramidHoneycomb" thickness = "23.5*mm" vis="aramidVis" /> + <layer material="Aramid" thickness = "0.07*mm" vis="aramidVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="G4_Cu" thickness = "0.01*mm" vis="CuVis" /> + <layer material="epoxy" thickness = "0.042*mm" vis="epoxy" /--> + <!--CF wall --> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="Polyimide" thickness = "0.05*mm" vis="KaptonVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + <layer material="G4_Cu" thickness = "0.010*mm" vis="CuVis"/> + </component> + <component name="Grip" type="TPCGrip" material="SiC_foam"> + <layer name="TPCinnerGrip" rmin="TPC_rMin_GasVolume" rmax="TPC_rMin_GasVolume+TPC_dr_InnerServiceArea" z_length="TPC_dz_Cathode_Grip" vis="KaptonVis"/> + <layer name="TPCouterGrip" rmin="TPC_rMax_GasVolume-TPC_dr_OuterServiceArea" rmax="TPC_rMax_GasVolume" z_length="TPC_dz_Cathode_Grip" vis="KaptonVis"/> + </component> + <component name="Cathode" type="TPCCathode"> + <layer name="Cathodeinsulator" material= "Kapton" rmin="TPC_rMin_Sensitive" rmax="TPC_rMax_Sensitive" z_length="TPC_dz_Cathode_Insulator" vis="KaptonVis"> + <position x="0.*mm" y="0.*mm" z="+ TPC_dz_Cathode_Insulator/2."/> + <position x="0.*mm" y="0.*mm" z="- TPC_dz_Cathode_Insulator/2."/> + </layer> + <layer name="Cathodeconductor" material= "G4_Cu" rmin="TPC_rMin_Sensitive" rmax="TPC_rMax_Sensitive" z_length="TPC_dz_Cathode_Conductor" vis="CuVis"> + <position x="0.*mm" y="0.*mm" z="+ (TPC_dz_Cathode_Insulator+ (TPC_dz_Cathode_Conductor/2.))"/> + <position x="0.*mm" y="0.*mm" z="- (TPC_dz_Cathode_Insulator+ (TPC_dz_Cathode_Conductor/2.))"/> + </layer> + </component> + <component name="TPCreadout" type="TPCreadout" material="T2KGas1"> + <dimensions rmin = "TPC_rMin_GasVolume" rmax = "TPC_rMax_GasVolume" z_length = "TPC_dz_Readout"/> + <position x="0.*mm" y="0.*mm" z="+(TPC_half_length-TPC_dz_Endplate-TPC_dz_Readout/2.)"/> + <!--Triple Gem readout structure from CEPCV4--> + <!--layer material="G4_Cu" dz="0.003*mm" comment="gating" vis="CuVis" /> + <layer material="G4_KAPTON" dz="0.030*mm" comment="gating" vis="KaptonVis" /> + <layer material="G4_Cu" dz="0.003*mm" comment="gating" vis="CuVis"/> + <layer material="T2KGas1" dz="4.447*mm" comment="gating" vis="gasVis"/> + <layer material="G4_Cu" dz="0.003*mm" comment="mpgd" vis="CuVis"/> + <layer material="G4_KAPTON" dz="0.030*mm" comment="mpgd" vis="Kapton"/> + <layer material="G4_Cu" dz="0.003*mm" comment="mpgd" vis="CuVis"/> + <layer material="T2KGas1" dz="4.447*mm" comment="mpgd" vis="gasVis"/> + <layer material="G4_Cu" dz="0.003*mm" comment="mpgd" vis="CuVis"/> + <layer material="G4_KAPTON" dz="0.030*mm" comment="mpgd" vis="KaptonVis"/> + <layer material="G4_Cu" dz="0.003*mm" comment="mpgd" vis="CuVis"/> + <layer material="T2KGas1" dz="4.447*mm" comment="mpgd" vis="gasVis"/> + <layer material="G4_Cu" dz="0.050*mm" comment="pads" vis="CuVis"/> + <layer material="g10" dz="2.000*mm" comment="structural" vis="gasVis"/> + <layer material="G4_Si" dz="0.500*mm" comment="electronics" vis="epoxyVis" /> + <layer material="epoxy" dz="2*mm" comment="structural" vis="epoxyVis"/> + <layer material="G4_KAPTON" dz="1*mm" comment="structural" vis="KaptonVis" /> + <layer material="G4_Al" dz="2*mm" comment="Cooling" vis="GrayVis"/> + <layer material="G4_KAPTON" dz="1*mm" comment="structural" vis="KaptonVis"/> + <layer material="CarbonFiber" dz="3*mm" comment="structural" vis="GrayVis" /--> + <!--MicroMegas readout structure--> + <layer material="G4_Fe" dz="0.025*mm" comment="Mesh" vis="GrayVis"/> + <layer material="T2KGas1" dz="0.128*mm" comment="GasAmpRegion" vis="gasVis"/> + <layer material="G4_KAPTON" dz="0.050*mm" comment="Kaptonfoil" vis="KaptonVis"/> + <layer material="Acrylicglue" dz="0.008*mm" comment="gule" vis="BlueVis"/> + <layer material="G4_Cu" dz="0.017*mm" comment="ReadoutPad" vis="CuVis"/> + <layer material="PCB" dz="1.000*mm" comment="PCBboard" vis="GreenVis"/> + <layer material="G4_Si" dz="0.500*mm" comment="electronics" vis="BlackVis"/> + <layer material="epoxy" dz="1.500*mm" comment="structural" vis="epoxyVis"/> + </component> + <component name="TPCSensitiveVol" type="TPCSensitiveVol" material="T2KGas1"> + <dimensions rmin = "TPC_rMin_Sensitive" rmax = "TPC_rMax_Sensitive" z_length = "TPC_dz_Sensitive"/> + <layer repeat="TPC_numberOfPadrows" thickness="TPC_pad_height"/> + </component> + <component name="TPCEndplate" type="TPCEndplate" z_frame="20.*mm" s_frame="20.*mm" > + <dimensions rmin = "TPC_inner_radius" rmax = "TPC_outer_radius" z_length = "TPC_dz_Endplate"/> + <layer name="InnerPlate" type="Frame" thickness="25.*mm"/> + <layer name="ring1" type="Frame" thickness="10.*mm"/> + <layer name="module1" type="Module" thickness="151.*mm" repeat="23" phi0_offset="0.*deg"> + <slice material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <slice material="G4_Al" dz="1.5*mm" comment="cooling"/> + <slice material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <slice material="CarbonFiber" dz="3.0*mm" comment="structural"/> + </layer> + <layer name="ring2" type="Frame" thickness="20.*mm"/> + <layer name="module2" type="Module" thickness="141.*mm" repeat="27" phi0_offset="+10.*deg"> + <slice material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <slice material="G4_Al" dz="1.5*mm" comment="cooling"/> + <slice material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <slice material="CarbonFiber" dz="3.0*mm" comment="structural"/> + <slice material="PCB" dz="10.0*mm" comment="cooling"/> + </layer> + <layer name="ring3" type="Frame" thickness="20.*mm"/> + <layer name="module3" type="Module" thickness="141.*mm" repeat="32" phi0_offset="-5.*deg"> + <slice material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <slice material="G4_Al" dz="1.5*mm" comment="cooling"/> + <slice material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <slice material="CarbonFiber" dz="3.0*mm" comment="structural"/> + </layer> + <layer name="ring4" type="Frame" thickness="20.*mm"/> + <layer name="module4" type="Module" thickness="141.*mm" repeat="34" phi0_offset="0.*deg"> + <slice material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <slice material="G4_Al" dz="1.5*mm" comment="cooling"/> + <slice material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <slice material="CarbonFiber" dz="3.0*mm" comment="structural"/> + </layer> + <layer name="ring5" type="Frame" thickness="20.*mm"/> + <layer name="module5" type="Module" thickness="141.*mm" repeat="39" phi0_offset="+5.*deg"> + <slice material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <slice material="G4_Al" dz="1.5*mm" comment="cooling"/> + <slice material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <slice material="CarbonFiber" dz="3.0*mm" comment="structural"/> + </layer> + <layer name="ring6" type="Frame" thickness="20.*mm"/> + <layer name="module6" type="Module" thickness="141.*mm" repeat="44" phi0_offset="-5.*deg"> + <slice material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <slice material="G4_Al" dz="1.5*mm" comment="cooling"/> + <slice material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <slice material="CarbonFiber" dz="3.0*mm" comment="structural"/> + </layer> + <layer name="ring7" type="Frame" thickness="20.*mm"/> + <layer name="module7" type="Module" thickness="141.*mm" repeat="49" phi0_offset="0.*deg"> + <slice material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <slice material="G4_Al" dz="1.5*mm" comment="cooling"/> + <slice material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <slice material="CarbonFiber" dz="3.0*mm" comment="structural"/> + </layer> + <layer name="ring8" type="Frame" thickness="23.*mm"/> + <layer name="Outerplate" type="Frame" thickness="25.*mm"/> + </component> + + </detector> + </detectors> + + <readouts> + <readout name="TPCCollection"> + <id>system:5,side:-2,layer:13,module:6,sensor:6</id> + </readout> + </readouts> + +</lccdd> diff --git a/Detector/DetCRD/compact/CRD_common_v02/TPC_Simple_o1_v01.xml b/Detector/DetCRD/compact/CRD_common_v02/TPC_Simple_o1_v01.xml new file mode 100644 index 0000000000000000000000000000000000000000..6b8298977f24449f0d28114e9c63f54bd057f1ea --- /dev/null +++ b/Detector/DetCRD/compact/CRD_common_v02/TPC_Simple_o1_v01.xml @@ -0,0 +1,160 @@ +<lccdd> + <info + name ="TPC_Simple_TDR_o1_v01" + status ="developing" + version = "TPC_Simple_TDR_o1_v01"> + <comment> The compact format for the CEPC TPC used for the TDR </comment> + </info> + + <define> + <!--from CDR baseline--> + <!--Readout pad size--> + <constant name="TPC_pad_height" value="0.5*mm" /> + <constant name="TPC_pad_width" value="0.5*mm" /> + <constant name="TPC_max_step_length" value="5*mm" /> + <!--Wall/Cathode/Readout/Endplate Honeycomb barrel--> + <constant name="TPC_dr_InnerWall" value="25.*mm" /> + <constant name="TPC_dr_InnerServiceArea" value="10*mm" /> + <constant name="TPC_dr_OuterServiceArea" value="23*mm" /> + <constant name="TPC_dr_OuterWall" value="25.*mm" /> + <constant name="TPC_dz_Cathode" value="0.06*mm" /> + <constant name="TPC_dz_Readout" value="3.50*mm" /> + <constant name="TPC_dz_Endplate" value="135*mm" /> + <constant name="TPC_sensitive_threshold_eV" value="32*eV" /> + <constant name="TPC_dz_Cathode_Insulator" value="0.0275*mm" /> + <constant name="TPC_dz_Cathode_Conductor" value="0.0025*mm" /> + <constant name="TPC_dr_Cathode_Grip" value="10.*mm"/> + <constant name="TPC_dz_Cathode_Grip" value="15*mm" /> + <!-- Inermeidate variables --> + <constant name="TPC_rMin_GasVolume" value="TPC_inner_radius+TPC_dr_InnerWall"/> + <constant name="TPC_rMax_GasVolume" value="TPC_outer_radius-TPC_dr_OuterWall"/> + <constant name="TPC_dz_GasVolume" value="TPC_half_length-TPC_dz_Endplate"/> + <constant name="TPC_rMin_Sensitive" value="TPC_rMin_GasVolume+TPC_dr_InnerServiceArea"/> + <constant name="TPC_rMax_Sensitive" value="TPC_rMax_GasVolume-TPC_dr_OuterServiceArea"/> + <constant name="TPC_dz_Wall" value="2*TPC_dz_GasVolume"/> + <constant name="TPC_dz_Sensitive" value="TPC_dz_GasVolume-TPC_dz_Readout-TPC_dz_Cathode/2."/> + <constant name="TPC_numberOfPadrows" value="int((TPC_rMax_Sensitive-TPC_rMin_Sensitive)/TPC_pad_height)"/> + </define> + + <display> + <vis name="CuVis" alpha="1.0" r="0.5" g=".5" b=".5" showDaughters="true" visible="true"/> + <vis name="KaptonVis" alpha="0.8" r="1" g="0." b="0." showDaughters="true" visible="true"/> + <vis name="gasVis" alpha="0.2" r="0.0" g="1.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="readoutVis" alpha="0.8" r="1.0" g=".0" b=".0" showDaughters="true" visible="true"/> + <vis name="aramidVis" alpha="1.0" r="0.0" g="0.3" b="0.7" showDaughters="true" visible="true"/> + <vis name="epoxyVis" alpha="0.2" r="0.0" g="0.3" b="0.3" showDaughters="true" visible="true"/> + <vis name="TPCMotherVis1" alpha="0.5" r="0.96" g="0.64" b="0.90" showDaughters="true" visible="true"/> + </display> + + <detectors> + <detector name="TPC" type="TPC_Simple_o1_v01" vis="TPCVis" id="DetID_TPC" limits="tracker_limits" readout="TPCCollection" insideTrackingVolume="true"> + + <envelope vis="TPCVis"> + <shape type="Tube" rmin="TPC_inner_radius" rmax="TPC_outer_radius" dz="TPC_half_length" material="Air"/> + </envelope> + + <type_flags type="DetType_TRACKER + DetType_BARREL + DetType_GASEOUS "/> + + <component name="TPCinnerWall" type="TPCinnerWall" R_start="TPC_inner_radius" R_end="TPC_rMin_GasVolume" Z_fulllength="TPC_dz_Wall"> + <!--HoneyComb wall --> + <!--layer material="G4_Cu" thickness = "0.01*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="Aramid" thickness = "0.07*mm" vis="aramidVis" /> + <layer material="AramidHoneycomb" thickness = "23.5*mm" vis="aramidVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="Kapton" thickness = "0.0125*mm" vis="KaptonVis" /> + <layer material="Copper80P" thickness = "0.035*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="Copper80P" thickness = "0.035*mm" vis="CuVis" /> + <layer material="epoxy" thickness = "0.042*mm" vis="epoxy" /--> + <!--CF wall --> + <layer material="G4_Cu" thickness = "0.010*mm" vis="CuVis"/> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="Polyimide" thickness = "0.05*mm" vis="KaptonVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + </component> + <component name="TPCouterWall" type="TPCouterWall" R_start="TPC_rMax_GasVolume" R_end="TPC_outer_radius" Z_fulllength="TPC_dz_Wall"> + <!--HoneyComb wall --> + <!--layer material="G4_Cu" thickness = "0.01*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="Aramid" thickness = "0.07*mm" vis="aramidVis" /> + <layer material="AramidHoneycomb" thickness = "23.5*mm" vis="aramidVis" /> + <layer material="g10-TPC" thickness = "0.3*mm" vis="gasVis" /> + <layer material="Kapton" thickness = "0.0125*mm" vis="KaptonVis" /> + <layer material="Copper80P" thickness = "0.035*mm" vis="CuVis" /> + <layer material="Kapton" thickness = "0.05*mm" vis="KaptonVis" /> + <layer material="Copper80P" thickness = "0.035*mm" vis="CuVis" /> + <layer material="epoxy" thickness = "0.042*mm" vis="epoxy" /--> + <!--CF wall --> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="Polyimide" thickness = "0.05*mm" vis="KaptonVis"/> + <layer material="G4_Cu" thickness = "0.03*mm" vis="CuVis"/> + <layer material="CarbonFiber" thickness = "0.1*mm" vis="aramidVis"/> + <layer material="G4_Cu" thickness = "0.010*mm" vis="CuVis"/> + </component> + <component name="Grip" type="TPCGrip" material="SiC_foam"> + <layer name="TPCinnerGrip" rmin="TPC_rMin_GasVolume" rmax="TPC_rMin_GasVolume+TPC_dr_InnerServiceArea" z_length="TPC_dz_Cathode_Grip" vis="KaptonVis"/> + <layer name="TPCouterGrip" rmin="TPC_rMax_GasVolume-TPC_dr_OuterServiceArea" rmax="TPC_rMax_GasVolume" z_length="TPC_dz_Cathode_Grip" vis="KaptonVis"/> + </component> + <component name="Cathode" type="TPCCathode"> + <layer name="Cathodeinsulator" material= "Kapton" rmin="TPC_rMin_Sensitive" rmax="TPC_rMax_Sensitive" z_length="TPC_dz_Cathode_Insulator" vis="KaptonVis"> + <position x="0.*mm" y="0.*mm" z="+ TPC_dz_Cathode_Insulator/2."/> + <position x="0.*mm" y="0.*mm" z="- TPC_dz_Cathode_Insulator/2."/> + </layer> + <layer name="Cathodeconductor" material= "G4_Cu" rmin="TPC_rMin_Sensitive" rmax="TPC_rMax_Sensitive" z_length="TPC_dz_Cathode_Conductor" vis="CuVis"> + <position x="0.*mm" y="0.*mm" z="+ (TPC_dz_Cathode_Insulator+ (TPC_dz_Cathode_Conductor/2.))"/> + <position x="0.*mm" y="0.*mm" z="- (TPC_dz_Cathode_Insulator+ (TPC_dz_Cathode_Conductor/2.))"/> + </layer> + </component> + <component name="TPCreadout" type="TPCreadout" material="T2KGas1"> + <dimensions rmin = "TPC_rMin_GasVolume" rmax = "TPC_rMax_GasVolume" z_length = "TPC_dz_Readout"/> + <position x="0.*mm" y="0.*mm" z="+(TPC_half_length-TPC_dz_Endplate-TPC_dz_Readout/2.)"/> + <!--layer thickness="0.003*mm" material="G4_Cu" comment="gating" vis="CuVis" /> + <layer thickness="0.03*mm" material="G4_KAPTON" comment="gating" vis="KaptonVis" /> + <layer thickness="0.003*mm" material="G4_Cu" comment="gating" vis="CuVis"/> + <layer thickness="4.447*mm" material="T2KGas1" comment="gating" vis="gasVis"/> + <layer thickness="0.003*mm" material="G4_Cu" comment="mpgd" vis="CuVis"/> + <layer thickness="0.03*mm" material="G4_KAPTON" comment="mpgd" vis="Kapton"/> + <layer thickness="0.003*mm" material="G4_Cu" comment="mpgd" vis="CuVis"/> + <layer thickness="4.447*mm" material="T2KGas1" comment="mpgd" vis="gasVis"/> + <layer thickness="0.003*mm" material="G4_Cu" comment="mpgd" vis="CuVis"/> + <layer thickness="0.03*mm" material="G4_KAPTON" comment="mpgd" vis="KaptonVis"/> + <layer thickness="0.003*mm" material="G4_Cu" comment="mpgd" vis="CuVis"/> + <layer thickness="4.447*mm" material="T2KGas1" comment="mpgd" vis="gasVis"/--> + <!--MicroMegas readout structure--> + <layer material="G4_Fe" dz="0.025*mm" comment="Mesh" vis="GrayVis"/> + <layer material="T2KGas1" dz="0.128*mm" comment="GasAmpRegion" vis="gasVis"/> + <layer material="G4_KAPTON" dz="0.050*mm" comment="Kaptonfoil" vis="KaptonVis"/> + <layer material="Acrylicglue" dz="0.008*mm" comment="gule" vis="BlueVis"/> + <layer material="G4_Cu" dz="0.017*mm" comment="ReadoutPad" vis="CuVis"/> + <layer material="PCB" dz="1.000*mm" comment="PCBboard" vis="GreenVis"/> + <layer material="G4_Si" dz="0.500*mm" comment="electronics" vis="BlackVis"/> + <layer material="epoxy" dz="1.500*mm" comment="structural" vis="epoxyVis"/> + </component> + <component name="TPCSensitiveVol" type="TPCSensitiveVol" material="T2KGas1"> + <dimensions rmin = "TPC_rMin_Sensitive" rmax = "TPC_rMax_Sensitive" z_length = "TPC_dz_Sensitive"/> + <layer repeat="TPC_numberOfPadrows" thickness="TPC_pad_height"/> + </component> + <component name="TPCEndplate" type="TPCEndplate"> + <dimensions rmin = "TPC_inner_radius" rmax = "TPC_outer_radius" z_length = "TPC_dz_Endplate"/> + <layer material="PCB" dz="5.0*mm" comment="FEE_BEEPCB"/> + <layer material="G4_Al" dz="1.5*mm" comment="cooling"/> + <layer material="TPC_endplate_mix" dz="50.0*mm" comment="MonitorMix"/> + <layer material="CarbonFiber" dz="3.0*mm" comment="structural"/> + </component> + + </detector> + </detectors> + + <readouts> + <readout name="TPCCollection"> + <id>system:5,side:-2,layer:13,module:6,sensor:6</id> + </readout> + </readouts> + +</lccdd> diff --git a/Detector/DetCRD/compact/CRD_common_v02/materials.xml b/Detector/DetCRD/compact/CRD_common_v02/materials.xml index 0cb4540c9e4eef5802afbe8b026314927ad9b417..d59e16913ed1379dd354177529ce493d338ad93c 100644 --- a/Detector/DetCRD/compact/CRD_common_v02/materials.xml +++ b/Detector/DetCRD/compact/CRD_common_v02/materials.xml @@ -685,6 +685,27 @@ <composite n="1" ref="O" /> </material> + <material name="T2KGas1" state="gas"> + <MEE unit="eV" value="177.374841770826"/> + <D value="0.0017357" unit="g/cm3"/> + <fraction n="0.908928" ref="Ar"/> + <fraction n="0.031643" ref="C"/> + <fraction n="0.004828" ref="H"/> + <fraction n="0.054601" ref="F"/> + </material> + + <material name="Polyimide" state="solide"> + <D value="1.38" unit="g/cm3"/> + <composite n="22" ref="C"/> + <composite n="10" ref="H"/> + <composite n="2" ref="N"/> + <composite n="5" ref="O"/> + </material> + <material name="TPC_Alframe" state="solid"> + <D value="1.8" unit="g/cm3"/> + <fraction n="1." ref="Al" /> + </material> + <material name="LYSO" state="solid"> <MEE unit="eV" value="9.5"/> <D value="7.15" unit="g/cm3" /> diff --git a/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01-onlyTracker.xml b/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01-onlyTracker.xml index 18e6abf042844778e86e79e1f2c412a87df7418d..4768589e12ec6228dc6b2cb6ae8f5ce3a29dca46 100644 --- a/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01-onlyTracker.xml +++ b/Detector/DetCRD/compact/TDR_o1_v01/TDR_o1_v01-onlyTracker.xml @@ -28,13 +28,14 @@ <include ref="./TDR_Dimensions_v01_01.xml"/> <!--TODO: vertex cooling--> - <include ref="../CRD_common_v02/Beampipe_v01_03.xml"/> + <!--include ref="../CRD_common_v02/Beampipe_v01_03.xml"/--> <!--preliminary vertex and tracker, to update/--> - <include ref="../CRD_common_v02/VXD_StaggeredLadder_v02_01.xml"/> + <!--include ref="../CRD_common_v02/VXD_StaggeredLadder_v02_01.xml"/> <include ref="../CRD_common_v02/FTD_SkewRing_v01_05.xml"/> <include ref="../CRD_common_v02/SIT_SimplePixel_v01_03.xml"/> <include ref="../CRD_common_v01/TPC_Simple_v10_02.xml"/> - <include ref="../CRD_common_v01/SET_SimplePixel_v01_01.xml"/> + <include ref="../CRD_common_v01/SET_SimplePixel_v01_01.xml"/--> + <include ref="./TPC_ModularEndcap_TDR_o1_v01.xml"/> <fields> <field name="InnerSolenoid" type="solenoid" diff --git a/Detector/DetCRD/src/Tracker/TPC_ModularEndcap_o1_v01.cpp b/Detector/DetCRD/src/Tracker/TPC_ModularEndcap_o1_v01.cpp new file mode 100644 index 0000000000000000000000000000000000000000..140f1f811be4081dfe2c6dd84a7c6aa7f7738cee --- /dev/null +++ b/Detector/DetCRD/src/Tracker/TPC_ModularEndcap_o1_v01.cpp @@ -0,0 +1,520 @@ +/********************************************************************* + * Author : Lan-sx & origin author: F. Gaede, Desy + * Email : shexin@ihep.ac.cn + * Last modified : 2024-06-02 20:37 + * Filename : TPC_ModularEndcap_o1_v01.cpp + * Description : + * ******************************************************************/ + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetType.h" +//#include "./include/LcgeoExceptions.h" +//#include "./include/lcgeo.h" +#include "DDRec/Surface.h" +#include "DDRec/DetectorData.h" +#include "XML/Utilities.h" +//#include "XMLHandlerDB.h" + +#include <math.h> + +using namespace std; +using namespace dd4hep; +//using namespace lcgeo; + +using dd4hep::rec::Vector3D; +using dd4hep::rec::VolCylinder; +using dd4hep::rec::SurfaceType; +using dd4hep::rec::volSurfaceList; +using dd4hep::rec::VolPlane; +using dd4hep::rec::FixedPadSizeTPCData; + +/** Construction of TPC detector, ported from Mokka driver TPC10.cc + * Mokka History: + * - modified version of TPC driver by Ties Behnke + * - modified version of TPC02 as TPC03 with selectable chamber gas -- Adrian Vogel, 2005-06-09 + * - modified version of TPC03 as TPC04 with limit of step length -- Adrian Vogel, 2006-02-01 + * - introduced self-scalability, no superdriver needed anymore -- Adrian Vogel, 2006-03-11 + * - modified version of TPC04 as TPC05 in order to have full MC + * information both at entry and exit hits in the TPC , + * more realistic central electrode and endplate -- Predrag Krstonosic, 2006-07-12 + * - implemented new GEAR interface -- K. Harder, T. Pinto Jayawardena 2007-07-31 + * - TPC10 implemented readout within the Gas volume and layered inner and outer wall -- SJA -- 2010-11-19 + * + * @author: F.Gaede, DESY, Nov 2013 + * + * - Modular Endcap TPC Geo implemention for CEPC TDR TPC + * @author: X.She, IHEP, May 2024 + */ + +static Ref_t create_element(Detector& theDetector, xml_h e, SensitiveDetector sens) { + + + //------------------------------------------ + // See comments starting with '//**' for + // hints on porting issues + //------------------------------------------ + xml_det_t x_det = e; + string name = x_det.nameStr(); + + DetElement tpc( name, x_det.id() ) ; + + // --- create an envelope volume and position it into the world --------------------- + + Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, e , tpc ) ; + + dd4hep::xml::setDetectorTypeFlag( e, tpc ) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return tpc ; + + //----------------------------------------------------------------------------------- + + PlacedVolume pv; + + sens.setType("tracker"); + + std::cout << " **Lan Lan building TPC_ModularEndcap_TDR_o1_v01 construction" << std::endl ; + + //###################################################################################################################################################################### + const double phi1 = 0.0 ; + const double phi2 = 2*M_PI ; + const double dzTotal = theDetector.constant<double>("TPC_half_length") * 2. ; + const double rInner = theDetector.constant<double>("TPC_inner_radius") ; + const double rOuter = theDetector.constant<double>("TPC_outer_radius") ; + const double drInnerWall = theDetector.constant<double>("TPC_dr_InnerWall"); + const double drOuterWall = theDetector.constant<double>("TPC_dr_OuterWall"); + const double dz_Cathode = theDetector.constant<double>("TPC_dz_Cathode"); + const double dz_Endplate = theDetector.constant<double>("TPC_dz_Endplate"); + const double dz_Readout = theDetector.constant<double>("TPC_dz_Readout"); + const double tpcpadheight = theDetector.constant<double>("TPC_pad_height"); + const double tpcpadwidth = theDetector.constant<double>("TPC_pad_width"); + const int tpcnumberOfPadRows = theDetector.constant<int>("TPC_numberOfPadrows"); + + + std::cout<< "============ TPC_HoneyComb_TDR_o1_v01 mother Volume(Tube) (Dz,Ri,Ro) : (" << dzTotal/dd4hep::mm/2. << "\t" + << rInner/dd4hep::mm << "\t" + << rOuter/dd4hep::mm <<" )"<<std::endl; + Material materialT2Kgas = theDetector.material("T2KGas1"); + Material materialAir = theDetector.material("Air"); + Material materialAlframe = theDetector.material("TPC_Alframe"); + //-------------------------------------------------------------------------------------------------------// + //-------------------------------- TPC mother volume ----------------------------------------------------// + //------------ Volume for the whole TPC, Field Cage, Cathode, and Endplate and Sensitive ----------------// + + Tube tpc_motherSolid(rInner ,rOuter ,dzTotal/2.0 , phi1 , phi1+phi2 ); + Volume tpc_motherLog( "TPCLog", tpc_motherSolid, materialT2Kgas); + pv = envelope.placeVolume( tpc_motherLog ) ; + tpc.setVisAttributes(theDetector, "TPCMotherVis1" , tpc_motherLog ) ; + + double gasRegion = ((rOuter-drOuterWall)-(rInner+drInnerWall))/dd4hep::mm; + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_HoneyComb_TDR_o1_v01: Total Gas material corresponds to " << ( ( gasRegion ) / (materialT2Kgas->GetMaterial()->GetRadLen() / dd4hep::mm ) * 100.0 ) + << "% of a radiation length." << std::endl; + std::cout << "================================================================"<< std::endl; + + //-------------------------------------------------------------------------------------------------------// + //Loop all sections + //-------------------------------------------------------------------------------------------------------// + + for(xml_coll_t si(x_det, Unicode("component"));si;++si) + { + xml_comp_t x_section(si); + std::string types = x_section.attr<std::string>(_Unicode(type)); + const std::string volName = x_section.nameStr(); + + //-------------------------------- inner/outer wall construction ----------------------------------------// + if(types == "TPCinnerWall" || types == "TPCouterWall") + { + double r_start = x_section.attr<double>(_Unicode(R_start)); + double r_end = x_section.attr<double>(_Unicode(R_end)); + double z_fulllength = x_section.attr<double>(_Unicode(Z_fulllength)); + + //Create Inner/Outer Wall mother logic volume + std::string volNameLog = volName + "Log"; + Tube WallSolid(r_start,r_end,z_fulllength/2., phi1 , phi1+phi2); + Volume WallLog(volNameLog,WallSolid,materialT2Kgas); + pv=tpc_motherLog.placeVolume(WallLog); + tpc.setVisAttributes(theDetector,"CyanVis",WallLog); + + Vector3D ocyl; + //SurfaceList data, same as TPC10(CEPCV4) + double dr_wall = r_end-r_start; + if(types == "TPCinnerWall") + ocyl.fill(r_start+0.5*dr_wall,0.,0.); + else + ocyl.fill(r_end-0.5*dr_wall,0.,0.); + + //std::cout<<"======> Vector3D cout : "<<ocyl.x()<<"\t"<<ocyl.y()<<"\t"<<ocyl.z()<<std::endl; + VolCylinder surfWall(WallLog,SurfaceType( SurfaceType::Helper ),0.5*dr_wall,0.5*dr_wall,ocyl); + volSurfaceList( tpc )->push_back( surfWall ); + + //Loop all layers of inner/outer wall + int ilayer =0; + double rCursor = r_start; + double fracRadLengthWall = 0.; + for(xml_coll_t li(x_section,_U(layer)); li;++li,++ilayer) + { + xml_comp_t x_layer(li); + + double thickness = x_layer.thickness(); + Material layerMaterial = theDetector.material( x_layer.materialStr() ); + char suffix[20]; + sprintf(suffix,"_%d",ilayer); + std::string layerName = volNameLog + suffix; + + Tube layerSolid(rCursor,rCursor+thickness,z_fulllength/2.,phi1,phi1+phi2); + Volume layerLog(layerName,layerSolid,layerMaterial); + //layerLog.setVisAttributes(theDetector,x_layer.visStr()); + pv=WallLog.placeVolume(layerLog); + + rCursor += thickness; + double layerRadLength = thickness/(layerMaterial->GetMaterial()->GetRadLen()); + fracRadLengthWall += layerRadLength; + + std::cout<<"-> "<<volName<<"layer"<<ilayer<<" : "<< thickness/dd4hep::mm << "mm \t Materials: "<<layerMaterial.name() + <<" X0= "<<layerMaterial->GetMaterial()->GetRadLen()/dd4hep::mm<<"mm \t" + <<layerRadLength<<" X0"<<std::endl; + } + + double drSumThickness = rCursor - r_start; + if(drSumThickness > (r_end-r_start)) + { + std::cout<<"Warning! sum_{i}layerThickness_{i} > drWall !\n"<<std::endl; + throw "$!!! TPC_ModularEndcap_TDR_o1_v01: Overfull TPC Wall - check your xml file -component <TPCInnerWall/TPCOuterWall>"; + } + + std::cout << "================================================================"<< std::endl; + std::cout<<"=====>$ "<<volName<<" material corresponds to "<< int(fracRadLengthWall*1000)/10. << "% of a radiation length."<<std::endl; + std::cout<<"=====>$ "<<volName<<" effective X0= "<<std::setw(4)<< (r_end-r_start)/fracRadLengthWall <<" cm "<<std::endl; + std::cout<<"=====>$ Sum of layer thickness = "<< drSumThickness/dd4hep::mm <<" mm "<<" \t Wall thickness = "<<(r_end-r_start)/dd4hep::mm <<" mm "<<std::endl; + std::cout << "================================================================"<< std::endl; + } + //-------------------------------- TPCGrip construction ----------------------------------------// + if(types == "TPCGrip") + { + Material gripMaterial = theDetector.material(x_section.attr<std::string>(_Unicode(material))) ; + for(xml_coll_t li(x_section,_U(layer));li;++li) + { + xml_comp_t x_layer(li); + + //std::string volNameLog = x_layer.nameStr()+"Log"; + Tube gripSolid(x_layer.rmin(),x_layer.rmax(),x_layer.z_length()/2., phi1 , phi1+phi2); + Volume gripLog(x_layer.nameStr()+"Log",gripSolid,gripMaterial); + pv=tpc_motherLog.placeVolume(gripLog); + tpc.setVisAttributes(theDetector,x_layer.visStr(),gripLog); + std::cout << "================================================================"<< std::endl; + std::cout<<"=====>$ "<<x_layer.nameStr()<<" Constructed ! "<<std::endl; + std::cout << "================================================================"<< std::endl; + } + } + //-------------------------------- TPCCathode construction ----------------------------------------// + if(types == "TPCCathode") + { + for(xml_coll_t li(x_section,_U(layer));li;++li) + { + xml_comp_t x_layer(li); + Material cathodeMaterial = theDetector.material( x_layer.materialStr()); + + Tube cathodeSolid(x_layer.rmin(),x_layer.rmax(),x_layer.z_length()/2,phi1,phi1+phi2); + Volume cathodeLog(x_layer.nameStr()+"Log",cathodeSolid,cathodeMaterial); + + for(xml_coll_t pj(x_layer,_U(position));pj;++pj) + { + xml_dim_t x_pos(pj); + pv = tpc_motherLog.placeVolume(cathodeLog,Position(x_pos.x(),x_pos.y(),x_pos.z())); + tpc.setVisAttributes(theDetector, x_layer.visStr(),cathodeLog); + std::cout<<"============>Cathod Z Position: "<<x_pos.z() / dd4hep::mm <<" mm "<<std::endl; + } + } + } + //-------------------------------- TPC Sensitive Volume construction ----------------------------------------// + if(types == "TPCSensitiveVol") + { + //Material T2KgasMaterial = theDetector.material(x_section.attr<std::string>(_Unicode(material))) ; + std::cout<<"============>T2K gas RadLen= "<< materialT2Kgas->GetMaterial()->GetRadLen()/dd4hep::mm<<" mm"<<std::endl; + + xml_dim_t dimSD = x_section.dimensions(); + std::cout<<"============>rmin,rmax,dz "<< dimSD.rmin()<<"\t"<<dimSD.rmax()<<"\t"<<dimSD.z_length()<<std::endl; + + Tube sensitiveGasSolid(dimSD.rmin(),dimSD.rmax(),dimSD.z_length()/2.,phi1,phi1+phi2); + Volume sensitiveGasLog(volName+"Log",sensitiveGasSolid,materialT2Kgas); + + DetElement sensGasDEfwd(tpc, "tpc_senGas_fwd",x_det.id()); + DetElement sensGasDEbwd(tpc, "tpc_senGas_bwd",x_det.id()); + + pv = tpc_motherLog.placeVolume(sensitiveGasLog,Transform3D(RotationY(0.),Position(0,0,+(dz_Cathode/2+dimSD.z_length()/2.)))); + pv.addPhysVolID("side",+1); + sensGasDEfwd.setPlacement(pv); + + pv = tpc_motherLog.placeVolume(sensitiveGasLog,Transform3D(RotationY(pi),Position(0,0,-(dz_Cathode/2+dimSD.z_length()/2.)))); + pv.addPhysVolID("side",-1); + sensGasDEbwd.setPlacement(pv); + + tpc.setVisAttributes(theDetector, "gasVis", sensitiveGasLog); + + //Pad row doublets construction + xml_coll_t cc(x_section,_U(layer)); + xml_comp_t x_layer = cc; + int numberPadRows = x_layer.repeat(); + double padHeight = x_layer.thickness(); + std::cout<<"##################$$$$$$$$$$$$$$ Number of Pad Rows: > "<<numberPadRows<<"\t padHeight= "<<padHeight/dd4hep::mm<<" mm"<<std::endl; + + //Sensitive Volume construction : readout pad layers + for(int ilayer=0; ilayer < numberPadRows; ++ilayer) + { + // create twice the number of rings as there are pads, producing an lower and upper part of the pad with the boundry between them the pad-ring centre + const double inner_lowerlayer_radius = dimSD.rmin()+ (ilayer * (padHeight)); + const double outer_lowerlayer_radius = inner_lowerlayer_radius + (padHeight/2.0); + + const double inner_upperlayer_radius = outer_lowerlayer_radius ; + const double outer_upperlayer_radius = inner_upperlayer_radius + (padHeight/2.0); + + Tube lowerlayerSolid( inner_lowerlayer_radius, outer_lowerlayer_radius, dimSD.z_length() / 2.0, phi1, phi2); + Tube upperlayerSolid( inner_upperlayer_radius, outer_upperlayer_radius, dimSD.z_length() / 2.0, phi1, phi2); + + Volume lowerlayerLog( _toString( ilayer ,"TPC_lowerlayer_log_%02d") ,lowerlayerSolid, materialT2Kgas ); + Volume upperlayerLog( _toString( ilayer ,"TPC_upperlayer_log_%02d") ,upperlayerSolid, materialT2Kgas ); + + tpc.setVisAttributes(theDetector, "Invisible" , lowerlayerLog) ; + tpc.setVisAttributes(theDetector, "Invisible" , upperlayerLog) ; + //tpc.setVisAttributes(theDetector, "RedVis" , lowerlayerLog) ; + //tpc.setVisAttributes(theDetector, "RedVis" , upperlayerLog) ; + + DetElement layerDEfwd( sensGasDEfwd , _toString( ilayer, "tpc_row_fwd_%03d") , x_det.id() ); + DetElement layerDEbwd( sensGasDEbwd , _toString( ilayer, "tpc_row_bwd_%03d") , x_det.id() ); + + Vector3D o( inner_upperlayer_radius + 1e-10 , 0. , 0. ) ; + // create an unbounded surface (i.e. an infinite cylinder) and assign it to the forward gaseous volume only + VolCylinder surf( upperlayerLog , SurfaceType(SurfaceType::Sensitive, SurfaceType::Invisible, SurfaceType::Unbounded ) , (padHeight/2.0) , (padHeight/2.0) ,o ) ; + + volSurfaceList( layerDEfwd )->push_back( surf ) ; + // volSurfaceList( layerDEbwd )->push_back( surf ) ; + + pv = sensitiveGasLog.placeVolume( lowerlayerLog ) ; + pv.addPhysVolID("layer", ilayer ).addPhysVolID( "module", 0 ).addPhysVolID("sensor", 1 ) ; + + pv = sensitiveGasLog.placeVolume( upperlayerLog ) ; + pv.addPhysVolID("layer", ilayer ).addPhysVolID( "module", 0 ).addPhysVolID("sensor", 0 ) ; + layerDEfwd.setPlacement( pv ) ; + layerDEbwd.setPlacement( pv ) ; + + lowerlayerLog.setSensitiveDetector(sens); + upperlayerLog.setSensitiveDetector(sens); + } + + } + //-------------------------------- TPC Endplate and readout construction ----------------------------------------// + if(types == "TPCEndplate") + { + xml_dim_t dimEndCap = x_section.dimensions(); + std::cout<<"============>(rmin,rmax,dz): "<< dimEndCap.rmin() / dd4hep::mm<<"mm " + << dimEndCap.rmax() / dd4hep::mm<<" mm " + << dimEndCap.z_length() / dd4hep::mm<< " mm" <<std::endl; + //Create endcap Log volume + Tube endcapSolid(dimEndCap.rmin(),dimEndCap.rmax(),dimEndCap.z_length()/2.,phi1,phi1+phi2); + Volume endcapLog(volName+"Log",endcapSolid,materialAir); + + DetElement endcapDEfwd(tpc, "tpc_endcap_fwd",x_det.id()); + DetElement endcapDEbwd(tpc, "tpc_endcap_bwd",x_det.id()); + + //Vectors for endplate plane + Vector3D u(0.,1.,0.); + Vector3D v(1.,0.,0.); + Vector3D n(0.,0.,1.); + + ////need to set the origin of the helper plane to be inside the material (otherwise it would pick up the vacuum at the origin) + double mid_r = 0.5*(rOuter + rInner); + Vector3D o(0., mid_r, 0.); + + VolPlane surf( endcapLog, SurfaceType( SurfaceType::Helper ), (dz_Endplate+dz_Readout)/2.,dz_Endplate/2.,u,v,n,o); + volSurfaceList(endcapDEfwd) -> push_back(surf); + volSurfaceList(endcapDEbwd) -> push_back(surf); + + pv = tpc_motherLog.placeVolume(endcapLog,Transform3D(RotationY(0.),Position(0,0,+(dzTotal/2.-dz_Endplate/2.)))); + endcapDEfwd.setPlacement(pv); + + pv = tpc_motherLog.placeVolume(endcapLog,Transform3D(RotationY(pi),Position(0,0,-(dzTotal/2.-dz_Endplate/2.)))); + endcapDEbwd.setPlacement(pv); + + tpc.setVisAttributes(theDetector, "transVis", endcapLog); + + //================================================================================================ + //Modular Endplate construction + //================================================================================================ + double dz_Endpaltelength = dimEndCap.z_length(); + double r_start = dimEndCap.rmin(); + double ds_reinforce = x_section.attr<double>(_Unicode(s_frame)); + double dz_Alframe = x_section.attr<double>(_Unicode(z_frame)); + double rCursor = r_start; + + //Loop all layers to construct frame-module + for(xml_coll_t ilayer(x_section,_U(layer)); ilayer; ++ilayer) + { + xml_comp_t x_layer(ilayer); + + const std::string layerName = x_layer.nameStr(); + const std::string layerType = x_layer.attr<std::string>(_Unicode(type)); + double layerThickness = x_layer.thickness(); + + double r_end = rCursor + layerThickness; + std::cout<<"===============>$ "<<layerName<<"\t"<<layerType + <<" thickness = "<<layerThickness / dd4hep::mm << "mm " + <<" inner radius = "<<rCursor / dd4hep::mm<<" mm" + <<" outer radius = "<<r_end /dd4hep::mm<<" mm" + <<std::endl; + + //-------------------------------------- + if(layerType == "Frame") + { + double phi_start = 0.; + double phi_end = 2*M_PI; + Tube ringSolid(rCursor, r_end, dz_Alframe/2., phi_start, phi_end) ; + Volume ringLog( layerName+"Log", ringSolid, materialAlframe) ; + pv = endcapLog.placeVolume( ringLog, Position(0., 0., -dz_Endpaltelength/2. + dz_Alframe) ) ; + tpc.setVisAttributes(theDetector,"GrayVis",ringLog); + } + if(layerType == "Module") + { + int numberofModules = x_layer.repeat(); + double phi_start = x_layer.phi0_offset(); + double phiCursor = phi_start; + double phiModule = (2*M_PI*rCursor-numberofModules*ds_reinforce)/numberofModules/rCursor; + double phiReinforce = ds_reinforce/rCursor; + + //Construct each module + for(int k=0; k<numberofModules;++k) + { + Tube moduleSolid1(rCursor,r_end,dz_Endpaltelength/2.,phiCursor,phiCursor+phiModule); + std::string moduleLogName1 = layerName + _toString(k,"Log%00d"); + Volume moduleLog1(moduleLogName1,moduleSolid1,materialAir); + + double z_cursor = -dz_Endpaltelength/2.; + int m_sli = 0; + for(xml_coll_t sli(x_layer,_U(slice)); sli; ++sli,++m_sli) + { + xml_comp_t x_slice = sli; + double dz_modulepiece = sli.attr<double>(_Unicode(dz)); + std::string moduleSliceName = moduleLogName1 + _toString(m_sli,"slice%d"); + Material slice_mat = theDetector.material(x_slice.materialStr()); + + Tube moduleSliceSolid(rCursor,r_end,dz_modulepiece/2.,phiCursor,phiCursor+phiModule); + Volume moduleSliceLog(moduleSliceName,moduleSliceSolid,slice_mat); + + pv = moduleLog1.placeVolume(moduleSliceLog,Position(0.,0.,z_cursor+dz_modulepiece/2.)); + tpc.setVisAttributes(theDetector, "Invisible" , moduleSliceLog) ; + z_cursor += dz_modulepiece; + + if(z_cursor > dz_Endpaltelength/2.) + { + //std::cout<<" Warning ! TPC_ModularEndcap_TDR_o1_v01: Overfull TPC Module- check your xml file - section <Endpalte>." <<std::endl; + throw " $!!! TPC_ModularEndcap_TDR_o1_v01: Overfull TPC Module- check your xml file - component <Endpalte>."; + } + } + + pv = endcapLog.placeVolume(moduleLog1); + tpc.setVisAttributes(theDetector,"RedVis",moduleLog1); + + phiCursor = phiCursor+phiModule; + + //Construct the Al frame between each module + Tube moduleSolid2(rCursor,r_end,dz_Alframe/2.,phiCursor,phiCursor+phiReinforce); + std::string moduleLogName2 = layerName + _toString(k,"Log_rein%00d"); + Volume moduleLog2(moduleLogName2,moduleSolid2,materialAlframe); + pv = endcapLog.placeVolume(moduleLog2, Position(0., 0., -dz_Endpaltelength/2.+dz_Alframe/2.)); + tpc.setVisAttributes(theDetector,"GrayVis",moduleLog2); + + phiCursor = phiCursor+phiReinforce; + } + } + rCursor = r_end; + } + + double RadlenOfAl_Frame = materialAlframe->GetMaterial()->GetRadLen(); + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_ModularEndcap_TDR_o1_v01: Endplate Al frame corresponds to " << (2. / RadlenOfAl_Frame*100)<< "% of a radiation length." << std::endl; + std::cout << "================================================================"<< std::endl; + } + //-------------------------------- TPCreadout construction ----------------------------------------// + if(types == "TPCreadout") + { + xml_dim_t dimReadout = x_section.dimensions(); + double dzReadout = dimReadout.z_length(); + Tube readoutSolid(dimReadout.rmin(),dimReadout.rmax(),dimReadout.z_length()/2.,phi1,phi1+phi2); + Volume readoutLog(volName+"Log",readoutSolid, materialT2Kgas); + + tpc.setVisAttributes(theDetector,"CyanVis",readoutLog); + + xml_dim_t posReadout = x_section.position(); + pv = tpc_motherLog.placeVolume(readoutLog,Transform3D(RotationY(0.),Position(0,0,posReadout.z()))); + pv = tpc_motherLog.placeVolume(readoutLog,Transform3D(RotationY(pi),Position(0,0,-posReadout.z()))); + + std::cout<<"=========ReadOut dim: "<< dimReadout.rmin() / dd4hep::mm<<" mm " + << dimReadout.rmax() / dd4hep::mm<<" mm " + << dzReadout / dd4hep::mm <<" mm "<<std::endl; + std::cout<<"=========ReadOut Z_pos: "<<posReadout.z() / dd4hep::mm << " mm "<<std::endl; + + int pieceCounter = 0; + double fracRadLengthReadout = 0; + double zCursor = -dzReadout/ 2; + + for(xml_coll_t li(x_section,_U(layer)); li;++li) + { + xml_comp_t x_layer( li ); + + const double dzPiece = x_layer.attr<double>(_Unicode(dz)); + Material pieceMaterial = theDetector.material( x_layer.materialStr() ); + Tube pieceSolid( dimReadout.rmin(),dimReadout.rmax(), dzPiece / 2, phi1, phi2); + Volume pieceLog ( _toString( pieceCounter ,"TPCReadoutPieceLog_%02d"), pieceSolid, pieceMaterial ) ; + + pieceLog.setVisAttributes(theDetector,x_layer.visStr()); + + pv = readoutLog.placeVolume( pieceLog , Position(0, 0, zCursor + dzPiece/2. ) ) ; + + ++pieceCounter; + fracRadLengthReadout += dzPiece / pieceMaterial->GetMaterial()->GetRadLen(); + zCursor += dzPiece; + + std::cout<<"==========> "<<dzPiece/dd4hep::mm<<" mm Material= "<<x_layer.materialStr()<<"\t" + <<"X0= "<<pieceMaterial->GetMaterial()->GetRadLen()/dd4hep::mm<<"\t" + <<dzPiece / pieceMaterial->GetMaterial()->GetRadLen() <<" X0"<< std::endl; + + if (zCursor > +dzReadout / 2) + { + //throw GeometryException( "TPC11: Overfull TPC readout - check your xml file - section <readout>." ) ; + //std::cout<<" TPC_ModularEndcap_TDR_o1_v01: Overfull TPC readout - check your xml file - component <TPCReadout>." <<std::endl; + throw " $!!! TPC_ModularEndcap_TDR_o1_v01: Overfull TPC readout - check your xml file - component <TPCReadout>."; + } + } + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_ModularEndcap_TDR_o1_v01: Readout material corresponds to " << int(fracRadLengthReadout * 1000) / 10.0 << "% of a radiation length." << std::endl; + std::cout << "================================================================"<< std::endl; + } + + } + + //TPC data + FixedPadSizeTPCData* tpcData = new FixedPadSizeTPCData(); + tpcData->zHalf = dzTotal/2.; + tpcData->rMin = rInner; + tpcData->rMax = rOuter; + tpcData->innerWallThickness = drInnerWall; + tpcData->outerWallThickness = drOuterWall; + tpcData->rMinReadout = rInner + drInnerWall; + tpcData->rMaxReadout = rInner + drInnerWall + tpcnumberOfPadRows*tpcpadheight; + tpcData->maxRow = tpcnumberOfPadRows; + tpcData->padHeight = tpcpadheight; + tpcData->padWidth = tpcpadwidth; + tpcData->driftLength = dzTotal/2.- dz_Endplate - dz_Readout - dz_Cathode/2.0; // SJA: cathode has to be added as the sensitive region does not start at 0.00 + tpcData->zMinReadout = dz_Cathode/2.0; + + //tpc.setVisAttributes( theDetector, x_det.visStr(), envelope ); + tpc.setVisAttributes( theDetector, "TPCMotherVis1", envelope ); + // if( tpc.isValid() ) + // tpc.setPlacement(pv); + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_ModularEndcap_TDR_o1_v01 Constructed!"<< std::endl; + std::cout << "================================================================"<< std::endl; + + return tpc; +} +DECLARE_DETELEMENT(TPC_ModularEndcap_o1_v01,create_element) diff --git a/Detector/DetCRD/src/Tracker/TPC_Simple_o1_v01.cpp b/Detector/DetCRD/src/Tracker/TPC_Simple_o1_v01.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ce7ec73a64af36138604f83fd7f30cc0a74803c --- /dev/null +++ b/Detector/DetCRD/src/Tracker/TPC_Simple_o1_v01.cpp @@ -0,0 +1,464 @@ +/********************************************************************* + * Author : Lan-sx & origin author: F. Gaede, Desy + * Email : shexin@ihep.ac.cn + * Last modified : 2024-06-02 20:40 + * Filename : TPC_Simple_o1_v01.cpp + * Description : + * ******************************************************************/ + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetType.h" +//#include "./include/LcgeoExceptions.h" +//#include "./include/lcgeo.h" +#include "DDRec/Surface.h" +#include "DDRec/DetectorData.h" +#include "XML/Utilities.h" +//#include "XMLHandlerDB.h" + +#include <math.h> + +using namespace std; +using namespace dd4hep; +//using namespace lcgeo; + +using dd4hep::rec::Vector3D; +using dd4hep::rec::VolCylinder; +using dd4hep::rec::SurfaceType; +using dd4hep::rec::volSurfaceList; +using dd4hep::rec::VolPlane; +using dd4hep::rec::FixedPadSizeTPCData; + +/** Construction of TPC detector, ported from Mokka driver TPC10.cc + * Mokka History: + * - modified version of TPC driver by Ties Behnke + * - modified version of TPC02 as TPC03 with selectable chamber gas -- Adrian Vogel, 2005-06-09 + * - modified version of TPC03 as TPC04 with limit of step length -- Adrian Vogel, 2006-02-01 + * - introduced self-scalability, no superdriver needed anymore -- Adrian Vogel, 2006-03-11 + * - modified version of TPC04 as TPC05 in order to have full MC + * information both at entry and exit hits in the TPC , + * more realistic central electrode and endplate -- Predrag Krstonosic, 2006-07-12 + * - implemented new GEAR interface -- K. Harder, T. Pinto Jayawardena 2007-07-31 + * - TPC10 implemented readout within the Gas volume and layered inner and outer wall -- SJA -- 2010-11-19 + * + * @author: F.Gaede, DESY, Nov 2013 + * + * - Simple TPC Geo implemention for CEPC TDR TPC + * @author: X.She, IHEP, May 2024 + */ + +static Ref_t create_element(Detector& theDetector, xml_h e, SensitiveDetector sens) { + + //------------------------------------------ + // See comments starting with '//**' for + // hints on porting issues + //------------------------------------------ + xml_det_t x_det = e; + string name = x_det.nameStr(); + + DetElement tpc( name, x_det.id() ) ; + + // --- create an envelope volume and position it into the world --------------------- + + Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, e , tpc ) ; + + dd4hep::xml::setDetectorTypeFlag( e, tpc ) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return tpc ; + + //----------------------------------------------------------------------------------- + + PlacedVolume pv; + + sens.setType("tracker"); + + std::cout << " **Lan Lan building TPC_Simple_TDR_o1_v01 construction" << std::endl ; + + //###################################################################################################################################################################### + + const double phi1 = 0.0 ; + const double phi2 = 2*M_PI ; + const double dzTotal = theDetector.constant<double>("TPC_half_length") * 2. ; + const double rInner = theDetector.constant<double>("TPC_inner_radius") ; + const double rOuter = theDetector.constant<double>("TPC_outer_radius") ; + const double drInnerWall = theDetector.constant<double>("TPC_dr_InnerWall"); + const double drOuterWall = theDetector.constant<double>("TPC_dr_OuterWall"); + const double dz_Cathode = theDetector.constant<double>("TPC_dz_Cathode"); + const double dz_Endplate = theDetector.constant<double>("TPC_dz_Endplate"); + const double dz_Readout = theDetector.constant<double>("TPC_dz_Readout"); + const double tpcpadheight = theDetector.constant<double>("TPC_pad_height"); + const double tpcpadwidth = theDetector.constant<double>("TPC_pad_width"); + const int tpcnumberOfPadRows = theDetector.constant<int>("TPC_numberOfPadrows"); + + + std::cout<< "============ TPC_Simple_TDR_o1_v01 mother Volume(Tube) (Dz,Ri,Ro) : (" << dzTotal/dd4hep::mm/2. << "\t" + << rInner/dd4hep::mm << "\t" + << rOuter/dd4hep::mm <<" )"<<std::endl; + Material materialT2Kgas = theDetector.material("T2KGas1"); + Material materialAir = theDetector.material("Air"); + //-------------------------------------------------------------------------------------------------------// + //-------------------------------- TPC mother volume ----------------------------------------------------// + //------------ Volume for the whole TPC, Field Cage, Cathode, and Endplate and Sensitive ----------------// + + Tube tpc_motherSolid(rInner ,rOuter ,dzTotal/2.0 , phi1 , phi1+phi2 ); + Volume tpc_motherLog( "TPCLog", tpc_motherSolid, materialT2Kgas); + pv = envelope.placeVolume( tpc_motherLog ) ; + tpc.setVisAttributes(theDetector, "TPCMotherVis1" , tpc_motherLog ) ; + + double gasRegion = ((rOuter-drOuterWall)-(rInner+drInnerWall))/dd4hep::mm; + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_Simple_TDR_o1_v01: Total Gas material corresponds to " << ( ( gasRegion ) / (materialT2Kgas->GetMaterial()->GetRadLen() / dd4hep::mm ) * 100.0 ) + << "% of a radiation length." << std::endl; + std::cout << "================================================================"<< std::endl; + + //-------------------------------------------------------------------------------------------------------// + //Loop all TPC components + //-------------------------------------------------------------------------------------------------------// + + for(xml_coll_t si(x_det, Unicode("component"));si;++si) + { + xml_comp_t x_section(si); + std::string types = x_section.attr<std::string>(_Unicode(type)); + const std::string volName = x_section.nameStr(); + + //-------------------------------- inner/outer wall construction ----------------------------------------// + if(types == "TPCinnerWall" || types == "TPCouterWall") + { + double r_start = x_section.attr<double>(_Unicode(R_start)); + double r_end = x_section.attr<double>(_Unicode(R_end)); + double z_fulllength = x_section.attr<double>(_Unicode(Z_fulllength)); + + //Create Inner/Outer Wall mother logic volume + std::string volNameLog = volName + "Log"; + Tube WallSolid(r_start,r_end,z_fulllength/2., phi1 , phi1+phi2); + Volume WallLog(volNameLog,WallSolid,materialT2Kgas); + pv=tpc_motherLog.placeVolume(WallLog); + tpc.setVisAttributes(theDetector,"CyanVis",WallLog); + + Vector3D ocyl; + //SurfaceList data, keep the CEPCV4 + double dr_wall = r_end-r_start; + if(types == "TPCinnerWall") + ocyl.fill(r_start+0.5*dr_wall,0.,0.); + else + ocyl.fill(r_end-0.5*dr_wall,0.,0.); + + //std::cout<<"======> Vector3D cout : "<<ocyl.x()<<"\t"<<ocyl.y()<<"\t"<<ocyl.z()<<std::endl; + VolCylinder surfWall(WallLog,SurfaceType( SurfaceType::Helper ),0.5*dr_wall,0.5*dr_wall,ocyl); + volSurfaceList( tpc )->push_back( surfWall ); + + //Loop all layers of TPC inner/outer wall + int ilayer =0; + double rCursor = r_start; + double fracRadLengthWall = 0.; + for(xml_coll_t li(x_section,_U(layer)); li;++li,++ilayer) + { + xml_comp_t x_layer(li); + + double thickness = x_layer.thickness(); + Material layerMaterial = theDetector.material( x_layer.materialStr() ); + char suffix[20]; + sprintf(suffix,"_%d",ilayer); + std::string layerName = volNameLog + suffix; + + Tube layerSolid(rCursor,rCursor+thickness,z_fulllength/2.,phi1,phi1+phi2); + Volume layerLog(layerName,layerSolid,layerMaterial); + //layerLog.setVisAttributes(theDetector,x_layer.visStr()); + pv=WallLog.placeVolume(layerLog); + + rCursor += thickness; + double layerRadLength = thickness/(layerMaterial->GetMaterial()->GetRadLen()); + fracRadLengthWall += layerRadLength; + + std::cout<<"-> "<<volName<<"layer"<<ilayer<<" : "<< thickness/dd4hep::mm << "mm \t Materials: "<<layerMaterial.name() + <<" X0= "<<layerMaterial->GetMaterial()->GetRadLen()/dd4hep::mm<<"mm \t" + <<layerRadLength<<" X0"<<std::endl; + } + + double drSumThickness = rCursor - r_start; + if(drSumThickness > (r_end-r_start)) + { + std::cout<<"Warning! sum_{i}layerThickness_{i} > drWall !\n"<<std::endl; + throw "$!!! TPC_Simple_TDR_o1_v01: Overfull TPC Wall - check your xml file -component <TPCInnerWall/TPCOuterWall>"; + } + + std::cout << "================================================================"<< std::endl; + std::cout<<"=====>$ "<<volName<<" material corresponds to "<< int(fracRadLengthWall*1000)/10. << "% of a radiation length."<<std::endl; + std::cout<<"=====>$ "<<volName<<" effective X0= "<<std::setw(4)<< (r_end-r_start)/fracRadLengthWall <<" cm "<<std::endl; + std::cout<<"=====>$ Sum of layer thickness = "<< drSumThickness/dd4hep::mm <<" mm "<<" \t Wall thickness = "<<(r_end-r_start)/dd4hep::mm <<" mm "<<std::endl; + std::cout << "================================================================"<< std::endl; + } + //-------------------------------- TPCGrip construction ----------------------------------------// + if(types == "TPCGrip") + { + Material gripMaterial = theDetector.material(x_section.attr<std::string>(_Unicode(material))) ; + for(xml_coll_t li(x_section,_U(layer));li;++li) + { + xml_comp_t x_layer(li); + + //std::string volNameLog = x_layer.nameStr()+"Log"; + Tube gripSolid(x_layer.rmin(),x_layer.rmax(),x_layer.z_length()/2., phi1 , phi1+phi2); + Volume gripLog(x_layer.nameStr()+"Log",gripSolid,gripMaterial); + pv=tpc_motherLog.placeVolume(gripLog); + + tpc.setVisAttributes(theDetector,x_layer.visStr(),gripLog); + std::cout << "================================================================"<< std::endl; + std::cout << "=====>$ "<<x_layer.nameStr()<<" Constructed ! "<<std::endl; + std::cout << "================================================================"<< std::endl; + } + } + //-------------------------------- TPCCathode construction ----------------------------------------// + if(types == "TPCCathode") + { + for(xml_coll_t li(x_section,_U(layer));li;++li) + { + xml_comp_t x_layer(li); + Material cathodeMaterial = theDetector.material( x_layer.materialStr()); + + Tube cathodeSolid(x_layer.rmin(),x_layer.rmax(),x_layer.z_length()/2,phi1,phi1+phi2); + Volume cathodeLog(x_layer.nameStr()+"Log",cathodeSolid,cathodeMaterial); + + for(xml_coll_t pj(x_layer,_U(position));pj;++pj) + { + xml_dim_t x_pos(pj); + pv = tpc_motherLog.placeVolume(cathodeLog,Position(x_pos.x(),x_pos.y(),x_pos.z())); + tpc.setVisAttributes(theDetector, x_layer.visStr(),cathodeLog); + std::cout<<"============>Cathod Z Position: "<<x_pos.z() / dd4hep::mm <<" mm "<<std::endl; + } + } + } + //-------------------------------- TPC Sensitive Volume construction ----------------------------------------// + if(types == "TPCSensitiveVol") + { + //Material T2KgasMaterial = theDetector.material(x_section.attr<std::string>(_Unicode(material))) ; + std::cout<<"============>T2K gas RadLen= "<< materialT2Kgas->GetMaterial()->GetRadLen()/dd4hep::mm<<" mm"<<std::endl; + + xml_dim_t dimSD = x_section.dimensions(); + std::cout<<"============>rmin,rmax,dz "<< dimSD.rmin()<<"\t"<<dimSD.rmax()<<"\t"<<dimSD.z_length()<<std::endl; + + Tube sensitiveGasSolid(dimSD.rmin(),dimSD.rmax(),dimSD.z_length()/2.,phi1,phi1+phi2); + Volume sensitiveGasLog(volName+"Log",sensitiveGasSolid,materialT2Kgas); + + DetElement sensGasDEfwd(tpc, "tpc_senGas_fwd",x_det.id()); + DetElement sensGasDEbwd(tpc, "tpc_senGas_bwd",x_det.id()); + + pv = tpc_motherLog.placeVolume(sensitiveGasLog,Transform3D(RotationY(0.),Position(0,0,+(dz_Cathode/2+dimSD.z_length()/2.)))); + pv.addPhysVolID("side",+1); + sensGasDEfwd.setPlacement(pv); + + pv = tpc_motherLog.placeVolume(sensitiveGasLog,Transform3D(RotationY(pi),Position(0,0,-(dz_Cathode/2+dimSD.z_length()/2.)))); + pv.addPhysVolID("side",-1); + sensGasDEbwd.setPlacement(pv); + + tpc.setVisAttributes(theDetector, "gasVis", sensitiveGasLog); + + //Pad row doublets construction + xml_coll_t cc(x_section,_U(layer)); + xml_comp_t x_layer = cc; + int numberPadRows = x_layer.repeat(); + double padHeight = x_layer.thickness(); + std::cout<<"##################$$$$$$$$$$$$$$ Number of Pad Rows: > "<<numberPadRows<<"\t padHeight= "<<padHeight/dd4hep::mm<<" mm"<<std::endl; + + //Sensitive Volume construction : readout pad layers + for(int ilayer=0; ilayer < numberPadRows; ++ilayer) + { + // create twice the number of rings as there are pads, producing an lower and upper part of the pad with the boundry between them the pad-ring centre + const double inner_lowerlayer_radius = dimSD.rmin()+ (ilayer * (padHeight)); + const double outer_lowerlayer_radius = inner_lowerlayer_radius + (padHeight/2.0); + + const double inner_upperlayer_radius = outer_lowerlayer_radius ; + const double outer_upperlayer_radius = inner_upperlayer_radius + (padHeight/2.0); + + Tube lowerlayerSolid( inner_lowerlayer_radius, outer_lowerlayer_radius, dimSD.z_length() / 2.0, phi1, phi2); + Tube upperlayerSolid( inner_upperlayer_radius, outer_upperlayer_radius, dimSD.z_length() / 2.0, phi1, phi2); + + Volume lowerlayerLog( _toString( ilayer ,"TPC_lowerlayer_log_%02d") ,lowerlayerSolid, materialT2Kgas ); + Volume upperlayerLog( _toString( ilayer ,"TPC_upperlayer_log_%02d") ,upperlayerSolid, materialT2Kgas ); + + tpc.setVisAttributes(theDetector, "Invisible" , lowerlayerLog) ; + tpc.setVisAttributes(theDetector, "Invisible" , upperlayerLog) ; + //tpc.setVisAttributes(theDetector, "RedVis" , lowerlayerLog) ; + //tpc.setVisAttributes(theDetector, "RedVis" , upperlayerLog) ; + + + DetElement layerDEfwd( sensGasDEfwd , _toString( ilayer, "tpc_row_fwd_%03d") , x_det.id() ); + DetElement layerDEbwd( sensGasDEbwd , _toString( ilayer, "tpc_row_bwd_%03d") , x_det.id() ); + + Vector3D o( inner_upperlayer_radius + 1e-10 , 0. , 0. ) ; + // create an unbounded surface (i.e. an infinite cylinder) and assign it to the forward gaseous volume only + VolCylinder surf( upperlayerLog , SurfaceType(SurfaceType::Sensitive, SurfaceType::Invisible, SurfaceType::Unbounded ) , (padHeight/2.0) , (padHeight/2.0) ,o ) ; + + volSurfaceList( layerDEfwd )->push_back( surf ) ; + // volSurfaceList( layerDEbwd )->push_back( surf ) ; + + pv = sensitiveGasLog.placeVolume( lowerlayerLog ) ; + pv.addPhysVolID("layer", ilayer ).addPhysVolID( "module", 0 ).addPhysVolID("sensor", 1 ) ; + + pv = sensitiveGasLog.placeVolume( upperlayerLog ) ; + pv.addPhysVolID("layer", ilayer ).addPhysVolID( "module", 0 ).addPhysVolID("sensor", 0 ) ; + layerDEfwd.setPlacement( pv ) ; + layerDEbwd.setPlacement( pv ) ; + + lowerlayerLog.setSensitiveDetector(sens); + upperlayerLog.setSensitiveDetector(sens); + } + + } + //-------------------------------- TPC Endplate construction ----------------------------------------// + if(types == "TPCEndplate") + { + //Material endplateMaterial = theDetector.material(x_section.attr<std::string>(_Unicode(material))) ; + //std::cout<<"============>Endplate Log material RadLen= "<< endplateMaterial->GetMaterial()->GetRadLen()/dd4hep::mm<<" mm "<<std::endl; + + xml_dim_t dimEndCap = x_section.dimensions(); + std::cout<<"============>(rmin,rmax,dz): "<< dimEndCap.rmin() / dd4hep::mm<<"mm " + << dimEndCap.rmax() / dd4hep::mm<<" mm " + << dimEndCap.z_length() / dd4hep::mm<< " mm" <<std::endl; + + Tube endcapSolid(dimEndCap.rmin(),dimEndCap.rmax(),dimEndCap.z_length()/2.,phi1,phi1+phi2); + Volume endcapLog(volName+"Log",endcapSolid,materialAir); + + DetElement endcapDEfwd(tpc, "tpc_endcap_fwd",x_det.id()); + DetElement endcapDEbwd(tpc, "tpc_endcap_bwd",x_det.id()); + + //Vectors for endplate plane + Vector3D u(0.,1.,0.); + Vector3D v(1.,0.,0.); + Vector3D n(0.,0.,1.); + + //need to set the origin of the helper plane to be inside the material (otherwise it would pick up the vacuum at the origin) + double mid_r = 0.5*(rOuter + rInner); + Vector3D o(0., mid_r, 0.); + + VolPlane surf( endcapLog, SurfaceType( SurfaceType::Helper ), (dz_Endplate+dz_Readout)/2.,dz_Endplate/2.,u,v,n,o); + volSurfaceList(endcapDEfwd) -> push_back(surf); + volSurfaceList(endcapDEbwd) -> push_back(surf); + + pv = tpc_motherLog.placeVolume(endcapLog,Transform3D(RotationY(0.),Position(0,0,+(dzTotal/2.-dz_Endplate/2.)))); + endcapDEfwd.setPlacement(pv); + + pv = tpc_motherLog.placeVolume(endcapLog,Transform3D(RotationY(pi),Position(0,0,-(dzTotal/2.-dz_Endplate/2.)))); + endcapDEbwd.setPlacement(pv); + + tpc.setVisAttributes(theDetector, "readoutVis", endcapLog); + + int pieceCounter = 0; + double fracRadLengthEndplate = 0; + double zCursor = -dz_Endplate/ 2; + + for(xml_coll_t li(x_section,_U(layer)); li;++li) + { + xml_comp_t x_layer( li ); + + const double dzPiece = x_layer.attr<double>(_Unicode(dz)); + Material pieceMaterial = theDetector.material( x_layer.materialStr() ); + Tube pieceSolid( dimEndCap.rmin(),dimEndCap.rmax(), dzPiece / 2, phi1, phi2); + Volume pieceLog ( _toString( pieceCounter ,"TPCReadoutPieceLog_%02d"), pieceSolid, pieceMaterial ) ; + + pieceLog.setVisAttributes(theDetector,x_layer.visStr()); + + pv = endcapLog.placeVolume( pieceLog , Position(0, 0, zCursor + dzPiece/2. ) ) ; + + ++pieceCounter; + fracRadLengthEndplate += dzPiece / pieceMaterial->GetMaterial()->GetRadLen(); + zCursor += dzPiece; + + std::cout<<"==========> z_pos ="<<zCursor/dd4hep::mm<<" mm "<<dzPiece/dd4hep::mm<<" mm Material= "<<x_layer.materialStr()<<"\t" + <<"X0= "<<pieceMaterial->GetMaterial()->GetRadLen()/dd4hep::mm<<"\t" + <<dzPiece / pieceMaterial->GetMaterial()->GetRadLen() <<" X0"<< std::endl; + + if (zCursor > + dz_Endplate/ 2) + { + //throw GeometryException( "TPC11: Overfull TPC endplate - check your xml file - section <readout>." ) ; + throw " $!!! TPC_Simple_TDR_o1_v01: Overfull TPC endplate - check your xml file - component <TPCEndplate>."; + } + + } + + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_Simple_TDR_o1_v01: Endplate material corresponds to " << int(fracRadLengthEndplate* 1000) / 10.0 << "% of a radiation length." << std::endl; + std::cout << "================================================================"<< std::endl; + } + //-------------------------------- TPCreadout construction ----------------------------------------// + if(types == "TPCreadout") + { + xml_dim_t dimReadout = x_section.dimensions(); + double dzReadout = dimReadout.z_length(); + Tube readoutSolid(dimReadout.rmin(),dimReadout.rmax(),dimReadout.z_length()/2.,phi1,phi1+phi2); + Volume readoutLog(volName+"Log",readoutSolid, materialT2Kgas); + + tpc.setVisAttributes(theDetector,"CyanVis",readoutLog); + + xml_dim_t posReadout = x_section.position(); + pv = tpc_motherLog.placeVolume(readoutLog,Transform3D(RotationY(0.),Position(0,0,posReadout.z()))); + pv = tpc_motherLog.placeVolume(readoutLog,Transform3D(RotationY(pi),Position(0,0,-posReadout.z()))); + + std::cout<<"=========ReadOut dim: "<< dimReadout.rmin() / dd4hep::mm<<" mm " + << dimReadout.rmax() / dd4hep::mm<<" mm" + << dzReadout / dd4hep::mm <<" mm "<<std::endl; + std::cout<<"=========ReadOut Z_pos: "<<posReadout.z() / dd4hep::mm << " mm "<<std::endl; + + int pieceCounter = 0; + double fracRadLengthReadout = 0; + double zCursor = -dzReadout/ 2; + + for(xml_coll_t li(x_section,_U(layer)); li;++li) + { + xml_comp_t x_layer( li ); + + const double dzPiece = x_layer.attr<double>(_Unicode(dz)); + Material pieceMaterial = theDetector.material( x_layer.materialStr() ); + Tube pieceSolid( dimReadout.rmin(),dimReadout.rmax(), dzPiece / 2, phi1, phi2); + Volume pieceLog ( _toString( pieceCounter ,"TPCReadoutPieceLog_%02d"), pieceSolid, pieceMaterial ) ; + + pieceLog.setVisAttributes(theDetector,x_layer.visStr()); + + pv = readoutLog.placeVolume( pieceLog , Position(0, 0, zCursor + dzPiece/2. ) ) ; + + ++pieceCounter; + fracRadLengthReadout += dzPiece / pieceMaterial->GetMaterial()->GetRadLen(); + zCursor += dzPiece; + + std::cout<<"==========> z_pos ="<<zCursor/dd4hep::mm<<" mm "<<dzPiece/dd4hep::mm<<" mm Material= "<<x_layer.materialStr()<<"\t" + <<"X0= "<<pieceMaterial->GetMaterial()->GetRadLen()/dd4hep::mm<<"\t" + <<dzPiece / pieceMaterial->GetMaterial()->GetRadLen() <<" X0"<< std::endl; + + if (zCursor > + dzReadout / 2) + { + //throw GeometryException( "TPC11: Overfull TPC readout - check your xml file - section <readout>." ) ; + throw " $!!! TPC_Simple_TDR_o1_v01: Overfull TPC readout - check your xml file - comment <TPCreadout>."; + } + } + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_Simple_TDR_o1_v01: Readout material corresponds to " << int(fracRadLengthReadout * 1000) / 10.0 << "% of a radiation length." << std::endl; + std::cout << "================================================================"<< std::endl; + } + + } + + //TPC data + FixedPadSizeTPCData* tpcData = new FixedPadSizeTPCData(); + tpcData->zHalf = dzTotal/2.; + tpcData->rMin = rInner; + tpcData->rMax = rOuter; + tpcData->innerWallThickness = drInnerWall; + tpcData->outerWallThickness = drOuterWall; + tpcData->rMinReadout = rInner + drInnerWall; + tpcData->rMaxReadout = rInner + drInnerWall + tpcnumberOfPadRows*tpcpadheight; + tpcData->maxRow = tpcnumberOfPadRows; + tpcData->padHeight = tpcpadheight; + tpcData->padWidth = tpcpadwidth; + tpcData->driftLength = dzTotal/2.- dz_Endplate - dz_Readout - dz_Cathode/2.0; // SJA: cathode has to be added as the sensitive region does not start at 0.00 + tpcData->zMinReadout = dz_Cathode/2.0; + + //tpc.setVisAttributes( theDetector, x_det.visStr(), envelope ); + tpc.setVisAttributes( theDetector, "TPCMotherVis1", envelope ); + // if( tpc.isValid() ) + // tpc.setPlacement(pv); + std::cout << "================================================================"<< std::endl; + std::cout << "TPC_Simple_TDR_o1_v01 Constructed!"<< std::endl; + std::cout << "================================================================"<< std::endl; + + return tpc; +} +DECLARE_DETELEMENT(TPC_Simple_o1_v01,create_element)