9 #include <arich/geometry/GeoARICHCreator.h>
10 #include <arich/dbobjects/tessellatedSolidStr.h>
12 #include <geometry/Materials.h>
13 #include <geometry/CreatorFactory.h>
14 #include <geometry/utilities.h>
15 #include <framework/gearbox/Unit.h>
16 #include <framework/logging/Logger.h>
17 #include <arich/simulation/SensitiveDetector.h>
18 #include <arich/simulation/SensitiveAero.h>
19 #include <simulation/background/BkgSensitiveDetector.h>
20 #include <arich/dbobjects/ARICHPositionElement.h>
23 #include <boost/format.hpp>
24 #include <boost/foreach.hpp>
25 #include <boost/algorithm/string.hpp>
28 #include <G4LogicalVolume.hh>
29 #include <G4PVPlacement.hh>
30 #include <G4AssemblyVolume.hh>
31 #include <G4UnionSolid.hh>
32 #include <G4LogicalSkinSurface.hh>
33 #include <G4OpticalSurface.hh>
40 #include <G4TessellatedSolid.hh>
41 #include <G4TriangularFacet.hh>
43 #include <G4SubtractionSolid.hh>
44 #include <G4Region.hh>
45 #include <G4Material.hh>
49 using namespace boost;
50 using namespace CLHEP;
58 using namespace geometry;
66 geometry::CreatorFactory<GeoARICHCreator> GeoARICHFactory(
"ARICHCreator");
72 GeoARICHCreator::GeoARICHCreator(): m_isBeamBkgStudy(0)
82 G4LogicalSkinSurface::CleanSurfaceTable();
103 if (!material) { B2FATAL(
"Material ARICH_Air required for ARICH master volume could not be found");}
105 B2WARNING(
"Material ARICH_Air required by ARICH master volume has no specified refractive index. Continuing, but no photons in ARICH will be propagated.");
108 G4LogicalVolume* masterLV =
new G4LogicalVolume(envelopeTube, material,
"ARICH.masterVolume");
112 G4Region* aRegion =
new G4Region(
"ARICHEnvelope");
113 masterLV->SetRegion(aRegion);
114 aRegion->AddRootLogicalVolume(masterLV);
116 G4RotationMatrix rotMaster;
124 if (
m_config.useGlobalDisplacement()) {
131 B2WARNING(
"ARICH global displacement parameters from DB will be taken into account.");
133 rotMaster.rotateX(rot_x);
134 rotMaster.rotateY(rot_y);
135 rotMaster.rotateZ(rot_z);
137 G4ThreeVector transMaster(tr_x, tr_y, tr_z);
139 new G4PVPlacement(G4Transform3D(rotMaster, transMaster), masterLV,
"ARICH.MasterVolume", &topVolume,
false, 1);
160 G4LogicalVolume* aeroPlaneLV;
164 B2INFO(
"GeoARICHCreator: using simple cosmic test geometry.");
168 G4RotationMatrix rotDetPlane;
176 G4RotationMatrix rotMergerPlane;
177 rotMergerPlane.rotateX(0.0);
178 rotMergerPlane.rotateY(0.0);
179 rotMergerPlane.rotateZ(0.0);
184 G4RotationMatrix rotCablesPlane;
185 rotCablesPlane.rotateX(0.0);
186 rotCablesPlane.rotateY(0.0);
187 rotCablesPlane.rotateZ(0.0);
189 G4RotationMatrix rotCoolingPlane;
190 rotCoolingPlane.rotateX(0.0);
191 rotCoolingPlane.rotateY(0.0);
192 rotCoolingPlane.rotateZ(0.0);
194 G4RotationMatrix rotAeroPlane;
222 new G4PVPlacement(G4Transform3D(rotDetPlane, transDetPlane), detPlaneLV,
"ARICH.detPlane", masterLV,
false, 1);
223 new G4PVPlacement(G4Transform3D(rotDetPlane, transDetSupportPlate), detSupportPlateLV,
"ARICH.detSupportPlane", masterLV,
false, 1);
224 if (mergerLV)
new G4PVPlacement(G4Transform3D(rotMergerPlane, transMergerPlate), mergerLV,
"ARICH.mergerPlane", masterLV,
false, 1);
225 new G4PVPlacement(G4Transform3D(rotCablesPlane, transCablesPlate), cablesLV,
"ARICH.cablesPlane", masterLV,
false, 1);
227 new G4PVPlacement(G4Transform3D(rotAeroPlane, transAeroPlane), aeroPlaneLV,
"ARICH.aeroPlane", masterLV,
false, 1);
254 double angl = mirStart;
255 double dphi = 2 * M_PI / nMirrors;
256 if (
m_config.useMirrorDisplacement()) B2WARNING(
"ARICH mirrors displacement parameters from DB will be used.");
257 for (
int i = 1; i < nMirrors + 1; i++) {
260 double mrot_z = angl;
261 double mtr_x = mirRad * cos(angl);
262 double mtr_y = mirRad * sin(angl);
263 double mtr_z = mirZPos + zShift;
264 if (
m_config.useMirrorDisplacement()) {
266 mrot_x += displ.getAlpha();
267 mrot_y += displ.getBeta();
268 mrot_z += displ.getGamma();
269 mtr_x += displ.getX();
270 mtr_y += displ.getY();
271 mtr_z += displ.getZ();
273 G4RotationMatrix rotMirror;
274 rotMirror.rotateX(mrot_x);
275 rotMirror.rotateY(mrot_y);
276 rotMirror.rotateZ(mrot_z);
277 G4ThreeVector transMirror(mtr_x, mtr_y, mtr_z);
278 new G4PVPlacement(G4Transform3D(rotMirror, transMirror), mirrorLV,
"ARICH.mirrorPlate", masterLV,
false, i);
285 std::vector<G4LogicalVolume*> shieldLV(2);
286 std::vector<double> shieldZ(2);
288 for (
int i = 0; i < nTubes; i++) {
293 if (supportPar.
getTubeName(i) ==
"ARICH.NeutronShield1") {
294 shieldLV[0] =
new G4LogicalVolume(tube, tubeMaterial, supportPar.
getTubeName(i));
297 }
else if (supportPar.
getTubeName(i) ==
"ARICH.NeutronShield2") {
298 shieldLV[1] =
new G4LogicalVolume(tube, tubeMaterial, supportPar.
getTubeName(i));
303 G4LogicalVolume* tubeLV =
new G4LogicalVolume(tube, tubeMaterial, supportPar.
getTubeName(i));
305 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0,
310 const std::vector<double> wedge1 = supportPar.
getWedge(1);
311 const std::vector<double> wedge2 = supportPar.
getWedge(2);
314 G4AssemblyVolume* assemblyWedge1 =
new G4AssemblyVolume();
315 G4AssemblyVolume* assemblyWedge2 =
new G4AssemblyVolume();
316 makeJoint(wedge1Material, wedge1, assemblyWedge1);
317 makeJoint(wedge2Material, wedge2, assemblyWedge2);
321 for (
int i = 0; i < nWedge; i++) {
328 G4ThreeVector Tb(r * cos(phi), r * sin(phi), z);
333 Tr = G4Transform3D(Rx, Tb);
334 if (wgtype == 1) assemblyWedge1->MakeImprint(shieldLV[0], Tr);
335 else if (wgtype == 2) assemblyWedge2->MakeImprint(shieldLV[0], Tr);
339 Tr = G4Transform3D(Rx, Tb);
340 if (wgtype == 1) assemblyWedge1->MakeImprint(masterLV, Tr);
341 else if (wgtype == 2) assemblyWedge2->MakeImprint(masterLV, Tr);
342 else B2ERROR(
"GeoARICHCreator: invalid support wedge type!");
347 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0, shieldZ[0])), shieldLV[0],
"ARICH.NeutronShield1", masterLV,
350 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0, shieldZ[1])), shieldLV[1],
"ARICH.NeutronShield2", masterLV,
414 for (
int i = 0; i < nBoxes; i++) {
416 G4Box* scintBox =
new G4Box(
"scintBox", box.size[0] * 10. / 2., box.size[1] * 10. / 2., box.size[2] * 10. / 2.);
418 G4LogicalVolume* scintLV =
new G4LogicalVolume(scintBox, scintMaterial, box.name);
420 G4RotationMatrix rotScint;
421 rotScint.rotateX(box.rotation[0]);
422 rotScint.rotateY(box.rotation[1]);
423 rotScint.rotateZ(box.rotation[2]);
424 TVector3 transScintTV(box.position[0], box.position[1], box.position[2]);
426 B2INFO(
"GeoARICHCreator: Scintilator " << box.name <<
" placed at global: " << transScintTV.X() <<
" " << transScintTV.Y() <<
" " <<
428 G4ThreeVector transScint(box.position[0] * 10., box.position[1] * 10., box.position[2] * 10.);
429 new G4PVPlacement(G4Transform3D(rotScint, transScint), scintLV,
"scintilator", masterLV,
false, 1);
435 delete assemblyWedge1;
436 delete assemblyWedge2;
460 G4Tubs* aerogelTube =
new G4Tubs(
"aerogelTube", rin, rout, (thick + wallHeight) / 2., 0, 2 * M_PI);
461 G4LogicalVolume* aerogelPlaneLV =
new G4LogicalVolume(aerogelTube, gapMaterial,
"ARICH.AaerogelPlane");
464 G4Tubs* supportTube =
new G4Tubs(
"aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
465 G4LogicalVolume* supportTubeLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.AerogelSupportPlate");
472 for (
unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
474 std::stringstream tileName;
475 tileName <<
"aerogelTile_" << iLayer;
477 G4Box* tileShape =
new G4Box(tileName.str(), params[0] * 10. / 2., params[1] * 10. / 2., layerThick / 2.);
481 G4LogicalVolume* tileLV =
new G4LogicalVolume(tileShape, aeroMaterial,
string(
"ARICH.") + tileName.str());
483 G4ThreeVector transTile(params[2] * 10., params[3] * 10., (thick + layerThick - wallHeight) / 2. + zLayer);
485 Ra.rotateZ(params[4]);
486 new G4PVPlacement(G4Transform3D(Ra, transTile), tileLV,
string(
"ARICH.") + tileName.str(), aerogelPlaneLV,
false, iLayer);
488 zLayer += layerThick;
491 new G4PVPlacement(G4Translate3D(0., 0., -wallHeight / 2.), supportTubeLV,
"ARICH.AerogelSupportPlate", aerogelPlaneLV,
false, 1);
493 return aerogelPlaneLV;
503 B2ERROR(
"GeoARICHCreator::buildAerogelPlane --> getFullAerogelMaterialDescriptionKey() is wrong");
528 G4Tubs* aerogelTube =
new G4Tubs(
"aerogelTube", rin, rout, (thick + wallHeight + imgTubeLen) / 2., 0, 2 * M_PI);
529 G4LogicalVolume* aerogelPlaneLV =
new G4LogicalVolume(aerogelTube, gapMaterial,
"ARICH.AaerogelPlane");
532 G4Tubs* supportTube =
new G4Tubs(
"aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
533 G4LogicalVolume* supportTubeLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.AerogelSupportPlate");
537 G4Tubs* imgTube =
new G4Tubs(
"imgTube", rin, rout, imgTubeLen / 2., 0, 2 * M_PI);
538 G4LogicalVolume* imgTubeLV =
new G4LogicalVolume(imgTube, imgMaterial,
"ARICH.AerogelImgPlate");
543 std::vector<double> wallR;
545 for (
unsigned iRing = 1; iRing < nRing + 1; iRing++) {
551 G4Transform3D transform = G4Translate3D(0., 0., (thick - imgTubeLen) / 2.);
553 for (
unsigned iRing = 0; iRing < nRing; iRing++) {
556 std::stringstream wallName;
557 wallName <<
"supportWallR_" << iRing + 1;
558 G4Tubs* supportWall =
new G4Tubs(wallName.str().c_str(), wallR[iRing], wallR[iRing] + wallThick, wallHeight / 2., 0, 2 * M_PI);
559 G4LogicalVolume* supportWallLV =
new G4LogicalVolume(supportWall, supportMaterial,
string(
"ARICH.") + wallName.str().c_str());
561 new G4PVPlacement(transform, supportWallLV,
string(
"ARICH.") + wallName.str().c_str(), aerogelPlaneLV,
false, 0);
563 if (iRing == 0)
continue;
569 wallName <<
"supportWallPhi_" << iRing + 1;
570 G4Box* wall =
new G4Box(wallName.str(), (wallR[iRing] - wallR[iRing - 1] - wallThick) / 2. - 1., thick / 2., wallHeight / 2.);
571 G4LogicalVolume* wallLV =
new G4LogicalVolume(wall, supportMaterial,
string(
"ARICH.") + wallName.str());
572 double r = (wallR[iRing - 1] + wallThick + wallR[iRing]) / 2.;
577 for (
unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
581 std::stringstream tileName;
582 tileName <<
"aerogelTile_" << iRing <<
"_" << iLayer;
584 G4Tubs* tileShape =
new G4Tubs(tileName.str(), wallR[iRing - 1] + wallThick + tileGap, wallR[iRing] - tileGap, layerThick / 2.,
585 (tileGap + wallThick / 2.) / wallR[iRing], dphi - (2.*tileGap + wallThick) / wallR[iRing]);
588 G4LogicalVolume* tileLV =
new G4LogicalVolume(tileShape, aeroMaterial,
string(
"ARICH.") + tileName.str());
590 while (iphi < 2 * M_PI - 0.0001) {
591 G4ThreeVector trans(r * cos(iphi), r * sin(iphi), (thick - imgTubeLen) / 2.);
595 if (iLayer == 1)
new G4PVPlacement(G4Transform3D(Ra, trans), wallLV,
string(
"ARICH.") + wallName.str(), aerogelPlaneLV,
false,
598 G4ThreeVector transTile(0, 0, (thick + layerThick - wallHeight - imgTubeLen) / 2. + zLayer);
599 new G4PVPlacement(G4Transform3D(Ra, transTile), tileLV,
string(
"ARICH.") + tileName.str(), aerogelPlaneLV,
false, iSlot);
603 zLayer += layerThick;
607 new G4PVPlacement(G4Translate3D(0., 0., -(wallHeight + imgTubeLen) / 2.), supportTubeLV,
"ARICH.AerogelSupportPlate",
611 new G4PVPlacement(G4Translate3D(0., 0., (wallHeight + thick) / 2.), imgTubeLV,
"ARICH.AerogelImgPlate", aerogelPlaneLV,
false, 1);
613 return aerogelPlaneLV;
638 double wallHeight = maxTotalAerogelThick + compensationARICHairVolumeThick_min;
643 G4Material* gapMaterial =
649 G4Tubs* aerogelTube =
new G4Tubs(
"aerogelTube", rin, rout, (thick + wallHeight + imgTubeLen) / 2., 0, 2 * M_PI);
650 G4LogicalVolume* aerogelPlaneLV =
new G4LogicalVolume(aerogelTube, gapMaterial,
"ARICH.AaerogelPlane");
653 G4Tubs* supportTube =
new G4Tubs(
"aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
654 G4LogicalVolume* supportTubeLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.AerogelSupportPlate");
658 G4Tubs* imgTube =
new G4Tubs(
"imgTube", rin, rout, imgTubeLen / 2., 0, 2 * M_PI);
659 G4LogicalVolume* imgTubeLV =
new G4LogicalVolume(imgTube, imgMaterial,
"ARICH.AerogelImgPlate");
663 std::vector<double> wallR;
665 for (
unsigned iRing = 1; iRing < nRing + 1; iRing++) {
671 G4Transform3D transform = G4Translate3D(0., 0., (thick - imgTubeLen) / 2.);
673 for (
unsigned iRing = 0; iRing < nRing; iRing++) {
676 std::stringstream wallName;
677 wallName <<
"supportWallR_" << iRing + 1;
679 G4Tubs* supportWall =
new G4Tubs(wallName.str().c_str(), wallR[iRing], wallR[iRing] + wallThick, wallHeight / 2., 0, 2 * M_PI);
680 G4LogicalVolume* supportWallLV =
new G4LogicalVolume(supportWall, supportMaterial,
string(
"ARICH.") + wallName.str().c_str());
681 new G4PVPlacement(transform, supportWallLV,
string(
"ARICH.") + wallName.str().c_str(), aerogelPlaneLV,
false, 0);
685 if (iRing == 0)
continue;
692 wallName <<
"supportWallPhi_" << iRing + 1;
693 G4Box* wall =
new G4Box(wallName.str(), (wallR[iRing] - wallR[iRing - 1] - wallThick) / 2. - 1., thick / 2., wallHeight / 2.);
694 G4LogicalVolume* wallLV =
new G4LogicalVolume(wall, supportMaterial,
string(
"ARICH.") + wallName.str());
695 double r = (wallR[iRing - 1] + wallThick + wallR[iRing]) / 2.;
700 for (
unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
706 while (iphi < 2 * M_PI - 0.0001) {
710 double layerThick = -1.0;
711 double tileUpThick = -1.0;
712 double tileDownThick = -1.0;
716 G4Material* aeroMaterial = NULL;
717 int ati_ring = iRing;
718 int ati_column = iicolumn + 1;
719 int ati_layerN = iLayer - 1;
725 B2ERROR(
"GeoARICHCreator::buildAerogelPlaneWithIndividualTilesProp --> getFullAerogelMaterialDescriptionKey() is wrong");
739 G4ThreeVector trans(r * cos(iphi), r * sin(iphi), (thick - imgTubeLen) / 2.);
743 new G4PVPlacement(G4Transform3D(Ra, trans),
745 string(
"ARICH.") + wallName.str(),
759 double compTileUpThick = wallHeight - tileUpThick - tileDownThick;
760 std::stringstream compTileName;
769 compTileName <<
"aerogelCompTile_" << iLayer <<
"_" << ati_ring <<
"_" << ati_column;
771 G4Tubs* compTileShape =
new G4Tubs(compTileName.str(),
772 wallR[iRing - 1] + wallThick + tileGap,
773 wallR[iRing] - tileGap,
774 compTileUpThick / 2.0,
775 (tileGap + wallThick / 2.0) / wallR[iRing],
776 dphi - (2.0 * tileGap + wallThick) / wallR[iRing]);
779 G4LogicalVolume* compTileLV =
new G4LogicalVolume(compTileShape,
781 string(
"ARICH.") + compTileName.str());
784 G4ThreeVector transCompTile(0, 0, (thick + wallHeight - compTileUpThick - imgTubeLen) / 2.0);
785 G4RotationMatrix compRa;
786 compRa.rotateZ(iphi);
787 new G4PVPlacement(G4Transform3D(compRa, transCompTile),
789 string(
"ARICH.") + compTileName.str(),
796 std::stringstream tileName;
797 tileName <<
"aerogelTile_" << iLayer <<
"_" << ati_ring <<
"_" << ati_column;
799 G4Tubs* tileShape =
new G4Tubs(tileName.str(),
800 wallR[iRing - 1] + wallThick + tileGap,
801 wallR[iRing] - tileGap,
803 (tileGap + wallThick / 2.0) / wallR[iRing],
804 dphi - (2.0 * tileGap + wallThick) / wallR[iRing]);
807 G4LogicalVolume* tileLV =
new G4LogicalVolume(tileShape,
809 string(
"ARICH.") + tileName.str());
814 zLayer = tileUpThick;
815 G4ThreeVector transTile(0, 0, (thick + layerThick - wallHeight - imgTubeLen) / 2.0 + zLayer);
816 new G4PVPlacement(G4Transform3D(Ra, transTile),
818 string(
"ARICH.") + tileName.str(),
833 new G4PVPlacement(G4Translate3D(0., 0., -(wallHeight + imgTubeLen) / 2.),
835 "ARICH.AerogelSupportPlate",
841 new G4PVPlacement(G4Translate3D(0., 0., (wallHeight + thick) / 2.),
843 "ARICH.AerogelImgPlate",
848 return aerogelPlaneLV;
870 if (!wref) B2WARNING(
"Material '" << winMat <<
871 "', required for ARICH photon detector window as no specified refractive index. Continuing, but no photons in ARICH will be detected.");
874 const double hapdSizeX = hapdGeo.
getSizeX();
875 const double hapdSizeY = hapdGeo.
getSizeY();
876 const double hapdSizeZ = hapdGeo.
getSizeZ();
882 const double botThick = wallThick;
886 G4Box* moduleBox =
new G4Box(
"moduleBox", hapdSizeX / 2., hapdSizeY / 2., modHeight / 2.);
887 G4LogicalVolume* lmoduleBox =
new G4LogicalVolume(moduleBox, moduleFill,
"ARICH.HAPDModule");
890 G4Box* hapdBox =
new G4Box(
"hapdBox", hapdSizeX / 2., hapdSizeY / 2., hapdSizeZ / 2.);
891 G4LogicalVolume* lhapdBox =
new G4LogicalVolume(hapdBox, fillMaterial,
"ARICH.HAPD");
894 G4Box* tempBox2 =
new G4Box(
"tempBox2", hapdSizeX / 2. - wallThick, hapdSizeY / 2. - wallThick,
895 hapdSizeZ / 2. + 0.1);
896 G4SubtractionSolid* moduleWall =
new G4SubtractionSolid(
"Box-tempBox", hapdBox, tempBox2);
897 G4LogicalVolume* lmoduleWall =
new G4LogicalVolume(moduleWall, wallMaterial,
"ARICH.HAPDWall");
898 setColor(*lmoduleWall,
"rgb(1.0,0.0,0.0,1.0)");
899 new G4PVPlacement(G4Transform3D(), lmoduleWall,
"ARICH.HAPDWall", lhapdBox,
false, 1);
902 G4Box* winBox =
new G4Box(
"winBox", hapdSizeX / 2. - wallThick, hapdSizeY / 2. - wallThick, winThick / 2.);
903 G4LogicalVolume* lmoduleWin =
new G4LogicalVolume(winBox, windowMaterial,
"ARICH.HAPDWindow");
904 setColor(*lmoduleWin,
"rgb(0.7,0.7,0.7,1.0)");
906 G4Transform3D transform = G4Translate3D(0., 0., (-hapdSizeZ + winThick) / 2.);
907 new G4PVPlacement(transform, lmoduleWin,
"ARICH.HAPDWindow", lhapdBox,
false, 1);
910 G4Box* botBox =
new G4Box(
"botBox", hapdSizeX / 2. - wallThick, hapdSizeY / 2. - wallThick, botThick / 2.);
911 G4LogicalVolume* lmoduleBot =
new G4LogicalVolume(botBox, wallMaterial,
"ARICH.HAPDBottom");
912 setColor(*lmoduleBot,
"rgb(0.0,1.0,0.0,1.0)");
913 G4Transform3D transform1 = G4Translate3D(0., 0., (hapdSizeZ - botThick) / 2.);
914 new G4PVPlacement(transform1, lmoduleBot,
"ARICH.HAPDBottom", lhapdBox,
false, 1);
917 G4Box* apdBox =
new G4Box(
"apdBox", apdSizeX / 2., apdSizeY / 2., apdSizeZ / 2.);
918 G4LogicalVolume* lApd =
new G4LogicalVolume(apdBox, apdMaterial,
"ARICH.HAPDApd");
926 new G4LogicalSkinSurface(
"apdSurface", lApd, optSurf);
927 G4Transform3D transform2 = G4Translate3D(0., 0., (hapdSizeZ - apdSizeZ) / 2. - botThick);
928 new G4PVPlacement(transform2, lApd,
"ARICH.HAPDApd", lhapdBox,
false, 1);
934 G4Box* febBox =
new G4Box(
"febBox", febSizeX / 2., febSizeY / 2., febSizeZ / 2.);
935 G4LogicalVolume* lfeb =
new G4LogicalVolume(febBox, febMaterial,
"ARICH.HAPDFeb");
937 setColor(*lfeb,
"rgb(0.0,0.6,0.0,1.0)");
938 G4Transform3D transform3 = G4Translate3D(0., 0., (modHeight - febSizeZ) / 2.);
939 new G4PVPlacement(transform3, lfeb,
"ARICH.HAPDFeb", lmoduleBox,
false, 1);
940 G4Transform3D transform4 = G4Translate3D(0., 0., - (modHeight - hapdSizeZ) / 2.);
941 new G4PVPlacement(transform4, lhapdBox,
"ARICH.HAPD", lmoduleBox,
false, 1);
951 G4LogicalVolume* hapdLV =
buildHAPD(hapdGeo);
955 G4Tubs* detTube =
new G4Tubs(
"detTube", detGeo.
getRingR(1) - hapdGeo.
getSizeX() * 1.4 / 2.,
957 G4LogicalVolume* detPlaneLV =
new G4LogicalVolume(detTube,
Materials::get(
"ARICH_Air"),
"ARICH.detectorPlane");
961 for (
unsigned iSlot = 1; iSlot < nSlots + 1; iSlot++) {
962 if (!
m_modInfo->isInstalled(iSlot))
continue;
965 G4ThreeVector trans(r * cos(phi), r * sin(phi), 0);
968 G4ThreeVector trans1(r * cos(phi), r * sin(phi), 0.0);
969 new G4PVPlacement(G4Transform3D(Ra, trans1), hapdLV,
"ARICH.HAPDModule", detPlaneLV,
false, iSlot);
988 G4VSolid* screwHoleTubeSubtracted_solid =
new G4Tubs(
"screwHoleTubeSubtracted_solid",
995 G4Box* merger_solid =
new G4Box(
"merger_solid",
1000 G4RotationMatrix Ra_sub;
1001 G4ThreeVector Ta_sub;
1002 G4Transform3D Tr_sub;
1003 Ta_sub.setX(-mergerGeo.
getSizeW() * mm / 2.0 + screwholedX1);
1004 Ta_sub.setY(mergerGeo.
getSizeL() * mm / 2.0 - screwholedY);
1006 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1007 G4SubtractionSolid* substraction_solid =
new G4SubtractionSolid(
"substraction_solid", merger_solid, screwHoleTubeSubtracted_solid,
1009 Ta_sub.setX(mergerGeo.
getSizeW() * mm / 2.0 - screwholedX2);
1010 Ta_sub.setY(mergerGeo.
getSizeL() * mm / 2.0 - screwholedY);
1012 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1013 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, screwHoleTubeSubtracted_solid, Tr_sub);
1014 Ta_sub.setX(mergerGeo.
getSizeW() * mm / 2.0 - screwholedX2);
1015 Ta_sub.setY(-mergerGeo.
getSizeL() * mm / 2.0 + screwholedY);
1017 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1018 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, screwHoleTubeSubtracted_solid, Tr_sub);
1019 Ta_sub.setX(-mergerGeo.
getSizeW() * mm / 2.0 + screwholedX1);
1020 Ta_sub.setY(-mergerGeo.
getSizeL() * mm / 2.0 + screwholedY);
1022 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1023 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, screwHoleTubeSubtracted_solid, Tr_sub);
1033 B2WARNING(
"ARICH geometry: no data available for merger " << iType <<
" cooling body geometry. Cooling body will not be placed.");
1037 std::stringstream shpName;
1038 shpName <<
"TessellatedSolid_" << + iType;
1040 G4TessellatedSolid* volume_solid =
new G4TessellatedSolid(shpName.str().c_str());
1042 G4ThreeVector point_1;
1043 G4ThreeVector point_2;
1044 G4ThreeVector point_3;
1048 if (mergerCoolingStr.nCells == 0) {
1049 B2WARNING(
"ARICH geometry: no data available for merger " << iType <<
" cooling body geometry. Cooling body will not be placed.");
1053 for (
unsigned int i = 0; i < mergerCoolingStr.nCells; i++) {
1055 point_1.setX(mergerCoolingStr.posV1[0][i]);
1056 point_1.setY(mergerCoolingStr.posV1[1][i]);
1057 point_1.setZ(mergerCoolingStr.posV1[2][i]);
1059 point_2.setX(mergerCoolingStr.posV2[0][i]);
1060 point_2.setY(mergerCoolingStr.posV2[1][i]);
1061 point_2.setZ(mergerCoolingStr.posV2[2][i]);
1063 point_3.setX(mergerCoolingStr.posV3[0][i]);
1064 point_3.setY(mergerCoolingStr.posV3[1][i]);
1065 point_3.setZ(mergerCoolingStr.posV3[2][i]);
1067 G4TriangularFacet* facet =
new G4TriangularFacet(point_1, point_2, point_3, ABSOLUTE);
1068 volume_solid->AddFacet((G4VFacet*) facet);
1072 volume_solid->SetSolidClosed(
true);
1073 std::stringstream volName;
1074 volName <<
"ARICH.mergerCooling_" << + iType;
1075 G4LogicalVolume* volume_logical =
new G4LogicalVolume(volume_solid,
1078 setColor(*volume_logical,
"rgb(0.6,0.0,0.2,1.0)");
1080 return volume_logical;
1086 G4Box* singlemergerenvelope_solid =
new G4Box(
"singlemergerenvelope_solid",
1090 std::stringstream volName;
1091 volName <<
"ARICH.singleMergerEnvelope_" << + iType;
1092 return new G4LogicalVolume(singlemergerenvelope_solid,
Materials::get(
"ARICH_Air"), volName.str().c_str());
1101 B2WARNING(
"GeoARICHCreator: Merger and merger cooling geometry will not be build as it is not availible in geometry configuration (ARICHGeometryConfig with ClasDef>4 is needed).");
1108 G4LogicalVolume* envelope_logical =
new G4LogicalVolume(envelope_solid,
Materials::get(
"ARICH_Air"),
"ARICH.mergerEnvelope");
1111 G4LogicalVolume* merger_logical =
buildMerger(mergerGeo);
1112 G4LogicalVolume* mergerCooling_logical[12] = {NULL};
1113 G4LogicalVolume* mergerEnvelope_logical[12] = {NULL};
1116 G4RotationMatrix RaPCB;
1119 G4RotationMatrix RaMergerCooling;
1120 RaMergerCooling.rotateY(180 * deg);
1121 RaMergerCooling.rotateZ(-90 * deg);
1124 for (
int iType = 1; iType < 13; iType++) {
1127 setColor(*mergerEnvelope_logical[iType - 1],
"rgb(0.0,0.0,1.0,1.0)");
1129 new G4PVPlacement(G4Transform3D(RaPCB, TaPCB),
1132 mergerEnvelope_logical[iType - 1],
1136 if (mergerCooling_logical[iType - 1] == NULL)
continue;
1138 new G4PVPlacement(G4Transform3D(RaMergerCooling, TaMergerCooling),
1139 mergerCooling_logical[iType - 1],
1140 "ARICH.mergerCooling",
1141 mergerEnvelope_logical[iType - 1],
1147 for (
unsigned iSlot = 0; iSlot < mergerGeo.
getMergerSlotID().size(); iSlot++) {
1156 G4RotationMatrix Ra;
1158 new G4PVPlacement(G4Transform3D(Ra, Ta),
1159 mergerEnvelope_logical[type - 1],
1160 "ARICH.singleMergerEnvelope",
1166 return envelope_logical;
1173 G4Tubs* cablesEnvelope_solid =
new G4Tubs(
"cablesEnvelope_solid",
1179 G4LogicalVolume* cablesEnvelope_logical =
new G4LogicalVolume(cablesEnvelope_solid,
1181 "ARICH.cablesEnvelope");
1183 return cablesEnvelope_logical;
1193 double feb_alcooling_singleObjectEnvelope_sizeY = feb_alcooling_singleObjectEnvelope_sizeX * mm;
1198 double feb_alcooling_box1_sizeY = feb_alcooling_box1_sizeX;
1202 double feb_alcooling_box2_sizeY = feb_alcooling_box2_sizeX;
1205 double feb_alcooling_box3_sizeX = coolingv2Geo.
getRectangleW() * mm;
1206 double feb_alcooling_box3_sizeY = coolingv2Geo.
getRectangleL() * mm;
1209 double feb_alcooling_box1_X0 = feb_alcooling_box2_sizeX / 2.0 + feb_alcooling_box1_sizeX / 2.0;
1210 double feb_alcooling_box1_Y0 = feb_alcooling_box2_sizeY / 2.0 + feb_alcooling_box1_sizeY / 2.0;
1211 double feb_alcooling_box1_Z0 = 0.0 * mm;
1218 double feb_alcooling_box3_Y0 = feb_alcooling_box3_X0;
1219 double feb_alcooling_box3_Z0 = feb_alcooling_box1_sizeZ / 2.0 + feb_alcooling_box3_sizeZ / 2.0;
1220 double feb_alcooling_box3_angle = 45.0 * deg;
1222 G4RotationMatrix Ra;
1229 G4VSolid* feb_alcoolingEnvelope_solid =
new G4Box(
"feb_alcoolingEnvelope_solid",
1230 feb_alcooling_singleObjectEnvelope_sizeX / 2.0,
1231 feb_alcooling_singleObjectEnvelope_sizeY / 2.0,
1232 feb_alcooling_singleObjectEnvelope_sizeZ / 2.0);
1233 G4LogicalVolume* feb_alcoolingEnvelope_logical =
new G4LogicalVolume(feb_alcoolingEnvelope_solid,
Materials::get(
"Air"),
1234 "feb_alcoolingEnvelope_logical");
1236 G4VSolid* feb_alcooling_box1_solid =
new G4Box(
"feb_alcooling_box1_solid", feb_alcooling_box1_sizeX / 2.0,
1237 feb_alcooling_box1_sizeY / 2.0, feb_alcooling_box1_sizeZ / 2.0);
1238 G4VSolid* feb_alcooling_box2_solid =
new G4Box(
"feb_alcooling_box2_solid", feb_alcooling_box2_sizeX / 2.0,
1239 feb_alcooling_box2_sizeY / 2.0, feb_alcooling_box2_sizeZ / 2.0);
1240 G4VSolid* feb_alcooling_box3_solid =
new G4Box(
"feb_alcooling_box3_solid", feb_alcooling_box3_sizeX / 2.0,
1241 feb_alcooling_box3_sizeY / 2.0, feb_alcooling_box3_sizeZ / 2.0);
1246 Ta.setX(feb_alcooling_box1_X0);
1247 Ta.setY(feb_alcooling_box1_Y0);
1248 Ta.setZ(feb_alcooling_box1_Z0);
1249 Tr = G4Transform3D(Ra, Ta);
1250 G4UnionSolid* feb_alcooling_assembly01_solid =
new G4UnionSolid(
"feb_alcooling_assembly01_solid", feb_alcooling_box2_solid,
1251 feb_alcooling_box1_solid, Tr);
1255 Ta.setX(-feb_alcooling_box1_X0);
1256 Ta.setY(-feb_alcooling_box1_Y0);
1257 Ta.setZ(feb_alcooling_box1_Z0);
1258 Tr = G4Transform3D(Ra, Ta);
1259 G4UnionSolid* feb_alcooling_assembly02_solid =
new G4UnionSolid(
"feb_alcooling_assembly02_solid", feb_alcooling_assembly01_solid,
1260 feb_alcooling_box1_solid, Tr);
1264 Ta.setX(feb_alcooling_box3_X0);
1265 Ta.setY(feb_alcooling_box3_Y0);
1266 Ta.setZ(feb_alcooling_box3_Z0);
1267 Ra.rotateZ(-feb_alcooling_box3_angle);
1268 Tr = G4Transform3D(Ra, Ta);
1269 G4UnionSolid* feb_alcooling_assembly03_solid =
new G4UnionSolid(
"feb_alcooling_assembly03_solid", feb_alcooling_assembly02_solid,
1270 feb_alcooling_box3_solid, Tr);
1271 Ra.rotateZ(feb_alcooling_box3_angle);
1275 Ta.setX(-feb_alcooling_box3_X0);
1276 Ta.setY(-feb_alcooling_box3_Y0);
1277 Ta.setZ(feb_alcooling_box3_Z0);
1278 Ra.rotateZ(-feb_alcooling_box3_angle);
1279 Tr = G4Transform3D(Ra, Ta);
1280 G4UnionSolid* feb_alcooling_assembly_solid =
new G4UnionSolid(
"feb_alcooling_assembly_solid", feb_alcooling_assembly03_solid,
1281 feb_alcooling_box3_solid, Tr);
1282 Ra.rotateZ(feb_alcooling_box3_angle);
1284 G4LogicalVolume* feb_alcooling_assembly_logical =
new G4LogicalVolume(feb_alcooling_assembly_solid,
Materials::get(
"Al"),
1285 "feb_alcooling_assembly_logical");
1288 Ta.setZ(-feb_alcooling_box3_sizeZ / 2.0);
1290 Tr = G4Transform3D(Ra, Ta);
1291 new G4PVPlacement(Tr,
1292 feb_alcooling_assembly_logical,
1293 "feb_alcooling_assembly",
1294 feb_alcoolingEnvelope_logical,
1298 return feb_alcoolingEnvelope_logical;
1304 B2ASSERT(
"ARICH cooling geometry ID (G4Tube) is wrong : coolingGeo.getCoolingGeometryID.at(i_volumeID) != 1",
1306 G4Tubs* coolingTube_solid =
new G4Tubs(
"coolingTube_solid",
1309 coolingGeo.
getCoolingL().at(i_volumeID) * mm / 2.0,
1319 B2ASSERT(
"ARICH cooling geometry ID (G4Torus) is wrong : coolingGeo.getCoolingGeometryID.at(i_volumeID) != 2",
1327 G4Torus* coolingTorus_solid =
new G4Torus(
"coolingTorus_solid",
1341 G4Tubs* coolingEnvelope_solid =
new G4Tubs(
"coolingEnvelope_solid",
1347 G4LogicalVolume* coolingEnvelope_logical =
new G4LogicalVolume(coolingEnvelope_solid,
1349 "ARICH.coolingEnvelope");
1353 for (
unsigned i = 0; i < nComponents; i++) {
1357 G4RotationMatrix Ra;
1358 G4LogicalVolume* coolingComponentLV;
1361 Ta.set(r * cos(phi), r * sin(phi), 0);
1364 Ra.rotateY(90.0 * deg);
1371 B2FATAL(
"ARICH cooling geometry component ID is wrong");
1373 new G4PVPlacement(G4Transform3D(Ra, Ta),
1376 coolingEnvelope_logical,
1381 return coolingEnvelope_logical;
1388 G4Box* coolingTestPlateEnvelop_solid =
new G4Box(
"coolingTestPlateEnvelop_solid",
1392 G4LogicalVolume* coolingTestPlateEnvelop_logical =
new G4LogicalVolume(coolingTestPlateEnvelop_solid,
Materials::get(
"Air"),
1393 "ARICH.coolingTestPlateEnvelop");
1395 G4Box* coolingTestPlate_solid =
new G4Box(
"coolingTestPlate_solid",
1401 G4VSolid* coldTubeSubtracted_solid =
new G4Tubs(
"coldTubeSubtracted_solid",
1408 G4VSolid* coldTube_solid =
new G4Tubs(
"coldTube_solid",
1416 G4RotationMatrix Ra_sub;
1417 G4ThreeVector Ta_sub;
1418 G4Transform3D Tr_sub;
1422 Ra_sub.rotateY(90.0 * deg);
1423 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1424 G4SubtractionSolid* substraction_solid =
new G4SubtractionSolid(
"substraction_solid", coolingTestPlate_solid,
1425 coldTubeSubtracted_solid, Tr_sub);
1431 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1432 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, coldTubeSubtracted_solid, Tr_sub);
1435 G4LogicalVolume* coolingTestPlate_logical =
new G4LogicalVolume(substraction_solid,
1438 new G4PVPlacement(G4Transform3D(),
1439 coolingTestPlate_logical,
1440 "ARICH.coolingTestPlate",
1441 coolingTestPlateEnvelop_logical,
1445 G4RotationMatrix Ra;
1448 Ra.rotateY(90.0 * deg);
1454 Tr = G4Transform3D(Ra, Ta);
1455 new G4PVPlacement(Tr,
1458 coolingTestPlateEnvelop_logical,
1463 return coolingTestPlateEnvelop_logical;
1475 G4LogicalVolume* detSupportLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.detectorSupportPlate");
1482 G4LogicalVolume* holeLV =
new G4LogicalVolume(hole,
Materials::get(
"Air"),
"ARICH.detectorSupportHole");
1485 std::vector<G4LogicalVolume*> hapdBackRadialWallLV;
1489 G4LogicalVolume* hapdSupportPlateLV =
new G4LogicalVolume(supportPlate, supportMaterial,
"hapdSupport");
1491 std::vector<double> wallR;
1492 wallR.assign(nRings + 1, 0);
1493 std::vector<double> thickR;
1494 thickR.assign(nRings + 1, 0);
1496 for (
int i = 1; i < nRings; i++) {
1498 double rp1 = detGeo.
getRingR(i + 1);
1499 wallR[i] = (rp1 + rm1) / 2.;
1501 wallR[0] = rm1 - (rp1 - rm1) / 2.;
1503 if (i == nRings - 1) {
1504 wallR[i + 1] = rp1 + (rp1 - rm1) / 2.;
1508 for (
int i = 0; i < nRings + 1; i++) {
1509 std::stringstream ringName1;
1510 ringName1 <<
"backWall_" << i;
1511 thickR[i] = backWallThick;
1513 thickR[i] = 2.*backWallThick;
1516 G4Tubs* backTube =
new G4Tubs(
"hapdBackRing", wallR[i] - thickR[i] / 2., wallR[i] + thickR[i] / 2., backWallHeight / 2., 0,
1518 G4LogicalVolume* hapdBackTubeLV =
new G4LogicalVolume(backTube, supportMaterial,
"backTube");
1520 new G4PVPlacement(transform3, hapdBackTubeLV,
"backTube", detSupportLV,
false, 1);
1521 if (i == 0)
continue;
1523 G4Box* backRadial =
new G4Box(
"backRadialBox", (wallR[i] - wallR[i - 1] - thickR[i] / 2. - thickR[i - 1] / 2.) / 2. - 1.,
1524 backWallThick / 2., backWallHeight / 2.);
1525 hapdBackRadialWallLV.push_back(
new G4LogicalVolume(backRadial, supportMaterial, ringName1.str().c_str()));
1528 G4SubtractionSolid* substraction = NULL;
1532 B2WARNING(
"GeoARICHCreator: No FEB colling body geometry available so they will not be placed (ARICHGeometryConfig with ClasDef>4 is needed).");
1533 return detSupportLV;
1538 for (
unsigned iSlot = 1; iSlot < nSlots + 1; iSlot++) {
1540 double r = (wallR[iRing] + wallR[iRing - 1]) / 2. - (thickR[iRing] - thickR[iRing - 1]) / 2.;
1543 G4ThreeVector trans(r * cos(phi), r * sin(phi), 0);
1544 G4RotationMatrix Ra;
1547 new G4PVPlacement(G4Transform3D(Ra, trans), holeLV,
"hole", hapdSupportPlateLV,
false, iSlot);
1548 if (substraction) substraction =
new G4SubtractionSolid(
"Box+CylinderMoved", substraction, hole, G4Transform3D(Ra, trans));
1549 else substraction =
new G4SubtractionSolid(
"Box+CylinderMoved", supportPlate, hole, G4Transform3D(Ra, trans));
1553 G4RotationMatrix RaBack;
1554 RaBack.rotateZ(phi);
1555 new G4PVPlacement(G4Transform3D(RaBack, transBack), hapdBackRadialWallLV[iRing - 1],
"hapdBack", detSupportLV,
false, iSlot);
1558 G4ThreeVector febCoolingTa;
1559 G4Transform3D febCoolingTr;
1560 febCoolingTa.setX(r * cos(detGeo.
getSlotPhi(iSlot)));
1561 febCoolingTa.setY(r * sin(detGeo.
getSlotPhi(iSlot)));
1566 double febCooling_envelope_Z0 = -supportTube_envelope_dZ / 2.0 + febCooling_envelope_dZ / 2.0 + detGeo.
getSupportThickness();
1567 febCoolingTa.setZ(febCooling_envelope_Z0);
1571 if (febcoolingv2GeometryID == 2) Ra.rotateZ(90.0 * deg);
1573 febCoolingTr = G4Transform3D(Ra, febCoolingTa);
1575 if (febcoolingv2GeometryID != 0) {
1578 new G4PVPlacement(febCoolingTr,
1589 G4Transform3D transform3 = G4Translate3D(0., 0., - backWallHeight / 2.);
1590 new G4PVPlacement(transform3, hapdSupportPlateLV,
"supportPlate", detSupportLV,
false, 1);
1593 G4Box* shieldBox1 =
new G4Box(
"shieldBox1", 20. / 2., 75. / 2., backWallHeight / 2.);
1594 G4Box* shieldBox2 =
new G4Box(
"shieldBox2", 55. / 2., 40. / 2., backWallHeight / 2.);
1595 G4LogicalVolume* shield1 =
new G4LogicalVolume(shieldBox1,
Materials::get(
"BoratedPoly"),
"ARICH.FWDShield1");
1596 G4LogicalVolume* shield2 =
new G4LogicalVolume(shieldBox2,
Materials::get(
"BoratedPoly"),
"ARICH.FWDShield2");
1597 double dphi = 2 * M_PI / 36.;
1598 double r1 = wallR[0] - 15.;
1599 double r2 = wallR[0] - 15. - 20. / 2. - 55. / 2.;
1600 for (
int i = 0; i < 36; i++) {
1601 double phi = (i + 0.5) * dphi;
1602 G4RotationMatrix rot;
1606 new G4PVPlacement(G4Transform3D(rot, trans), shield1,
"ARICH.FWDShield1", detSupportLV,
false, i);
1607 new G4PVPlacement(G4Transform3D(rot, trans1), shield2,
"ARICH.FWDShield2", detSupportLV,
false, i);
1610 return detSupportLV;
1627 G4Box* mirrPlate =
new G4Box(
"mirrPlate", mThick / 2., mLength / 2., mWidth / 2.);
1629 G4LogicalVolume* lmirror =
new G4LogicalVolume(mirrPlate, mirrorMaterial,
"ARICH.mirrorPlate");
1634 new G4LogicalSkinSurface(
"mirrorSurface", lmirror, optSurf);
1642 G4MaterialPropertiesTable* mTable = material->GetMaterialPropertiesTable();
1643 if (!mTable)
return 0;
1644 G4MaterialPropertyVector* mVector = mTable->GetProperty(
"RINDEX");
1645 if (!mVector)
return 0;
1653 int size = par.size();
1654 if (size < 4 || size > 8) B2ERROR(
"GeoARICHCreator::makeJoint: invalid number of joint wedge parameters");
1655 double lenx = par.at(0);
1656 double leny = par.at(1);
1657 double lenz = par.at(2);
1658 double thick = par.at(3);
1660 G4Box* wedgeBox1 =
new G4Box(
"wedgeBox1", thick / 2., lenx / 2., leny / 2.);
1661 G4Box* wedgeBox2 =
new G4Box(
"wedgeBox2", lenz / 2., lenx / 2., thick / 2.);
1663 G4LogicalVolume* wedgeBox1LV =
new G4LogicalVolume(wedgeBox1, supportMaterial,
"ARICH.supportWedge");
1664 G4LogicalVolume* wedgeBox2LV =
new G4LogicalVolume(wedgeBox2, supportMaterial,
"ARICH.supportWedge");
1666 G4RotationMatrix Rm;
1667 G4ThreeVector Ta(0, 0, 0);
1669 Tr = G4Transform3D(Rm, Ta);
1671 assemblyWedge->AddPlacedVolume(wedgeBox1LV, Tr);
1673 Ta.setX(lenz / 2. + thick / 2.);
1674 Ta.setZ(leny / 2. - thick / 2.);
1675 Tr = G4Transform3D(Rm, Ta);
1676 assemblyWedge->AddPlacedVolume(wedgeBox2LV, Tr);
1678 if (size == 4)
return;
1679 double edge = par.at(4);
1681 G4Box* wedgeBox3 =
new G4Box(
"wedgeBox3", lenz / 2., edge / 2., thick / 2.);
1682 G4LogicalVolume* wedgeBox3LV =
new G4LogicalVolume(wedgeBox3, supportMaterial,
"ARICH.supportWedge");
1684 Ta.setZ(leny / 2. - thick - thick / 2.);
1685 Tr = G4Transform3D(Rm, Ta);
1686 assemblyWedge->AddPlacedVolume(wedgeBox3LV, Tr);
1688 G4Trap* wedgeBoxTmp =
new G4Trap(
"wedgeBoxTmp", thick, leny - 2 * thick, lenz, edge);
1689 G4LogicalVolume* wedgeBox4LV;
1691 G4Tubs* wedgeBoxTmp1 =
new G4Tubs(
"wedgeBoxTmp1", 0.0, par.at(5), thick, 0, 2.*M_PI);
1692 G4RotationMatrix rotHole;
1693 G4ThreeVector transHole(par.at(6), par.at(7), 0);
1694 G4SubtractionSolid* wedgeBox4 =
new G4SubtractionSolid(
"wedgeBox4", wedgeBoxTmp, wedgeBoxTmp1, G4Transform3D(rotHole, transHole));
1695 wedgeBox4LV =
new G4LogicalVolume(wedgeBox4, supportMaterial,
"ARICH.supportWedge");
1696 }
else wedgeBox4LV =
new G4LogicalVolume(wedgeBoxTmp, supportMaterial,
"ARICH.supportWedge");
1698 Rm.rotateX(-M_PI / 2.);
1699 Ta.setX(thick / 2. + edge / 4. + lenz / 4.);
1700 Ta.setZ(-thick / 2. - edge / 2.);
1701 Tr = G4Transform3D(Rm, Ta);
1702 assemblyWedge->AddPlacedVolume(wedgeBox4LV, Tr);
Geometry parameters of HAPD.
bool isSimple() const
Use simple aerogel configuration.
double getLayerThickness(unsigned iLayer) const
Get thickness of tiles i-th aerogel layer.
double getSupportThickness() const
Get support plate thickness.
unsigned getNRings() const
Get number of aluminum wall rings (should be number of tile rings + 1)
double getSupportOuterR() const
Get support plate outer radius.
double getCompensationARICHairVolumeThick_min() const
Get minimum thickness of the compensation volume with ARICH air.
double getImgTubeThickness() const
Get imaginary tube thikness just after aerogel layers used as volume to which tracks are extrapolated...
double getWallHeight() const
Get height of aluminum walls between aerogel tiles.
double getRingDPhi(unsigned iRing) const
Get phi (angle) distance between "phi" aluminum wall between aerogel tiles in i-th tile ring.
double getRotationY() const
Get angle of rotation around Y axis.
const std::string & getLayerMaterial(unsigned iLayer) const
Get material name of tiles i-th aerogel layer.
double getRotationZ() const
Get angle of rotation around Z axis.
const std::string & getSupportMaterial() const
Get material of support plate.
double getTileThickness(int ring, int column, int layerN) const
Get thickness of individual tile.
TVector3 getPosition() const
get position vector of aerogel plane in ARICH local frame
double getWallThickness() const
Get thickness of aluminum walls between aerogel tiles.
double getRingRadius(unsigned iRing) const
Get radius of i-th aluminum ring between aerogel tiles (inner radius of ring)
unsigned getNLayers() const
Get number of aerogel layers.
double getSupportInnerR() const
Get support plate inner radius.
int getFullAerogelMaterialDescriptionKey() const
Get full aerogel material description key.
std::string getTileMaterialName(int ring, int column, int layerN) const
Get material name of individual tile.
double getMaximumTotalTileThickness() const
Get maximum total thickness of the aerogel tiles tile_up + tile_down for all the slots.
double getTileGap() const
Get gap between aerogel tile and aluminum wall.
const std::vector< double > & getSimpleParams() const
Get parameters of simple aerogel configuration.
double getRotationX() const
Get angle of rotation around X axis.
Geometry parameters of cable envelope.
double getEnvelopeOuterRadius() const
Returns Outer radius of cables envelop.
const std::string & getCablesEffectiveMaterialName() const
Returns Effective material name describing cables.
TVector3 getEnvelopeCenterPosition() const
Returns position vector (TVector3) of cables envelop.
double getEnvelopeInnerRadius() const
Returns Inner radius of cables envelop.
double getEnvelopeThickness() const
Returns Thickness of cables envelop.
Geometry parameters of Cooling System.
double getColdTubeWallThickness() const
Returns cold tube wall thickness.
const std::vector< double > & getCoolingPosR() const
Returns vector of radial distance (r, pho) of the cooling system object center in polar coordinate sy...
const std::vector< double > & getCoolingL() const
Returns vector of lengs of the cooling system object with given geometry ID.
const std::string & getCoolingPipeMaterialName() const
Returns material name of cooling pipe.
double getEnvelopeOuterRadius() const
Returns Outer radius of cooling system assembly envelope.
double getColdTubeSpacing() const
Returns distance from center of the cold tube to edge of cooling plate.
const std::vector< double > & getCoolingPosPhi() const
Returns vector of azimuthal angle of the cooling system object center in polar coordinate system in d...
double getColdTubeR() const
Returns radius of cold tubes.
const std::vector< double > & getCoolingGeometryID() const
Returns vector of cooling system object geometry ID.
const std::string & getCoolingTestPlateMaterialName() const
Returns material name of cooling test plates.
TVector3 getEnvelopeCenterPosition() const
Returns position vector (TVector3) of cooling system assembly envelope.
TVector3 getCoolingTestPlateslengths() const
Returns sizes vector (TVector3) of cooling test plates.
double getRmax() const
Returns Size of cooling system pipe : outer radius in mm.
const std::string & getColdTubeMaterialName() const
Returns material name of cold tube.
const std::vector< double > & getCoolinRotationAngle() const
Returns vector of azimuthal angle of rotation aroud Z - axis of the cooling system object in polar co...
double getEnvelopeInnerRadius() const
Returns Inner radius of cooling system assembly envelope.
double getRmin() const
Returns Size of cooling system pipe : inner radius in mm.
double getDepthColdTubeInPlate() const
Returns depth of the cold tube in the cooling plate.
double getEnvelopeThickness() const
Returns Thickness of cooling system assembly envelope.
double getColdTubeSubtractedR() const
Returns outer radius of subtracted tubes for cold tube.
int getColdTubeNumber() const
Returns number of cold tubes in one plate.
Geometry parameters of ARICH photon detector plane.
unsigned getNSlots() const
Get total number of module slots.
unsigned getSlotRing(unsigned slotID) const
Get ring number of slot with slot ID.
double getSupportBackWallHeight() const
Get height of the aluminum walls between modules on the electronics side of aluminum support plate.
double getSlotR(unsigned modID) const
Get radial position of module with given module ID number.
double getSupportBackWallThickness() const
Get thickness of aluminum walls between modules on the electronics side of aluminum support plate.
double getSupportThickness() const
Get support plate thickness.
unsigned getNRings() const
Get number of module slot rings.
double getSupportOuterR() const
Get support plate outer radius.
double getSupportZPosition() const
Get Z position of support plate (start point in Z)
double getRingDPhi(unsigned iRing) const
Get phi (angle) distance between module slots in i-th ring.
double getRotationY() const
Get angle of rotation around Y axis.
double getRotationZ() const
Get angle of rotation around Z axis.
double getSlotPhi(unsigned modID) const
Get phi (angle) position of module with given module ID number.
double getModuleHoleSize() const
Get size of module hole in support plate.
const std::string & getSupportMaterial() const
Get material of support plate.
TVector3 getPosition() const
Get center point.
double getSupportInnerR() const
Get support plate inner radius.
double getRingR(unsigned iRing) const
Get radius of i-th module slot ring (radius of center point)
double getRotationX() const
Get angle of rotation around X axis.
Geometry parameters of Cooling System - version2 (v2).
double getBigSquareThickness() const
Returns thickness of the big square in mm.
double getBigSquareSize() const
Returns size of the big square in mm.
double getSmallSquareSize() const
Returns size of the small square in mm.
double getRectangleThickness() const
Returns thickness of the rectangle in mm.
const std::vector< double > & getFebcoolingv2GeometryID() const
Returns vector of feb cooling configuration/geometry ID.
double getSmallSquareThickness() const
Returns thickness of the small square in mm.
double getRectangleW() const
Returns width of the rectangle in mm.
double getRectangleL() const
Returns length of the rectangle in mm.
double getRectangleDistanceFromCenter() const
Returns distance from center of the rectangle in mm.
double getGamma() const
Returns rotation angle around z.
double getX() const
Returns translation in x.
double getAlpha() const
Returns rotation angle around x.
double getZ() const
Returns translation in z.
double getY() const
Returns translation in y.
double getBeta() const
Returns rotation angle around y.
Geometry parameters of HAPD.
double getSizeZ() const
Returns HAPD size in z.
const std::string & getFillMaterial() const
Returns fill (inside) material name.
const GeoOpticalSurface & getAPDSurface() const
Returns APD reflective optical surface.
const std::string & getWinMaterial() const
Returns window material name.
double getAPDSizeZ() const
Returns APD size in z.
double getWinThickness() const
Returns window thickness.
const std::string & getWallMaterial() const
Returns wall (casing) material name.
const std::string & getAPDMaterial() const
Returns APD material name.
const std::string & getFEBMaterial() const
Returns FEB material name.
double getSizeX() const
Returns HAPD size in x.
double getSizeY() const
Returns HAPD size in y.
double getFEBSizeY() const
Returns FEB size in y.
double getWallThickness() const
Returns wall thickness.
double getFEBSizeZ() const
Returns FEB size in z.
double getModuleSizeZ() const
Returns module size in z (HAPD + FEB height)
double getAPDSizeY() const
Returns APD size in y.
double getFEBSizeX() const
Returns FEB size in x.
double getAPDSizeX() const
Returns APD size in x.
double getRotationY() const
Get angle of rotation around Y axis.
double getRotationZ() const
Get angle of rotation around Z axis.
double getOuterRadius() const
Get ARICH master volume outer radius.
double getInnerRadius() const
Get ARICH master volume inner radius.
TVector3 getPosition() const
Get position of ARICH master volume center point in global Belle II coordinates.
const std::string & getMaterial() const
Get material of ARICH master volume.
double getLength() const
Get ARICH master volume length.
double getRotationX() const
Get angle of rotation around X axis.
Geometry parameters of Merger PCB.
const std::vector< double > & getMergerSlotID() const
Returns vector of merger boards slot numbers.
double getMergerPCBscrewholeR() const
Returns merger PCB screw hole radius.
double getSingleMergerEnvelopeThickness() const
Returns single merger PCB and merger cooling envelop thickness.
double getSizeW() const
Returns merger PCB width.
const std::string & getMergerPCBMaterialName() const
Returns merger PCB material name.
double getMergerPCBscrewholePosdX1() const
Returns merger PCB screw hole position from the bottom edge.
double getEnvelopeOuterRadius() const
Returns Outer radius of merger PCB assembly envelope.
double getMergerPCBscrewholePosdX2() const
Returns merger PCB screw hole position from the top edge.
TVector3 getEnvelopeCenterPosition() const
Returns position vector (TVector3) of merger PCB assembly envelope.
TVector3 getSingleMergeEnvelopePosition() const
Returns position vector (TVector3) of merger PCB inside the single merger envelope.
double getThickness() const
Returns merger PCB thickness.
double getSingleMergerEnvelopeSizeW() const
Returns single merger PCB and merger cooling envelop width.
double getEnvelopeInnerRadius() const
Returns Inner radius of merger PCB assembly envelope.
const std::vector< double > & getMergerPosR() const
Returns vector of merger boards distances from the center in mm.
const std::vector< double > & getMergerOrientation() const
Returns vector of merger boarts orientations in deg.
double getSingleMergerEnvelopeSizeL() const
Returns single merger PCB and merger cooling envelop length.
double getSizeL() const
Returns merger PCB lenght.
double getEnvelopeThickness() const
Returns Thickness of merger PCB assembly envelope.
double getMergerPCBscrewholePosdY() const
Returns merger PCB screw hole position from the left and right sides.
const std::vector< double > & getSingleMergerenvelopeDeltaZ() const
Returns vector of Z position of the single merger and merger cooling body envelope inside global merg...
const std::vector< double > & getMergerAngle() const
Returns vector of merger boarts azimuthal angles in polar coordinate system in deg.
const ARICHPositionElement & getDisplacementElement(int mirrorID) const
Returns displacement parameters for given mirror plate.
Geometry parameters of HAPD.
double getZPosition() const
Get nominal Z position of mirror plates (center point in ARICH local frame)
const GeoOpticalSurface & getMirrorSurface() const
Returns mirror reflective optical surface.
unsigned getNMirrors() const
Get number of mirror plates.
double getPlateWidth() const
Get width of mirror plate.
const std::string & getMaterial() const
Get material name of mirror plates.
double getPlateLength() const
Get length of mirror plate.
double getRadius() const
Get nominal radius at which mirror plates are placed (center of plate)
double getStartAngle() const
Get phi angle of position of the first mirror plate.
double getPlateThickness() const
Get thickness of mirror plate.
Geometry parameters of ARICH support structures and neutron shield.
double getWedgeR(unsigned i) const
Get radius at which i-th wedge is placed.
double getWedgePhi(unsigned i) const
Get phi angle at which i-th wedge is placed.
const std::string & getWedgeMaterial(unsigned i) const
Get material of i-th wedge.
const std::string & getTubeMaterial(unsigned i) const
Get material of i-th tube.
double getTubeInnerR(unsigned i) const
Get tube inner radius.
double getTubeLength(unsigned i) const
Get tube length.
double getTubeOuterR(unsigned i) const
Get tube outer radius.
double getWedgeZ(unsigned i) const
Get Z position of i-th wedge.
unsigned getNTubes() const
Get number of tube volumes to be placed.
const std::vector< double > getWedge(unsigned i) const
Get parameters of wedge.
int getWedgeType(unsigned i) const
Get type of i-th wedge.
const std::string & getTubeName(unsigned i) const
Get name of i-th tube.
unsigned getNWedges() const
Get number of wedges to be placed.
double getTubeZPosition(unsigned i) const
Get tube Z position.
box getBox(unsigned i) const
Get box paramaters.
unsigned getNBoxes() const
Get number of box volumes.
The Class for ARICH Geometry Parameters.
const ARICHGeoMirrorDisplacement & getMirrorDisplacement() const
Get mirror displacement parameters.
const ARICHGeoCooling & getCoolingGeometry() const
Get ARICH cooling system geometry parameters.
const ARICHGeoMirrors & getMirrors() const
Get mirrors geometry configuration.
const ARICHGeoCablesEnvelope & getCablesEnvelope() const
Get ARICH cables envelop geometry parameters.
static void useGeantUnits()
Use Geant4 units when returning geometry parameters.
const ARICHGeoHAPD & getHAPDGeometry() const
Get HAPD geometry parameters.
const ARICHGeoGlobalDisplacement & getGlobalDisplacement() const
Get global displacement parameters.
const ARICHGeoFEBCooling & getFEBCoolingGeometry() const
Get ARICH FEB cooling system (v2) geometry parameters.
const ARICHGeoMerger & getMergerGeometry() const
Get Merger PCB geometry parameters.
const ARICHGeoAerogelPlane & getAerogelPlane() const
Get geometry configuration of aerogel plane.
const ARICHGeoSupport & getSupportStructure() const
Get ARICH support structure geometry configuration.
static void useBasf2Units()
Use basf2 units when returning geometry parameters.
const ARICHGeoDetectorPlane & getDetectorPlane() const
Get geometry configuration of HAPD plane.
const ARICHGeoMasterVolume & getMasterVolume() const
Get ARICH master volume geometry configuration.
Position element for ARICH.
The Class for BeamBackground Sensitive Detector.
static const double eV
[electronvolt]
static const double MeV
[megaelectronvolt]
G4LogicalVolume * buildSimpleAerogelPlane(const ARICHGeometryConfig &detectorGeo)
build simple aerogel plane (for cosmic test)
G4LogicalVolume * buildHAPD(const ARICHGeoHAPD &hapdPar)
build the HAPD modules
void makeJoint(G4Material *supportMaterial, const std::vector< double > &pars, G4AssemblyVolume *assemblyWedge)
build joints of the ARICH support structure
virtual ~GeoARICHCreator()
The destructor of the GeoARICHreator class.
OptionalDBObjPtr< ARICHGeoMergerCooling > m_mergerCooling
merger cooling bodies geometry from the DB
G4LogicalVolume * buildMergerPCBEnvelopePlane(const ARICHGeometryConfig &detectorGeo)
build merger PCB assembly envelope plane
G4LogicalVolume * buildFEBCoolingBody(const ARICHGeoFEBCooling &coolingv2Geo)
build FEB cooling bodies (cooling system update after phase 2)
G4LogicalVolume * buildCoolingTorus(const unsigned i_volumeID, const ARICHGeoCooling &coolingGeo)
build cooling tube (G4Torus)
G4LogicalVolume * buildAerogelPlaneAveragedOverLayers(const ARICHGeometryConfig &detectorGeo)
build aerogel plane with average properties of aerogel per layer
G4LogicalVolume * buildCables(const ARICHGeoCablesEnvelope &cablesGeo)
build the cables envelop with effective material describing cables
G4LogicalVolume * buildMergerCooling(unsigned iType)
build merger cooling bodies (cooling system update after phase 2)
double getAvgRINDEX(G4Material *material)
get refractive index of the material
G4LogicalVolume * buildCoolingTube(const unsigned i_volumeID, const ARICHGeoCooling &coolingGeo)
build cooling tube (G4Tubs)
void createGeometry(G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create detector geometry.
G4LogicalVolume * buildDetectorSupportPlate(const ARICHGeometryConfig &detectorGeo)
build detector support plate
DBObjPtr< ARICHModulesInfo > m_modInfo
information on installed modules from the DB
G4LogicalVolume * buildAerogelPlane(const ARICHGeometryConfig &detectorGeo)
build aerogel plane
SensitiveAero * m_sensitiveAero
pointer to sensitive aerogel - used instead of tracking
G4LogicalVolume * buildDetectorPlane(const ARICHGeometryConfig &detectorGeo)
build detector plane
ARICHGeometryConfig m_config
geometry configuration
G4LogicalVolume * buildCoolingEnvelopePlane(const ARICHGeoCooling &coolingGeo)
build cooling system assembly envelope plane
int m_isBeamBkgStudy
flag the beam background study
G4LogicalVolume * buildMergerEnvelope(const ARICHGeoMerger &mergerGeo, int type)
build single merger and merger cooling body envelope logical volume
G4LogicalVolume * buildMerger(const ARICHGeoMerger &mergerGeo)
build the merger PCB logical volume
SensitiveDetector * m_sensitive
pointer to sensitive detector
G4LogicalVolume * buildAerogelPlaneWithIndividualTilesProp(const ARICHGeometryConfig &detectorGeo)
with individual properties of aerogel tiles
G4LogicalVolume * buildMirror(const ARICHGeometryConfig &detectorGeo)
build mirrors
G4LogicalVolume * buildCoolingTestPlate(const ARICHGeoCooling &coolingGeo)
build cooling test plates
This is optional (temporary) class that provides information on track parameters on aerogel plane,...
The Class for ARICH Sensitive Detector.
Thin wrapper around the Geant4 Material system.
static G4Material * get(const std::string &name)
Find given material.
static Materials & getInstance()
Get a reference to the singleton instance.
G4OpticalSurface * createOpticalSurface(const gearbox::Interface ¶meters)
Create an optical surface from parameters, will abort on error.
int doBeamBackgroundStudy() const
returns 1 if beam background study (to add additional sensitive modules, detect neutrons,...
double sqrt(double a)
sqrt for double
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
GeometryTypes
Flag indiciating the type of geometry to be used.
Abstract base class for different kinds of events.
Struct to hold parameters of box volumes (examples, scintilators for cosmic test)
Structure which holds apexes of the tessellation volumes.