Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-06 16:41:35

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Shima Shimizu, Jihee Kim, Wouter Deconinck
0003 
0004 #include "DD4hep/DetFactoryHelper.h"
0005 #include "DD4hep/OpticalSurfaces.h"
0006 #include "DD4hep/Printout.h"
0007 #include "DDRec/DetectorData.h"
0008 #include "DDRec/Surface.h"
0009 #include <XML/Helper.h>
0010 #include <XML/Utilities.h>
0011 #include <algorithm>
0012 #include <iostream>
0013 #include <math.h>
0014 #include <tuple>
0015 //////////////////////////////////////////////////
0016 // Far Forward Ion Zero Degree Calorimeter - Ecal
0017 // Reference from ATHENA ScFiCalorimeter_geo.cpp
0018 //////////////////////////////////////////////////
0019 
0020 using namespace std;
0021 using namespace dd4hep;
0022 
0023 // main
0024 static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) {
0025   xml::DetElement detElem = handle;
0026   std::string detName     = detElem.nameStr();
0027   int detID               = detElem.id();
0028   DetElement det(detName, detID);
0029   sens.setType("calorimeter");
0030   auto dim      = detElem.dimensions();
0031   auto xwidth   = dim.x();
0032   auto ywidth   = dim.y();
0033   auto length   = dim.z();
0034   xml_dim_t pos = detElem.position();
0035   xml_dim_t rot = detElem.rotation();
0036 
0037   // apply any detector type flags set in XML
0038   dd4hep::xml::setDetectorTypeFlag(detElem, det);
0039 
0040   // envelope
0041   Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5);
0042   Volume env(detName + "_envelope", envShape, desc.material("Air"));
0043   env.setVisAttributes(desc.visAttributes(detElem.visStr()));
0044 
0045   xml_comp_t mod_x = detElem.child(_Unicode(module));
0046   auto nbox        = mod_x.attr<int>(_Unicode(nbox));
0047   auto boxgap      = mod_x.attr<int>(_Unicode(gapspace));
0048 
0049   xml_comp_t x_lyr = mod_x.child(_Unicode(layer));
0050   auto nlyr        = x_lyr.attr<int>(_Unicode(nlayer));
0051 
0052   map<int, string> v_sl_name;
0053   map<string, Volume> slices;
0054   map<string, double> sl_thickness;
0055 
0056   int nsl = 0;
0057   xml_coll_t ci(x_lyr, _Unicode(slice));
0058   for (ci.reset(); ci; ++ci) {
0059     xml_comp_t x_sl = ci;
0060     Material sl_mat = desc.material(x_sl.materialStr());
0061     string sl_name  = x_sl.nameStr();
0062     double sl_z     = x_sl.thickness();
0063 
0064     Box sl_Shape(xwidth / 2., ywidth / 2., sl_z / 2.);
0065     Volume sl_Vol("slice_vol", sl_Shape, sl_mat);
0066     sl_Vol.setVisAttributes(desc.visAttributes(x_sl.visStr()));
0067     if (x_sl.isSensitive())
0068       sl_Vol.setSensitiveDetector(sens);
0069 
0070     nsl++;
0071     v_sl_name[nsl]        = sl_name;
0072     slices[sl_name]       = sl_Vol;
0073     sl_thickness[sl_name] = sl_z;
0074   }
0075 
0076   double zpos_0 = -length / 2.;
0077   int layerid   = 0;
0078   for (int ibox = 0; ibox < nbox; ibox++) {
0079     for (int ilyr = 0; ilyr < nlyr; ilyr++) {
0080       layerid++;
0081       for (int isl = 0; isl < nsl; isl++) {
0082         string sl_name = v_sl_name[isl + 1];
0083 
0084         double zpos = zpos_0 + sl_thickness[sl_name] / 2.;
0085         Position sl_pos(0, 0, zpos);
0086         PlacedVolume pv = env.placeVolume(slices[sl_name], sl_pos);
0087         if (slices[sl_name].isSensitive())
0088           pv.addPhysVolID(sl_name, layerid);
0089 
0090         zpos_0 += sl_thickness[sl_name];
0091       }
0092     }
0093     zpos_0 += boxgap;
0094   }
0095 
0096   // detector position and rotation
0097   Volume motherVol = desc.pickMotherVolume(det);
0098   Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z()));
0099   PlacedVolume envPV = motherVol.placeVolume(env, tr);
0100   envPV.addPhysVolID("system", detID);
0101   det.setPlacement(envPV);
0102   return det;
0103 }
0104 
0105 DECLARE_DETELEMENT(ZDC_SamplingCal, create_detector)