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 
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());
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 = false;
0057 
0058   std::map<std::string,int> vol_max;
0059 
0060   //Repeat layers until we reach the rmax
0061   while(r<x_det_dim.rmax()){
0062 
0063     //Loop over layers of type: XML Collection_t object: DDCore/XML/XMLElements.h
0064     for(dd4hep::xml::Collection_t layerIt(x_det,_U(layer));layerIt; ++layerIt){
0065       
0066       //Build a layer volume
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       //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
0091       Trapezoid layer_shape(x1,x2,y1,y2,z);
0092       
0093       //Create a volume with trapezoid shape
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       //DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id());
0098       
0099       //Fill the volume with tiles
0100       
0101       
0102       int tile_number = 0;  
0103       vector<Volume> tiles;
0104       
0105       //Repeat slices until we reach the end of the calorimeter
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     //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h
0117     Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z);
0118     
0119     //Create a volume with trapezoid shape
0120     Volume tile_vol(tile_name,tile_shape,tile_material);
0121     
0122     if ( tile_xml.isSensitive() ) {
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     
0129     tiles.push_back(tile_vol);
0130     tile_number++;
0131       }
0132 
0133       //Place the same volumes inside the envelope
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       //Place the tile inside the layer
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       //Increment the z pos of the tile
0152       tile_pos_z += tile_thickness;
0153       tile_number++;
0154       slice_num++;
0155     }
0156       }
0157       
0158       //Place the same layer around the beam axis phiBins times
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     //DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d"));
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   //Place the calo inside the world
0180   
0181   return d_det;
0182 }
0183 
0184 DECLARE_DETELEMENT(FCC_HcalBarrel2,create_detector)