File indexing completed on 2024-11-15 08:59:18
0001 #include "DD4hep/DetFactoryHelper.h"
0002 #include "DD4hep/OpticalSurfaces.h"
0003 #include "DD4hep/Printout.h"
0004 #include "DDRec/DetectorData.h"
0005 #include "DDRec/Surface.h"
0006 #include <XML/Helper.h>
0007
0008
0009
0010
0011
0012 using namespace std;
0013 using namespace dd4hep;
0014
0015
0016
0017
0018 dd4hep::Trap MakeTrap( const std::string& pName, double pZ, double pY, double pX, double pLTX );
0019
0020 static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens)
0021 {
0022 xml_det_t xml_det = e;
0023 string det_name = xml_det.nameStr();
0024 int det_id = xml_det.id();
0025
0026
0027 xml_dim_t dirc_dim = xml_det.dimensions();
0028 xml_dim_t dirc_pos = xml_det.position();
0029 xml_dim_t dirc_rot = xml_det.rotation();
0030 double det_rin = dirc_dim.rmin();
0031 double det_rout = dirc_dim.rmax();
0032 double SizeZ = dirc_dim.length();
0033
0034
0035
0036
0037
0038 xml_comp_t xml_box_module = xml_det.child(_U(module));
0039
0040 Material Vacuum = desc.material("Vacuum");
0041 Material air = desc.material("AirOptical");
0042 Material quartz = desc.material("Quartz");
0043 Material epotek = desc.material("Epotek");
0044 Material nlak33a = desc.material("Nlak33a");
0045 auto& bar_material = quartz;
0046 auto mirror_material = desc.material("Aluminum");
0047
0048 Tube det_geo(det_rin, det_rout, SizeZ / 2., 0., 360.0 * deg);
0049
0050 Assembly det_volume("DIRC");
0051 det_volume.setVisAttributes(desc.visAttributes(xml_det.visStr()));
0052
0053 DetElement det(det_name, det_id);
0054 Volume mother_vol = desc.pickMotherVolume(det);
0055
0056 Transform3D tr(RotationZYX(0, dirc_rot.theta(), 0.0), Position(0.0, 0.0, dirc_pos.z()));
0057 PlacedVolume det_plvol = mother_vol.placeVolume(det_volume, tr);
0058
0059 det_plvol.addPhysVolID("system", det_id);
0060 det.setPlacement(det_plvol);
0061
0062
0063
0064 int fLensId = 6;
0065
0066
0067
0068
0069
0070
0071 int fGeomType = 0;
0072 int fRunType = 0;
0073
0074
0075 double fPrizm[4];
0076 fPrizm[0] = 360 * mm;
0077 fPrizm[1] = 300 * mm;
0078 fPrizm[3] = 50 * mm;
0079 fPrizm[2] = fPrizm[3] + 300 * tan(32 * deg) * mm;
0080 double fBarsGap = 0.15 * mm;
0081
0082 std::cout << "DIRC: fPrizm[2] " << fPrizm[2] << std::endl;
0083
0084 double fdTilt = 80 * deg;
0085 double fPrizmT[6];
0086 fPrizmT[0] = 390 * mm;
0087 fPrizmT[1] = (400 - 290 * cos(fdTilt)) * mm;
0088 fPrizmT[2] = 290 * sin(fdTilt) * mm;
0089 fPrizmT[3] = 50 * mm;
0090 fPrizmT[4] = 290 * mm;
0091 fPrizmT[5] = 290 * cos(fdTilt)* mm;
0092
0093 double fMirror[3];
0094 fMirror[0] = 20 * mm;
0095 fMirror[1] = fPrizm[0];
0096 fMirror[2] = 1 * mm;
0097
0098
0099
0100
0101
0102
0103
0104 double fMcpTotal[3];
0105 double fMcpActive[3];
0106 fMcpTotal[0] = fMcpTotal[1] = 53 + 4;
0107 fMcpTotal[2] = 1*mm;
0108 fMcpActive[0] = fMcpActive[1] = 53;
0109 fMcpActive[2] = 1*mm;
0110
0111 double fLens[4];
0112 fLens[0] = fLens[1] = 40 * mm;
0113 fLens[2] = 10 * mm;
0114 double fRadius = (det_rin + det_rout)/2;
0115
0116 double fBoxWidth = fPrizm[0];
0117
0118 double fFd[3];
0119 fFd[0] = fBoxWidth;
0120 fFd[1] = fPrizm[2];
0121 fFd[2] = 1 * mm;
0122
0123 fLens[0] = fPrizm[3];
0124 fLens[1] = fPrizm[0];
0125 fLens[2] = 12 * mm;
0126
0127
0128 const int fNBoxes = xml_box_module.repeat();
0129 const double box_width = xml_box_module.width();
0130 const double box_height = xml_box_module.height();
0131 const double box_length = xml_box_module.length() + 550*mm;
0132
0133
0134
0135 Assembly dirc_module("DIRCModule");
0136
0137
0138 dirc_module.setVisAttributes(desc.visAttributes(xml_box_module.visStr()));
0139
0140
0141
0142 xml_comp_t xml_fd = xml_box_module.child(_Unicode(fd));
0143 Box gFd("gFd", xml_fd.height()/2, xml_fd.width()/2, xml_fd.thickness()/2);
0144 Volume lFd ("lFd", gFd, desc.material(xml_fd.materialStr()));
0145 lFd.setVisAttributes(desc.visAttributes(xml_fd.visStr()));
0146
0147
0148
0149
0150 xml_comp_t xml_bar = xml_box_module.child(_Unicode(bar));
0151 double bar_height = xml_bar.height();
0152 double bar_width = xml_bar.width();
0153 double bar_length = xml_bar.length();
0154 Box gBar("gBar", bar_height/2, bar_width/2, bar_length/2);
0155 Volume lBar("lBar", gBar, desc.material(xml_bar.materialStr()));
0156 lBar.setVisAttributes(desc.visAttributes(xml_bar.visStr()));
0157
0158
0159 xml_comp_t xml_glue = xml_box_module.child(_Unicode(glue));
0160 double glue_thickness = xml_glue.thickness();
0161 Box gGlue("gGlue", bar_height/2, bar_width/2, glue_thickness/2);
0162 Volume lGlue("lGlue", gGlue, desc.material(xml_glue.materialStr()));
0163 lGlue.setVisAttributes(desc.visAttributes(xml_glue.visStr()));
0164
0165 sens.setType("tracker");
0166 lBar.setSensitiveDetector(sens);
0167
0168 int bars_repeat_z = 4;
0169 double bar_assm_length = (bar_length + glue_thickness) * bars_repeat_z;
0170 int fNBar = xml_bar.repeat();
0171 double bar_gap = xml_bar.gap();
0172 for (int y_index = 0; y_index < fNBar; y_index++) {
0173 double shift_y = y_index * (bar_width + bar_gap) - 0.5 * box_width + 0.5 * bar_width;
0174 for (int z_index = 0; z_index < bars_repeat_z; z_index++) {
0175 double z = -0.5 * bar_assm_length + 0.5 * bar_length + (bar_length + glue_thickness) * z_index;
0176 auto placed_bar = dirc_module.placeVolume(lBar, Position(0, shift_y, z));
0177 dirc_module.placeVolume(lGlue, Position(0, shift_y, z + 0.5 * (bar_length + glue_thickness)));
0178 placed_bar.addPhysVolID("section", z_index);
0179 placed_bar.addPhysVolID("bar", y_index);
0180 }
0181 }
0182
0183
0184
0185 xml_comp_t xml_mirror = xml_box_module.child(_Unicode(mirror));
0186 Box gMirror("gMirror", xml_mirror.height()/2, xml_mirror.width()/2, xml_mirror.thickness()/2);
0187 Volume lMirror("lMirror", gMirror, desc.material(xml_mirror.materialStr()));
0188 dirc_module.placeVolume(lMirror, Position(0, 0, -0.5 * (bar_assm_length - xml_mirror.thickness())));
0189 lMirror.setVisAttributes(desc.visAttributes(xml_mirror.visStr()));
0190
0191
0192 OpticalSurfaceManager surfMgr = desc.surfaceManager();
0193 auto surf = surfMgr.opticalSurface("MirrorOpticalSurface");
0194 SkinSurface skin(desc, det, Form("dirc_mirror_optical_surface"), surf, lMirror);
0195 skin.isValid();
0196
0197
0198
0199 Volume lLens1;
0200 Volume lLens2;
0201 Volume lLens3;
0202
0203 double lensMinThikness = 2.0 * mm;
0204 double layer12 = lensMinThikness * 2;
0205
0206
0207
0208
0209 double r1 = 33 * mm;
0210 double r2 = 24 * mm;
0211 double shight = 25 * mm;
0212
0213 Position zTrans1(0, 0, -r1 - fLens[2] / 2. + r1 - sqrt(r1 * r1 - shight / 2. * shight / 2.) + lensMinThikness);
0214 Position zTrans2(0, 0, -r2 - fLens[2] / 2. + r2 - sqrt(r2 * r2 - shight / 2. * shight / 2.) + layer12);
0215
0216 Box gfbox("fbox", 0.5 * fLens[0], 0.5 * fLens[1], 0.5 * fLens[2]);
0217 Box gcbox("cbox", 0.5 * fLens[0], 0.5 * fLens[1] + 1*mm, 0.5 * fLens[2]);
0218
0219
0220
0221
0222
0223
0224
0225
0226 Position tTrans1(0.5 * (fLens[0] + shight), 0, -fLens[2] + layer12);
0227 Position tTrans0(-0.5 * (fLens[0] + shight), 0, -fLens[2] + layer12);
0228 SubtractionSolid tubox("tubox", gfbox, gcbox, tTrans1);
0229 SubtractionSolid gubox("gubox", tubox, gcbox, tTrans0);
0230
0231
0232
0233
0234
0235
0236
0237 Tube gcylinder1("Cylinder1", 0, r1, 0.5 * fLens[1], 0 * deg, 360 * deg);
0238 Tube gcylinder2("Cylinder2", 0, r2, 0.5 * fLens[1] - 0.5*mm, 0 * deg, 360 * deg);
0239 Tube gcylinder1c("Cylinder1c", 0, r1, 0.5 * fLens[1] + 0.5*mm, 0 * deg, 360 * deg);
0240 Tube gcylinder2c("Cylinder2c", 0, r2, 0.5 * fLens[1] + 0.5*mm, 0 * deg, 360 * deg);
0241 RotationX xRot(-M_PI / 2.);
0242
0243 IntersectionSolid gLens1("Lens1", gubox, gcylinder1, Transform3D(xRot, zTrans1));
0244 SubtractionSolid gLenst("temp", gubox, gcylinder1c, Transform3D(xRot, zTrans1));
0245
0246
0247
0248
0249
0250
0251
0252 IntersectionSolid gLens2("Lens2", gLenst, gcylinder2, Transform3D(xRot, zTrans2));
0253 SubtractionSolid gLens3("Lens3", gLenst, gcylinder2c, Transform3D(xRot, zTrans2));
0254
0255 lLens1 = Volume("lLens1", gLens1, bar_material);
0256 lLens2 = Volume("lLens2", gLens2, nlak33a);
0257 lLens3 = Volume("lLens3", gLens3, bar_material);
0258
0259 lLens1.setVisAttributes(desc.visAttributes("DIRCLens1"));
0260 lLens2.setVisAttributes(desc.visAttributes("DIRCLens2"));
0261 lLens3.setVisAttributes(desc.visAttributes("DIRCLens3"));
0262
0263
0264 double shifth = 0.5 * (bar_assm_length + fLens[2]);
0265
0266
0267 lLens1.setVisAttributes(desc.visAttributes("AnlTeal"));
0268 dirc_module.placeVolume(lLens1, Position(0, 0, shifth));
0269 dirc_module.placeVolume(lLens2, Position(0, 0, shifth));
0270 dirc_module.placeVolume(lLens3, Position(0, 0, shifth));
0271
0272
0273 Trap gPrizm = MakeTrap("gPrizm", fPrizm[0], fPrizm[1], fPrizm[2], fPrizm[3]);
0274 Volume lPrizm("lPrizm", gPrizm, bar_material);
0275 lPrizm.setVisAttributes(desc.visAttributes("DIRCPrism"));
0276
0277
0278
0279 double evshiftz = 0.5 * bar_assm_length + fPrizm[1] + fMcpActive[2] / 2. + fLens[2];
0280 double evshiftx = -3*mm;
0281
0282 double prism_shift_x = (fPrizm[2] + fPrizm[3]) / 4. - 0.5 * fPrizm[3] + 1.5*mm;
0283 double prism_shift_z = 0.5 * (bar_assm_length + fPrizm[1]) + fLens[2];
0284
0285 Position fPrismShift(prism_shift_x, 0, prism_shift_z);
0286 dirc_module.placeVolume(lPrizm, Transform3D(xRot, fPrismShift));
0287 dirc_module.placeVolume(lFd, Position(0.5 * fFd[1] - 0.5 * fPrizm[3] - evshiftx, 0, evshiftz));
0288
0289 double dphi = 2 * M_PI / (double)fNBoxes;
0290 for (int i = 0; i < fNBoxes; i++) {
0291 double phi = dphi * i;
0292 double dx = -fRadius * cos(phi);
0293 double dy = -fRadius * sin(phi);
0294
0295
0296
0297 Transform3D tr(RotationZ(phi+M_PI), Position(dx, dy, 0));
0298 PlacedVolume box_placement = det_volume.placeVolume(dirc_module, tr);
0299 box_placement.addPhysVolID("module", i);
0300
0301
0302
0303
0304
0305 }
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335 return det;
0336 }
0337
0338 DECLARE_DETELEMENT(cb_DIRC, createDetector)
0339
0340 dd4hep::Trap MakeTrap( const std::string& pName, double pZ, double pY, double pX, double pLTX )
0341 {
0342
0343
0344
0345
0346 double fDz = 0.5*pZ;
0347 double fTthetaCphi = 0;
0348 double fTthetaSphi = 0;
0349 double fDy1 = 0.5*pY;
0350 double fDx1 = 0.5*pX;
0351 double fDx2 = 0.5*pLTX;
0352 double fTalpha1 = 0.5*(pLTX - pX)/pY;
0353 double fDy2 = fDy1;
0354 double fDx3 = fDx1;
0355 double fDx4 = fDx2;
0356 double fTalpha2 = fTalpha1;
0357
0358 return Trap(pName, fDz, fTthetaCphi, fTthetaSphi,
0359 fDy1, fDx1, fDx2, fTalpha1,
0360 fDy2, fDx3, fDx4, fTalpha2);
0361 }
0362