Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:16:00

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Shima Shimizu, Jihee Kim
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 <algorithm>
0011 #include <iostream>
0012 #include <math.h>
0013 #include <tuple>
0014 //////////////////////////////////////////////////
0015 // Far Forward Ion Zero Degree Calorimeter - Ecal
0016 // Reference from ATHENA ScFiCalorimeter_geo.cpp
0017 //////////////////////////////////////////////////
0018 
0019 using namespace std;
0020 using namespace dd4hep;
0021 
0022 // main
0023 static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) {
0024   xml::DetElement detElem = handle;
0025   std::string detName     = detElem.nameStr();
0026   int detID               = detElem.id();
0027   DetElement det(detName, detID);
0028   sens.setType("calorimeter");
0029   auto dim      = detElem.dimensions();
0030   auto xwidth   = dim.x();
0031   auto ywidth   = dim.y();
0032   auto length   = dim.z();
0033   xml_dim_t pos = detElem.position();
0034   xml_dim_t rot = detElem.rotation();
0035 
0036   // envelope
0037   Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5);
0038   Volume env(detName + "_envelope", envShape, desc.material("Air"));
0039   env.setVisAttributes(desc.visAttributes(detElem.visStr()));
0040 
0041   // build frame
0042   xml_comp_t fr   = detElem.child(_Unicode(support));
0043   auto fx         = xwidth;
0044   auto fy         = ywidth;
0045   auto fz         = fr.attr<double>(_Unicode(sizez));
0046   auto fthickness = fr.attr<double>(_Unicode(thickness));
0047 
0048   Box frShape(fx / 2., fy / 2., fz / 2.);
0049   auto frMat = desc.material(fr.attr<std::string>(_Unicode(material)));
0050   Volume frVol("frame_vol", frShape, frMat);
0051   frVol.setVisAttributes(desc.visAttributes(fr.visStr()));
0052 
0053   xml_comp_t mod_x = detElem.child(_Unicode(module));
0054   auto nx          = mod_x.attr<int>(_Unicode(nx));
0055   auto ny          = mod_x.attr<int>(_Unicode(ny));
0056 
0057   // crystal tower
0058   xml_comp_t twr = mod_x.child(_Unicode(tower));
0059   double tsx     = twr.attr<double>(_Unicode(cellx));
0060   double tsy     = twr.attr<double>(_Unicode(celly));
0061   double tsz     = twr.thickness();
0062   Material t_mat = desc.material(twr.materialStr());
0063   string t_name  = twr.nameStr();
0064 
0065   Box t_Shape(tsx / 2., tsy / 2., tsz / 2.);
0066   Volume t_Vol("tower_vol", t_Shape, t_mat);
0067   t_Vol.setVisAttributes(desc.visAttributes(twr.visStr()));
0068   if (twr.isSensitive())
0069     t_Vol.setSensitiveDetector(sens);
0070 
0071   // readout socket
0072   xml_comp_t sct = mod_x.child(_Unicode(socket));
0073   double ssx     = sct.attr<double>(_Unicode(cellx));
0074   double ssy     = sct.attr<double>(_Unicode(celly));
0075   double ssz     = sct.thickness();
0076   Material s_mat = desc.material(sct.materialStr());
0077   string s_name  = sct.nameStr();
0078 
0079   Box s_Shape(ssx / 2., ssy / 2., ssz / 2.);
0080   Volume s_Vol("socket_vol", s_Shape, s_mat);
0081   s_Vol.setVisAttributes(desc.visAttributes(sct.visStr()));
0082 
0083   PlacedVolume pv;
0084   double x_pos_0          = -(nx * tsx + (nx - 1) * fthickness) / 2.;
0085   double y_pos_0          = -(ny * tsy + (ny - 1) * fthickness) / 2.;
0086   double twr_z_pos_in_fr  = -fz / 2. + tsz / 2.;
0087   double sct_z_pos_in_env = -length / 2. + tsz + ssz / 2.;
0088   int mod_i               = 0;
0089   for (int ix = 0; ix < nx; ix++) {
0090     double x_pos = x_pos_0 + ix * (tsx + fthickness) + tsx / 2.;
0091 
0092     for (int iy = 0; iy < ny; iy++) {
0093       double y_pos = y_pos_0 + iy * (tsy + fthickness) + tsy / 2.;
0094 
0095       mod_i++;
0096 
0097       Position twr_pos(x_pos, y_pos, twr_z_pos_in_fr);
0098       pv = frVol.placeVolume(t_Vol, twr_pos);
0099       pv.addPhysVolID(t_name, mod_i);
0100 
0101       Position sct_pos(x_pos, y_pos, sct_z_pos_in_env);
0102       pv = env.placeVolume(s_Vol, sct_pos);
0103     }
0104   }
0105 
0106   double f_zpos = -length / 2. + fz / 2.;
0107   Position fr_pos(0, 0, f_zpos);
0108   pv = env.placeVolume(frVol, fr_pos);
0109 
0110   // detector position and rotation
0111   Volume motherVol = desc.pickMotherVolume(det);
0112   Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z()));
0113   PlacedVolume envPV = motherVol.placeVolume(env, tr);
0114   envPV.addPhysVolID("system", detID);
0115   det.setPlacement(envPV);
0116   return det;
0117 }
0118 
0119 DECLARE_DETELEMENT(ZDC_Crystal, create_detector)