Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:15:56

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Whitney Armstrong
0003 
0004 #include "DD4hep/DetFactoryHelper.h"
0005 #include <map>
0006 
0007 using namespace std;
0008 using namespace dd4hep;
0009 using namespace dd4hep::detail;
0010 
0011 using Placements = vector<PlacedVolume>;
0012 
0013 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0014   xml_det_t x_det = e;
0015   // Material air = description.air();
0016   Material vacuum    = description.vacuum();
0017   string det_name    = x_det.nameStr();
0018   xml::Component pos = x_det.position();
0019   xml::Component rot = x_det.rotation();
0020   DetElement sdet(det_name, x_det.id());
0021   Assembly assembly(det_name);
0022   sens.setType("tracker");
0023 
0024   PlacedVolume pv;
0025 
0026   map<string, Volume> modules;
0027   map<string, Placements> sensitives;
0028   map<string, Volume> module_assemblies;
0029 
0030   int m_id = 0;
0031   // mi ~ module iterator
0032   for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) {
0033     xml_comp_t x_mod           = mi;
0034     string m_nam               = x_mod.nameStr();
0035     double mod_width           = getAttrOrDefault<double>(x_mod, _U(width), 1.6 * cm);
0036     double mod_height          = getAttrOrDefault<double>(x_mod, _U(height), 1.6 * cm);
0037     double mod_total_thickness = 0.;
0038 
0039     xml_coll_t ci(x_mod, _U(module_component));
0040     for (ci.reset(), mod_total_thickness = 0.0; ci; ++ci)
0041       mod_total_thickness += xml_comp_t(ci).thickness();
0042 
0043     Box m_solid(mod_width / 2.0, mod_height / 2.0, mod_total_thickness / 2.0);
0044     Volume m_volume(m_nam, m_solid, vacuum);
0045     m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
0046 
0047     double comp_z_pos = -mod_total_thickness / 2.0;
0048     int n_sensor      = 1;
0049     int c_id;
0050     for (ci.reset(), n_sensor = 1, c_id = 0; ci; ++ci, ++c_id) {
0051       xml_comp_t c   = ci;
0052       double c_thick = c.thickness();
0053       double comp_x  = getAttrOrDefault<double>(c, _Unicode(width), mod_width);
0054       double comp_y  = getAttrOrDefault<double>(c, _Unicode(height), mod_height);
0055 
0056       Material c_mat = description.material(c.materialStr());
0057       string c_name  = _toString(c_id, "RP_component%d");
0058 
0059       Box comp_s1(comp_x / 2.0, comp_y / 2.0, c_thick / 2.0);
0060       Solid comp_shape = comp_s1;
0061       Volume c_vol(c_name, comp_shape, c_mat);
0062       c_vol.setVisAttributes(description.visAttributes(c.visStr()));
0063 
0064       Position c_position(0, 0.0, comp_z_pos + c_thick / 2.0);
0065       if (c.hasChild(_U(position))) {
0066         xml_comp_t c_pos = c.child(_U(position));
0067         c_position       = Position(c_pos.x(), c_pos.y(), c_pos.z());
0068       }
0069       pv = m_volume.placeVolume(c_vol, c_position);
0070       if (c.isSensitive()) {
0071         // sdet.check(n_sensor > 2, "SiTrackerEndcap2::fromCompact: " + c_name +
0072         // " Max of 2 modules allowed!");
0073         pv.addPhysVolID("sensor", n_sensor);
0074         c_vol.setSensitiveDetector(sens);
0075         sensitives[m_nam].push_back(pv);
0076         ++n_sensor;
0077       }
0078       comp_z_pos += c_thick;
0079     }
0080     modules[m_nam] = m_volume;
0081   }
0082 
0083   std::map<std::string, DetElement> module_assembly_delements;
0084   // module assemblies
0085   for (xml_coll_t ma(x_det, _Unicode(module_assembly)); ma; ++ma) {
0086     xml_comp_t x_ma = ma;
0087     string ma_name  = x_ma.nameStr();
0088     Assembly ma_vol(ma_name);
0089     DetElement ma_de(ma_name, x_det.id());
0090     module_assemblies[ma_name]         = ma_vol;
0091     module_assembly_delements[ma_name] = ma_de;
0092 
0093     int i_mod = 0;
0094     // array of modules
0095     for (xml_coll_t ai(x_ma, _Unicode(array)); ai; ++ai) {
0096       xml_comp_t x_array     = ai;
0097       double nx              = getAttrOrDefault<double>(x_array, _Unicode(nx), 1);
0098       double ny              = getAttrOrDefault<double>(x_array, _Unicode(ny), 1);
0099       double dz              = getAttrOrDefault<double>(x_array, _Unicode(dz), 0 * mm);
0100       double arr_width       = getAttrOrDefault<double>(x_array, _Unicode(width), 1.6 * cm);
0101       double arr_height      = getAttrOrDefault<double>(x_array, _Unicode(height), 1.6 * cm);
0102       std::string arr_module = getAttrOrDefault<std::string>(x_array, _Unicode(module), "");
0103       // TODO: add check here
0104       auto arr_vol         = modules[arr_module];
0105       Placements& sensVols = sensitives[arr_module];
0106 
0107       double arr_x_delta = arr_width / double(nx);
0108       double arr_y_delta = arr_height / double(ny);
0109 
0110       xml_comp_t x_pos = x_array.position(false);
0111 
0112       for (int ix = 0; ix < nx; ix++) {
0113         for (int iy = 0; iy < ny; iy++) {
0114           double z_pos = dz; //(ix%2)? dz : -dz;
0115           i_mod++;
0116           Position arr_pos(-arr_width / 2.0 + arr_x_delta / 2.0 + ix * arr_x_delta,
0117                            -arr_height / 2.0 + arr_y_delta / 2.0 + iy * arr_y_delta, z_pos);
0118           if (x_pos) {
0119             arr_pos += Position(x_pos.x(0), x_pos.y(0), x_pos.z(0));
0120           }
0121 
0122           DetElement mod_de(ma_de, ma_name + std::string("_mod") + std::to_string(i_mod), i_mod);
0123           pv = ma_vol.placeVolume(arr_vol, arr_pos);
0124           pv.addPhysVolID("module", i_mod);
0125           mod_de.setPlacement(pv);
0126           for (size_t ic = 0; ic < sensVols.size(); ++ic) {
0127             PlacedVolume sens_pv = sensVols[ic];
0128             DetElement comp_de(mod_de, std::string("de_") + sens_pv.volume().name(), ic + 1);
0129             comp_de.setPlacement(sens_pv);
0130           }
0131         }
0132       }
0133     }
0134   }
0135 
0136   int l_num = 0;
0137   for (xml_coll_t i(x_det, _U(layer)); i; ++i, ++l_num) {
0138     xml_comp_t x_layer = i;
0139     string l_nam       = det_name + _toString(l_num, "_layer%d");
0140     xml_comp_t l_pos   = x_layer.position(false);
0141     Assembly l_vol(l_nam); //(l_nam, l_box, air);
0142 
0143     Position layer_pos(0, 0, 0);
0144     if (l_pos) {
0145       layer_pos = Position(l_pos.x(), l_pos.y(), l_pos.z());
0146     }
0147     DetElement layer(sdet, l_nam + "_pos", l_num);
0148 
0149     int i_assembly = 1;
0150     xml_coll_t ci(x_layer, _U(component));
0151     for (ci.reset(); ci; ++ci) {
0152       xml_comp_t x_comp = ci;
0153       xml_comp_t c_pos  = x_comp.position(false);
0154 
0155       string comp_assembly = getAttrOrDefault<std::string>(x_comp, _Unicode(assembly), "");
0156 
0157       auto comp_vol = module_assemblies[comp_assembly];
0158       auto comp_de =
0159           module_assembly_delements[comp_assembly].clone(comp_assembly + std::to_string(l_num));
0160       if (c_pos) {
0161         pv = l_vol.placeVolume(comp_vol, Position(c_pos.x(), c_pos.y(), c_pos.z()));
0162       } else {
0163         pv = l_vol.placeVolume(comp_vol);
0164       }
0165       pv.addPhysVolID("assembly", i_assembly);
0166       comp_de.setPlacement(pv);
0167       layer.add(comp_de);
0168       i_assembly++;
0169     }
0170     pv = assembly.placeVolume(l_vol, l_pos);
0171     pv.addPhysVolID("layer", l_num);
0172   }
0173 
0174   Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()),
0175                         Position(pos.x(), pos.y(), pos.z()));
0176   pv = description.pickMotherVolume(sdet).placeVolume(assembly, posAndRot);
0177   pv.addPhysVolID("system", x_det.id()); // Set the subdetector system ID.
0178   sdet.setPlacement(pv);
0179   return sdet;
0180 }
0181 
0182 DECLARE_DETELEMENT(ip6_ForwardRomanPot, create_detector)