Back to home page

EIC code displayed by LXR

 
 

    


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

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 
0019   //XML detector object: DDCore/XML/XMLDetector.h
0020   dd4hep::xml::DetElement x_det = e;
0021   
0022   //Create the DetElement for dd4hep
0023   DetElement d_det(x_det.nameStr(),x_det.id());
0024   
0025   //Pick the mothervolume
0026   Volume det_vol = description.pickMotherVolume(d_det);
0027 
0028   //XML dimension object: DDCore/XML/XMLDimension.h
0029   dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
0030   
0031   //Tube: DDCore/DD4hep/Shapes.h
0032   Tube calo_shape(x_det_dim.rmin(),x_det_dim.rmax(),x_det_dim.z(),2*M_PI/x_det_dim.phiBins());
0033   
0034   //Create the detector mother volume
0035   Volume calo_vol(x_det.nameStr()+"_envelope",calo_shape,description.air());
0036 
0037   //Set envelope volume attributes
0038   calo_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0039 
0040   //Place inside the mother volume
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   //Declare this sensitive detector as a calorimeter
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 = true;
0057 
0058   //Repeat layers until we reach the rmax
0059   while(r<x_det_dim.rmax()){
0060 
0061     //Loop over layers of type: XML Collection_t object: DDCore/XML/XMLElements.h
0062     for(dd4hep::xml::Collection_t layerIt(x_det,_U(layer));layerIt; ++layerIt){
0063       
0064       //Build a layer volume
0065       dd4hep::xml::Component x_det_layer = layerIt;
0066       
0067       float dr = x_det_layer.dr();
0068       
0069       string layer_name =  x_det.nameStr()+_toString(layer_num,"_layer%d");
0070       
0071       float    x1  = r * tan(tile_phi/2.);
0072       float    x2  = (r+dr) * tan(tile_phi/2.);
0073       float    y1  = x_det_dim.z();
0074       float    y2  = x_det_dim.z();
0075       float    z   = x_det_layer.dr();
0076       
0077       if(debug){
0078     cout << " r:" << r 
0079          << " dr:" << dr 
0080          << " x1:" << x1 
0081          << " x2:" << x2
0082          << " y1:" << y1 
0083          << " y2:" << y2 
0084          << " z:" << z 
0085          << endl;
0086       }
0087       
0088       //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
0089       Trapezoid layer_shape(x1,x2,y1,y2,z);
0090       
0091       //Create a volume with trapezoid shape
0092       Volume layer_vol(layer_name, layer_shape, description.air());
0093       layer_vol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det_layer.visStr());
0094       
0095       //DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id());
0096       
0097       //Fill the volume with tiles
0098       
0099       
0100       int tile_number = 0;  
0101       vector<Volume> tiles;
0102       
0103       //Repeat slices until we reach the end of the calorimeter
0104       for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k)  {
0105     
0106     dd4hep::xml::Component tile_xml       = k;
0107     string                 tile_name      = layer_name + _toString(tile_number,"_slice%d");
0108     Material               tile_material  = description.material(tile_xml.materialStr());
0109     float                  tile_thickness = tile_xml.dz();
0110     float                  tile_y1        = tile_thickness;
0111     float                  tile_y2        = tile_thickness;
0112     float                  tile_z         = x_det_layer.dr();
0113     
0114     //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
0115     Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z);
0116     
0117     //Create a volume with trapezoid shape
0118     Volume tile_vol(tile_name,tile_shape,tile_material);
0119     
0120     if ( tile_xml.isSensitive() ) {
0121       tile_vol.setSensitiveDetector(sens);
0122     }
0123     
0124     //Set region, limitset, and visibility settings
0125     tile_vol.setAttributes(description,tile_xml.regionStr(),tile_xml.limitsStr(),tile_xml.visStr());
0126     
0127     tiles.push_back(tile_vol);
0128     tile_number++;
0129       }
0130 
0131       //Place the same volumes inside the envelope
0132       float tile_pos_z = -x_det_dim.z()/2.;
0133       while(tile_pos_z<x_det_dim.z()/2.){
0134     tile_number=0;
0135     for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k)  {
0136       
0137       dd4hep::xml::Component tile_xml       = k;
0138       float                  tile_thickness = tile_xml.dz();
0139       
0140       //Place the tile inside the layer
0141       // PlacedVolume tile_plv = 
0142         layer_vol.placeVolume(tiles.at(tile_number),Position(0,tile_pos_z,0));
0143       
0144       //Increment the z pos of the tile
0145       tile_pos_z += tile_thickness;
0146       tile_number++;
0147       
0148     }
0149       }
0150       
0151       //Place the same layer around the beam axis phiBins times
0152       double mod_x_off = r;  
0153       double mod_y_off = 0;  
0154       for(int i=0;i<x_det_dim.phiBins();i++){
0155     if(debug) cout << "Layer:" << i << " phi:" << tile_phi << " rotz:" << (tile_phi*i) << endl;
0156     double layer_pos_x = mod_x_off * cos(tile_phi*i) - mod_y_off * sin(tile_phi*i);
0157     double layer_pos_y = mod_x_off * sin(tile_phi*i) + mod_y_off * cos(tile_phi*i);
0158     Transform3D tr(RotationZYX(M_PI*0.5,M_PI*0.5,0)*RotationZYX(0,tile_phi*i,0),
0159                Translation3D(layer_pos_x,layer_pos_y,layer_pos_z));
0160     PlacedVolume pv = calo_vol.placeVolume(layer_vol,tr);
0161     pv.addPhysVolID("system",x_det.id());
0162     pv.addPhysVolID("barrel",0);
0163     pv.addPhysVolID("layer",i+1);
0164     //DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d"));
0165       }
0166       
0167       r += dr;
0168     }
0169   }
0170   
0171   //Place the calo inside the world
0172   
0173   return d_det;
0174 }
0175 
0176 DECLARE_DETELEMENT(ORG_HcalBarrel,create_detector)
0177