Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:40

0001 /*********************************
0002  * HcalBarrel_geo
0003  * Implementing a detector
0004  *
0005  * Carlos.Solans@cern.ch
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   //XML detector object: DDCore/XML/XMLDetector.h
0019   xml_dim_t x_det = e;  
0020   //Create the DetElement for dd4hep
0021   DetElement d_det(x_det.nameStr(),x_det.id());
0022 
0023   //XML dimension object: DDCore/XML/XMLDimension.h
0024   xml_dim_t x_det_dim(x_det.dimensions());
0025   //double inner_r = x_det_dim.rmin();
0026   //double outer_r = x_det_dim.rmax();
0027   Assembly calo_vol(x_det.nameStr()+"_envelope");
0028   PlacedVolume pv;
0029 
0030   //Set envelope volume attributes
0031   calo_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0032 
0033 #if 0
0034 
0035   //Declare this sensitive detector as a calorimeter
0036   Tube tub(inner_r,outer_r,x_det_dim.z()/2.0,0.0,2*M_PI);
0037   //Volume tub_vol(x_det.nameStr()+"_tube",tub,description.material("PyrexGlass"));
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   //Repeat layers until we reach the rmax
0058   while(r<x_det_dim.rmax()){
0059 
0060     //Loop over layers of type: XML Collection_t object: DDCore/XML/XMLElements.h
0061     for(dd4hep::xml::Collection_t layerIt(x_det,_U(layer));layerIt; ++layerIt, ++layer_num)   {
0062       
0063       //Build a layer volume
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       //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
0088       Trapezoid layer_shape(x1,x2,y1,y2,z);
0089       
0090       //Create a volume with trapezoid shape
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       //DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id());
0095       
0096       //Fill the volume with tiles
0097       vector<Volume> tiles;
0098 
0099       //Assembly tile_seq(layer_name+"_seq");
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       //Repeat slices until we reach the end of the calorimeter
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         // Set region, limitset, and visibility settings
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       // Place the same volumes inside the envelope
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       // Place the same layer around the beam axis phiBins times
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   //double mod_x_off = outer_r - (outer_r-inner_r)/2.0;
0151   //double mod_y_off = 0;
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     //double pos_x = mod_x_off * cos(phi) - mod_y_off * sin(phi);
0157     //double pos_y = mod_x_off * sin(phi) + mod_y_off * cos(phi);
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   //Place the calo inside the world
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