Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-09-27 07:02:36

0001 /** \addtogroup Trackers Trackers
0002  * \brief Type: **BarrelTrackerWithFrame**.
0003  * \author W. Armstrong
0004  *
0005  * \ingroup trackers
0006  *
0007  * @{
0008  */
0009 #include <array>
0010 #include <map>
0011 #include "DD4hep/DetFactoryHelper.h"
0012 #include "DD4hep/Printout.h"
0013 #include "DD4hep/Shapes.h"
0014 #include "DDRec/Surface.h"
0015 #include "DDRec/DetectorData.h"
0016 #include "XML/Utilities.h"
0017 #include "XML/Layering.h"
0018 
0019 #if defined(USE_ACTSDD4HEP)
0020 #include "ActsDD4hep/ActsExtension.hpp"
0021 #include "ActsDD4hep/ConvertMaterial.hpp"
0022 #else
0023 #include "Acts/Plugins/DD4hep/ActsExtension.hpp"
0024 #include "Acts/Plugins/DD4hep/ConvertDD4hepMaterial.hpp"
0025 #endif
0026 
0027 using namespace std;
0028 using namespace dd4hep;
0029 using namespace dd4hep::rec;
0030 using namespace dd4hep::detail;
0031 
0032 /** Endcap Trapezoidal Tracker.
0033  *
0034  * @author Whitney Armstrong
0035  *
0036  */
0037 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)
0038 {
0039   typedef vector<PlacedVolume> Placements;
0040   xml_det_t                    x_det    = e;
0041   Material                     vacuum   = description.vacuum();
0042   int                          det_id   = x_det.id();
0043   string                       det_name = x_det.nameStr();
0044   bool                         reflect  = x_det.reflect(false);
0045   DetElement                   sdet(det_name, det_id);
0046   Assembly                     assembly(det_name);
0047 
0048   Material  air  = description.material("Air");
0049   // Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
0050   Volume                  motherVol = description.pickMotherVolume(sdet);
0051   int                     m_id = 0, c_id = 0, n_sensor = 0;
0052   map<string, Volume>     modules;
0053   map<string, Placements> sensitives;
0054   map<string, std::vector<VolPlane>>        volplane_surfaces;
0055   map<string, std::array<double, 2>> module_thicknesses;
0056   PlacedVolume            pv;
0057 
0058 
0059   // ACTS extension
0060   {
0061     Acts::ActsExtension* detWorldExt = new Acts::ActsExtension();
0062     detWorldExt->addType("endcap", "detector");
0063     // SJJ probably need to set the envelope here, as ACTS can't figure
0064     // that out for Assembly volumes. May also need binning to properly pick up
0065     // on the support material @TODO
0066     //
0067     // Add the volume boundary material if configured
0068     for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) {
0069       xml_comp_t x_boundary_material = bmat;
0070       Acts::xmlToProtoSurfaceMaterial(x_boundary_material, *detWorldExt, "boundary_material");
0071     }
0072     sdet.addExtension<Acts::ActsExtension>(detWorldExt);
0073   }
0074 
0075   assembly.setVisAttributes(description.invisible());
0076   sens.setType("tracker");
0077 
0078   for (xml_coll_t su(x_det, _U(support)); su; ++su) {
0079     xml_comp_t x_support = su;
0080     double      support_thickness = getAttrOrDefault(x_support, _U(thickness), 2.0 * mm);
0081     double      support_length    = getAttrOrDefault(x_support, _U(length), 2.0 * mm);
0082     double      support_rmin      = getAttrOrDefault(x_support, _U(rmin), 2.0 * mm);
0083     double      support_zstart    = getAttrOrDefault(x_support, _U(zstart), 2.0 * mm);
0084     std::string support_name      = getAttrOrDefault<std::string>(x_support, _Unicode(name), "support_tube");
0085     std::string support_vis       = getAttrOrDefault<std::string>(x_support, _Unicode(vis), "AnlRed");
0086     xml_dim_t  pos        (x_support.child(_U(position), false));
0087     xml_dim_t  rot        (x_support.child(_U(rotation), false));
0088     Solid support_solid;
0089     if(x_support.hasChild("shape")){
0090       xml_comp_t shape(x_support.child(_U(shape)));
0091       string     shape_type = shape.typeStr();
0092       support_solid  = xml::createShape(description, shape_type, shape);
0093     } else {
0094       support_solid = Tube(support_rmin, support_rmin + support_thickness, support_length / 2);
0095     }
0096     Transform3D tr = Transform3D(Rotation3D(),Position(0,0,(reflect?-1.0:1.0) * (support_zstart + support_length / 2)));
0097     if ( pos.ptr() && rot.ptr() )  {
0098       Rotation3D  rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
0099       Position    pos3D(pos.x(0),pos.y(0),pos.z(0));
0100       tr = Transform3D(rot3D, pos3D);
0101     }
0102     else if ( pos.ptr() )  {
0103       tr = Transform3D(Rotation3D(),Position(pos.x(0),pos.y(0),pos.z(0)));
0104     }
0105     else if ( rot.ptr() )  {
0106       Rotation3D rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
0107       tr = Transform3D(rot3D,Position());
0108     }
0109     Material    support_mat       = description.material(x_support.materialStr());
0110     Volume      support_vol(support_name, support_solid, support_mat);
0111     support_vol.setVisAttributes(description.visAttributes(support_vis));
0112     pv = assembly.placeVolume(support_vol, tr);
0113     // pv = assembly.placeVolume(support_vol, Position(0, 0, support_zstart + support_length / 2));
0114   }
0115 
0116   for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) {
0117     xml_comp_t x_mod = mi;
0118     string     m_nam = x_mod.nameStr();
0119     xml_comp_t trd   = x_mod.trd();
0120 
0121     double     posY;
0122     double     x1 = trd.x1();
0123     double     x2 = trd.x2();
0124     double     z  = trd.z();
0125     double     total_thickness = 0.;
0126     xml_coll_t ci(x_mod, _U(module_component));
0127     for (ci.reset(), total_thickness = 0.0; ci; ++ci)
0128       total_thickness += xml_comp_t(ci).thickness();
0129 
0130     double     thickness_so_far = 0.0;
0131     double     thickness_sum    = -total_thickness / 2.0;
0132     double     y1               = total_thickness / 2;
0133     double     y2               = total_thickness / 2;
0134     Trapezoid m_solid(x1, x2, y1, y2, z);
0135     Volume m_volume(m_nam, m_solid, vacuum);
0136     m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
0137 
0138     Solid  frame_s;
0139     if(x_mod.hasChild("frame")){
0140       // build frame from trd (assumed to be smaller)
0141       xml_comp_t m_frame         = x_mod.child(_U(frame));
0142       xml_comp_t f_pos           = m_frame.child(_U(position));
0143       xml_comp_t frame_trd       = m_frame.trd();
0144       double     frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness);
0145       double     frame_x1        = frame_trd.x1();
0146       double     frame_x2        = frame_trd.x2();
0147       double     frame_z         = frame_trd.z();
0148       // make the frame match the total thickness if thickness attribute is not given
0149       Trapezoid        f_solid1(x1, x2,frame_thickness / 2.0, frame_thickness / 2.0, z);
0150       Trapezoid        f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z) ;
0151       SubtractionSolid frame_shape(f_solid1, f_solid);
0152       frame_s = frame_shape;
0153 
0154       Material f_mat  = description.material(m_frame.materialStr());
0155       Volume f_vol(m_nam + "_frame", frame_shape, f_mat);
0156       f_vol.setVisAttributes(description.visAttributes(m_frame.visStr()));
0157 
0158       // figure out how to best place
0159       pv = m_volume.placeVolume(f_vol, Position(f_pos.x(), f_pos.y(),  f_pos.z()));
0160     }
0161 
0162     for (ci.reset(), n_sensor = 1, c_id = 0, posY = -y1; ci; ++ci, ++c_id) {
0163       xml_comp_t c           = ci;
0164       double     c_thick     = c.thickness();
0165       auto       comp_x1     = getAttrOrDefault(c, _Unicode(x1), x1);
0166       auto       comp_x2     = getAttrOrDefault(c, _Unicode(x2), x2);
0167       auto       comp_height = getAttrOrDefault(c, _Unicode(height), z);
0168 
0169       Material c_mat  = description.material(c.materialStr());
0170       string   c_name = _toString(c_id, "component%d");
0171 
0172       Trapezoid comp_s1(comp_x1, comp_x2, c_thick / 2e0, c_thick / 2e0, comp_height);
0173       Solid  comp_shape = comp_s1;
0174       if(frame_s.isValid()) {
0175         comp_shape = SubtractionSolid( comp_s1, frame_s); 
0176       }
0177       Volume   c_vol(c_name, comp_shape, c_mat);
0178 
0179       c_vol.setVisAttributes(description.visAttributes(c.visStr()));
0180       pv = m_volume.placeVolume(c_vol, Position(0, posY + c_thick / 2, 0));
0181       if (c.isSensitive()) {
0182         module_thicknesses[m_nam] = {thickness_so_far + c_thick/2.0, total_thickness-thickness_so_far - c_thick/2.0};
0183         //std::cout << " adding sensitive volume" << c_name << "\n";
0184         sdet.check(n_sensor > 2, "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!");
0185         pv.addPhysVolID("sensor", n_sensor);
0186         sens.setType("tracker");
0187         c_vol.setSensitiveDetector(sens);
0188         sensitives[m_nam].push_back(pv);
0189         ++n_sensor;
0190         // -------- create a measurement plane for the tracking surface attched to the sensitive volume -----
0191         Vector3D u(0., 0., -1.);
0192         Vector3D v(-1., 0., 0.);
0193         Vector3D n(0., 1., 0.);
0194         // Vector3D o( 0. , 0. , 0. ) ;
0195 
0196         // compute the inner and outer thicknesses that need to be assigned to the tracking surface
0197         // depending on wether the support is above or below the sensor
0198         double inner_thickness = module_thicknesses[m_nam][0];
0199         double outer_thickness = module_thicknesses[m_nam][1];
0200 
0201         SurfaceType type(SurfaceType::Sensitive);
0202 
0203         // if( isStripDetector )
0204         //  type.setProperty( SurfaceType::Measurement1D , true ) ;
0205 
0206         VolPlane surf(c_vol, type, inner_thickness, outer_thickness, u, v, n); //,o ) ;
0207         volplane_surfaces[m_nam].push_back(surf);
0208 
0209         //--------------------------------------------
0210       }
0211       posY += c_thick;
0212       thickness_sum += c_thick;
0213       thickness_so_far += c_thick;
0214     }
0215     modules[m_nam] = m_volume;
0216   }
0217 
0218   for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
0219     xml_comp_t x_layer(li);
0220     int        l_id    = x_layer.id();
0221     int        mod_num = 1;
0222 
0223     xml_comp_t l_env      = x_layer.child(_U(envelope));
0224     string     layer_name = det_name + std::string("_layer") + std::to_string(l_id);
0225 
0226     std::string layer_vis    = l_env.attr<std::string>(_Unicode(vis));
0227     double      layer_rmin   = l_env.attr<double>(_Unicode(rmin));
0228     double      layer_rmax   = l_env.attr<double>(_Unicode(rmax));
0229     double      layer_length = l_env.attr<double>(_Unicode(length));
0230     double      layer_zstart = l_env.attr<double>(_Unicode(zstart));
0231     double      layer_center_z =  layer_zstart + layer_length/2.0;
0232     //printout(INFO,"ROOTGDMLParse","+++ Read geometry from GDML file file:%s",input.c_str());
0233     //std::cout << "SiTracker Endcap layer " << l_id << " zstart = " << layer_zstart/dd4hep::mm << "mm ( " << layer_length/dd4hep::mm << " mm thick )\n";
0234 
0235     //Assembly    layer_assembly(layer_name);
0236     //assembly.placeVolume(layer_assembly);
0237     Tube       layer_tub(layer_rmin, layer_rmax, layer_length / 2);
0238     Volume     layer_vol(layer_name, layer_tub, air); // Create the layer envelope volume.
0239     layer_vol.setVisAttributes(description.visAttributes(layer_vis));
0240 
0241     PlacedVolume layer_pv;
0242     if (reflect) {
0243       layer_pv =
0244           assembly.placeVolume(layer_vol, Transform3D(RotationZYX(0.0, -M_PI, 0.0), Position(0, 0, -layer_center_z)));
0245       layer_pv.addPhysVolID("layer", l_id);
0246       layer_name += "_N";
0247     } else {
0248       layer_pv = assembly.placeVolume(layer_vol, Position(0, 0, layer_center_z));
0249       layer_pv.addPhysVolID("layer", l_id);
0250       layer_name += "_P";
0251     }
0252     DetElement layer_element(sdet, layer_name, l_id);
0253     layer_element.setPlacement(layer_pv);
0254 
0255     Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
0256     layerExtension->addType("sensitive disk", "layer");
0257     //layerExtension->addType("axes", "definitions", "XZY");
0258     //layerExtension->addType("sensitive disk", "layer");
0259     //layerExtension->addType("axes", "definitions", "XZY");
0260     for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
0261       xml_comp_t x_layer_material = lmat;
0262       xmlToProtoSurfaceMaterial(x_layer_material, *layerExtension, "layer_material");
0263     }
0264     layer_element.addExtension<Acts::ActsExtension>(layerExtension);
0265 
0266     for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) {
0267       xml_comp_t  x_ring   = ri;
0268       double      r        = x_ring.r();
0269       double      phi0     = x_ring.phi0(0);
0270       double      zstart   = x_ring.zstart();
0271       double      dz       = x_ring.dz(0);
0272       int         nmodules = x_ring.nmodules();
0273       string      m_nam    = x_ring.moduleStr();
0274       Volume      m_vol    = modules[m_nam];
0275       double      iphi     = 2 * M_PI / nmodules;
0276       double      phi      = phi0;
0277       Placements& sensVols = sensitives[m_nam];
0278 
0279       for (int k = 0; k < nmodules; ++k) {
0280         string     m_base = _toString(l_id, "layer%d") + _toString(mod_num, "_module%d");
0281         double     x      = -r * std::cos(phi);
0282         double     y      = -r * std::sin(phi);
0283 
0284         if (!reflect) {
0285           DetElement module(layer_element, m_base + "_pos", det_id);
0286           pv = layer_vol.placeVolume(
0287               m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, zstart + dz)));
0288           pv.addPhysVolID("module", mod_num);
0289           module.setPlacement(pv);
0290           for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0291             PlacedVolume sens_pv = sensVols[ic];
0292             DetElement   comp_elt(module, sens_pv.volume().name(), mod_num);
0293             comp_elt.setPlacement(sens_pv);
0294         //std::cout << " adding ACTS extension" << "\n";
0295             Acts::ActsExtension* moduleExtension = new Acts::ActsExtension("XZY");
0296             comp_elt.addExtension<Acts::ActsExtension>(moduleExtension);
0297             volSurfaceList(comp_elt)->push_back(volplane_surfaces[m_nam][ic]);
0298           }
0299         } else {
0300           pv = layer_vol.placeVolume(
0301               m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, -zstart - dz)));
0302           pv.addPhysVolID("module", mod_num);
0303           DetElement r_module(layer_element, m_base + "_neg", det_id);
0304           r_module.setPlacement(pv);
0305           for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0306             PlacedVolume sens_pv = sensVols[ic];
0307             DetElement   comp_elt(r_module, sens_pv.volume().name(), mod_num);
0308             comp_elt.setPlacement(sens_pv);
0309         //std::cout << " adding ACTS extension" << "\n";
0310             Acts::ActsExtension* moduleExtension = new Acts::ActsExtension("XZY");
0311             comp_elt.addExtension<Acts::ActsExtension>(moduleExtension);
0312             volSurfaceList(comp_elt)->push_back(volplane_surfaces[m_nam][ic]);
0313           }
0314         }
0315         dz = -dz;
0316         phi += iphi;
0317         ++mod_num;
0318       }
0319     }
0320   }
0321   pv = motherVol.placeVolume(assembly,Position(0,0,(reflect?-1.0e-9:1.0e-9)) );
0322   pv.addPhysVolID("system", det_id);
0323   sdet.setPlacement(pv);
0324   return sdet;
0325 }
0326 
0327 //@}
0328 // clang-format off
0329 DECLARE_DETELEMENT(athena_TrapEndcapTracker, create_detector)
0330 DECLARE_DETELEMENT(athena_GEMTrackerEndcap, create_detector)