diff --git a/Detector/DetCRD/CMakeLists.txt b/Detector/DetCRD/CMakeLists.txt index 7dcd2a1d15f3ed97bf9739b4e5a436ddcb737dd5..b6e71ca3e315306d16608371171e9448573e596c 100644 --- a/Detector/DetCRD/CMakeLists.txt +++ b/Detector/DetCRD/CMakeLists.txt @@ -20,7 +20,8 @@ gaudi_add_module(DetCRD src/Tracker/SiTrackerStaggeredLadder_v01_geo.cpp src/Tracker/TPC_Simple_o1_v01.cpp src/Tracker/TPC_ModularEndcap_o1_v01.cpp - src/Tracker/SiTracker_otkbarrel_v01_geo.cpp + src/Tracker/SiTracker_otkbarrel_v01_geo.cpp + src/Tracker/SiTracker_otkendcap_v01_geo.cpp LINK ${DD4hep_COMPONENT_LIBRARIES} ) diff --git a/Detector/DetCRD/compact/CRD_common_v01/OTKEndCap_v01_01.xml b/Detector/DetCRD/compact/CRD_common_v01/OTKEndCap_v01_01.xml new file mode 100644 index 0000000000000000000000000000000000000000..fb0b4375f9f8a4ca5f6c3611577c79d2a4aaad78 --- /dev/null +++ b/Detector/DetCRD/compact/CRD_common_v01/OTKEndCap_v01_01.xml @@ -0,0 +1,96 @@ +<lccdd> + <info name="OTKEndCap_v01_01" + title="CepC OTKEndCap" + author="D.Yu, " + url="http://cepc.ihep.ac.cn" + contact="yudian2002@sjtu.edu.cn" + status="developing" + version="v01"> + <!-- OTKEndCap stands for outer tracker endcap, OTK_EndCap --> + </info> + <define> + <constant name="OTKEndCap_total_sections" value="10" /> + <constant name="OTKEndCap_r0" value="400*mm" /> + <constant name="OTKEndCap_r1" value="540*mm" /> + <constant name="OTKEndCap_r2" value="680*mm" /> + <constant name="OTKEndCap_r3" value="820*mm" /> + <constant name="OTKEndCap_r4" value="960*mm" /> + <constant name="OTKEndCap_r5" value="1100*mm" /> + <constant name="OTKEndCap_r6" value="1240*mm" /> + <constant name="OTKEndCap_r7" value="1380*mm" /> + <constant name="OTKEndCap_r8" value="1520*mm" /> + <constant name="OTKEndCap_r9" value="1660*mm" /> + <constant name="OTKEndCap_r10" value="1800*mm" /> + <constant name="OTKEndCap_inner_radius" value="OTKEndCap_r0" /> + <constant name="OTKEndCap_outer_radius" value="OTKEndCap_r10" /> + <constant name="OTKEndCap_half_length" value="2900*mm" /> + <constant name="OTKEndCap_piece_deg" value="8" /><!-- variable OTKEndCap_piece_deg needs no dimension --> + <constant name="OTKEndCap_piece_num" value="24" /> + <constant name="OTKEndCap_asic_num_0" value="5" /> + <constant name="OTKEndCap_asic_num_1" value="7" /> + <constant name="OTKEndCap_asic_num_2" value="9" /> + <constant name="OTKEndCap_asic_num_3" value="11" /> + <constant name="OTKEndCap_asic_num_4" value="13" /> + <constant name="OTKEndCap_asic_num_5" value="15" /> + <constant name="OTKEndCap_asic_num_6" value="17" /> + <constant name="OTKEndCap_asic_num_7" value="19" /> + <constant name="OTKEndCap_asic_num_8" value="21" /> + <constant name="OTKEndCap_asic_num_9" value="23" /> + <constant name="OTKEndCap_module_num_0" value="1" /> + <constant name="OTKEndCap_module_num_1" value="1" /> + <constant name="OTKEndCap_module_num_2" value="1" /> + <constant name="OTKEndCap_module_num_3" value="1" /> + <constant name="OTKEndCap_module_num_4" value="1" /> + <constant name="OTKEndCap_module_num_5" value="2" /> + <constant name="OTKEndCap_module_num_6" value="2" /> + <constant name="OTKEndCap_module_num_7" value="2" /> + <constant name="OTKEndCap_module_num_8" value="2" /> + <constant name="OTKEndCap_module_num_9" value="2" /> + <constant name="OTKEndCap_layer_thickness" value="25*mm" /> + <constant name="OTKEndCap_layer0_zpos" value="2850*mm" /> + <constant name="OTKEndCap_layer1_zpos" value="2875*mm" /> + <constant name="OTKEndCap_support_thickness" value="1*mm" /> + <constant name="OTKEndCap_sensor_thickness" value="500*um" /> + <constant name="OTKEndCap_sensor_gap" value="0.1*mm" /> + <constant name="OTKEndCap_sensor_dead_width" value="0.001*mm" /><!-- do not set it to 0 --> + <constant name="OTKEndCap_pcb_thickness" value="500*um" /> + <constant name="OTKEndCap_pcb_rlength" value="10*mm" /> + <constant name="OTKEndCap_pcb_rgap" value="10*mm" /> + <constant name="OTKEndCap_asic_thickness" value="500*um" /> + <constant name="OTKEndCap_asic_width" value="6*mm" /> + <constant name="OTKEndCap_asic_rlength" value="6*mm" /> + <constant name="OTKEndCap_asic_rgap" value="12*mm" /> + + </define> + + <detectors> + <detector id="DetID_OTKEndCap" name="OTKEndCap" type="SiTracker_otkendcap_v01" vis="OTKEndCapVis" readout="OTKEndCapCollection" insideTrackingVolume="true"> + <envelope> + <shape type="BooleanShape" operation="Union" material="Air" > + <shape type="Tube" rmin="OTKEndCap_inner_radius" rmax="OTKEndCap_outer_radius" dz="OTKEndCap_half_length" /> + </shape> + </envelope> + <display support="WhiteVis" sens_env="SeeThrough" sens="GrayVis" deadsensor="GreenVis" + pcb="GreenVis" asic="YellowVis"/> + <type_flags type="DetType_TRACKER + DetType_ENDCAP + DetType_STRIP "/> + <global sensitive_mat="G4_Si" support_mat="G4_C" sensitive_threshold_KeV="64*keV"/> + <support thickness="OTKEndCap_support_thickness" inner_radius="OTKEndCap_inner_radius" outer_radius="OTKEndCap_outer_radius" mat="CarbonFiber"/> + <layer id="0" thickness="OTKEndCap_layer_thickness" zpos="OTKEndCap_layer0_zpos"> + <sensor gap="OTKEndCap_sensor_gap" thickness="OTKEndCap_sensor_thickness" dead_width="OTKEndCap_sensor_dead_width" mat="G4_Si"/> + <pcb thickness="OTKEndCap_pcb_thickness" rlength="OTKEndCap_pcb_rlength" rgap="OTKEndCap_pcb_rgap" mat="epoxy"/> + <asic thickness="OTKEndCap_asic_thickness" width="OTKEndCap_asic_width" rlength="OTKEndCap_asic_rlength" rgap="OTKEndCap_asic_rgap" mat="G4_Si"/> + </layer> + <layer id="1" thickness="OTKEndCap_layer_thickness" zpos="OTKEndCap_layer1_zpos"> + <sensor gap="OTKEndCap_sensor_gap" thickness="OTKEndCap_sensor_thickness" dead_width="OTKEndCap_sensor_dead_width" mat="G4_Si"/> + <pcb thickness="OTKEndCap_pcb_thickness" rlength="OTKEndCap_pcb_rlength" rgap="OTKEndCap_pcb_rgap" mat="epoxy"/> + <asic thickness="OTKEndCap_asic_thickness" width="OTKEndCap_asic_width" rlength="OTKEndCap_asic_rlength" rgap="OTKEndCap_asic_rgap" mat="G4_Si"/> + </layer> + </detector> + </detectors> + + <readouts> + <readout name="OTKEndCapCollection"> + <id>system:5,side:-2,layer:9,module:8,active:8,sensor:8</id> + </readout> + </readouts> +</lccdd> \ No newline at end of file diff --git a/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml b/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml index c7bfa391d977ea3f7d47d7ae76690111f8cf960f..b353a49e6d2c919df1298d1285e9108af1d375a9 100644 --- a/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml +++ b/Detector/DetCRD/compact/TDR_o1_v01/TDR_Dimensions_v01_01.xml @@ -34,7 +34,8 @@ <constant name="DetID_TPC" value=" 4"/> <constant name="DetID_SET" value=" 5"/> <constant name="DetID_ETD" value=" 6"/> - <constant name="DetID_OTKBarrel" value=" 8"/> + <constant name="DetID_OTKBarrel" value=" 8"/> + <constant name="DetID_OTKEndCap" value=" 9"/> <constant name="DetID_ECAL" value=" 20"/> <constant name="DetID_ECAL_PLUG" value=" 21"/> diff --git a/Detector/DetCRD/src/Tracker/SiTracker_otkendcap_v01_geo.cpp b/Detector/DetCRD/src/Tracker/SiTracker_otkendcap_v01_geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c4e61611664f359c2712178bbf2a0e51fe218b3 --- /dev/null +++ b/Detector/DetCRD/src/Tracker/SiTracker_otkendcap_v01_geo.cpp @@ -0,0 +1,516 @@ +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/DetType.h" +#include "DDRec/Surface.h" +#include "DDRec/DetectorData.h" +#include "XML/Utilities.h" +#include <cmath> + +using namespace std; + +using dd4hep::Box; +using dd4hep::DetElement; +using dd4hep::Material; +using dd4hep::Position; +using dd4hep::RotationY; +using dd4hep::RotationZYX; +using dd4hep::Transform3D; +using dd4hep::Rotation3D; +using dd4hep::Volume; +using dd4hep::_toString; +using dd4hep::rec::volSurfaceList; +using dd4hep::rec::ZPlanarData; +using dd4hep::mm; + + +static dd4hep::Ref_t create_element(dd4hep::Detector& theDetector, xml_h e, dd4hep::SensitiveDetector sens) { + + xml_det_t x_det = e; + Material air = theDetector.air(); + int det_id = x_det.id(); + string name = x_det.nameStr(); + DetElement otkendcap(name, det_id); + + Volume envelope = dd4hep::xml::createPlacedEnvelope(theDetector, e, otkendcap); + dd4hep::xml::setDetectorTypeFlag(e, otkendcap) ; + if(theDetector.buildType()==dd4hep::BUILD_ENVELOPE) return otkendcap; + envelope.setVisAttributes(theDetector.visAttributes("SeeThrough")); + + if (x_det.hasAttr(_U(sensitive))) { + xml_dim_t sd_typ = x_det.child(_U(sensitive)); + sens.setType(sd_typ.typeStr()); + } + else { + sens.setType("tracker"); + } + std::cout << " ** building SiTracker_otkendcap ..." << std::endl ; + + dd4hep::rec::ZPlanarData* zPlanarData = new dd4hep::rec::ZPlanarData; + //*****************************************************************// + + // Reading parameters from the .xml file + + //*****************************************************************// + + //fetch the geometry parameters + const double inner_radius = theDetector.constant<double>("OTKEndCapBarrel_inner_radius"); + const double outer_radius = theDetector.constant<double>("OTKEndCap_outer_radius"); + const double total_length = theDetector.constant<double>("OTKEndCap_half_length")*2.; + const int total_sections = theDetector.constant<int>("OTKEndCap_total_sections"); + const double deg = theDetector.constant<double>("OTKEndCap_piece_deg")*dd4hep::degree; + const double piece_number = theDetector.constant<double>("OTKEndCap_piece_num"); + const double deg_interval = 360 / piece_number * dd4hep::degree; + const double r0 = theDetector.constant<double>("OTKEndCap_r0"); + const double r1 = theDetector.constant<double>("OTKEndCap_r1"); + const double r2 = theDetector.constant<double>("OTKEndCap_r2"); + const double r3 = theDetector.constant<double>("OTKEndCap_r3"); + const double r4 = theDetector.constant<double>("OTKEndCap_r4"); + const double r5 = theDetector.constant<double>("OTKEndCap_r5"); + const double r6 = theDetector.constant<double>("OTKEndCap_r6"); + const double r7 = theDetector.constant<double>("OTKEndCap_r7"); + const double r8 = theDetector.constant<double>("OTKEndCap_r8"); + const double r9 = theDetector.constant<double>("OTKEndCap_r9"); + const double r10 = theDetector.constant<double>("OTKEndCap_r10"); + const int asic_num_0 = theDetector.constant<int>("OTKEndCap_asic_num_0"); + const int asic_num_1 = theDetector.constant<int>("OTKEndCap_asic_num_1"); + const int asic_num_2 = theDetector.constant<int>("OTKEndCap_asic_num_2"); + const int asic_num_3 = theDetector.constant<int>("OTKEndCap_asic_num_3"); + const int asic_num_4 = theDetector.constant<int>("OTKEndCap_asic_num_4"); + const int asic_num_5 = theDetector.constant<int>("OTKEndCap_asic_num_5"); + const int asic_num_6 = theDetector.constant<int>("OTKEndCap_asic_num_6"); + const int asic_num_7 = theDetector.constant<int>("OTKEndCap_asic_num_7"); + const int asic_num_8 = theDetector.constant<int>("OTKEndCap_asic_num_8"); + const int asic_num_9 = theDetector.constant<int>("OTKEndCap_asic_num_9"); + const int module_num_0 = theDetector.constant<int>("OTKEndCap_module_num_0"); + const int module_num_1 = theDetector.constant<int>("OTKEndCap_module_num_1"); + const int module_num_2 = theDetector.constant<int>("OTKEndCap_module_num_2"); + const int module_num_3 = theDetector.constant<int>("OTKEndCap_module_num_3"); + const int module_num_4 = theDetector.constant<int>("OTKEndCap_module_num_4"); + const int module_num_5 = theDetector.constant<int>("OTKEndCap_module_num_5"); + const int module_num_6 = theDetector.constant<int>("OTKEndCap_module_num_6"); + const int module_num_7 = theDetector.constant<int>("OTKEndCap_module_num_7"); + const int module_num_8 = theDetector.constant<int>("OTKEndCap_module_num_8"); + const int module_num_9 = theDetector.constant<int>("OTKEndCap_module_num_9"); + + std::cout << "inner_radius: " << inner_radius/mm << "mm" << std::endl; + std::cout << "outer_radius: " << outer_radius/mm << "mm" << std::endl; + std::cout << "total_length: " << total_length/mm << "mm" << std::endl; + std::cout << "total_sections: " << total_sections << std::endl; + std::cout << "deg: " << deg/dd4hep::degree << "deg" << std::endl; + std::cout << "piece_number: " << piece_number << std::endl; + std::cout << "deg interval: " << deg_interval/dd4hep::degree << "deg" << std::endl; + std::cout << "r0: " << r0/mm << "mm" << std::endl; + std::cout << "r1: " << r1/mm << "mm" << std::endl; + std::cout << "r2: " << r2/mm << "mm" << std::endl; + std::cout << "r3: " << r3/mm << "mm" << std::endl; + std::cout << "r4: " << r4/mm << "mm" << std::endl; + std::cout << "r5: " << r5/mm << "mm" << std::endl; + std::cout << "r6: " << r6/mm << "mm" << std::endl; + std::cout << "r7: " << r7/mm << "mm" << std::endl; + std::cout << "r8: " << r8/mm << "mm" << std::endl; + std::cout << "r9: " << r9/mm << "mm" << std::endl; + std::cout << "r10: " << r10/mm << "mm" << std::endl; + std::cout << "asic_num_0: " << asic_num_0 << std::endl; + std::cout << "asic_num_1: " << asic_num_1 << std::endl; + std::cout << "asic_num_2: " << asic_num_2 << std::endl; + std::cout << "asic_num_3: " << asic_num_3 << std::endl; + std::cout << "asic_num_4: " << asic_num_4 << std::endl; + std::cout << "asic_num_5: " << asic_num_5 << std::endl; + std::cout << "asic_num_6: " << asic_num_6 << std::endl; + std::cout << "asic_num_7: " << asic_num_7 << std::endl; + std::cout << "asic_num_8: " << asic_num_8 << std::endl; + std::cout << "asic_num_9: " << asic_num_9 << std::endl; + std::cout << "module_num_0: " << module_num_0 << std::endl; + std::cout << "module_num_1: " << module_num_1 << std::endl; + std::cout << "module_num_2: " << module_num_2 << std::endl; + std::cout << "module_num_3: " << module_num_3 << std::endl; + std::cout << "module_num_4: " << module_num_4 << std::endl; + std::cout << "module_num_5: " << module_num_5 << std::endl; + std::cout << "module_num_6: " << module_num_6 << std::endl; + std::cout << "module_num_7: " << module_num_7 << std::endl; + std::cout << "module_num_8: " << module_num_8 << std::endl; + std::cout << "module_num_9: " << module_num_9 << std::endl; + + double r[11] = {r0, + r1, + r2, + r3, + r4, + r5, + r6, + r7, + r8, + r9, + r10}; + int asic_num[10] = {asic_num_0, + asic_num_1, + asic_num_2, + asic_num_3, + asic_num_4, + asic_num_5, + asic_num_6, + asic_num_7, + asic_num_8, + asic_num_9}; + int module_num[10] = {module_num_0, + module_num_1, + module_num_2, + module_num_3, + module_num_4, + module_num_5, + module_num_6, + module_num_7, + module_num_8, + module_num_9}; + + //fetch the display parameters + xml_comp_t x_display(x_det.child(_Unicode(display))); + std::string supportVis = x_display.attr<string>(_Unicode(support)); + std::string sensEnvVis = x_display.attr<string>(_Unicode(sens_env)); + std::string sensVis = x_display.attr<string>(_Unicode(sens)); + std::string deadsensVis = x_display.attr<string>(_Unicode(deadsensor)); + std::string pcbVis = x_display.attr<string>(_Unicode(pcb)); + std::string asicVis = x_display.attr<string>(_Unicode(asic)); + + //fetch the support parameters + xml_comp_t x_support(x_det.child(_Unicode(support))); + double support_thickness = x_support.attr<double>(_Unicode(thickness)); + double support_inner_radius = x_support.attr<double>(_Unicode(inner_radius)); + double support_outer_radius = x_support.attr<double>(_Unicode(outer_radius)); + Material support_mat = theDetector.material(x_support.attr<string>(_Unicode(mat))); + std::cout << "support_thickness: " << support_thickness/mm << " mm" << std::endl; + std::cout << "support_inner_radius: " << support_inner_radius/mm << " mm" << std::endl; + std::cout << "support_outer_radius: " << support_outer_radius/mm << " mm" << std::endl; + + for(xml_coll_t layer_i(x_det,_U(layer));layer_i;++layer_i){ + //fetch the overall parameters of this layer + xml_comp_t x_layer(layer_i); + dd4hep::PlacedVolume pv; + int layer_id = x_layer.attr<int>(_Unicode(id)); + double layer_thickness = x_layer.attr<double>(_Unicode(thickness)); + double layer_zpos = x_layer.attr<double>(_Unicode(zpos)); + std::cout << "layer_id: " << layer_id << std::endl; + std::cout << "layer_thickness: " << layer_thickness/mm << "mm" << std::endl; + std::cout << "layer_zpos: " << layer_zpos/mm << "mm" << std::endl; + + //fetch the sensor parameters + xml_comp_t x_sensor(x_layer.child(_Unicode(sensor))); + double sensor_dead_gap = x_sensor.attr<double>(_Unicode(gap)); + double sensor_thickness = x_sensor.attr<double>(_Unicode(thickness)); + double sensor_dead_width = x_sensor.attr<double>(_Unicode(dead_width)); + Material sensor_mat = theDetector.material(x_sensor.attr<string>(_Unicode(mat))); + + //fetch parameters for the pcb and asic parts + xml_comp_t x_pcb(x_layer.child(_Unicode(pcb))); + double pcb_thickness = x_pcb.attr<double>(_Unicode(thickness)); + double pcb_rlength = x_pcb.attr<double>(_Unicode(rlength)); + double pcb_rgap = x_pcb.attr<double>(_Unicode(rgap)); + Material pcb_mat = theDetector.material(x_pcb.attr<string>(_Unicode(mat))); + + xml_comp_t x_asic(x_layer.child(_Unicode(asic))); + double asic_thickness = x_asic.attr<double>(_Unicode(thickness)); + double asic_width = x_asic.attr<double>(_Unicode(width)); + double asic_rlength = x_asic.attr<double>(_Unicode(rlength)); + double asic_rgap = x_asic.attr<double>(_Unicode(rgap)); + Material asic_mat = theDetector.material(x_asic.attr<string>(_Unicode(mat))); + + std::cout << "sensor_dead_gap: " << sensor_dead_gap/mm << " mm" << std::endl; + std::cout << "sensor_thickness: " << sensor_thickness/mm << " mm" << std::endl; + std::cout << "sensor_dead_width: " << sensor_dead_width/mm << " mm" << std::endl; + std::cout << "pcb_thickness: " << pcb_thickness/mm << " mm" << std::endl; + std::cout << "pcb_rlength: " << pcb_rlength/mm << " mm" << std::endl; + std::cout << "pcb_rgap: " << pcb_rgap/mm << " mm" << std::endl; + std::cout << "asic_thickness: " << asic_thickness/mm << " mm" << std::endl; + std::cout << "asic_width: " << asic_width/mm << " mm" << std::endl; + std::cout << "asic_rlength: " << asic_rlength/mm << " mm" << std::endl; + std::cout << "asic_rgap: " << asic_rgap/mm << " mm" << std::endl; + + //*****************************************************************// + + // Creating objects + + //*****************************************************************// + + //layer definition + std::string layer_name = dd4hep::_toString(layer_id, "layer_%d"); + dd4hep::Assembly layer_assembly(layer_name); + pv = envelope.placeVolume(layer_assembly); + dd4hep::DetElement layerDE(otkendcap, layer_name, x_det.id()); + layerDE.setPlacement(pv); + + //create piece envelope logical volume + dd4hep::Tube PieceEnvSolid( inner_radius, + outer_radius, + layer_thickness / 2.0, + 0., + deg); + Volume PieceEnvLogical( name + dd4hep::_toString(layer_id, "_PieceEnvLogical_%02d"), + PieceEnvSolid, + air); + + //create and place support logical volume + dd4hep::Tube SupportSolid( support_inner_radius, + support_outer_radius, + support_thickness / 2.0, + 0., + deg); + Volume SupportLogical( name + dd4hep::_toString(layer_id, "_SupportLogical_%02d"), + SupportSolid, + support_mat); + + SupportLogical.setVisAttributes(theDetector.visAttributes(supportVis)); + pv = PieceEnvLogical.placeVolume(SupportLogical, Position(0, 0, (-layer_thickness + support_thickness) / 2.0)); + + //create sensor envelope logical volume + dd4hep::Tube SensorEnvSolid( inner_radius, + outer_radius, + (sensor_thickness + pcb_thickness + asic_thickness) / 2.0, + 0., + deg); + Volume SensorEnvLogical( name + dd4hep::_toString(layer_id, "SensorEnvLogical_%02d"), + SensorEnvSolid, + air); + SensorEnvLogical.setVisAttributes(theDetector.visAttributes(sensEnvVis)); + + //create and place utilities in each ring + std::vector<dd4hep::PlacedVolume> sensor_pv; + std::vector<dd4hep::rec::VolPlane> sensor_surf; + dd4hep::rec::Vector3D o(0., 0., 0.); + dd4hep::rec::Vector3D u(0., 1., 0.); + dd4hep::rec::Vector3D v(1., 0., 0.); + dd4hep::rec::Vector3D n(0., 0., 1.); + double inner_thick = sensor_thickness/2.0; + double outer_thick = (support_thickness + sensor_thickness)/2.0; + double ring_inner_radius; + double ring_outer_radius = r[0] - sensor_dead_gap; + int ring_asic_number; + int ring_module_number; + double ring_dead_angle; + double ring_active_angle; + double ring_active_module_angle; + double ring_asic_angle; + double ring_asic_interval; + double asic_mid_angle; + for(int i=0;i<10;i++){ + ring_inner_radius = ring_outer_radius + sensor_dead_gap * 2; + ring_outer_radius = r[i+1] - sensor_dead_gap; + ring_asic_number = asic_num[i]; + ring_module_number = module_num[i]; + ring_dead_angle = sensor_dead_width / ring_inner_radius * 360 * dd4hep::degree; + ring_active_angle = deg - ring_dead_angle * 2 * ring_module_number; + ring_active_module_angle = ring_active_angle / ring_module_number; + ring_asic_angle = asic_width / ring_outer_radius; + ring_asic_interval = deg / ring_asic_number; + //create and place sensor logical volume + dd4hep::Tube SensorSolid( ring_inner_radius, + ring_outer_radius, + sensor_thickness/2.0, + ring_dead_angle, + ring_dead_angle + ring_active_module_angle); + Volume SensorLogical( name + dd4hep::_toString(layer_id, "_SensorLogical_%02d_") + std::to_string(i), + SensorSolid, + sensor_mat); + dd4hep::Tube DeadSensorSolidA( ring_inner_radius, + ring_outer_radius, + sensor_thickness/2.0, + 0., + ring_dead_angle); + Volume DeadSensorLogicalA( name + dd4hep::_toString(layer_id, "_DeadSensorLogicalA_%02d_") + std::to_string(i), + DeadSensorSolidA, + sensor_mat); + dd4hep::Tube DeadSensorSolidB( ring_inner_radius, + ring_outer_radius, + sensor_thickness/2.0, + ring_dead_angle + ring_active_module_angle, + ring_dead_angle*2 + ring_active_module_angle); + Volume DeadSensorLogicalB( name + dd4hep::_toString(layer_id, "_DeadSensorLogicalB_%02d_") + std::to_string(i), + DeadSensorSolidB, + sensor_mat); + + SensorLogical.setSensitiveDetector(sens); + SensorLogical.setVisAttributes(theDetector.visAttributes(sensVis)); + if (x_det.hasAttr(_U(limits))) SensorLogical.setLimitSet(theDetector, x_det.limitsStr()); + dd4hep::rec::VolPlane surfsens( SensorLogical, + dd4hep::rec::SurfaceType(dd4hep::rec::SurfaceType::Sensitive), + inner_thick, + outer_thick, + u,v,n,o); + sensor_surf.push_back(surfsens); + DeadSensorLogicalA.setVisAttributes(theDetector.visAttributes(deadsensVis)); + DeadSensorLogicalB.setVisAttributes(theDetector.visAttributes(deadsensVis)); + pv = SensorEnvLogical.placeVolume(SensorLogical, Position(0, 0, -(pcb_thickness + asic_thickness) / 2.0)); + pv.addPhysVolID("layer", layer_id).addPhysVolID("active", 0).addPhysVolID("sensor", i); + sensor_pv.push_back(pv); + pv = SensorEnvLogical.placeVolume(DeadSensorLogicalA, Position(0, 0, -(pcb_thickness + asic_thickness) / 2.0)); + pv = SensorEnvLogical.placeVolume(DeadSensorLogicalB, Position(0, 0, -(pcb_thickness + asic_thickness) / 2.0)); + + if(ring_module_number==2){ + dd4hep::Tube SensorSolid( ring_inner_radius, + ring_outer_radius, + sensor_thickness/2.0, + ring_dead_angle*3 + ring_active_module_angle, + ring_dead_angle*3 + ring_active_module_angle*2); + Volume SensorLogical( name + dd4hep::_toString(layer_id, "_SensorLogical_%02d_2_") + std::to_string(i), + SensorSolid, + sensor_mat); + dd4hep::Tube DeadSensorSolidA(ring_inner_radius, + ring_outer_radius, + sensor_thickness/2.0, + ring_dead_angle*2 + ring_active_module_angle, + ring_dead_angle*3 + ring_active_module_angle); + Volume DeadSensorLogicalA( name + dd4hep::_toString(layer_id, "_DeadSensorLogicalA_%02d_2_") + std::to_string(i), + DeadSensorSolidA, + sensor_mat); + dd4hep::Tube DeadSensorSolidB(ring_inner_radius, + ring_outer_radius, + sensor_thickness/2.0, + ring_dead_angle*3 + ring_active_module_angle*2, + ring_dead_angle*4 + ring_active_module_angle*2); + Volume DeadSensorLogicalB( name + dd4hep::_toString(layer_id, "_DeadSensorLogicalB_%02d_2_") + std::to_string(i), + DeadSensorSolidB, + sensor_mat); + + SensorLogical.setSensitiveDetector(sens); + SensorLogical.setVisAttributes(theDetector.visAttributes(sensVis)); + if (x_det.hasAttr(_U(limits))) SensorLogical.setLimitSet(theDetector, x_det.limitsStr()); + dd4hep::rec::VolPlane surfsens( SensorLogical , + dd4hep::rec::SurfaceType(dd4hep::rec::SurfaceType::Sensitive), + inner_thick, + outer_thick, + u,v,n,o); + sensor_surf.push_back(surfsens); + DeadSensorLogicalA.setVisAttributes(theDetector.visAttributes(sensVis)); + DeadSensorLogicalB.setVisAttributes(theDetector.visAttributes(sensVis)); + pv = SensorEnvLogical.placeVolume(SensorLogical, Position(0, 0, -(pcb_thickness + asic_thickness) / 2.0)); + pv.addPhysVolID("layer", layer_id).addPhysVolID("active", 0).addPhysVolID("sensor", i + 10); + sensor_pv.push_back(pv); + pv = SensorEnvLogical.placeVolume(DeadSensorLogicalA, Position(0, 0, -(pcb_thickness + asic_thickness) / 2.0)); + pv = SensorEnvLogical.placeVolume(DeadSensorLogicalB, Position(0, 0, -(pcb_thickness + asic_thickness) / 2.0)); + } + + //create and place pcb logical volume + dd4hep::Tube PcbSolidA( ring_inner_radius + pcb_rgap, + ring_inner_radius + pcb_rgap + pcb_rlength, + pcb_thickness / 2.0, + 0., + deg); + Volume PcbLogicalA( name + dd4hep::_toString(layer_id, "_PcbLogicalA_%02d_") + std::to_string(i), + PcbSolidA, + pcb_mat); + dd4hep::Tube PcbSolidB( ring_outer_radius - pcb_rgap - pcb_rlength, + ring_outer_radius - pcb_rgap, + pcb_thickness / 2.0, + 0., + deg); + Volume PcbLogicalB( name + dd4hep::_toString(layer_id, "_PcbLogicalB_%02d_") + std::to_string(i), + PcbSolidB, + pcb_mat); + + PcbLogicalA.setVisAttributes(theDetector.visAttributes(pcbVis)); + PcbLogicalB.setVisAttributes(theDetector.visAttributes(pcbVis)); + pv = SensorEnvLogical.placeVolume(PcbLogicalA, Position(0, 0, (sensor_thickness - asic_thickness) / 2.0)); + pv = SensorEnvLogical.placeVolume(PcbLogicalB, Position(0, 0, (sensor_thickness - asic_thickness) / 2.0)); + + //create and place asic logical volume + for(int j=0;j<ring_asic_number;j++){ + asic_mid_angle = ring_asic_interval * (j + 0.5); + dd4hep::Tube AsicSolidA( ring_inner_radius + asic_rgap, + ring_inner_radius + asic_rgap + asic_rlength, + asic_thickness / 2.0, + asic_mid_angle - ring_asic_angle / 2.0, + asic_mid_angle + ring_asic_angle / 2.0); + Volume AsicLogicalA( name + dd4hep::_toString(layer_id, "_AsicLogicalA_%02d_") + std::to_string(i) + std::to_string(j), + AsicSolidA, + asic_mat); + dd4hep::Tube AsicSolidB( ring_outer_radius - asic_rgap - asic_rlength, + ring_outer_radius - asic_rgap, + asic_thickness / 2.0, + asic_mid_angle - ring_asic_angle / 2.0, + asic_mid_angle + ring_asic_angle / 2.0); + Volume AsicLogicalB( name + dd4hep::_toString(layer_id, "_AsicLogicalB_%02d_") + std::to_string(i) + std::to_string(j), + AsicSolidB, + asic_mat); + + AsicLogicalA.setVisAttributes(theDetector.visAttributes(asicVis)); + AsicLogicalB.setVisAttributes(theDetector.visAttributes(asicVis)); + pv = SensorEnvLogical.placeVolume(AsicLogicalA, Position(0, 0, (sensor_thickness + pcb_thickness) / 2.0)); + pv = SensorEnvLogical.placeVolume(AsicLogicalB, Position(0, 0, (sensor_thickness + pcb_thickness) / 2.0)); + } + + } + double zpos = (-layer_thickness + support_thickness*2 + sensor_thickness + pcb_thickness + asic_thickness) / 2.0; + pv = PieceEnvLogical.placeVolume(SensorEnvLogical, Position(0, 0, zpos)); + + //*****************************************************************// + + // Assembling + + //*****************************************************************// + + for(int i=0;i<piece_number; i++){ + float rot = layer_id*0.5; + std::stringstream piece_enum; + piece_enum << "otkendcap_piece_" << layer_id << "_" << i; + DetElement pieceDE(layerDE, piece_enum.str(), x_det.id()); + + //create the meassurement surface + // int sensor_num = std::accumulate(module_num_v.begin(), module_num_v.end(), 0); + int sensor_num = 15; + for(int isensor=0;isensor<sensor_num;++isensor){ + std::stringstream sensor_str; + sensor_str << piece_enum.str() << "_" << isensor; + DetElement sensorDE(pieceDE, sensor_str.str(), x_det.id()); + sensorDE.setPlacement(sensor_pv[isensor]); + volSurfaceList(sensorDE)->push_back(sensor_surf[isensor]); + } + Transform3D trA ( RotationZYX(deg_interval*(i+rot), + 180*dd4hep::degree, + 0.), + Position(0., + 0., + layer_zpos)); + Transform3D trB ( RotationZYX(deg_interval*(i+rot), + 0., + 0.), + Position(0., + 0., + -layer_zpos)); + pv = layer_assembly.placeVolume(PieceEnvLogical,trA); + pv.addPhysVolID("module", i*2); + pieceDE.setPlacement(pv); + pv = layer_assembly.placeVolume(PieceEnvLogical,trB); + pv.addPhysVolID("module", i*2+1); + pieceDE.setPlacement(pv); + std::cout << piece_enum.str() << " done." << std::endl; + } + + // package the reconstruction data + dd4hep::rec::ZPlanarData::LayerLayout otkendcapLayer; + + otkendcapLayer.ladderNumber = piece_number; + otkendcapLayer.phi0 = 0.; + otkendcapLayer.sensorsPerLadder = 15; + otkendcapLayer.lengthSensor = r1-r0-sensor_dead_gap*2; + otkendcapLayer.distanceSupport = support_thickness/2.0; + otkendcapLayer.thicknessSupport = support_thickness/2.0; + otkendcapLayer.offsetSupport = 0.; + otkendcapLayer.widthSupport = support_inner_radius; + otkendcapLayer.zHalfSupport = support_outer_radius; + otkendcapLayer.distanceSensitive = support_thickness; + otkendcapLayer.thicknessSensitive = sensor_thickness; + otkendcapLayer.offsetSensitive = 0.; + otkendcapLayer.widthSensitive = 0.; + otkendcapLayer.zHalfSensitive = 0.; + + zPlanarData->layers.push_back(otkendcapLayer); + } + std::cout << (*zPlanarData) << endl; + otkendcap.addExtension< ZPlanarData >(zPlanarData); + if ( x_det.hasAttr(_U(combineHits)) ) { + otkendcap.setCombineHits(x_det.attr<bool>(_U(combineHits)),sens); + } + std::cout << "otkendcap done." << std::endl; + return otkendcap; +} +DECLARE_DETELEMENT(SiTracker_otkendcap_v01,create_element) + diff --git a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp index 25968ec70baf76650f9fa9d57ebd0e83c703dc9b..ade2b4a5597d1e6815f20e9701c9642c1f9b0b1b 100644 --- a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp +++ b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp @@ -114,6 +114,7 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) { auto tpccols = m_TPCCol.createAndPut(); auto setcols = m_SETCol.createAndPut(); auto otkbarrelcols = m_OTKBarrelCol.createAndPut(); + auto otkendcapcols = m_OTKEndCapCol.createAndPut(); auto ecalbarrelcol = m_EcalBarrelCol.createAndPut(); auto ecalbarrelcontribcols = m_EcalBarrelContributionCol.createAndPut(); @@ -191,6 +192,8 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) { tracker_col_ptr = setcols; } else if (collect->GetName() == "OTKBarrelCollection") { tracker_col_ptr = otkbarrelcols; + } else if (collect->GetName() == "OTKEndCapCollection") { + tracker_col_ptr = otkendcapcols; } else if (collect->GetName() == "CaloHitsCollection") { calo_col_ptr = calorimetercols; calo_contrib_col_ptr = calocontribcols; diff --git a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h index ea6922d3ded4c73ec161e0555f7540c03340aaa5..cfc0839470e4e89b135a96111458bf51fb1d9634 100644 --- a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h +++ b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h @@ -74,6 +74,8 @@ private: Gaudi::DataHandle::Writer, this}; DataHandle<edm4hep::SimTrackerHitCollection> m_OTKBarrelCol{"OTKBarrelCollection", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::SimTrackerHitCollection> m_OTKEndCapCol{"OTKEndCapCollection", + Gaudi::DataHandle::Writer, this}; // Ecal DataHandle<edm4hep::SimCalorimeterHitCollection> m_EcalBarrelCol{"EcalBarrelCollection", diff --git a/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp b/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp index bffa2119cd5bef1d2879316fbed6026553ef24f6..e63e6802444c868a194b05c554c28a27a5174421 100644 --- a/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp +++ b/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp @@ -45,6 +45,7 @@ ExampleAnaElemTool::EndOfEventAction(const G4Event* anEvent) { auto tpccols = m_TPCCol.createAndPut(); auto setcols = m_SETCol.createAndPut(); auto otkbarrelcols = m_OTKBarrelCol.createAndPut(); + auto otkendcapcols = m_OTKEndCapCol.createAndPut(); // readout defined in DD4hep auto lcdd = &(dd4hep::Detector::getInstance()); @@ -95,6 +96,8 @@ ExampleAnaElemTool::EndOfEventAction(const G4Event* anEvent) { tracker_col_ptr = setcols; } else if (collect->GetName() == "OTKBarrelCollection") { tracker_col_ptr = otkbarrelcols; + } else if (collect->GetName() == "OTKEndCapCollection") { + tracker_col_ptr = otkendcapcols; } else if (collect->GetName() == "CaloHitsCollection") { calo_col_ptr = calorimetercols; } else { diff --git a/Simulation/DetSimAna/src/ExampleAnaElemTool.h b/Simulation/DetSimAna/src/ExampleAnaElemTool.h index cda8ff16c02b8289b939feca86664891552b9e86..fba1f1e51d767683e0fff2aa5a4c8fec62a62af1 100644 --- a/Simulation/DetSimAna/src/ExampleAnaElemTool.h +++ b/Simulation/DetSimAna/src/ExampleAnaElemTool.h @@ -63,6 +63,8 @@ private: Gaudi::DataHandle::Writer, this}; DataHandle<plcio::SimTrackerHitCollection> m_OTKBarrelCol{"OTKBarrelCollection", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::SimTrackerHitCollection> m_OTKEndCapCol{"OTKEndCapCollection", + Gaudi::DataHandle::Writer, this}; };