Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-10 08:26:47

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Aranya Giri
0003 
0004 // Start Date - 10/31/2022
0005 // Homogeneous PbWO4 (EM Calorimeter) Pair Spectrometer
0006 
0007 #include "DD4hep/DetFactoryHelper.h"
0008 #include <XML/Helper.h>
0009 #include <XML/Utilities.h>
0010 #include <algorithm>
0011 #include <iostream>
0012 #include <tuple>
0013 
0014 using namespace std;
0015 using namespace dd4hep;
0016 
0017 // Definition of function to build the modules
0018 static tuple<Volume, Position> build_specHomoCAL_module(const Detector& description,
0019                                                         const xml::Component& mod_x,
0020                                                         SensitiveDetector& sens);
0021 
0022 // Driver Function
0023 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0024   sens.setType("calorimeter");
0025 
0026   xml_det_t x_det  = e;
0027   xml_comp_t x_mod = x_det.child(_Unicode(module));
0028   string det_name  = x_det.nameStr();
0029   int det_ID       = x_det.id();
0030 
0031   // Create main detector element to be returned at the end
0032   DetElement det(det_name, det_ID);
0033 
0034   // Mother volume
0035   Volume motherVol = description.pickMotherVolume(det);
0036 
0037   // apply any detector type flags set in XML
0038   dd4hep::xml::setDetectorTypeFlag(x_det, det);
0039 
0040   // Detector assembly
0041   Assembly assembly(det_name);
0042   assembly.setVisAttributes(description.invisible());
0043 
0044   // Create Modules
0045 
0046   auto [modVol, modSize] = build_specHomoCAL_module(description, x_mod, sens);
0047   double detSizeXY       = getAttrOrDefault(x_det, _Unicode(sizeXY), 20);
0048   int nxy                = int(detSizeXY / modSize.x());
0049   double xypos0          = -nxy * modSize.x() / 2.0 + modSize.x() / 2.0;
0050 
0051   // Build detector components
0052   // loop over sectors
0053   for (xml_coll_t si(x_det, _Unicode(sector)); si; si++) { // sectors (top,bottom)
0054 
0055     xml_comp_t x_sector(si);
0056     int sector_id = x_sector.id();
0057     int mod_id    = 0;
0058 
0059     xml_comp_t x_pos = x_sector.position();
0060     xml_comp_t x_rot = x_sector.rotation();
0061 
0062     for (int ix = 0; ix < nxy; ix++) {
0063       for (int iy = 0; iy < nxy; iy++) {
0064 
0065         double mod_pos_x = x_pos.x() + xypos0 + ix * modSize.x();
0066         double mod_pos_y = x_pos.y() + xypos0 + iy * modSize.y();
0067         double mod_pos_z = x_pos.z() + 0.0 * cm;
0068 
0069         PlacedVolume modPV =
0070             assembly.placeVolume(modVol, Transform3D(RotationZYX(x_rot.x(), x_rot.y(), x_rot.z()),
0071                                                      Position(mod_pos_x, mod_pos_y, mod_pos_z)));
0072 
0073         modPV.addPhysVolID("sector", sector_id).addPhysVolID("module", mod_id);
0074         mod_id++;
0075       }
0076     }
0077 
0078   } // sectors
0079 
0080   // Place assembly into mother volume.  Assembly is centered at origin
0081   PlacedVolume detPV = motherVol.placeVolume(assembly, Position(0.0, 0.0, 0.0));
0082   detPV.addPhysVolID("system", det_ID);
0083 
0084   // Connect to system ID
0085   det.setPlacement(detPV);
0086 
0087   return det;
0088 } //Driver class close
0089 
0090 //--------------------------------------------------------------------
0091 //Function for building the module
0092 static tuple<Volume, Position> build_specHomoCAL_module(const Detector& description,
0093                                                         const xml::Component& mod_x,
0094                                                         SensitiveDetector& sens) {
0095 
0096   double sx         = mod_x.attr<double>(_Unicode(sizex));
0097   double sy         = mod_x.attr<double>(_Unicode(sizey));
0098   double sz         = mod_x.attr<double>(_Unicode(sizez));
0099   double frame_size = mod_x.attr<double>(_Unicode(frameSize));
0100 
0101   Box modShape((sx / 2.0 - frame_size), (sy / 2.0 - frame_size), sz / 2.0);
0102   auto modMat = description.material(mod_x.attr<std::string>(_Unicode(material)));
0103   Volume modVol("module_vol", modShape, modMat);
0104 
0105   if (mod_x.hasAttr(_Unicode(vis))) {
0106     modVol.setVisAttributes(description.visAttributes(mod_x.attr<std::string>(_Unicode(vis))));
0107   }
0108 
0109   modVol.setSensitiveDetector(sens);
0110   return make_tuple(modVol, Position{sx, sy, sz});
0111 }
0112 
0113 DECLARE_DETELEMENT(LumiSpecHomoCAL, create_detector) //(det_type, driver func)