Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 #include "DD4hep/DetFactoryHelper.h"
0015 #include "XML/Layering.h"
0016 #include <limits>
0017 
0018 using namespace dd4hep;
0019 
0020 static void placeStaves(DetElement&   parent,
0021             DetElement&   stave,
0022             double        rmin, 
0023             int           numsides, 
0024             double        total_thickness, 
0025             Volume        envelopeVolume, 
0026             double        innerAngle, 
0027             Volume        sectVolume)
0028 {
0029   double innerRotation    = innerAngle;
0030   double offsetRotation   = -innerRotation / 2;
0031   double sectCenterRadius = rmin + total_thickness / 2;
0032   double rotX =  M_PI / 2;
0033   double rotY = -offsetRotation;
0034   double posX = -sectCenterRadius  * std::sin(rotY);
0035   double posY =  sectCenterRadius  * std::cos(rotY);
0036 
0037   for (int module = 1; module <= numsides; ++module)  {
0038     DetElement det  = module>1 ? stave.clone(_toString(module,"stave%d")) : stave;
0039     PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,Transform3D(RotationZYX(0,rotY,rotX),
0040                                     Translation3D(-posX,-posY,0)));
0041     // Not a valid volID: pv.addPhysVolID("stave", 0);
0042     pv.addPhysVolID("module",module);
0043     det.setPlacement(pv);
0044     parent.add(det);
0045     rotY -=  innerRotation;
0046     posX  = -sectCenterRadius * std::sin(rotY);
0047     posY  =  sectCenterRadius * std::cos(rotY);
0048   }
0049 }
0050 
0051 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)  {
0052   xml_det_t   x_det     = e;
0053   Layering    layering(x_det);
0054   //xml_comp_t  staves      = x_det.staves();
0055   xml_dim_t   dim         = x_det.dimensions();
0056   std::string det_name    = x_det.nameStr();
0057   Material    air         = description.air();
0058   double      totalThickness = layering.totalThickness();
0059   int         numSides    = dim.numsides();
0060   double      detZ        = dim.z();
0061   double      rmin        = dim.rmin();
0062   double      rmax        = dim.rmax();
0063   DetElement  sdet(det_name,x_det.id());
0064   DetElement  stave("stave1",x_det.id());
0065   Volume      motherVol = description.pickMotherVolume(sdet);
0066   PolyhedraRegular polyhedron(numSides,0.,rmin,detZ+10);
0067   Tube tube(0.,rmin+totalThickness,detZ/2,0,2*M_PI);
0068   SubtractionSolid sub(tube,polyhedron);  
0069   Volume           envelopeVol(det_name+"_envelope",sub,air);
0070 
0071   // Add the subdetector envelope to the structure.
0072   double externalAngle     = 2*M_PI/numSides;
0073   double halfExternalAngle = externalAngle/2;
0074   double tan_external      = std::tan(externalAngle);
0075   double tan_half      = std::tan(halfExternalAngle);
0076   
0077   double half_polyFace = rmin * tan_half;
0078   
0079   double innerFaceLen   = std::sqrt(rmax*rmax - rmin*rmin)+half_polyFace;
0080   //double outerFaceLen   = (rmin+totalThickness) * tan_external;
0081   double staveThickness = totalThickness;
0082 
0083 //   Trapezoid staveTrdOuter(innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2);
0084 //   Volume    staveOuterVol(det_name+"_stave",staveTrdOuter,air);
0085   Assembly    staveOuterVol(det_name+"_stave");
0086   
0087 //   Trapezoid staveTrdInner(innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2);
0088 //   Volume    staveInnerVol(det_name+"_inner",staveTrdInner,air);
0089   
0090   //double layerOuterAngle = (M_PI-externalAngle)/2;
0091   //double layerexternalAngle = (M_PI/2 - layerOuterAngle);
0092   double layer_pos_z = -(staveThickness / 2);    
0093   double layer_pos_x = 0; 
0094   
0095   double layer_dim_x = innerFaceLen/2;
0096   int layer_num = 1;
0097   
0098   double layerR = rmin;
0099 
0100   // Set envelope volume attributes.
0101   envelopeVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0102 
0103   for(xml_coll_t c(x_det,_U(layer)); c; ++c)  {
0104     xml_comp_t   x_layer = c;
0105     int          repeat = x_layer.repeat();            // Get number of times to repeat this layer.
0106     const Layer* lay    = layering.layer(layer_num-1); // Get the layer from the layering engine.
0107     // Loop over repeats for this layer.
0108     for (int j = 0; j < repeat; j++)    {
0109       std::string layer_name      = det_name+_toString(layer_num,"_layer%d");
0110       double      layer_thickness = lay->thickness();
0111       DetElement  layer(stave,_toString(layer_num,"layer%d"),x_det.id());
0112 
0113       // Layer position in Z within the stave.
0114       layer_pos_z += layer_thickness / 2;
0115       // Layer box & volume
0116       Volume layer_vol(layer_name, Box(layer_dim_x,detZ/2,layer_thickness/2), air);
0117 
0118       // Create the slices (sublayers) within the layer.
0119       double slice_pos_z = -(layer_thickness / 2);
0120       int slice_number = 1;
0121       for(xml_coll_t k(x_layer,_U(slice)); k; ++k)  {
0122     xml_comp_t  x_slice = k;
0123     std::string slice_name      = layer_name + _toString(slice_number,"_slice%d");
0124     double      slice_thickness = x_slice.thickness();
0125     Material    slice_material  = description.material(x_slice.materialStr());
0126     DetElement  slice(layer,_toString(slice_number,"slice%d"),x_det.id());
0127 
0128     slice_pos_z += slice_thickness / 2;
0129     // Slice volume & box
0130     Volume slice_vol(slice_name,Box(layer_dim_x,detZ/2,slice_thickness/2),slice_material);
0131 
0132     if ( x_slice.isSensitive() ) {
0133       sens.setType("calorimeter");
0134       slice_vol.setSensitiveDetector(sens);
0135     }
0136     // Set region, limitset, and vis.
0137     slice_vol.setAttributes(description,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
0138     // slice PlacedVolume
0139     PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z));
0140     slice_phv.addPhysVolID("slice",slice_number);
0141 
0142     slice.setPlacement(slice_phv);
0143     // Increment Z position for next slice.
0144     slice_pos_z += slice_thickness / 2;
0145     // Increment slice number.
0146     ++slice_number;
0147       }
0148       // Set region, limitset, and vis.
0149       layer_vol.setAttributes(description,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
0150 
0151       // Layer physical volume.
0152       PlacedVolume layer_phv = staveOuterVol.placeVolume(layer_vol,Position((layer_dim_x+layer_pos_x-half_polyFace),0,layer_pos_z));
0153       layer_phv.addPhysVolID("layer",layer_num);
0154       layer.setPlacement(layer_phv);
0155 
0156       layerR += layer_thickness;
0157       // Increment the layer X dimension.
0158       layer_pos_x = (layerR-rmin)/tan_external;
0159       layer_dim_x =  (std::sqrt(rmax*rmax - layerR*layerR)+half_polyFace - layer_pos_x)/2.0;
0160       std::cout << "Rmin: " <<  rmin << " Rmax: " << rmax
0161                 << " half_polyFace: " << half_polyFace
0162                 << " Layer "  << layer_num << " layerR: " << layerR << " layer_dim_x:"  << layer_dim_x
0163                 << std::endl;
0164       // Increment the layer Z position.
0165       layer_pos_z += layer_thickness / 2;
0166       // Increment the layer number.
0167       ++layer_num;
0168     }
0169   }
0170 
0171   // Add stave inner physical volume to outer stave volume.
0172 //   staveOuterVol.placeVolume(staveInnerVol); //not needed
0173   // Set the vis attributes of the outer stave section.
0174 //   stave.setVisAttributes(description,staves.visStr(),staveOuterVol); //not applicable for Assembly
0175   // Place the staves.
0176   placeStaves(sdet,stave,rmin,numSides,totalThickness,envelopeVol,externalAngle,staveOuterVol);
0177 
0178   double z_offset = dim.hasAttr(_U(z_offset)) ? dim.z_offset() : 0.0;
0179   Transform3D transform(RotationZ(M_PI-(M_PI/numSides)),Translation3D(0,0,z_offset));
0180   PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,transform);
0181   env_phv.addPhysVolID("system", sdet.id());
0182   env_phv.addPhysVolID("barrel", 0);
0183   sdet.setPlacement(env_phv);
0184 
0185   //sdet.addExtension<LayerStack>(new PolyhedralCalorimeterLayerStack(sdet));
0186   return sdet;
0187 }
0188 
0189 DECLARE_DETELEMENT(SectorBarrelCalorimeter,create_detector)