File indexing completed on 2025-01-18 09:14:40
0001
0002
0003
0004
0005
0006
0007
0008 #include "DD4hep/DetFactoryHelper.h"
0009 #include "XML/Layering.h"
0010
0011 #include <vector>
0012
0013 using namespace std;
0014 using namespace dd4hep;
0015 using namespace dd4hep::detail;
0016
0017 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0018
0019 xml_dim_t x_det = e;
0020
0021 DetElement d_det(x_det.nameStr(),x_det.id());
0022
0023
0024 xml_dim_t x_det_dim(x_det.dimensions());
0025
0026
0027 Assembly calo_vol(x_det.nameStr()+"_envelope");
0028 PlacedVolume pv;
0029
0030
0031 calo_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0032
0033 #if 0
0034
0035
0036 Tube tub(inner_r,outer_r,x_det_dim.z()/2.0,0.0,2*M_PI);
0037
0038 Volume tub_vol(x_det.nameStr()+"_tube",tub,description.material("Iron"));
0039 calo_vol.placeVolume(tub_vol);
0040 sens.setType("calorimeter");
0041 tub_vol.setSensitiveDetector(sens);
0042 d_det.setAttributes(description,tub_vol,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0043 #endif
0044
0045 #if 1
0046
0047 int layer_num = 0;
0048 float layer_pos_z = 0;
0049 double tile_phi = 2*M_PI/x_det_dim.phiBins();
0050 float r = x_det_dim.rmin();
0051
0052 bool debug = true;
0053
0054 Assembly stave_vol(x_det.nameStr()+"_stave_0");
0055
0056
0057
0058 while(r<x_det_dim.rmax()){
0059
0060
0061 for(dd4hep::xml::Collection_t layerIt(x_det,_U(layer));layerIt; ++layerIt, ++layer_num) {
0062
0063
0064 xml_comp_t x_det_layer = layerIt;
0065
0066 float dr = x_det_layer.dr();
0067
0068 string layer_name = x_det.nameStr()+_toString(layer_num,"_layer%d");
0069
0070 float x1 = r * tan(tile_phi/2.);
0071 float x2 = (r+dr) * tan(tile_phi/2.);
0072 float y1 = x_det_dim.z();
0073 float y2 = x_det_dim.z();
0074 float z = x_det_layer.dr();
0075
0076 if(debug){
0077 cout << " r:" << r
0078 << " dr:" << dr
0079 << " x1:" << x1
0080 << " x2:" << x2
0081 << " y1:" << y1
0082 << " y2:" << y2
0083 << " z:" << z
0084 << endl;
0085 }
0086
0087
0088 Trapezoid layer_shape(x1,x2,y1,y2,z);
0089
0090
0091 Volume layer_vol(layer_name, layer_shape, description.air());
0092 layer_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det_layer.visStr());
0093
0094
0095
0096
0097 vector<Volume> tiles;
0098
0099
0100 Trapezoid tile_seq_shape(x1,x2,x_det_layer.dz(),x_det_layer.dz(),x_det_layer.dr());
0101 Volume tile_seq(layer_name + "_seq",tile_seq_shape,description.air());
0102 double total_thickness = 0;
0103
0104 int slice_num = 0, tile_number = 0;
0105
0106 tile_seq.setVisAttributes(description.visAttributes("VisibleGreen"));
0107 for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k, ++slice_num) {
0108 xml_comp_t tile_xml = k;
0109 string tile_name = layer_name + _toString(tile_number,"_slice%d");
0110 Material tile_material = description.material(tile_xml.materialStr());
0111 float tile_thickness = tile_xml.dz();
0112 float tile_y1 = tile_thickness;
0113 float tile_y2 = tile_thickness;
0114 float tile_z = x_det_layer.dr();
0115
0116 Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z);
0117 Volume tile_vol(tile_name,tile_shape,tile_material);
0118 pv = tile_seq.placeVolume(tile_vol,Position(0,total_thickness,0));
0119 pv.addPhysVolID("slice",slice_num);
0120 total_thickness += tile_thickness;
0121 if ( tile_xml.isSensitive() ) {
0122 cout << "Set volume " << tile_name << " sensitive...." << endl;
0123 tile_vol.setSensitiveDetector(sens);
0124 }
0125
0126
0127 tile_vol.setAttributes(description,tile_xml.regionStr(),tile_xml.limitsStr(),tile_xml.visStr());
0128 tiles.push_back(tile_vol);
0129 tile_number++;
0130 }
0131
0132
0133 float tile_pos_z = -x_det_dim.z()/2.;
0134 int tile_num = 0;
0135 while(tile_pos_z<x_det_dim.z()/2.){
0136 pv = layer_vol.placeVolume(tile_seq,Position(0,tile_pos_z,0));
0137 pv.addPhysVolID("tile",tile_num);
0138 tile_pos_z += total_thickness;
0139 tile_num++;
0140 }
0141
0142
0143 Transform3D tr(RotationZYX(M_PI*0.5,M_PI*0.5,0),Translation3D(r,0,layer_pos_z));
0144 pv = stave_vol.placeVolume(layer_vol,tr);
0145 pv.addPhysVolID("layer",layer_num);
0146 r += dr;
0147 cout << "+++ R=" << r << endl;
0148 }
0149 }
0150
0151
0152 int nphi_bins = x_det_dim.phiBins();
0153 for(int i=0;i<nphi_bins;i++){
0154 if(debug) cout << "Layer:" << i << " phi:" << tile_phi << " rotz:" << (tile_phi*i) << endl;
0155 double phi = tile_phi*i;
0156
0157
0158 Transform3D tr(RotationZYX(phi,0,0),Translation3D(0,0,0));
0159 pv = calo_vol.placeVolume(stave_vol,tr);
0160 pv.addPhysVolID("stave",i+1);
0161 }
0162
0163 cout << "Number of layers: " << layer_num << endl;
0164 #endif
0165
0166 PlacedVolume calo_plv = description.pickMotherVolume(d_det).placeVolume(calo_vol);
0167 calo_plv.addPhysVolID("system",x_det.id());
0168 calo_plv.addPhysVolID("barrel",0);
0169 d_det.setPlacement(calo_plv);
0170
0171 return d_det;
0172 }
0173
0174 DECLARE_DETELEMENT(FCC_HcalBarrel,create_detector)
0175