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
0020 dd4hep::xml::DetElement x_det = e;
0021
0022
0023 DetElement d_det(x_det.nameStr(),x_det.id());
0024
0025
0026 Volume det_vol = description.pickMotherVolume(d_det);
0027
0028
0029 dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
0030
0031
0032 Tube calo_shape(x_det_dim.rmin(),x_det_dim.rmax(),x_det_dim.z());
0033
0034
0035 Volume calo_vol(x_det.nameStr()+"_envelope",calo_shape,description.air());
0036
0037
0038 calo_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0039
0040
0041 PlacedVolume calo_plv = det_vol.placeVolume(calo_vol);
0042
0043 calo_plv.addPhysVolID("system",x_det.id());
0044 calo_plv.addPhysVolID("barrel",0);
0045 d_det.setPlacement(calo_plv);
0046
0047
0048 sens.setType("calorimeter");
0049
0050
0051 int layer_num = 0;
0052 float layer_pos_z = 0;
0053 double tile_phi = 2*M_PI/x_det_dim.phiBins();
0054 float r = x_det_dim.rmin();
0055
0056 bool debug = false;
0057
0058 std::map<std::string,int> vol_max;
0059
0060
0061 while(r<x_det_dim.rmax()){
0062
0063
0064 for(dd4hep::xml::Collection_t layerIt(x_det,_U(layer));layerIt; ++layerIt){
0065
0066
0067 dd4hep::xml::Component x_det_layer = layerIt;
0068
0069 float dr = x_det_layer.dr();
0070
0071 string layer_name = x_det.nameStr()+_toString(layer_num,"_layer%d");
0072
0073 float x1 = r * tan(tile_phi/2.);
0074 float x2 = (r+dr) * tan(tile_phi/2.);
0075 float y1 = x_det_dim.z();
0076 float y2 = x_det_dim.z();
0077 float z = x_det_layer.dr();
0078
0079 if(debug){
0080 cout << " r:" << r
0081 << " dr:" << dr
0082 << " x1:" << x1
0083 << " x2:" << x2
0084 << " y1:" << y1
0085 << " y2:" << y2
0086 << " z:" << z
0087 << endl;
0088 }
0089
0090
0091 Trapezoid layer_shape(x1,x2,y1,y2,z);
0092
0093
0094 Volume layer_vol(layer_name, layer_shape, description.air());
0095 layer_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det_layer.visStr());
0096
0097
0098
0099
0100
0101
0102 int tile_number = 0;
0103 vector<Volume> tiles;
0104
0105
0106 for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k) {
0107
0108 dd4hep::xml::Component 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
0117 Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z);
0118
0119
0120 Volume tile_vol(tile_name,tile_shape,tile_material);
0121
0122 if ( tile_xml.isSensitive() ) {
0123 tile_vol.setSensitiveDetector(sens);
0124 }
0125
0126
0127 tile_vol.setAttributes(description,tile_xml.regionStr(),tile_xml.limitsStr(),tile_xml.visStr());
0128
0129 tiles.push_back(tile_vol);
0130 tile_number++;
0131 }
0132
0133
0134 float tile_pos_z = -x_det_dim.z()/2.;
0135 int slice_num = 0;
0136 while(tile_pos_z<x_det_dim.z()/2.){
0137 tile_number=0;
0138 for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k) {
0139
0140 dd4hep::xml::Component tile_xml = k;
0141 float tile_thickness = tile_xml.dz();
0142
0143
0144 PlacedVolume tile_plv = layer_vol.placeVolume(tiles.at(tile_number),Position(0,tile_pos_z,0));
0145 tile_plv.addPhysVolID("layer",layer_num);
0146 tile_plv.addPhysVolID("slice",slice_num);
0147
0148 vol_max["layer"] = std::max(vol_max["layer"],layer_num);
0149 vol_max["slice"] = std::max(vol_max["slice"],slice_num);
0150
0151
0152 tile_pos_z += tile_thickness;
0153 tile_number++;
0154 slice_num++;
0155 }
0156 }
0157
0158
0159 double mod_x_off = r;
0160 double mod_y_off = 0;
0161 for(int i=0;i<x_det_dim.phiBins();i++){
0162 if(debug) cout << "Layer:" << i << " phi:" << tile_phi << " rotz:" << (tile_phi*i) << endl;
0163 double layer_pos_x = mod_x_off * cos(tile_phi*i) - mod_y_off * sin(tile_phi*i);
0164 double layer_pos_y = mod_x_off * sin(tile_phi*i) + mod_y_off * cos(tile_phi*i);
0165 Transform3D tr(RotationZYX(M_PI*0.5,M_PI*0.5,0)*RotationZYX(0,tile_phi*i,0),
0166 Translation3D(layer_pos_x,layer_pos_y,layer_pos_z));
0167 PlacedVolume pv = calo_vol.placeVolume(layer_vol,tr);
0168 pv.addPhysVolID("module",i+1);
0169 vol_max["module"] = std::max(vol_max["module"],i+1);
0170
0171 }
0172
0173 r += dr;
0174 layer_num += 1;
0175 }
0176 }
0177 for(map<string,int>::const_iterator i=vol_max.begin(); i!=vol_max.end();++i)
0178 cout << "Volume ID:" << (*i).first << " max:" << (*i).second << endl;
0179
0180
0181 return d_det;
0182 }
0183
0184 DECLARE_DETELEMENT(FCC_HcalBarrel2,create_detector)