File indexing completed on 2025-01-18 09:15:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "DD4hep/DetFactoryHelper.h"
0011 #include "DD4hep/Printout.h"
0012 #include "DD4hep/Shapes.h"
0013 #include "DDRec/DetectorData.h"
0014 #include "DDRec/Surface.h"
0015 #include <XML/Helper.h>
0016 #include "XML/Layering.h"
0017 #include "XML/Utilities.h"
0018 using namespace dd4hep;
0019
0020 struct moduleParamsStrct {
0021 moduleParamsStrct()
0022 : mod_BIwidth(0.)
0023 , mod_BIheight(0.)
0024 , mod_SWThick(0.)
0025 , mod_TWThick(0.)
0026 , mod_MPThick(0.)
0027 , mod_FWThick(0.)
0028 , mod_BWThick(0.)
0029 , mod_width(0.)
0030 , mod_height(0.)
0031 , mod_notchDepth(0.)
0032 , mod_notchHeight(0.)
0033 , mod_foilThick(0.)
0034 , mod_pcbLength(0.)
0035 , mod_pcbThick(0.)
0036 , mod_pcbWidth(0.)
0037 , mod_visStr("")
0038 , mod_regStr("")
0039 , mod_limStr("") {}
0040 moduleParamsStrct(double BIwidth, double BIheight, double SWThick, double TWThick, double MPThick,
0041 double FWThick, double BWThick, double width, double height, double notchDepth,
0042 double notchHeight, double foilThick, double pcbLegth, double pcbThick,
0043 double pcbWidth, std::string visStr, std::string regStr, std::string limStr) {
0044 mod_BIwidth = BIwidth;
0045 mod_BIheight = BIheight;
0046 mod_SWThick = SWThick;
0047 mod_TWThick = TWThick;
0048 mod_MPThick = MPThick;
0049 mod_FWThick = FWThick;
0050 mod_BWThick = BWThick;
0051 mod_width = width;
0052 mod_height = height;
0053 mod_notchDepth = notchDepth;
0054 mod_notchHeight = notchHeight;
0055 mod_foilThick = foilThick;
0056 mod_pcbLength = pcbLegth;
0057 mod_pcbThick = pcbThick;
0058 mod_pcbWidth = pcbWidth;
0059 mod_visStr = visStr;
0060 mod_regStr = regStr;
0061 mod_limStr = limStr;
0062 }
0063 double mod_BIwidth = 0.;
0064 double mod_BIheight = 0.;
0065 double mod_SWThick = 0.;
0066 double mod_TWThick = 0.;
0067 double mod_MPThick = 0.;
0068 double mod_FWThick = 0.;
0069 double mod_BWThick = 0.;
0070 double mod_width = 0.;
0071 double mod_height = 0.;
0072 double mod_notchDepth = 0.;
0073 double mod_notchHeight = 0.;
0074 double mod_foilThick = 0.;
0075 double mod_pcbLength = 0.;
0076 double mod_pcbThick = 0.;
0077 double mod_pcbWidth = 0.;
0078 std::string mod_visStr = "";
0079 std::string mod_regStr = "";
0080 std::string mod_limStr = "";
0081 };
0082
0083 struct sliceParamsStrct {
0084 sliceParamsStrct()
0085 : layer_ID(0)
0086 , slice_ID(0)
0087 , slice_partID(0)
0088 , slice_thick(0.)
0089 , slice_offset(0.)
0090 , slice_readoutLayer(0)
0091 , slice_matStr("")
0092 , slice_visStr("")
0093 , slice_regStr("")
0094 , slice_limStr("") {}
0095 sliceParamsStrct(int l_ID, int sl_ID, int sl_partID, double sl_thick, double sl_off, int l_rl,
0096 std::string sl_matStr, std::string sl_visStr, std::string sl_regStr,
0097 std::string sl_limStr) {
0098 layer_ID = l_ID;
0099 slice_ID = sl_ID;
0100 slice_partID = sl_partID;
0101 slice_thick = sl_thick;
0102 slice_offset = sl_off;
0103 slice_readoutLayer = l_rl;
0104 slice_matStr = sl_matStr;
0105 slice_visStr = sl_visStr;
0106 slice_regStr = sl_regStr;
0107 slice_limStr = sl_limStr;
0108 }
0109 int layer_ID = 0;
0110 int slice_ID = 0;
0111 int slice_partID = 0;
0112 double slice_thick = 0.;
0113 double slice_offset = 0.;
0114 int slice_readoutLayer = 0;
0115 std::string slice_matStr = "";
0116 std::string slice_visStr = "";
0117 std::string slice_regStr = "";
0118 std::string slice_limStr = "";
0119 };
0120
0121
0122
0123
0124 Volume createAbsorberPlate(Detector& desc, std::string basename, double h_mod, double w_mod,
0125 double t_mod_tp, double t_mod_sp, double t_slice, double w_notch,
0126 double h_notch, Material slice_mat, std::string region,
0127 std::string limit, std::string vis, bool renderComp) {
0128
0129 double w_plate = (w_mod / 2 - t_mod_sp) * 2;
0130 double l_A = -w_plate / 2;
0131 double l_B = -(w_plate / 2 - w_notch);
0132 double r_A = w_plate / 2;
0133
0134 const std::vector<double> xCoord = {l_A, r_A, r_A, l_A, l_A,
0135
0136 l_B, l_B, l_A};
0137
0138
0139 double topA = h_mod / 2 - t_mod_tp;
0140 double topB = h_notch / 2;
0141 double botA = -(h_mod / 2 - t_mod_tp);
0142 double botB = -(h_notch / 2);
0143
0144 const std::vector<double> yCoord = {topA, topA, botA, botA, botB,
0145
0146 botB, topB, topB};
0147
0148 const std::vector<double> zStep = {-t_slice / 2, t_slice / 2};
0149 const std::vector<double> zStepX = {0., 0.};
0150 const std::vector<double> zStepY = {0., 0.};
0151 const std::vector<double> zStepScale = {1., 1.};
0152
0153 ExtrudedPolygon absplate = ExtrudedPolygon(xCoord, yCoord, zStep, zStepX, zStepY, zStepScale);
0154
0155 Volume absplate_vol(basename, absplate, slice_mat);
0156
0157 if (renderComp) {
0158 absplate_vol.setAttributes(desc, region, limit, vis);
0159 } else {
0160 absplate_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0161 }
0162
0163 return absplate_vol;
0164 }
0165
0166
0167
0168
0169 Volume createFillerPlate(Detector& desc, std::string basename, double h_mod, double w_mod,
0170 double t_mod_tp, double t_mod_sp, double t_slice, double w_notch,
0171 Material slice_mat, std::string region, std::string limit, std::string vis,
0172 bool renderComp) {
0173 double w_plate = w_mod - 2 * t_mod_sp - w_notch;
0174 double h_plate = h_mod - 2 * t_mod_tp;
0175
0176 Box filler(w_plate / 2., h_plate / 2., t_slice / 2.);
0177 Volume filler_vol(basename, filler, slice_mat);
0178
0179 if (renderComp) {
0180 filler_vol.setAttributes(desc, region, limit, vis);
0181 } else {
0182 filler_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0183 }
0184
0185 return filler_vol;
0186 }
0187
0188
0189
0190
0191 Volume createScintillatorTower(Detector& desc, std::string basename, double w_tow, double h_tow,
0192 double t_slice, Material slice_mat, std::string region,
0193 std::string limit, std::string vis, SensitiveDetector sens,
0194 bool renderComp) {
0195
0196 Box scintplate(w_tow / 2., h_tow / 2., t_slice / 2.);
0197 Volume slice_vol(basename, scintplate, slice_mat);
0198
0199 sens.setType("calorimeter");
0200 slice_vol.setSensitiveDetector(sens);
0201
0202 if (renderComp) {
0203 slice_vol.setAttributes(desc, region, limit, vis);
0204 } else {
0205 slice_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0206 }
0207 return slice_vol;
0208 }
0209
0210
0211
0212
0213 Assembly createScintillatorPlateEightM(Detector& desc, std::string basename,
0214
0215 int layerID, double h_mod, double w_mod, double t_mod_tp,
0216 double t_mod_sp, double t_slice, double w_notch,
0217 double t_foil, Material slice_mat, int roLayer,
0218 std::string region, std::string limit, std::string vis,
0219 SensitiveDetector sens, bool renderComp) {
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 Assembly modScintAssembly(basename);
0231 double w_plate = w_mod - w_notch - 2 * t_mod_sp - 2 * t_foil;
0232 double h_plate = h_mod - 2 * t_mod_tp - 2 * t_foil;
0233 double w_tow = (w_plate - 6 * t_foil) / 4;
0234 double h_tow = (h_plate - 2 * t_foil) / 2;
0235
0236
0237 PlacedVolume pvm;
0238
0239
0240 const std::vector<double> xCoordTi = {
0241 -(w_plate / 2.), -(w_tow + 3 * t_foil), -(w_tow + 3 * t_foil), -(w_tow + 1 * t_foil),
0242 -(w_tow + 1 * t_foil),
0243
0244 -t_foil, -t_foil, t_foil, t_foil, w_tow + 1 * t_foil,
0245
0246 w_tow + 1 * t_foil, w_tow + 3 * t_foil, w_tow + 3 * t_foil, w_plate / 2., w_plate / 2.,
0247
0248 w_tow + 3 * t_foil, w_tow + 3 * t_foil, w_tow + 1 * t_foil, w_tow + 1 * t_foil, t_foil,
0249
0250 t_foil, -t_foil, -t_foil, -(w_tow + 1 * t_foil), -(w_tow + 1 * t_foil),
0251
0252 -(w_tow + 3 * t_foil), -(w_tow + 3 * t_foil), -(w_plate / 2.)};
0253
0254 const std::vector<double> yCoordTi = {
0255 t_foil, t_foil, (h_plate / 2.), (h_plate / 2.), t_foil,
0256
0257 t_foil, (h_plate / 2.), (h_plate / 2.), t_foil, t_foil,
0258
0259 (h_plate / 2.), (h_plate / 2.), t_foil, t_foil, -t_foil,
0260
0261 -t_foil, -(h_plate / 2.), -(h_plate / 2.), -t_foil, -t_foil,
0262
0263 -(h_plate / 2.), -(h_plate / 2.), -t_foil, -t_foil, -(h_plate / 2.),
0264
0265 -(h_plate / 2.), -t_foil, -t_foil};
0266
0267 const std::vector<double> zStepTi = {-t_slice / 2, t_slice / 2};
0268 const std::vector<double> zStepXTi = {0., 0.};
0269 const std::vector<double> zStepYTi = {0., 0.};
0270 const std::vector<double> zStepScaleTi = {1., 1.};
0271
0272 ExtrudedPolygon foilgrid =
0273 ExtrudedPolygon(xCoordTi, yCoordTi, zStepTi, zStepXTi, zStepYTi, zStepScaleTi);
0274 Box foil_t((w_plate + 2 * t_foil) / 2., t_foil / 2., t_slice / 2.);
0275 Box foil_s(t_foil / 2., h_plate / 2., t_slice / 2.);
0276 Volume foilgrid_vol(basename + "_ESRFoil_" + _toString(layerID, "_layer_%d"), foilgrid,
0277 slice_mat);
0278 Volume foil_t_vol(basename + "_ESRFoilT_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat);
0279 Volume foil_b_vol(basename + "_ESRFoilB_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat);
0280 Volume foil_l_vol(basename + "_ESRFoilL_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat);
0281 Volume foil_r_vol(basename + "_ESRFoilR_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat);
0282
0283 if (renderComp) {
0284 foilgrid_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0285 foil_t_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0286 foil_b_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0287 foil_l_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0288 foil_r_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0289 } else {
0290 foilgrid_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0291 foil_t_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0292 foil_b_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0293 foil_l_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0294 foil_r_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0295 }
0296 pvm = modScintAssembly.placeVolume(foilgrid_vol, Position(0, 0, 0));
0297 pvm = modScintAssembly.placeVolume(foil_t_vol, Position(0, 1.5 * t_foil + h_tow, 0));
0298 pvm = modScintAssembly.placeVolume(foil_b_vol, Position(0, -(1.5 * t_foil + h_tow), 0));
0299 pvm = modScintAssembly.placeVolume(foil_l_vol, Position(-(3.5 * t_foil + 2 * w_tow), 0, 0));
0300 pvm = modScintAssembly.placeVolume(foil_r_vol, Position((3.5 * t_foil + 2 * w_tow), 0, 0));
0301
0302
0303 double rotZ[8] = {0, 0, 0, 0, 0, 0, 0, 0};
0304 double rotY[8] = {0, 0, 0, 0, 0, 0, 0, 0};
0305 double rotX[8] = {0, 0, 0, 0, 0, 0, 0, 0};
0306 double posX[8] = {(w_tow * 1.5 + 3 * t_foil), (w_tow * 0.5 + t_foil),
0307 -(w_tow * 0.5 + t_foil), -(w_tow * 1.5 + 3 * t_foil),
0308 (w_tow * 1.5 + 3 * t_foil), (w_tow * 0.5 + t_foil),
0309 -(w_tow * 0.5 + t_foil), -(w_tow * 1.5 + 3 * t_foil)};
0310 double posY[8] = {0.5 * (h_tow) + t_foil, 0.5 * (h_tow) + t_foil, 0.5 * (h_tow) + t_foil,
0311 0.5 * (h_tow) + t_foil, -(0.5 * (h_tow) + t_foil), -(0.5 * (h_tow) + t_foil),
0312 -(0.5 * (h_tow) + t_foil), -(0.5 * (h_tow) + t_foil)};
0313 double posZ[8] = {0, 0, 0, 0, 0, 0, 0, 0};
0314 int towerx = 0;
0315 int towery = 0;
0316
0317
0318 for (int i = 0; i < 8; i++) {
0319
0320 Volume modScintTowerAss =
0321 createScintillatorTower(desc, basename + _toString(i, "_tower_%d"), w_tow, h_tow, t_slice,
0322 slice_mat, region, limit, vis, sens, renderComp);
0323 pvm = modScintAssembly.placeVolume(
0324 modScintTowerAss,
0325 Transform3D(RotationZYX(rotZ[i], rotY[i], rotX[i]), Position(posX[i], posY[i], posZ[i])));
0326 towerx = i % 4;
0327 towery = 0;
0328 if (i > 3)
0329 towery = 1;
0330 pvm.addPhysVolID("towerx", towerx)
0331 .addPhysVolID("towery", towery)
0332 .addPhysVolID("layerz", layerID)
0333 .addPhysVolID("passive", 0)
0334 .addPhysVolID("rlayerz", roLayer);
0335 }
0336 return modScintAssembly;
0337 }
0338
0339
0340
0341
0342 Assembly createScintillatorPlateFourM(Detector& desc, std::string basename,
0343
0344 int layerID, double h_mod, double w_mod, double t_mod_tp,
0345 double t_mod_sp, double t_slice, double w_notch,
0346 double t_foil, Material slice_mat, int roLayer,
0347 std::string region, std::string limit, std::string vis,
0348 SensitiveDetector sens, bool renderComp) {
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359 Assembly modScintAssembly(basename);
0360
0361 double w_plate = w_mod - w_notch - 2 * t_mod_sp - 2 * t_foil;
0362 double h_plate = h_mod - 2 * t_mod_tp - 2 * t_foil;
0363 double w_tow = (w_plate - 2 * t_foil) / 2;
0364 double h_tow = (h_plate - 2 * t_foil) / 2;
0365
0366
0367 PlacedVolume pvm;
0368
0369
0370
0371 const std::vector<double> xCoordTi = {
0372 -(w_plate / 2.), -t_foil, -t_foil, t_foil, t_foil,
0373
0374 w_plate / 2., w_plate / 2., t_foil, t_foil, -t_foil,
0375
0376 -t_foil, -(w_plate / 2.)};
0377
0378 const std::vector<double> yCoordTi = {
0379 t_foil,
0380 t_foil,
0381 (h_plate / 2.),
0382 (h_plate / 2.),
0383 t_foil,
0384
0385 t_foil,
0386 -t_foil,
0387 -t_foil,
0388 -(h_plate / 2.),
0389 -(h_plate / 2.),
0390
0391 -t_foil,
0392 -t_foil,
0393 };
0394
0395 const std::vector<double> zStepTi = {-t_slice / 2, t_slice / 2};
0396 const std::vector<double> zStepXTi = {0., 0.};
0397 const std::vector<double> zStepYTi = {0., 0.};
0398 const std::vector<double> zStepScaleTi = {1., 1.};
0399
0400 ExtrudedPolygon foilgrid =
0401 ExtrudedPolygon(xCoordTi, yCoordTi, zStepTi, zStepXTi, zStepYTi, zStepScaleTi);
0402 Box foil_t((w_plate + 2 * t_foil) / 2., t_foil / 2., t_slice / 2.);
0403 Box foil_s(t_foil / 2., h_plate / 2., t_slice / 2.);
0404 Volume foilgrid_vol(basename + "_ESRFoil_" + _toString(layerID, "_layer_%d"), foilgrid,
0405 slice_mat);
0406 Volume foil_t_vol(basename + "_ESRFoilT_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat);
0407 Volume foil_b_vol(basename + "_ESRFoilB_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat);
0408 Volume foil_l_vol(basename + "_ESRFoilL_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat);
0409 Volume foil_r_vol(basename + "_ESRFoilR_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat);
0410
0411 if (renderComp) {
0412 foilgrid_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0413 foil_t_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0414 foil_b_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0415 foil_l_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0416 foil_r_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis");
0417 } else {
0418 foilgrid_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0419 foil_t_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0420 foil_b_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0421 foil_l_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0422 foil_r_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters");
0423 }
0424 pvm = modScintAssembly.placeVolume(foilgrid_vol, Position(0, 0, 0));
0425 pvm = modScintAssembly.placeVolume(foil_t_vol, Position(0, 1.5 * t_foil + h_tow, 0));
0426 pvm = modScintAssembly.placeVolume(foil_b_vol, Position(0, -(1.5 * t_foil + h_tow), 0));
0427 pvm = modScintAssembly.placeVolume(foil_l_vol, Position(-(1.5 * t_foil + w_tow), 0, 0));
0428 pvm = modScintAssembly.placeVolume(foil_r_vol, Position((1.5 * t_foil + w_tow), 0, 0));
0429
0430
0431 double rotZ[4] = {0, 0, 0, 0};
0432 double rotY[4] = {0, 0, 0, 0};
0433 double rotX[4] = {0, 0, 0, 0};
0434 double posX[4] = {(w_tow * 0.5 + t_foil), -(w_tow * 0.5 + t_foil), (w_tow * 0.5 + t_foil),
0435 -(w_tow * 0.5 + t_foil)};
0436 double posY[4] = {0.5 * (h_tow) + t_foil, 0.5 * (h_tow) + t_foil, -(0.5 * (h_tow) + t_foil),
0437 -(0.5 * (h_tow) + t_foil)};
0438 double posZ[4] = {0, 0, 0, 0};
0439 int towerx = 0;
0440 int towery = 0;
0441
0442
0443 for (int i = 0; i < 4; i++) {
0444
0445 Volume modScintTowerAss =
0446 createScintillatorTower(desc, basename + _toString(i, "_tower_%d"), w_tow, h_tow, t_slice,
0447 slice_mat, region, limit, vis, sens, renderComp);
0448 pvm = modScintAssembly.placeVolume(
0449 modScintTowerAss,
0450 Transform3D(RotationZYX(rotZ[i], rotY[i], rotX[i]), Position(posX[i], posY[i], posZ[i])));
0451 towerx = i % 2;
0452 towery = 0;
0453 if (i > 1)
0454 towery = 1;
0455 pvm.addPhysVolID("towerx", towerx)
0456 .addPhysVolID("towery", towery)
0457 .addPhysVolID("layerz", layerID)
0458 .addPhysVolID("passive", 0)
0459 .addPhysVolID("rlayerz", roLayer);
0460 }
0461 return modScintAssembly;
0462 }
0463
0464
0465
0466
0467 Volume createEightMModule(Detector& desc, moduleParamsStrct mod_params,
0468 std::vector<sliceParamsStrct> sl_params,
0469
0470 double length, SensitiveDetector sens, bool renderComp, bool allSen) {
0471 std::string baseName = "LFHCAL_8M";
0472
0473
0474 Box modBox(mod_params.mod_width / 2., mod_params.mod_height / 2., length / 2.);
0475 Volume vol_mod(baseName, modBox, desc.material("Air"));
0476 vol_mod.setVisAttributes(desc.visAttributes(mod_params.mod_visStr.data()));
0477
0478
0479 PlacedVolume pvm;
0480
0481
0482
0483
0484 Box MountingPlate(mod_params.mod_width / 2., mod_params.mod_height / 2.,
0485 mod_params.mod_MPThick / 2.);
0486 Box modFrontPlate(mod_params.mod_width / 2., mod_params.mod_height / 2.,
0487 mod_params.mod_FWThick / 2.);
0488 Box modSidePlateL(
0489 mod_params.mod_SWThick / 2., mod_params.mod_height / 2.,
0490 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0491 Box modSidePlateR(
0492 mod_params.mod_SWThick / 2., mod_params.mod_height / 2.,
0493 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0494 Box modTopPlate(
0495 (mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2.,
0496 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0497 Box modBottomPlate(
0498 (mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2.,
0499 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0500 Box modBackCutOut(mod_params.mod_BIwidth / 2., mod_params.mod_BIheight / 2.,
0501 mod_params.mod_BWThick / 2.);
0502 Box modBackPlateFull(mod_params.mod_width / 2., mod_params.mod_height / 2.,
0503 mod_params.mod_BWThick / 2.);
0504 SubtractionSolid modBackPlate(modBackPlateFull, modBackCutOut);
0505
0506
0507 Volume vol_mountingPlate(baseName + "_MountingPlate", MountingPlate, desc.material("Steel235"));
0508 Volume vol_modFrontPlate(baseName + "_FrontPlate", modFrontPlate, desc.material("Steel235"));
0509 Volume vol_modBackPlate(baseName + "_BackPlate", modBackPlate, desc.material("Steel235"));
0510 Volume vol_modSidePlateL(baseName + "_LeftSidePlate", modSidePlateL, desc.material("Steel235"));
0511 Volume vol_modSidePlateR(baseName + "_RightSidePlate", modSidePlateR, desc.material("Steel235"));
0512 Volume vol_modTopPlate(baseName + "_TopPlate", modTopPlate, desc.material("Steel235"));
0513 Volume vol_modBottomPlate(baseName + "_BottomPlate", modBottomPlate, desc.material("Steel235"));
0514
0515 if (allSen) {
0516 sens.setType("calorimeter");
0517 vol_mountingPlate.setSensitiveDetector(sens);
0518 vol_modFrontPlate.setSensitiveDetector(sens);
0519 vol_modBackPlate.setSensitiveDetector(sens);
0520 vol_modSidePlateL.setSensitiveDetector(sens);
0521 vol_modSidePlateR.setSensitiveDetector(sens);
0522 vol_modTopPlate.setSensitiveDetector(sens);
0523 vol_modBottomPlate.setSensitiveDetector(sens);
0524 }
0525
0526 if (renderComp) {
0527 vol_mountingPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0528
0529 "LFHCALLayerTungstenVis");
0530 vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0531
0532 "LFHCALLayerSteelVis");
0533 vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0534
0535 "LFHCALLayerSteelVis");
0536 vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0537 mod_params.mod_visStr);
0538 vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0539 mod_params.mod_visStr);
0540 vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0541
0542 "LFHCALLayerSteelVis");
0543 vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0544
0545 "LFHCALLayerSteelVis");
0546 } else {
0547 vol_mountingPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0548 "InvisibleNoDaughters");
0549 vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0550 "InvisibleNoDaughters");
0551 vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0552 "InvisibleNoDaughters");
0553 vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0554 "InvisibleNoDaughters");
0555 vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0556 "InvisibleNoDaughters");
0557 vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0558 "InvisibleNoDaughters");
0559 vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0560 "InvisibleNoDaughters");
0561 }
0562
0563
0564
0565
0566 Box modPCB(mod_params.mod_pcbThick / 2., mod_params.mod_pcbWidth / 2.,
0567 (mod_params.mod_pcbLength) / 2.);
0568 Volume vol_modPCB(baseName + "_PCB", modPCB, desc.material("Fr4"));
0569 if (renderComp) {
0570 vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "LFHCALModPCB");
0571 } else {
0572 vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0573 "InvisibleNoDaughters");
0574 }
0575
0576 int layer_num = 0;
0577 double slice_z = -length / 2 + mod_params.mod_MPThick +
0578 mod_params.mod_FWThick;
0579
0580 for (int i = 0; i < (int)sl_params.size(); i++) {
0581 slice_z += sl_params[i].slice_offset +
0582 sl_params[i].slice_thick / 2.;
0583 layer_num = sl_params[i].layer_ID;
0584
0585
0586
0587 Material slice_mat = desc.material(sl_params[i].slice_matStr);
0588 if (sl_params[i].slice_partID == 1) {
0589 Volume modAbsAssembly = createAbsorberPlate(
0590 desc, baseName + "_Abs" + _toString(sl_params[i].layer_ID, "_layer_%d"),
0591 mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick,
0592 mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth,
0593 mod_params.mod_notchHeight, slice_mat, sl_params[i].slice_regStr,
0594 sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp);
0595
0596 if (allSen)
0597 modAbsAssembly.setSensitiveDetector(sens);
0598 pvm = vol_mod.placeVolume(modAbsAssembly,
0599 Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z)));
0600 if (allSen)
0601 pvm.addPhysVolID("towerx", 0)
0602 .addPhysVolID("towery", 0)
0603 .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer)
0604 .addPhysVolID("layerz", layer_num)
0605 .addPhysVolID("passive", 1);
0606
0607
0608
0609 } else if (sl_params[i].slice_partID == 2) {
0610 Volume modFillAssembly =
0611 createFillerPlate(desc,
0612 baseName + "_Fill" + _toString(sl_params[i].layer_ID, "_layer_%d") +
0613 _toString(sl_params[i].slice_ID, "slice_%d"),
0614 mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick,
0615 mod_params.mod_SWThick, sl_params[i].slice_thick,
0616 mod_params.mod_notchDepth, slice_mat, sl_params[i].slice_regStr,
0617 sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp);
0618
0619 if (allSen)
0620 modFillAssembly.setSensitiveDetector(sens);
0621 pvm = vol_mod.placeVolume(
0622 modFillAssembly, Transform3D(RotationZYX(0, 0, 0),
0623 Position((mod_params.mod_notchDepth) / 2., 0., slice_z)));
0624 if (allSen)
0625 pvm.addPhysVolID("towerx", 1)
0626 .addPhysVolID("towery", 0)
0627 .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer)
0628 .addPhysVolID("layerz", layer_num)
0629 .addPhysVolID("passive", 1);
0630
0631
0632
0633 } else {
0634 Assembly modScintAssembly = createScintillatorPlateEightM(
0635 desc, baseName + "_ScintAssembly" + _toString(sl_params[i].layer_ID, "_layer_%d"),
0636 layer_num, mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick,
0637 mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth,
0638 mod_params.mod_foilThick, slice_mat, sl_params[i].slice_readoutLayer,
0639 sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, sens,
0640 renderComp);
0641
0642 pvm = vol_mod.placeVolume(
0643 modScintAssembly, Transform3D(RotationZYX(0, 0, 0),
0644 Position((mod_params.mod_notchDepth) / 2., 0, slice_z)));
0645 }
0646 slice_z += sl_params[i].slice_thick / 2.;
0647 }
0648
0649
0650 pvm = vol_mod.placeVolume(vol_mountingPlate,
0651 Position(0, 0, -(length - mod_params.mod_MPThick) / 2.));
0652 pvm = vol_mod.placeVolume(
0653 vol_modFrontPlate,
0654 Position(0, 0, -(length - mod_params.mod_FWThick) / 2. + mod_params.mod_MPThick));
0655 if (allSen)
0656 pvm.addPhysVolID("towerx", 2)
0657 .addPhysVolID("towery", 0)
0658 .addPhysVolID("layerz", 0)
0659 .addPhysVolID("passive", 1);
0660 pvm =
0661 vol_mod.placeVolume(vol_modBackPlate, Position(0, 0, (length - mod_params.mod_BWThick) / 2.));
0662 if (allSen)
0663 pvm.addPhysVolID("towerx", 2)
0664 .addPhysVolID("towery", 0)
0665 .addPhysVolID("layerz", layer_num)
0666 .addPhysVolID("passive", 1);
0667 pvm = vol_mod.placeVolume(
0668 vol_modSidePlateL,
0669 Position(-(mod_params.mod_width - mod_params.mod_SWThick) / 2., 0,
0670 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0671 if (allSen)
0672 pvm.addPhysVolID("towerx", 3)
0673 .addPhysVolID("towery", 0)
0674 .addPhysVolID("layerz", 0)
0675 .addPhysVolID("passive", 1);
0676 pvm = vol_mod.placeVolume(
0677 vol_modSidePlateR,
0678 Position((mod_params.mod_width - mod_params.mod_SWThick) / 2., 0,
0679 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0680 if (allSen)
0681 pvm.addPhysVolID("towerx", 0)
0682 .addPhysVolID("towery", 1)
0683 .addPhysVolID("layerz", 0)
0684 .addPhysVolID("passive", 1);
0685 pvm = vol_mod.placeVolume(
0686 vol_modTopPlate,
0687 Position(0, (mod_params.mod_height - mod_params.mod_TWThick) / 2.,
0688 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0689 if (allSen)
0690 pvm.addPhysVolID("towerx", 1)
0691 .addPhysVolID("towery", 1)
0692 .addPhysVolID("layerz", 0)
0693 .addPhysVolID("passive", 1);
0694 pvm = vol_mod.placeVolume(
0695 vol_modBottomPlate,
0696 Position(0, -(mod_params.mod_height - mod_params.mod_TWThick) / 2.,
0697 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0698 if (allSen)
0699 pvm.addPhysVolID("towerx", 2)
0700 .addPhysVolID("towery", 1)
0701 .addPhysVolID("layerz", 0)
0702 .addPhysVolID("passive", 1);
0703
0704 double lengthA =
0705 length - mod_params.mod_FWThick - mod_params.mod_MPThick + mod_params.mod_BWThick / 2;
0706 double z_offSetPCB =
0707 (mod_params.mod_FWThick + mod_params.mod_MPThick + mod_params.mod_BWThick) / 2 -
0708 (lengthA - mod_params.mod_pcbLength) / 2.;
0709
0710 pvm = vol_mod.placeVolume(
0711 vol_modPCB,
0712 Position(-(mod_params.mod_width - 2 * mod_params.mod_SWThick - mod_params.mod_notchDepth) /
0713 2.,
0714 0, z_offSetPCB));
0715
0716 return vol_mod;
0717 }
0718
0719
0720
0721
0722 Volume createFourMModule(Detector& desc, moduleParamsStrct mod_params,
0723 std::vector<sliceParamsStrct> sl_params,
0724
0725 double length, SensitiveDetector sens, bool renderComp, bool allSen) {
0726
0727 std::string baseName = "LFHCAL_4M";
0728
0729
0730 Box modBox(mod_params.mod_width / 2., mod_params.mod_height / 2., length / 2.);
0731 Volume vol_mod(baseName, modBox, desc.material("Air"));
0732 printout(DEBUG, "LFHCAL_geo", "visualization string module: " + mod_params.mod_visStr);
0733 vol_mod.setVisAttributes(desc.visAttributes(mod_params.mod_visStr.data()));
0734
0735
0736 PlacedVolume pvm;
0737
0738
0739
0740
0741 Box MountingPlate(mod_params.mod_width / 2., mod_params.mod_height / 2.,
0742 mod_params.mod_MPThick / 2.);
0743 Box modFrontPlate(mod_params.mod_width / 2., mod_params.mod_height / 2.,
0744 mod_params.mod_FWThick / 2.);
0745 Box modSidePlateL(
0746 mod_params.mod_SWThick / 2., mod_params.mod_height / 2.,
0747 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0748 Box modSidePlateR(
0749 mod_params.mod_SWThick / 2., mod_params.mod_height / 2.,
0750 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0751 Box modTopPlate(
0752 (mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2.,
0753 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0754 Box modBottomPlate(
0755 (mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2.,
0756 (length - mod_params.mod_MPThick - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.);
0757 Box modBackCutOut(mod_params.mod_BIwidth / 2., mod_params.mod_BIheight / 2.,
0758 mod_params.mod_BWThick / 2.);
0759 Box modBackPlateFull(mod_params.mod_width / 2., mod_params.mod_height / 2.,
0760 mod_params.mod_BWThick / 2.);
0761 SubtractionSolid modBackPlate(modBackPlateFull, modBackCutOut);
0762
0763
0764 Volume vol_mountingPlate(baseName + "_MountingPlate", MountingPlate, desc.material("Steel235"));
0765 Volume vol_modFrontPlate(baseName + "_FrontPlate", modFrontPlate, desc.material("Steel235"));
0766 Volume vol_modBackPlate(baseName + "_BackPlate", modBackPlate, desc.material("Steel235"));
0767 Volume vol_modSidePlateL(baseName + "_LeftSidePlate", modSidePlateL, desc.material("Steel235"));
0768 Volume vol_modSidePlateR(baseName + "_RightSidePlate", modSidePlateR, desc.material("Steel235"));
0769 Volume vol_modTopPlate(baseName + "_TopPlate", modTopPlate, desc.material("Steel235"));
0770 Volume vol_modBottomPlate(baseName + "_BottomPlate", modBottomPlate, desc.material("Steel235"));
0771
0772 if (allSen) {
0773 sens.setType("calorimeter");
0774 vol_mountingPlate.setSensitiveDetector(sens);
0775 vol_modFrontPlate.setSensitiveDetector(sens);
0776 vol_modBackPlate.setSensitiveDetector(sens);
0777 vol_modSidePlateL.setSensitiveDetector(sens);
0778 vol_modSidePlateR.setSensitiveDetector(sens);
0779 vol_modTopPlate.setSensitiveDetector(sens);
0780 vol_modBottomPlate.setSensitiveDetector(sens);
0781 }
0782
0783 if (renderComp) {
0784 vol_mountingPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0785
0786 "LFHCALLayerTungstenVis");
0787 vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0788
0789 "LFHCALLayerSteelVis");
0790 vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0791
0792 "LFHCALLayerSteelVis");
0793 vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0794 mod_params.mod_visStr);
0795 vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0796 mod_params.mod_visStr);
0797 vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0798
0799 "LFHCALLayerSteelVis");
0800 vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0801
0802 "LFHCALLayerSteelVis");
0803 } else {
0804 vol_mountingPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0805 "InvisibleNoDaughters");
0806 vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0807 "InvisibleNoDaughters");
0808 vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0809 "InvisibleNoDaughters");
0810 vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0811 "InvisibleNoDaughters");
0812 vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0813 "InvisibleNoDaughters");
0814 vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0815 "InvisibleNoDaughters");
0816 vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0817 "InvisibleNoDaughters");
0818 }
0819
0820
0821
0822
0823 Box modPCB(mod_params.mod_pcbThick / 2., mod_params.mod_pcbWidth / 2.,
0824 (mod_params.mod_pcbLength) / 2.);
0825 Volume vol_modPCB(baseName + "_PCB", modPCB, desc.material("Fr4"));
0826 if (renderComp) {
0827 vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "LFHCALModPCB");
0828 } else {
0829 vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr,
0830 "InvisibleNoDaughters");
0831 }
0832
0833 int layer_num = 0;
0834 double slice_z = -length / 2 + mod_params.mod_MPThick +
0835 mod_params.mod_FWThick;
0836
0837
0838 for (int i = 0; i < (int)sl_params.size(); i++) {
0839 slice_z += sl_params[i].slice_offset +
0840 sl_params[i].slice_thick / 2.;
0841 layer_num = sl_params[i].layer_ID;
0842
0843
0844
0845 Material slice_mat = desc.material(sl_params[i].slice_matStr);
0846 if (sl_params[i].slice_partID == 1) {
0847 Volume modAbsAssembly = createAbsorberPlate(
0848 desc, baseName + "_Abs" + _toString(sl_params[i].layer_ID, "_layer_%d"),
0849 mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick,
0850 mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth,
0851 mod_params.mod_notchHeight, slice_mat, sl_params[i].slice_regStr,
0852 sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp);
0853
0854 if (allSen)
0855 modAbsAssembly.setSensitiveDetector(sens);
0856 pvm = vol_mod.placeVolume(modAbsAssembly,
0857 Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z)));
0858 if (allSen)
0859 pvm.addPhysVolID("towerx", 0)
0860 .addPhysVolID("towery", 0)
0861 .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer)
0862 .addPhysVolID("layerz", layer_num)
0863 .addPhysVolID("passive", 1);
0864
0865
0866
0867 } else if (sl_params[i].slice_partID == 2) {
0868 Volume modFillAssembly =
0869 createFillerPlate(desc,
0870 baseName + "_Fill" + _toString(sl_params[i].layer_ID, "_layer_%d") +
0871 _toString(sl_params[i].slice_ID, "slice_%d"),
0872 mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick,
0873 mod_params.mod_SWThick, sl_params[i].slice_thick,
0874 mod_params.mod_notchDepth, slice_mat, sl_params[i].slice_regStr,
0875 sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp);
0876
0877 if (allSen)
0878 modFillAssembly.setSensitiveDetector(sens);
0879 pvm = vol_mod.placeVolume(
0880 modFillAssembly, Transform3D(RotationZYX(0, 0, 0),
0881 Position((mod_params.mod_notchDepth) / 2., 0., slice_z)));
0882 if (allSen)
0883 pvm.addPhysVolID("towerx", 1)
0884 .addPhysVolID("towery", 0)
0885 .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer)
0886 .addPhysVolID("layerz", layer_num)
0887 .addPhysVolID("passive", 1);
0888
0889
0890
0891 } else {
0892 Assembly modScintAssembly = createScintillatorPlateFourM(
0893 desc, baseName + "_ScintAssembly" + _toString(sl_params[i].layer_ID, "_layer_%d"),
0894 layer_num, mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick,
0895 mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth,
0896 mod_params.mod_foilThick, slice_mat, sl_params[i].slice_readoutLayer,
0897 sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, sens,
0898 renderComp);
0899
0900 pvm = vol_mod.placeVolume(
0901 modScintAssembly, Transform3D(RotationZYX(0, 0, 0),
0902 Position((mod_params.mod_notchDepth) / 2., 0, slice_z)));
0903 }
0904 slice_z += sl_params[i].slice_thick / 2.;
0905 }
0906
0907
0908 pvm = vol_mod.placeVolume(vol_mountingPlate,
0909 Position(0, 0, -(length - mod_params.mod_MPThick) / 2.));
0910 pvm = vol_mod.placeVolume(
0911 vol_modFrontPlate,
0912 Position(0, 0, -(length - mod_params.mod_FWThick) / 2. + mod_params.mod_MPThick));
0913 if (allSen)
0914 pvm.addPhysVolID("towerx", 2)
0915 .addPhysVolID("towery", 0)
0916 .addPhysVolID("layerz", 0)
0917 .addPhysVolID("passive", 1);
0918 pvm =
0919 vol_mod.placeVolume(vol_modBackPlate, Position(0, 0, (length - mod_params.mod_BWThick) / 2.));
0920 if (allSen)
0921 pvm.addPhysVolID("towerx", 2)
0922 .addPhysVolID("towery", 0)
0923 .addPhysVolID("layerz", layer_num)
0924 .addPhysVolID("passive", 1);
0925 pvm = vol_mod.placeVolume(
0926 vol_modSidePlateL,
0927 Position(-(mod_params.mod_width - mod_params.mod_SWThick) / 2., 0,
0928 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0929 if (allSen)
0930 pvm.addPhysVolID("towerx", 3)
0931 .addPhysVolID("towery", 0)
0932 .addPhysVolID("layerz", 0)
0933 .addPhysVolID("passive", 1);
0934 pvm = vol_mod.placeVolume(
0935 vol_modSidePlateR,
0936 Position((mod_params.mod_width - mod_params.mod_SWThick) / 2., 0,
0937 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0938 if (allSen)
0939 pvm.addPhysVolID("towerx", 0)
0940 .addPhysVolID("towery", 1)
0941 .addPhysVolID("layerz", 0)
0942 .addPhysVolID("passive", 1);
0943 pvm = vol_mod.placeVolume(
0944 vol_modTopPlate,
0945 Position(0, (mod_params.mod_height - mod_params.mod_TWThick) / 2.,
0946 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0947 if (allSen)
0948 pvm.addPhysVolID("towerx", 1)
0949 .addPhysVolID("towery", 1)
0950 .addPhysVolID("layerz", 0)
0951 .addPhysVolID("passive", 1);
0952 pvm = vol_mod.placeVolume(
0953 vol_modBottomPlate,
0954 Position(0, -(mod_params.mod_height - mod_params.mod_TWThick) / 2.,
0955 (mod_params.mod_FWThick + mod_params.mod_MPThick - mod_params.mod_BWThick) / 2));
0956 if (allSen)
0957 pvm.addPhysVolID("towerx", 2)
0958 .addPhysVolID("towery", 1)
0959 .addPhysVolID("layerz", 0)
0960 .addPhysVolID("passive", 1);
0961
0962 double lengthA =
0963 length - mod_params.mod_FWThick - mod_params.mod_MPThick + mod_params.mod_BWThick / 2;
0964 double z_offSetPCB =
0965 (mod_params.mod_FWThick + mod_params.mod_MPThick + mod_params.mod_BWThick) / 2 -
0966 (lengthA - mod_params.mod_pcbLength) / 2.;
0967
0968 pvm = vol_mod.placeVolume(
0969 vol_modPCB,
0970 Position(-(mod_params.mod_width - 2 * mod_params.mod_SWThick - mod_params.mod_notchDepth) /
0971 2.,
0972 0, z_offSetPCB));
0973 return vol_mod;
0974 }
0975
0976
0977
0978
0979
0980
0981
0982 static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) {
0983
0984 xml_det_t detElem = handle;
0985 std::string detName = detElem.nameStr();
0986 int detID = detElem.id();
0987
0988
0989 xml_dim_t dim = detElem.dimensions();
0990 double length = dim.z();
0991
0992
0993 xml_dim_t pos = detElem.position();
0994 printout(DEBUG, "LFHCAL_geo",
0995 "global LFHCal position " + _toString(pos.x()) + "\t" + _toString(pos.y()) + "\t" +
0996 _toString(pos.z()));
0997
0998
0999 xml_comp_t x_env = detElem.child(_Unicode(envelope));
1000 Tube rmaxtube(0, dim.rmax(), dim.z() / 2);
1001 Box beampipe(dim.x() / 2, dim.y() / 2, dim.z() / 2);
1002 Solid env = SubtractionSolid(rmaxtube, beampipe, Position(dim.x0(), 0, 0));
1003 Volume env_vol(detName + "_env", env, desc.material(x_env.materialStr()));
1004
1005 bool renderComponents = getAttrOrDefault(detElem, _Unicode(renderComponents), 0.);
1006 bool allSensitive = getAttrOrDefault(detElem, _Unicode(allSensitive), 0.);
1007 if (renderComponents) {
1008 printout(DEBUG, "LFHCAL_geo", "enabled visualization");
1009 } else {
1010 printout(DEBUG, "LFHCAL_geo", "switchted off visualization");
1011 }
1012
1013
1014 xml_comp_t eightM_xml = detElem.child(_Unicode(eightmodule));
1015 xml_dim_t eightMmod_dim = eightM_xml.dimensions();
1016 moduleParamsStrct eightM_params(
1017 getAttrOrDefault(eightMmod_dim, _Unicode(widthBackInner), 0.),
1018 getAttrOrDefault(eightMmod_dim, _Unicode(heightBackInner), 0.),
1019 getAttrOrDefault(eightMmod_dim, _Unicode(widthSideWall), 0.),
1020 getAttrOrDefault(eightMmod_dim, _Unicode(widthTopWall), 0.),
1021 getAttrOrDefault(eightMmod_dim, _Unicode(thicknessMountingPlate), 0.),
1022 getAttrOrDefault(eightMmod_dim, _Unicode(thicknessFrontWall), 0.),
1023 getAttrOrDefault(eightMmod_dim, _Unicode(thicknessBackWall), 0.),
1024 getAttrOrDefault(eightMmod_dim, _Unicode(width), 0.),
1025 getAttrOrDefault(eightMmod_dim, _Unicode(height), 0.),
1026 getAttrOrDefault(eightMmod_dim, _Unicode(notchDepth), 0.),
1027 getAttrOrDefault(eightMmod_dim, _Unicode(notchHeight), 0.),
1028 getAttrOrDefault(eightMmod_dim, _Unicode(foilThick), 0.),
1029 getAttrOrDefault(eightMmod_dim, _Unicode(pcbLength), 0.),
1030 getAttrOrDefault(eightMmod_dim, _Unicode(pcbThick), 0.),
1031 getAttrOrDefault(eightMmod_dim, _Unicode(pcbWidth), 0.), eightM_xml.visStr(),
1032 eightM_xml.regionStr(), eightM_xml.limitsStr());
1033
1034
1035 xml_comp_t fourM_xml = detElem.child(_Unicode(fourmodule));
1036 xml_dim_t fourMmod_dim = fourM_xml.dimensions();
1037 moduleParamsStrct fourM_params(
1038 getAttrOrDefault(fourMmod_dim, _Unicode(widthBackInner), 0.),
1039 getAttrOrDefault(fourMmod_dim, _Unicode(heightBackInner), 0.),
1040 getAttrOrDefault(fourMmod_dim, _Unicode(widthSideWall), 0.),
1041 getAttrOrDefault(fourMmod_dim, _Unicode(widthTopWall), 0.),
1042 getAttrOrDefault(fourMmod_dim, _Unicode(thicknessMountingPlate), 0.),
1043 getAttrOrDefault(fourMmod_dim, _Unicode(thicknessFrontWall), 0.),
1044 getAttrOrDefault(fourMmod_dim, _Unicode(thicknessBackWall), 0.),
1045 getAttrOrDefault(fourMmod_dim, _Unicode(width), 0.),
1046 getAttrOrDefault(fourMmod_dim, _Unicode(height), 0.),
1047 getAttrOrDefault(fourMmod_dim, _Unicode(notchDepth), 0.),
1048 getAttrOrDefault(fourMmod_dim, _Unicode(notchHeight), 0.),
1049 getAttrOrDefault(fourMmod_dim, _Unicode(foilThick), 0.),
1050 getAttrOrDefault(fourMmod_dim, _Unicode(pcbLength), 0.),
1051 getAttrOrDefault(fourMmod_dim, _Unicode(pcbThick), 0.),
1052 getAttrOrDefault(fourMmod_dim, _Unicode(pcbWidth), 0.), fourM_xml.visStr(),
1053 fourM_xml.regionStr(), fourM_xml.limitsStr());
1054
1055 std::vector<sliceParamsStrct> slice_Params;
1056 int layer_num = 0;
1057 int readLayerC = 0;
1058 for (xml_coll_t c(detElem, _U(layer)); c; ++c) {
1059 xml_comp_t x_layer = c;
1060 int repeat = x_layer.repeat();
1061 int readlayer = getAttrOrDefault(x_layer, _Unicode(readoutlayer), 0.);
1062 if (readLayerC != readlayer) {
1063 readLayerC = readlayer;
1064 layer_num = 0;
1065 }
1066
1067 for (int i = 0; i < repeat; i++) {
1068 int slice_num = 0;
1069
1070
1071 for (xml_coll_t l(x_layer, _U(slice)); l; ++l) {
1072 xml_comp_t x_slice = l;
1073 sliceParamsStrct slice_param(layer_num, slice_num, getAttrOrDefault(l, _Unicode(type), 0.),
1074 x_slice.thickness(), getAttrOrDefault(l, _Unicode(offset), 0.),
1075 readlayer, x_slice.materialStr(), x_slice.visStr(),
1076 x_slice.regionStr(), x_slice.limitsStr());
1077 slice_Params.push_back(slice_param);
1078 ++slice_num;
1079 }
1080 layer_num++;
1081 }
1082 }
1083
1084
1085 DetElement det(detName, detID);
1086 Assembly assembly(detName);
1087 PlacedVolume phv;
1088
1089 int moduleIDx = -1;
1090 int moduleIDy = -1;
1091
1092 struct position {
1093 double x, y, z;
1094 };
1095
1096 std::vector<position> pos8M;
1097
1098 xml_coll_t eightMPos(detElem, _Unicode(eightmodulepositions));
1099 for (xml_coll_t position_i(eightMPos, _U(position)); position_i; ++position_i) {
1100 xml_comp_t position_comp = position_i;
1101 if (!getAttrOrDefault(position_comp, _Unicode(if), true)) {
1102 printout(DEBUG, "LFHCAL_geo", "skipping x = %.1f cm, y = %.1f cm", position_comp.x(),
1103 position_comp.y());
1104 continue;
1105 }
1106 pos8M.push_back({position_comp.x(), position_comp.y(), position_comp.z()});
1107 }
1108
1109
1110 Volume eightMassembly = createEightMModule(desc, eightM_params, slice_Params, length, sens,
1111 renderComponents, allSensitive);
1112 for (int e = 0; e < (int)pos8M.size(); e++) {
1113 if (e % 20 == 0)
1114 printout(DEBUG, "LFHCAL_geo",
1115 "LFHCAL placing 8M module: " + _toString(e) + "/" + _toString((int)pos8M.size()) +
1116 "\t" + _toString(pos8M[e].x) + "\t" + _toString(pos8M[e].y) + "\t" +
1117 _toString(pos8M[e].z));
1118 if (moduleIDx < 0 || moduleIDy < 0) {
1119 printout(DEBUG, "LFHCAL_geo",
1120 "LFHCAL WRONG ID FOR 8M module: " + _toString(e) + "/" +
1121 _toString((int)pos8M.size()) + "\t" + _toString(moduleIDx) + "\t" +
1122 _toString(moduleIDy));
1123 }
1124 moduleIDx = ((pos8M[e].x + 270) / 10);
1125 moduleIDy = ((pos8M[e].y + 265) / 10);
1126
1127
1128 auto tr8M = Transform3D(Position(-pos8M[e].x, -pos8M[e].y, pos8M[e].z));
1129 phv = assembly.placeVolume(eightMassembly, tr8M);
1130 phv.addPhysVolID("moduleIDx", moduleIDx)
1131 .addPhysVolID("moduleIDy", moduleIDy)
1132 .addPhysVolID("moduletype", 0);
1133 }
1134
1135 std::vector<position> pos4M;
1136
1137 xml_coll_t fourMPos(detElem, _Unicode(fourmodulepositions));
1138 for (xml_coll_t position_i(fourMPos, _U(position)); position_i; ++position_i) {
1139 xml_comp_t position_comp = position_i;
1140 if (!getAttrOrDefault(position_comp, _Unicode(if), true)) {
1141 printout(DEBUG, "LFHCAL_geo", "skipping x = %.1f cm, y = %.1f cm", position_comp.x(),
1142 position_comp.y());
1143 continue;
1144 }
1145 pos4M.push_back({position_comp.x(), position_comp.y(), position_comp.z()});
1146 }
1147
1148
1149 Volume fourMassembly = createFourMModule(desc, fourM_params, slice_Params, length, sens,
1150 renderComponents, allSensitive);
1151 for (int f = 0; f < (int)pos4M.size(); f++) {
1152 if (f % 20 == 0)
1153 printout(DEBUG, "LFHCAL_geo",
1154 "LFHCAL placing 4M module: " + _toString(f) + "/" + _toString((int)pos4M.size()) +
1155 "\t" + _toString(pos4M[f].x) + "\t" + _toString(pos4M[f].y) + "\t" +
1156 _toString(pos4M[f].z));
1157
1158 moduleIDx = ((pos4M[f].x + 265) / 10);
1159 moduleIDy = ((pos4M[f].y + 265) / 10);
1160 if (moduleIDx < 0 || moduleIDy < 0) {
1161 printout(DEBUG, "LFHCAL_geo",
1162 "LFHCAL WRONG ID FOR 4M module: " + _toString(f) + "/" +
1163 _toString((int)pos4M.size()) + "\t" + _toString(moduleIDx) + "\t" +
1164 _toString(moduleIDy));
1165 }
1166 auto tr4M = Transform3D(Position(-pos4M[f].x, -pos4M[f].y, pos4M[f].z));
1167 phv = assembly.placeVolume(fourMassembly, tr4M);
1168 phv.addPhysVolID("moduleIDx", moduleIDx)
1169 .addPhysVolID("moduleIDy", moduleIDy)
1170 .addPhysVolID("moduletype", 1);
1171 }
1172
1173 Volume motherVol = desc.pickMotherVolume(det);
1174 phv = env_vol.placeVolume(assembly);
1175 phv = motherVol.placeVolume(env_vol,
1176 Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.)));
1177 phv.addPhysVolID("system", detID);
1178 det.setPlacement(phv);
1179
1180 return det;
1181 }
1182 DECLARE_DETELEMENT(epic_LFHCAL, createDetector)