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>
25#include <G4LogicalVolume.hh>
26#include <G4PVPlacement.hh>
27#include <G4AssemblyVolume.hh>
28#include <G4UnionSolid.hh>
29#include <G4LogicalSkinSurface.hh>
30#include <G4OpticalSurface.hh>
37#include <G4TessellatedSolid.hh>
38#include <G4TriangularFacet.hh>
40#include <G4SubtractionSolid.hh>
42#include <G4Material.hh>
61 geometry::CreatorFactory<GeoARICHCreator> GeoARICHFactory(
"ARICHCreator");
77 G4LogicalSkinSurface::CleanSurfaceTable();
93 G4Tubs* envelopeTube =
new G4Tubs(
"Envelope",
m_config.getMasterVolume().getInnerRadius(),
94 m_config.getMasterVolume().getOuterRadius(),
m_config.getMasterVolume().getLength() / 2., 0, 2 * M_PI);
98 if (!material) { B2FATAL(
"Material ARICH_Air required for ARICH master volume could not be found");}
100 B2WARNING(
"Material ARICH_Air required by ARICH master volume has no specified refractive index. Continuing, but no photons in ARICH will be propagated.");
103 G4LogicalVolume* masterLV =
new G4LogicalVolume(envelopeTube, material,
"ARICH.masterVolume");
107 G4Region* aRegion =
new G4Region(
"ARICHEnvelope");
108 masterLV->SetRegion(aRegion);
109 aRegion->AddRootLogicalVolume(masterLV);
111 G4RotationMatrix rotMaster;
112 double rot_x =
m_config.getMasterVolume().getRotationX();
113 double rot_y =
m_config.getMasterVolume().getRotationY();
114 double rot_z =
m_config.getMasterVolume().getRotationZ();
115 double tr_x =
m_config.getMasterVolume().getPosition().X();
116 double tr_y =
m_config.getMasterVolume().getPosition().Y();
117 double tr_z =
m_config.getMasterVolume().getPosition().Z();
119 if (
m_config.useGlobalDisplacement()) {
120 rot_x +=
m_config.getGlobalDisplacement().getAlpha();
121 rot_y +=
m_config.getGlobalDisplacement().getBeta();
122 rot_z +=
m_config.getGlobalDisplacement().getGamma();
123 tr_x +=
m_config.getGlobalDisplacement().getX();
124 tr_y +=
m_config.getGlobalDisplacement().getY();
125 tr_z +=
m_config.getGlobalDisplacement().getZ();
126 B2WARNING(
"ARICH global displacement parameters from DB will be taken into account.");
128 rotMaster.rotateX(rot_x);
129 rotMaster.rotateY(rot_y);
130 rotMaster.rotateZ(rot_z);
132 G4ThreeVector transMaster(tr_x, tr_y, tr_z);
134 new G4PVPlacement(G4Transform3D(rotMaster, transMaster), masterLV,
"ARICH.MasterVolume", &topVolume,
false, 1);
155 G4LogicalVolume* aeroPlaneLV;
156 if (!
m_config.getAerogelPlane().isSimple()) {
159 B2INFO(
"GeoARICHCreator: using simple cosmic test geometry.");
163 G4RotationMatrix rotDetPlane;
164 rotDetPlane.rotateX(
m_config.getDetectorPlane().getRotationX());
165 rotDetPlane.rotateY(
m_config.getDetectorPlane().getRotationY());
166 rotDetPlane.rotateZ(
m_config.getDetectorPlane().getRotationZ());
171 G4RotationMatrix rotMergerPlane;
172 rotMergerPlane.rotateX(0.0);
173 rotMergerPlane.rotateY(0.0);
174 rotMergerPlane.rotateZ(0.0);
179 G4RotationMatrix rotCablesPlane;
180 rotCablesPlane.rotateX(0.0);
181 rotCablesPlane.rotateY(0.0);
182 rotCablesPlane.rotateZ(0.0);
184 G4RotationMatrix rotCoolingPlane;
185 rotCoolingPlane.rotateX(0.0);
186 rotCoolingPlane.rotateY(0.0);
187 rotCoolingPlane.rotateZ(0.0);
189 G4RotationMatrix rotAeroPlane;
190 rotAeroPlane.rotateX(
m_config.getAerogelPlane().getRotationX());
191 rotAeroPlane.rotateY(
m_config.getAerogelPlane().getRotationY());
192 rotAeroPlane.rotateZ(
m_config.getAerogelPlane().getRotationZ());
194 G4ThreeVector transDetPlane(
m_config.getDetectorPlane().getPosition().X(),
m_config.getDetectorPlane().getPosition().Y(),
195 m_config.getDetectorPlane().getPosition().Z() + zShift);
197 G4ThreeVector transDetSupportPlate(
m_config.getDetectorPlane().getPosition().X(),
m_config.getDetectorPlane().getPosition().Y(),
198 m_config.getDetectorPlane().getSupportZPosition() + zShift);
200 G4ThreeVector transMergerPlate(
m_config.getMergerGeometry().getEnvelopeCenterPosition().X() * mm,
201 m_config.getMergerGeometry().getEnvelopeCenterPosition().Y() * mm,
202 m_config.getMergerGeometry().getEnvelopeCenterPosition().Z() * mm + zShift);
204 G4ThreeVector transCablesPlate(
m_config.getCablesEnvelope().getEnvelopeCenterPosition().X(),
205 m_config.getCablesEnvelope().getEnvelopeCenterPosition().Y(),
206 m_config.getCablesEnvelope().getEnvelopeCenterPosition().Z() + zShift);
208 G4ThreeVector transCoolingPlate(
m_config.getCoolingGeometry().getEnvelopeCenterPosition().X() * mm,
209 m_config.getCoolingGeometry().getEnvelopeCenterPosition().Y() * mm,
210 m_config.getCoolingGeometry().getEnvelopeCenterPosition().Z() * mm + zShift);
212 G4ThreeVector transAeroPlane(
m_config.getAerogelPlane().getPosition().X(),
213 m_config.getAerogelPlane().getPosition().Y(),
214 m_config.getAerogelPlane().getPosition().Z() + zShift);
217 new G4PVPlacement(G4Transform3D(rotDetPlane, transDetPlane), detPlaneLV,
"ARICH.detPlane", masterLV,
false, 1);
218 new G4PVPlacement(G4Transform3D(rotDetPlane, transDetSupportPlate), detSupportPlateLV,
"ARICH.detSupportPlane", masterLV,
false, 1);
219 if (mergerLV)
new G4PVPlacement(G4Transform3D(rotMergerPlane, transMergerPlate), mergerLV,
"ARICH.mergerPlane", masterLV,
false, 1);
220 new G4PVPlacement(G4Transform3D(rotCablesPlane, transCablesPlate), cablesLV,
"ARICH.cablesPlane", masterLV,
false, 1);
222 new G4PVPlacement(G4Transform3D(rotAeroPlane, transAeroPlane), aeroPlaneLV,
"ARICH.aeroPlane", masterLV,
false, 1);
244 int nMirrors =
m_config.getMirrors().getNMirrors();
245 int mirStart =
m_config.getMirrors().getStartAngle();
246 int mirZPos =
m_config.getMirrors().getZPosition();
247 int mirRad =
m_config.getMirrors().getRadius();
249 double angl = mirStart;
250 double dphi = 2 * M_PI / nMirrors;
251 if (
m_config.useMirrorDisplacement()) B2WARNING(
"ARICH mirrors displacement parameters from DB will be used.");
252 for (
int i = 1; i < nMirrors + 1; i++) {
255 double mrot_z = angl;
256 double mtr_x = mirRad * cos(angl);
257 double mtr_y = mirRad * sin(angl);
258 double mtr_z = mirZPos + zShift;
259 if (
m_config.useMirrorDisplacement()) {
261 mrot_x += displ.getAlpha();
262 mrot_y += displ.getBeta();
263 mrot_z += displ.getGamma();
264 mtr_x += displ.getX();
265 mtr_y += displ.getY();
266 mtr_z += displ.getZ();
268 G4RotationMatrix rotMirror;
269 rotMirror.rotateX(mrot_x);
270 rotMirror.rotateY(mrot_y);
271 rotMirror.rotateZ(mrot_z);
272 G4ThreeVector transMirror(mtr_x, mtr_y, mtr_z);
273 new G4PVPlacement(G4Transform3D(rotMirror, transMirror), mirrorLV,
"ARICH.mirrorPlate", masterLV,
false, i);
280 std::vector<G4LogicalVolume*> shieldLV(2);
281 std::vector<double> shieldZ(2);
283 for (
int i = 0; i < nTubes; i++) {
288 if (supportPar.
getTubeName(i) ==
"ARICH.NeutronShield1") {
289 shieldLV[0] =
new G4LogicalVolume(tube, tubeMaterial, supportPar.
getTubeName(i));
292 }
else if (supportPar.
getTubeName(i) ==
"ARICH.NeutronShield2") {
293 shieldLV[1] =
new G4LogicalVolume(tube, tubeMaterial, supportPar.
getTubeName(i));
298 G4LogicalVolume* tubeLV =
new G4LogicalVolume(tube, tubeMaterial, supportPar.
getTubeName(i));
300 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0,
305 const std::vector<double> wedge1 = supportPar.
getWedge(1);
306 const std::vector<double> wedge2 = supportPar.
getWedge(2);
309 G4AssemblyVolume* assemblyWedge1 =
new G4AssemblyVolume();
310 G4AssemblyVolume* assemblyWedge2 =
new G4AssemblyVolume();
311 makeJoint(wedge1Material, wedge1, assemblyWedge1);
312 makeJoint(wedge2Material, wedge2, assemblyWedge2);
316 for (
int i = 0; i < nWedge; i++) {
323 G4ThreeVector Tb(r * cos(phi), r * sin(phi), z);
328 Tr = G4Transform3D(Rx, Tb);
329 if (wgtype == 1) assemblyWedge1->MakeImprint(shieldLV[0], Tr);
330 else if (wgtype == 2) assemblyWedge2->MakeImprint(shieldLV[0], Tr);
334 Tr = G4Transform3D(Rx, Tb);
335 if (wgtype == 1) assemblyWedge1->MakeImprint(masterLV, Tr);
336 else if (wgtype == 2) assemblyWedge2->MakeImprint(masterLV, Tr);
337 else B2ERROR(
"GeoARICHCreator: invalid support wedge type!");
342 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0, shieldZ[0])), shieldLV[0],
"ARICH.NeutronShield1", masterLV,
345 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0, shieldZ[1])), shieldLV[1],
"ARICH.NeutronShield2", masterLV,
407 if (
m_config.getAerogelPlane().isSimple()) {
409 for (
int i = 0; i < nBoxes; i++) {
411 G4Box* scintBox =
new G4Box(
"scintBox", box.
size[0] * 10. / 2., box.
size[1] * 10. / 2., box.
size[2] * 10. / 2.);
413 G4LogicalVolume* scintLV =
new G4LogicalVolume(scintBox, scintMaterial, box.
name);
415 G4RotationMatrix rotScint;
420 transScintTV =
m_config.getMasterVolume().pointToGlobal(transScintTV);
421 B2INFO(
"GeoARICHCreator: Scintilator " << box.
name <<
" placed at global: " << transScintTV.X() <<
" " << transScintTV.Y() <<
" " <<
424 new G4PVPlacement(G4Transform3D(rotScint, transScint), scintLV,
"scintilator", masterLV,
false, 1);
430 delete assemblyWedge1;
431 delete assemblyWedge2;
455 G4Tubs* aerogelTube =
new G4Tubs(
"aerogelTube", rin, rout, (thick + wallHeight) / 2., 0, 2 * M_PI);
456 G4LogicalVolume* aerogelPlaneLV =
new G4LogicalVolume(aerogelTube, gapMaterial,
"ARICH.AaerogelPlane");
459 G4Tubs* supportTube =
new G4Tubs(
"aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
460 G4LogicalVolume* supportTubeLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.AerogelSupportPlate");
467 for (
unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
469 std::stringstream tileName;
470 tileName <<
"aerogelTile_" << iLayer;
472 G4Box* tileShape =
new G4Box(tileName.str(), params[0] * 10. / 2., params[1] * 10. / 2., layerThick / 2.);
476 G4LogicalVolume* tileLV =
new G4LogicalVolume(tileShape, aeroMaterial,
string(
"ARICH.") + tileName.str());
478 G4ThreeVector transTile(params[2] * 10., params[3] * 10., (thick + layerThick - wallHeight) / 2. + zLayer);
480 Ra.rotateZ(params[4]);
481 new G4PVPlacement(G4Transform3D(Ra, transTile), tileLV,
string(
"ARICH.") + tileName.str(), aerogelPlaneLV,
false, iLayer);
483 zLayer += layerThick;
486 new G4PVPlacement(G4Translate3D(0., 0., -wallHeight / 2.), supportTubeLV,
"ARICH.AerogelSupportPlate", aerogelPlaneLV,
false, 1);
488 return aerogelPlaneLV;
498 B2ERROR(
"GeoARICHCreator::buildAerogelPlane --> getFullAerogelMaterialDescriptionKey() is wrong");
523 G4Tubs* aerogelTube =
new G4Tubs(
"aerogelTube", rin, rout, (thick + wallHeight + imgTubeLen) / 2., 0, 2 * M_PI);
524 G4LogicalVolume* aerogelPlaneLV =
new G4LogicalVolume(aerogelTube, gapMaterial,
"ARICH.AaerogelPlane");
527 G4Tubs* supportTube =
new G4Tubs(
"aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
528 G4LogicalVolume* supportTubeLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.AerogelSupportPlate");
532 G4Tubs* imgTube =
new G4Tubs(
"imgTube", rin, rout, imgTubeLen / 2., 0, 2 * M_PI);
533 G4LogicalVolume* imgTubeLV =
new G4LogicalVolume(imgTube, imgMaterial,
"ARICH.AerogelImgPlate");
538 std::vector<double> wallR;
540 for (
unsigned iRing = 1; iRing < nRing + 1; iRing++) {
546 G4Transform3D transform = G4Translate3D(0., 0., (thick - imgTubeLen) / 2.);
548 for (
unsigned iRing = 0; iRing < nRing; iRing++) {
551 std::stringstream wallName;
552 wallName <<
"supportWallR_" << iRing + 1;
553 G4Tubs* supportWall =
new G4Tubs(wallName.str().c_str(), wallR[iRing], wallR[iRing] + wallThick, wallHeight / 2., 0, 2 * M_PI);
554 G4LogicalVolume* supportWallLV =
new G4LogicalVolume(supportWall, supportMaterial,
string(
"ARICH.") + wallName.str().c_str());
556 new G4PVPlacement(transform, supportWallLV,
string(
"ARICH.") + wallName.str().c_str(), aerogelPlaneLV,
false, 0);
558 if (iRing == 0)
continue;
564 wallName <<
"supportWallPhi_" << iRing + 1;
565 G4Box* wall =
new G4Box(wallName.str(), (wallR[iRing] - wallR[iRing - 1] - wallThick) / 2. - 1., thick / 2., wallHeight / 2.);
567 G4LogicalVolume* wallLV =
new G4LogicalVolume(wall, supportMaterial,
string(
"ARICH.") + wallName.str());
568 double r = (wallR[iRing - 1] + wallThick + wallR[iRing]) / 2.;
573 for (
unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
577 std::stringstream tileName;
578 tileName <<
"aerogelTile_" << iRing <<
"_" << iLayer;
580 G4Tubs* tileShape =
new G4Tubs(tileName.str(), wallR[iRing - 1] + wallThick + tileGap, wallR[iRing] - tileGap, layerThick / 2.,
581 (tileGap + wallThick / 2.) / wallR[iRing], dphi - (2.*tileGap + wallThick) / wallR[iRing]);
585 G4LogicalVolume* tileLV =
new G4LogicalVolume(tileShape, aeroMaterial,
string(
"ARICH.") + tileName.str());
587 while (iphi < 2 * M_PI - 0.0001) {
588 G4ThreeVector trans(r * cos(iphi), r * sin(iphi), (thick - imgTubeLen) / 2.);
592 if (iLayer == 1)
new G4PVPlacement(G4Transform3D(Ra, trans), wallLV,
string(
"ARICH.") + wallName.str(), aerogelPlaneLV,
false,
595 G4ThreeVector transTile(0, 0, (thick + layerThick - wallHeight - imgTubeLen) / 2. + zLayer);
596 new G4PVPlacement(G4Transform3D(Ra, transTile), tileLV,
string(
"ARICH.") + tileName.str(), aerogelPlaneLV,
false, iSlot);
600 zLayer += layerThick;
604 new G4PVPlacement(G4Translate3D(0., 0., -(wallHeight + imgTubeLen) / 2.), supportTubeLV,
"ARICH.AerogelSupportPlate",
608 new G4PVPlacement(G4Translate3D(0., 0., (wallHeight + thick) / 2.), imgTubeLV,
"ARICH.AerogelImgPlate", aerogelPlaneLV,
false, 1);
610 return aerogelPlaneLV;
635 double wallHeight = maxTotalAerogelThick + compensationARICHairVolumeThick_min;
640 G4Material* gapMaterial =
646 G4Tubs* aerogelTube =
new G4Tubs(
"aerogelTube", rin, rout, (thick + wallHeight + imgTubeLen) / 2., 0, 2 * M_PI);
647 G4LogicalVolume* aerogelPlaneLV =
new G4LogicalVolume(aerogelTube, gapMaterial,
"ARICH.AaerogelPlane");
650 G4Tubs* supportTube =
new G4Tubs(
"aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
651 G4LogicalVolume* supportTubeLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.AerogelSupportPlate");
655 G4Tubs* imgTube =
new G4Tubs(
"imgTube", rin, rout, imgTubeLen / 2., 0, 2 * M_PI);
656 G4LogicalVolume* imgTubeLV =
new G4LogicalVolume(imgTube, imgMaterial,
"ARICH.AerogelImgPlate");
660 std::vector<double> wallR;
662 for (
unsigned iRing = 1; iRing < nRing + 1; iRing++) {
668 G4Transform3D transform = G4Translate3D(0., 0., (thick - imgTubeLen) / 2.);
670 for (
unsigned iRing = 0; iRing < nRing; iRing++) {
673 std::stringstream wallName;
674 wallName <<
"supportWallR_" << iRing + 1;
676 G4Tubs* supportWall =
new G4Tubs(wallName.str().c_str(), wallR[iRing], wallR[iRing] + wallThick, wallHeight / 2., 0, 2 * M_PI);
677 G4LogicalVolume* supportWallLV =
new G4LogicalVolume(supportWall, supportMaterial,
string(
"ARICH.") + wallName.str().c_str());
678 new G4PVPlacement(transform, supportWallLV,
string(
"ARICH.") + wallName.str().c_str(), aerogelPlaneLV,
false, 0);
682 if (iRing == 0)
continue;
689 wallName <<
"supportWallPhi_" << iRing + 1;
690 G4Box* wall =
new G4Box(wallName.str(), (wallR[iRing] - wallR[iRing - 1] - wallThick) / 2. - 1., thick / 2., wallHeight / 2.);
692 G4LogicalVolume* wallLV =
new G4LogicalVolume(wall, supportMaterial,
string(
"ARICH.") + wallName.str());
693 double r = (wallR[iRing - 1] + wallThick + wallR[iRing]) / 2.;
698 for (
unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
704 while (iphi < 2 * M_PI - 0.0001) {
708 double layerThick = -1.0;
709 double tileUpThick = -1.0;
710 double tileDownThick = -1.0;
714 G4Material* aeroMaterial = NULL;
715 int ati_ring = iRing;
716 int ati_column = iicolumn + 1;
717 int ati_layerN = iLayer - 1;
723 B2ERROR(
"GeoARICHCreator::buildAerogelPlaneWithIndividualTilesProp --> getFullAerogelMaterialDescriptionKey() is wrong");
737 G4ThreeVector trans(r * cos(iphi), r * sin(iphi), (thick - imgTubeLen) / 2.);
741 new G4PVPlacement(G4Transform3D(Ra, trans),
743 string(
"ARICH.") + wallName.str(),
757 double compTileUpThick = wallHeight - tileUpThick - tileDownThick;
758 std::stringstream compTileName;
767 compTileName <<
"aerogelCompTile_" << iLayer <<
"_" << ati_ring <<
"_" << ati_column;
769 G4Tubs* compTileShape =
new G4Tubs(compTileName.str(),
770 wallR[iRing - 1] + wallThick + tileGap,
771 wallR[iRing] - tileGap,
772 compTileUpThick / 2.0,
773 (tileGap + wallThick / 2.0) / wallR[iRing],
774 dphi - (2.0 * tileGap + wallThick) / wallR[iRing]);
777 G4LogicalVolume* compTileLV =
new G4LogicalVolume(compTileShape,
779 string(
"ARICH.") + compTileName.str());
782 G4ThreeVector transCompTile(0, 0, (thick + wallHeight - compTileUpThick - imgTubeLen) / 2.0);
783 G4RotationMatrix compRa;
784 compRa.rotateZ(iphi);
785 new G4PVPlacement(G4Transform3D(compRa, transCompTile),
787 string(
"ARICH.") + compTileName.str(),
794 std::stringstream tileName;
795 tileName <<
"aerogelTile_" << iLayer <<
"_" << ati_ring <<
"_" << ati_column;
797 G4Tubs* tileShape =
new G4Tubs(tileName.str(),
798 wallR[iRing - 1] + wallThick + tileGap,
799 wallR[iRing] - tileGap,
801 (tileGap + wallThick / 2.0) / wallR[iRing],
802 dphi - (2.0 * tileGap + wallThick) / wallR[iRing]);
805 G4LogicalVolume* tileLV =
new G4LogicalVolume(tileShape,
807 string(
"ARICH.") + tileName.str());
812 zLayer = tileUpThick;
813 G4ThreeVector transTile(0, 0, (thick + layerThick - wallHeight - imgTubeLen) / 2.0 + zLayer);
814 new G4PVPlacement(G4Transform3D(Ra, transTile),
816 string(
"ARICH.") + tileName.str(),
831 new G4PVPlacement(G4Translate3D(0., 0., -(wallHeight + imgTubeLen) / 2.),
833 "ARICH.AerogelSupportPlate",
839 new G4PVPlacement(G4Translate3D(0., 0., (wallHeight + thick) / 2.),
841 "ARICH.AerogelImgPlate",
846 return aerogelPlaneLV;
868 if (!wref) B2WARNING(
"Material '" << winMat <<
869 "', required for ARICH photon detector window as no specified refractive index. Continuing, but no photons in ARICH will be detected.");
872 const double hapdSizeX = hapdGeo.
getSizeX();
873 const double hapdSizeY = hapdGeo.
getSizeY();
874 const double hapdSizeZ = hapdGeo.
getSizeZ();
880 const double botThick = wallThick;
884 G4Box* moduleBox =
new G4Box(
"moduleBox", hapdSizeX / 2., hapdSizeY / 2., modHeight / 2.);
885 G4LogicalVolume* lmoduleBox =
new G4LogicalVolume(moduleBox, moduleFill,
"ARICH.HAPDModule");
888 G4Box* hapdBox =
new G4Box(
"hapdBox", hapdSizeX / 2., hapdSizeY / 2., hapdSizeZ / 2.);
889 G4LogicalVolume* lhapdBox =
new G4LogicalVolume(hapdBox, fillMaterial,
"ARICH.HAPD");
892 G4Box* tempBox2 =
new G4Box(
"tempBox2", hapdSizeX / 2. - wallThick, hapdSizeY / 2. - wallThick,
893 hapdSizeZ / 2. + 0.1);
894 G4SubtractionSolid* moduleWall =
new G4SubtractionSolid(
"Box-tempBox", hapdBox, tempBox2);
895 G4LogicalVolume* lmoduleWall =
new G4LogicalVolume(moduleWall, wallMaterial,
"ARICH.HAPDWall");
896 setColor(*lmoduleWall,
"rgb(1.0,0.0,0.0,1.0)");
897 new G4PVPlacement(G4Transform3D(), lmoduleWall,
"ARICH.HAPDWall", lhapdBox,
false, 1);
900 G4Box* winBox =
new G4Box(
"winBox", hapdSizeX / 2. - wallThick, hapdSizeY / 2. - wallThick, winThick / 2.);
901 G4LogicalVolume* lmoduleWin =
new G4LogicalVolume(winBox, windowMaterial,
"ARICH.HAPDWindow");
902 setColor(*lmoduleWin,
"rgb(0.7,0.7,0.7,1.0)");
904 G4Transform3D transform = G4Translate3D(0., 0., (-hapdSizeZ + winThick) / 2.);
905 new G4PVPlacement(transform, lmoduleWin,
"ARICH.HAPDWindow", lhapdBox,
false, 1);
908 G4Box* botBox =
new G4Box(
"botBox", hapdSizeX / 2. - wallThick, hapdSizeY / 2. - wallThick, botThick / 2.);
909 G4LogicalVolume* lmoduleBot =
new G4LogicalVolume(botBox, wallMaterial,
"ARICH.HAPDBottom");
910 setColor(*lmoduleBot,
"rgb(0.0,1.0,0.0,1.0)");
911 G4Transform3D transform1 = G4Translate3D(0., 0., (hapdSizeZ - botThick) / 2.);
912 new G4PVPlacement(transform1, lmoduleBot,
"ARICH.HAPDBottom", lhapdBox,
false, 1);
915 G4Box* apdBox =
new G4Box(
"apdBox", apdSizeX / 2., apdSizeY / 2., apdSizeZ / 2.);
916 G4LogicalVolume* lApd =
new G4LogicalVolume(apdBox, apdMaterial,
"ARICH.HAPDApd");
924 new G4LogicalSkinSurface(
"apdSurface", lApd, optSurf);
925 G4Transform3D transform2 = G4Translate3D(0., 0., (hapdSizeZ - apdSizeZ) / 2. - botThick);
926 new G4PVPlacement(transform2, lApd,
"ARICH.HAPDApd", lhapdBox,
false, 1);
932 G4Box* febBox =
new G4Box(
"febBox", febSizeX / 2., febSizeY / 2., febSizeZ / 2.);
933 G4LogicalVolume* lfeb =
new G4LogicalVolume(febBox, febMaterial,
"ARICH.HAPDFeb");
935 setColor(*lfeb,
"rgb(0.0,0.6,0.0,1.0)");
936 G4Transform3D transform3 = G4Translate3D(0., 0., (modHeight - febSizeZ) / 2.);
937 new G4PVPlacement(transform3, lfeb,
"ARICH.HAPDFeb", lmoduleBox,
false, 1);
938 G4Transform3D transform4 = G4Translate3D(0., 0., - (modHeight - hapdSizeZ) / 2.);
939 new G4PVPlacement(transform4, lhapdBox,
"ARICH.HAPD", lmoduleBox,
false, 1);
949 G4LogicalVolume* hapdLV =
buildHAPD(hapdGeo);
953 G4Tubs* detTube =
new G4Tubs(
"detTube", detGeo.
getRingR(1) - hapdGeo.
getSizeX() * 1.4 / 2.,
955 G4LogicalVolume* detPlaneLV =
new G4LogicalVolume(detTube,
Materials::get(
"ARICH_Air"),
"ARICH.detectorPlane");
959 for (
unsigned iSlot = 1; iSlot < nSlots + 1; iSlot++) {
960 if (!
m_modInfo->isInstalled(iSlot))
continue;
963 G4ThreeVector trans(r * cos(phi), r * sin(phi), 0);
966 G4ThreeVector trans1(r * cos(phi), r * sin(phi), 0.0);
967 new G4PVPlacement(G4Transform3D(Ra, trans1), hapdLV,
"ARICH.HAPDModule", detPlaneLV,
false, iSlot);
986 G4VSolid* screwHoleTubeSubtracted_solid =
new G4Tubs(
"screwHoleTubeSubtracted_solid",
993 G4Box* merger_solid =
new G4Box(
"merger_solid",
998 G4RotationMatrix Ra_sub;
999 G4ThreeVector Ta_sub;
1000 G4Transform3D Tr_sub;
1001 Ta_sub.setX(-mergerGeo.
getSizeW() * mm / 2.0 + screwholedX1);
1002 Ta_sub.setY(mergerGeo.
getSizeL() * mm / 2.0 - screwholedY);
1004 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1005 G4SubtractionSolid* substraction_solid =
new G4SubtractionSolid(
"substraction_solid", merger_solid, screwHoleTubeSubtracted_solid,
1007 Ta_sub.setX(mergerGeo.
getSizeW() * mm / 2.0 - screwholedX2);
1008 Ta_sub.setY(mergerGeo.
getSizeL() * mm / 2.0 - screwholedY);
1010 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1011 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, screwHoleTubeSubtracted_solid, Tr_sub);
1012 Ta_sub.setX(mergerGeo.
getSizeW() * mm / 2.0 - screwholedX2);
1013 Ta_sub.setY(-mergerGeo.
getSizeL() * mm / 2.0 + screwholedY);
1015 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1016 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, screwHoleTubeSubtracted_solid, Tr_sub);
1017 Ta_sub.setX(-mergerGeo.
getSizeW() * mm / 2.0 + screwholedX1);
1018 Ta_sub.setY(-mergerGeo.
getSizeL() * mm / 2.0 + screwholedY);
1020 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1021 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, screwHoleTubeSubtracted_solid, Tr_sub);
1031 B2WARNING(
"ARICH geometry: no data available for merger " << iType <<
" cooling body geometry. Cooling body will not be placed.");
1035 std::stringstream shpName;
1036 shpName <<
"TessellatedSolid_" << + iType;
1038 G4TessellatedSolid* volume_solid =
new G4TessellatedSolid(shpName.str().c_str());
1040 G4ThreeVector point_1;
1041 G4ThreeVector point_2;
1042 G4ThreeVector point_3;
1046 if (mergerCoolingStr.
nCells == 0) {
1047 B2WARNING(
"ARICH geometry: no data available for merger " << iType <<
" cooling body geometry. Cooling body will not be placed.");
1051 for (
unsigned int i = 0; i < mergerCoolingStr.
nCells; i++) {
1053 point_1.setX(mergerCoolingStr.
posV1[0][i]);
1054 point_1.setY(mergerCoolingStr.
posV1[1][i]);
1055 point_1.setZ(mergerCoolingStr.
posV1[2][i]);
1057 point_2.setX(mergerCoolingStr.
posV2[0][i]);
1058 point_2.setY(mergerCoolingStr.
posV2[1][i]);
1059 point_2.setZ(mergerCoolingStr.
posV2[2][i]);
1061 point_3.setX(mergerCoolingStr.
posV3[0][i]);
1062 point_3.setY(mergerCoolingStr.
posV3[1][i]);
1063 point_3.setZ(mergerCoolingStr.
posV3[2][i]);
1065 G4TriangularFacet* facet =
new G4TriangularFacet(point_1, point_2, point_3, ABSOLUTE);
1066 volume_solid->AddFacet((G4VFacet*) facet);
1070 volume_solid->SetSolidClosed(
true);
1071 std::stringstream volName;
1072 volName <<
"ARICH.mergerCooling_" << + iType;
1073 G4LogicalVolume* volume_logical =
new G4LogicalVolume(volume_solid,
1076 setColor(*volume_logical,
"rgb(0.6,0.0,0.2,1.0)");
1078 return volume_logical;
1084 G4Box* singlemergerenvelope_solid =
new G4Box(
"singlemergerenvelope_solid",
1088 std::stringstream volName;
1089 volName <<
"ARICH.singleMergerEnvelope_" << + iType;
1090 return new G4LogicalVolume(singlemergerenvelope_solid,
Materials::get(
"ARICH_Air"), volName.str().c_str());
1099 B2WARNING(
"GeoARICHCreator: Merger and merger cooling geometry will not be build as it is not available in geometry configuration (ARICHGeometryConfig with ClasDef>4 is needed).");
1106 G4LogicalVolume* envelope_logical =
new G4LogicalVolume(envelope_solid,
Materials::get(
"ARICH_Air"),
"ARICH.mergerEnvelope");
1109 G4LogicalVolume* merger_logical =
buildMerger(mergerGeo);
1110 G4LogicalVolume* mergerCooling_logical[12] = {NULL};
1111 G4LogicalVolume* mergerEnvelope_logical[12] = {NULL};
1114 G4RotationMatrix RaPCB;
1117 G4RotationMatrix RaMergerCooling;
1118 RaMergerCooling.rotateY(180 * deg);
1119 RaMergerCooling.rotateZ(-90 * deg);
1122 for (
int iType = 1; iType < 13; iType++) {
1125 setColor(*mergerEnvelope_logical[iType - 1],
"rgb(0.0,0.0,1.0,1.0)");
1127 new G4PVPlacement(G4Transform3D(RaPCB, TaPCB),
1130 mergerEnvelope_logical[iType - 1],
1134 if (mergerCooling_logical[iType - 1] == NULL)
continue;
1136 new G4PVPlacement(G4Transform3D(RaMergerCooling, TaMergerCooling),
1137 mergerCooling_logical[iType - 1],
1138 "ARICH.mergerCooling",
1139 mergerEnvelope_logical[iType - 1],
1145 for (
unsigned iSlot = 0; iSlot < mergerGeo.
getMergerSlotID().size(); iSlot++) {
1154 G4RotationMatrix Ra;
1156 new G4PVPlacement(G4Transform3D(Ra, Ta),
1157 mergerEnvelope_logical[type - 1],
1158 "ARICH.singleMergerEnvelope",
1164 return envelope_logical;
1171 G4Tubs* cablesEnvelope_solid =
new G4Tubs(
"cablesEnvelope_solid",
1177 G4LogicalVolume* cablesEnvelope_logical =
new G4LogicalVolume(cablesEnvelope_solid,
1179 "ARICH.cablesEnvelope");
1181 return cablesEnvelope_logical;
1191 double feb_alcooling_singleObjectEnvelope_sizeY = feb_alcooling_singleObjectEnvelope_sizeX * mm;
1196 double feb_alcooling_box1_sizeY = feb_alcooling_box1_sizeX;
1200 double feb_alcooling_box2_sizeY = feb_alcooling_box2_sizeX;
1203 double feb_alcooling_box3_sizeX = coolingv2Geo.
getRectangleW() * mm;
1204 double feb_alcooling_box3_sizeY = coolingv2Geo.
getRectangleL() * mm;
1207 double feb_alcooling_box1_X0 = feb_alcooling_box2_sizeX / 2.0 + feb_alcooling_box1_sizeX / 2.0;
1208 double feb_alcooling_box1_Y0 = feb_alcooling_box2_sizeY / 2.0 + feb_alcooling_box1_sizeY / 2.0;
1209 double feb_alcooling_box1_Z0 = 0.0 * mm;
1216 double feb_alcooling_box3_Y0 = feb_alcooling_box3_X0;
1217 double feb_alcooling_box3_Z0 = feb_alcooling_box1_sizeZ / 2.0 + feb_alcooling_box3_sizeZ / 2.0;
1218 double feb_alcooling_box3_angle = 45.0 * deg;
1220 G4RotationMatrix Ra;
1227 G4VSolid* feb_alcoolingEnvelope_solid =
new G4Box(
"feb_alcoolingEnvelope_solid",
1228 feb_alcooling_singleObjectEnvelope_sizeX / 2.0,
1229 feb_alcooling_singleObjectEnvelope_sizeY / 2.0,
1230 feb_alcooling_singleObjectEnvelope_sizeZ / 2.0);
1231 G4LogicalVolume* feb_alcoolingEnvelope_logical =
new G4LogicalVolume(feb_alcoolingEnvelope_solid,
Materials::get(
"Air"),
1232 "feb_alcoolingEnvelope_logical");
1234 G4VSolid* feb_alcooling_box1_solid =
new G4Box(
"feb_alcooling_box1_solid", feb_alcooling_box1_sizeX / 2.0,
1235 feb_alcooling_box1_sizeY / 2.0, feb_alcooling_box1_sizeZ / 2.0);
1236 G4VSolid* feb_alcooling_box2_solid =
new G4Box(
"feb_alcooling_box2_solid", feb_alcooling_box2_sizeX / 2.0,
1237 feb_alcooling_box2_sizeY / 2.0, feb_alcooling_box2_sizeZ / 2.0);
1238 G4VSolid* feb_alcooling_box3_solid =
new G4Box(
"feb_alcooling_box3_solid", feb_alcooling_box3_sizeX / 2.0,
1239 feb_alcooling_box3_sizeY / 2.0, feb_alcooling_box3_sizeZ / 2.0);
1244 Ta.setX(feb_alcooling_box1_X0);
1245 Ta.setY(feb_alcooling_box1_Y0);
1246 Ta.setZ(feb_alcooling_box1_Z0);
1247 Tr = G4Transform3D(Ra, Ta);
1248 G4UnionSolid* feb_alcooling_assembly01_solid =
new G4UnionSolid(
"feb_alcooling_assembly01_solid", feb_alcooling_box2_solid,
1249 feb_alcooling_box1_solid, Tr);
1253 Ta.setX(-feb_alcooling_box1_X0);
1254 Ta.setY(-feb_alcooling_box1_Y0);
1255 Ta.setZ(feb_alcooling_box1_Z0);
1256 Tr = G4Transform3D(Ra, Ta);
1257 G4UnionSolid* feb_alcooling_assembly02_solid =
new G4UnionSolid(
"feb_alcooling_assembly02_solid", feb_alcooling_assembly01_solid,
1258 feb_alcooling_box1_solid, Tr);
1262 Ta.setX(feb_alcooling_box3_X0);
1263 Ta.setY(feb_alcooling_box3_Y0);
1264 Ta.setZ(feb_alcooling_box3_Z0);
1265 Ra.rotateZ(-feb_alcooling_box3_angle);
1266 Tr = G4Transform3D(Ra, Ta);
1267 G4UnionSolid* feb_alcooling_assembly03_solid =
new G4UnionSolid(
"feb_alcooling_assembly03_solid", feb_alcooling_assembly02_solid,
1268 feb_alcooling_box3_solid, Tr);
1269 Ra.rotateZ(feb_alcooling_box3_angle);
1273 Ta.setX(-feb_alcooling_box3_X0);
1274 Ta.setY(-feb_alcooling_box3_Y0);
1275 Ta.setZ(feb_alcooling_box3_Z0);
1276 Ra.rotateZ(-feb_alcooling_box3_angle);
1277 Tr = G4Transform3D(Ra, Ta);
1278 G4UnionSolid* feb_alcooling_assembly_solid =
new G4UnionSolid(
"feb_alcooling_assembly_solid", feb_alcooling_assembly03_solid,
1279 feb_alcooling_box3_solid, Tr);
1280 Ra.rotateZ(feb_alcooling_box3_angle);
1282 G4LogicalVolume* feb_alcooling_assembly_logical =
new G4LogicalVolume(feb_alcooling_assembly_solid,
Materials::get(
"Al"),
1283 "feb_alcooling_assembly_logical");
1286 Ta.setZ(-feb_alcooling_box3_sizeZ / 2.0);
1288 Tr = G4Transform3D(Ra, Ta);
1289 new G4PVPlacement(Tr,
1290 feb_alcooling_assembly_logical,
1291 "feb_alcooling_assembly",
1292 feb_alcoolingEnvelope_logical,
1296 return feb_alcoolingEnvelope_logical;
1302 B2ASSERT(
"ARICH cooling geometry ID (G4Tube) is wrong : coolingGeo.getCoolingGeometryID.at(i_volumeID) != 1",
1304 G4Tubs* coolingTube_solid =
new G4Tubs(
"coolingTube_solid",
1307 coolingGeo.
getCoolingL().at(i_volumeID) * mm / 2.0,
1317 B2ASSERT(
"ARICH cooling geometry ID (G4Torus) is wrong : coolingGeo.getCoolingGeometryID.at(i_volumeID) != 2",
1325 G4Torus* coolingTorus_solid =
new G4Torus(
"coolingTorus_solid",
1339 G4Tubs* coolingEnvelope_solid =
new G4Tubs(
"coolingEnvelope_solid",
1345 G4LogicalVolume* coolingEnvelope_logical =
new G4LogicalVolume(coolingEnvelope_solid,
1347 "ARICH.coolingEnvelope");
1351 for (
unsigned i = 0; i < nComponents; i++) {
1355 G4RotationMatrix Ra;
1356 G4LogicalVolume* coolingComponentLV;
1359 Ta.set(r * cos(phi), r * sin(phi), 0);
1362 Ra.rotateY(90.0 * deg);
1369 B2FATAL(
"ARICH cooling geometry component ID is wrong");
1371 new G4PVPlacement(G4Transform3D(Ra, Ta),
1374 coolingEnvelope_logical,
1379 return coolingEnvelope_logical;
1386 G4Box* coolingTestPlateEnvelop_solid =
new G4Box(
"coolingTestPlateEnvelop_solid",
1390 G4LogicalVolume* coolingTestPlateEnvelop_logical =
new G4LogicalVolume(coolingTestPlateEnvelop_solid,
Materials::get(
"Air"),
1391 "ARICH.coolingTestPlateEnvelop");
1393 G4Box* coolingTestPlate_solid =
new G4Box(
"coolingTestPlate_solid",
1399 G4VSolid* coldTubeSubtracted_solid =
new G4Tubs(
"coldTubeSubtracted_solid",
1406 G4VSolid* coldTube_solid =
new G4Tubs(
"coldTube_solid",
1415 G4RotationMatrix Ra_sub;
1416 G4ThreeVector Ta_sub;
1417 G4Transform3D Tr_sub;
1421 Ra_sub.rotateY(90.0 * deg);
1422 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1423 G4SubtractionSolid* substraction_solid =
new G4SubtractionSolid(
"substraction_solid", coolingTestPlate_solid,
1424 coldTubeSubtracted_solid, Tr_sub);
1430 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1431 substraction_solid =
new G4SubtractionSolid(
"substraction_solid", substraction_solid, coldTubeSubtracted_solid, Tr_sub);
1434 G4LogicalVolume* coolingTestPlate_logical =
new G4LogicalVolume(substraction_solid,
1437 new G4PVPlacement(G4Transform3D(),
1438 coolingTestPlate_logical,
1439 "ARICH.coolingTestPlate",
1440 coolingTestPlateEnvelop_logical,
1444 G4RotationMatrix Ra;
1447 Ra.rotateY(90.0 * deg);
1453 Tr = G4Transform3D(Ra, Ta);
1454 new G4PVPlacement(Tr,
1457 coolingTestPlateEnvelop_logical,
1462 return coolingTestPlateEnvelop_logical;
1474 G4LogicalVolume* detSupportLV =
new G4LogicalVolume(supportTube, supportMaterial,
"ARICH.detectorSupportPlate");
1482 G4LogicalVolume* holeLV =
new G4LogicalVolume(hole,
Materials::get(
"Air"),
"ARICH.detectorSupportHole");
1485 std::vector<G4LogicalVolume*> hapdBackRadialWallLV;
1490 G4LogicalVolume* hapdSupportPlateLV =
new G4LogicalVolume(supportPlate, supportMaterial,
"hapdSupport");
1492 std::vector<double> wallR;
1493 wallR.assign(nRings + 1, 0);
1494 std::vector<double> thickR;
1495 thickR.assign(nRings + 1, 0);
1497 for (
int i = 1; i < nRings; i++) {
1499 double rp1 = detGeo.
getRingR(i + 1);
1500 wallR[i] = (rp1 + rm1) / 2.;
1502 wallR[0] = rm1 - (rp1 - rm1) / 2.;
1504 if (i == nRings - 1) {
1505 wallR[i + 1] = rp1 + (rp1 - rm1) / 2.;
1509 for (
int i = 0; i < nRings + 1; i++) {
1510 std::stringstream ringName1;
1511 ringName1 <<
"backWall_" << i;
1512 thickR[i] = backWallThick;
1514 thickR[i] = 2.*backWallThick;
1517 G4Tubs* backTube =
new G4Tubs(
"hapdBackRing", wallR[i] - thickR[i] / 2., wallR[i] + thickR[i] / 2., backWallHeight / 2., 0,
1519 G4LogicalVolume* hapdBackTubeLV =
new G4LogicalVolume(backTube, supportMaterial,
"backTube");
1521 new G4PVPlacement(transform3, hapdBackTubeLV,
"backTube", detSupportLV,
false, 1);
1522 if (i == 0)
continue;
1524 G4Box* backRadial =
new G4Box(
"backRadialBox", (wallR[i] - wallR[i - 1] - thickR[i] / 2. - thickR[i - 1] / 2.) / 2. - 1.,
1525 backWallThick / 2., backWallHeight / 2.);
1526 hapdBackRadialWallLV.push_back(
new G4LogicalVolume(backRadial, supportMaterial, ringName1.str().c_str()));
1529 G4SubtractionSolid* substraction = NULL;
1533 B2WARNING(
"GeoARICHCreator: No FEB colling body geometry available so they will not be placed (ARICHGeometryConfig with ClasDef>4 is needed).");
1534 return detSupportLV;
1539 for (
unsigned iSlot = 1; iSlot < nSlots + 1; iSlot++) {
1541 double r = (wallR[iRing] + wallR[iRing - 1]) / 2. - (thickR[iRing] - thickR[iRing - 1]) / 2.;
1544 G4ThreeVector trans(r * cos(phi), r * sin(phi), 0);
1545 G4RotationMatrix Ra;
1548 new G4PVPlacement(G4Transform3D(Ra, trans), holeLV,
"hole", hapdSupportPlateLV,
false, iSlot);
1549 if (substraction) substraction =
new G4SubtractionSolid(
"Box+CylinderMoved", substraction, hole, G4Transform3D(Ra, trans));
1550 else substraction =
new G4SubtractionSolid(
"Box+CylinderMoved", supportPlate, hole, G4Transform3D(Ra, trans));
1554 G4RotationMatrix RaBack;
1555 RaBack.rotateZ(phi);
1556 new G4PVPlacement(G4Transform3D(RaBack, transBack), hapdBackRadialWallLV[iRing - 1],
"hapdBack", detSupportLV,
false, iSlot);
1559 G4ThreeVector febCoolingTa;
1560 G4Transform3D febCoolingTr;
1561 febCoolingTa.setX(r * cos(detGeo.
getSlotPhi(iSlot)));
1562 febCoolingTa.setY(r * sin(detGeo.
getSlotPhi(iSlot)));
1567 double febCooling_envelope_Z0 = -supportTube_envelope_dZ / 2.0 + febCooling_envelope_dZ / 2.0 + detGeo.
getSupportThickness();
1568 febCoolingTa.setZ(febCooling_envelope_Z0);
1572 if (febcoolingv2GeometryID == 2) Ra.rotateZ(90.0 * deg);
1574 febCoolingTr = G4Transform3D(Ra, febCoolingTa);
1576 if (febcoolingv2GeometryID != 0) {
1579 new G4PVPlacement(febCoolingTr,
1590 G4Transform3D transform3 = G4Translate3D(0., 0., - backWallHeight / 2.);
1591 new G4PVPlacement(transform3, hapdSupportPlateLV,
"supportPlate", detSupportLV,
false, 1);
1594 G4Box* shieldBox1 =
new G4Box(
"shieldBox1", 20. / 2., 75. / 2., backWallHeight / 2.);
1595 G4Box* shieldBox2 =
new G4Box(
"shieldBox2", 55. / 2., 40. / 2., backWallHeight / 2.);
1596 G4LogicalVolume* shield1 =
new G4LogicalVolume(shieldBox1,
Materials::get(
"BoratedPoly"),
"ARICH.FWDShield1");
1597 G4LogicalVolume* shield2 =
new G4LogicalVolume(shieldBox2,
Materials::get(
"BoratedPoly"),
"ARICH.FWDShield2");
1598 double dphi = 2 * M_PI / 36.;
1599 double r1 = wallR[0] - 15.;
1600 double r2 = wallR[0] - 15. - 20. / 2. - 55. / 2.;
1601 for (
int i = 0; i < 36; i++) {
1602 double phi = (i + 0.5) * dphi;
1603 G4RotationMatrix rot;
1607 new G4PVPlacement(G4Transform3D(rot, trans), shield1,
"ARICH.FWDShield1", detSupportLV,
false, i);
1608 new G4PVPlacement(G4Transform3D(rot, trans1), shield2,
"ARICH.FWDShield2", detSupportLV,
false, i);
1611 return detSupportLV;
1628 G4Box* mirrPlate =
new G4Box(
"mirrPlate", mThick / 2., mLength / 2., mWidth / 2.);
1630 G4LogicalVolume* lmirror =
new G4LogicalVolume(mirrPlate, mirrorMaterial,
"ARICH.mirrorPlate");
1635 new G4LogicalSkinSurface(
"mirrorSurface", lmirror, optSurf);
1643 G4MaterialPropertiesTable* mTable = material->GetMaterialPropertiesTable();
1644 if (!mTable)
return 0;
1645 G4MaterialPropertyVector* mVector = mTable->GetProperty(
"RINDEX");
1646 if (!mVector)
return 0;
1654 int size = par.size();
1655 if (size < 4 || size > 8) B2ERROR(
"GeoARICHCreator::makeJoint: invalid number of joint wedge parameters");
1656 double lenx = par.at(0);
1657 double leny = par.at(1);
1658 double lenz = par.at(2);
1659 double thick = par.at(3);
1661 G4Box* wedgeBox1 =
new G4Box(
"wedgeBox1", thick / 2., lenx / 2., leny / 2.);
1662 G4Box* wedgeBox2 =
new G4Box(
"wedgeBox2", lenz / 2., lenx / 2., thick / 2.);
1664 G4LogicalVolume* wedgeBox1LV =
new G4LogicalVolume(wedgeBox1, supportMaterial,
"ARICH.supportWedge");
1665 G4LogicalVolume* wedgeBox2LV =
new G4LogicalVolume(wedgeBox2, supportMaterial,
"ARICH.supportWedge");
1667 G4RotationMatrix Rm;
1668 G4ThreeVector Ta(0, 0, 0);
1670 Tr = G4Transform3D(Rm, Ta);
1672 assemblyWedge->AddPlacedVolume(wedgeBox1LV, Tr);
1674 Ta.setX(lenz / 2. + thick / 2.);
1675 Ta.setZ(leny / 2. - thick / 2.);
1676 Tr = G4Transform3D(Rm, Ta);
1677 assemblyWedge->AddPlacedVolume(wedgeBox2LV, Tr);
1679 if (size == 4)
return;
1680 double edge = par.at(4);
1682 G4Box* wedgeBox3 =
new G4Box(
"wedgeBox3", lenz / 2., edge / 2., thick / 2.);
1683 G4LogicalVolume* wedgeBox3LV =
new G4LogicalVolume(wedgeBox3, supportMaterial,
"ARICH.supportWedge");
1685 Ta.setZ(leny / 2. - thick - thick / 2.);
1686 Tr = G4Transform3D(Rm, Ta);
1687 assemblyWedge->AddPlacedVolume(wedgeBox3LV, Tr);
1689 G4Trap* wedgeBoxTmp =
new G4Trap(
"wedgeBoxTmp", thick, leny - 2 * thick, lenz, edge);
1690 G4LogicalVolume* wedgeBox4LV;
1692 G4Tubs* wedgeBoxTmp1 =
new G4Tubs(
"wedgeBoxTmp1", 0.0, par.at(5), thick, 0, 2.*M_PI);
1693 G4RotationMatrix rotHole;
1694 G4ThreeVector transHole(par.at(6), par.at(7), 0);
1695 G4SubtractionSolid* wedgeBox4 =
new G4SubtractionSolid(
"wedgeBox4", wedgeBoxTmp, wedgeBoxTmp1, G4Transform3D(rotHole, transHole));
1696 wedgeBox4LV =
new G4LogicalVolume(wedgeBox4, supportMaterial,
"ARICH.supportWedge");
1697 }
else wedgeBox4LV =
new G4LogicalVolume(wedgeBoxTmp, supportMaterial,
"ARICH.supportWedge");
1699 Rm.rotateX(-M_PI / 2.);
1700 Ta.setX(thick / 2. + edge / 4. + lenz / 4.);
1701 Ta.setZ(-thick / 2. - edge / 2.);
1702 Tr = G4Transform3D(Rm, Ta);
1703 assemblyWedge->AddPlacedVolume(wedgeBox4LV, Tr);
Geometry parameters of HAPD.
const std::vector< double > & getSimpleParams() const
Get parameters of simple aerogel configuration.
double getLayerThickness(unsigned iLayer) const
Get thickness of tiles in 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 thickness just after aerogel layers used as volume to which tracks are extrapolate...
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 getTileThickness(int ring, int column, int layerN) const
Get thickness of individual tile.
const std::string & getLayerMaterial(unsigned iLayer) const
Get material name of tiles in i-th aerogel layer.
const std::string & getSupportMaterial() const
Get material of support plate.
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.
Geometry parameters of cable envelope.
const std::string & getCablesEffectiveMaterialName() const
Returns Effective material name describing cables.
double getEnvelopeOuterRadius() const
Returns Outer radius 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
Get cold tube wall thickness.
const std::vector< double > & getCoolinRotationAngle() const
Get vector of azimuthal angle of rotation around Z - axis of the cooling system object in polar coord...
const std::vector< double > & getCoolingPosPhi() const
Get vector of azimuthal angle of the cooling system object center in polar coordinate system in deg.
double getEnvelopeOuterRadius() const
Get outer radius of cooling system assembly envelope.
const std::vector< double > & getCoolingGeometryID() const
Get vector of cooling system object geometry ID.
double getColdTubeSpacing() const
Get distance from center of the cold tube to edge of cooling plate.
const std::string & getCoolingPipeMaterialName() const
Get material name of cooling pipe.
double getColdTubeR() const
Get radius of cold tubes.
const std::vector< double > & getCoolingL() const
Get vector of lengs of the cooling system object with given geometry ID.
const std::vector< double > & getCoolingPosR() const
Get vector of radial distance (r, pho) of the cooling system object center in polar coordinate system...
const std::string & getColdTubeMaterialName() const
Get material name of cold tube.
const std::string & getCoolingTestPlateMaterialName() const
Get material name of cooling test plates.
double getRmax() const
Get size of cooling system pipe : outer radius in mm.
double getEnvelopeInnerRadius() const
Get inner radius of cooling system assembly envelope.
ROOT::Math::XYZVector getCoolingTestPlateslengths() const
Get sizes vector (ROOT::Math::XYZVector) of cooling test plates.
double getRmin() const
Get size of cooling system pipe : inner radius in mm.
double getDepthColdTubeInPlate() const
Get depth of the cold tube in the cooling plate.
double getEnvelopeThickness() const
Get thickness of cooling system assembly envelope.
double getColdTubeSubtractedR() const
Get outer radius of subtracted tubes for cold tube.
int getColdTubeNumber() const
Get 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 getRingDPhi(unsigned iRing) const
Get phi (angle) distance between module slots in i-th ring.
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.
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).
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.
double getSmallSquareThickness() const
Returns thickness of the small square in mm.
const std::vector< double > & getFebcoolingv2GeometryID() const
Returns vector of feb cooling configuration/geometry ID.
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.
Geometry parameters of HAPD.
double getSizeZ() const
Returns HAPD size in z.
const std::string & getFEBMaterial() const
Returns FEB material name.
double getAPDSizeZ() const
Returns APD size in z.
double getWinThickness() const
Returns window thickness.
const std::string & getAPDMaterial() const
Returns APD material name.
const GeoOpticalSurface & getAPDSurface() const
Returns APD reflective optical surface.
const std::string & getWallMaterial() const
Returns wall (casing) material name.
const std::string & getFillMaterial() const
Returns fill (inside) 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.
const std::string & getWinMaterial() const
Returns window material name.
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.
Geometry parameters of Merger PCB.
const std::vector< double > & getSingleMergerenvelopeDeltaZ() const
Returns vector of Z position of the single merger and merger cooling body envelope inside global merg...
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.
double getMergerPCBscrewholePosdX1() const
Returns merger PCB screw hole position from the bottom edge.
double getEnvelopeOuterRadius() const
Returns Outer radius of merger PCB assembly envelope.
const std::vector< double > & getMergerSlotID() const
Returns vector of merger boards slot numbers.
double getMergerPCBscrewholePosdX2() const
Returns merger PCB screw hole position from the top edge.
const std::vector< double > & getMergerAngle() const
Returns vector of merger boarts azimuthal angles in polar coordinate system in deg.
double getThickness() const
Returns merger PCB thickness.
ROOT::Math::XYZVector getSingleMergeEnvelopePosition() const
Returns position vector (ROOT::Math::XYZVector) of merger PCB inside the single merger envelope.
const std::vector< double > & getMergerOrientation() const
Returns vector of merger boarts orientations in deg.
const std::vector< double > & getMergerPosR() const
Returns vector of merger boards distances from the center in mm.
const std::string & getMergerPCBMaterialName() const
Returns merger PCB material name.
double getSingleMergerEnvelopeSizeW() const
Returns single merger PCB and merger cooling envelop width.
double getEnvelopeInnerRadius() const
Returns Inner radius of merger PCB assembly envelope.
double getSingleMergerEnvelopeSizeL() const
Returns single merger PCB and merger cooling envelop length.
double getSizeL() const
Returns merger PCB length.
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.
Geometry parameters of HAPD.
const GeoOpticalSurface & getMirrorSurface() const
Returns mirror reflective optical surface.
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 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::vector< double > getWedge(unsigned i) const
Get parameters of wedge.
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::string & getTubeMaterial(unsigned i) const
Get material of i-th tube.
int getWedgeType(unsigned i) const
Get type of i-th wedge.
unsigned getNWedges() const
Get number of wedges to be placed.
double getTubeZPosition(unsigned i) const
Get tube Z position.
const std::string & getWedgeMaterial(unsigned i) const
Get material of i-th wedge.
box getBox(unsigned i) const
Get box parameters.
const std::string & getTubeName(unsigned i) const
Get name of i-th tube.
unsigned getNBoxes() const
Get number of box volumes.
The Class for ARICH Geometry Parameters.
const ARICHGeoAerogelPlane & getAerogelPlane() const
Get geometry configuration of aerogel plane.
const ARICHGeoMerger & getMergerGeometry() const
Get Merger PCB geometry parameters.
const ARICHGeoFEBCooling & getFEBCoolingGeometry() const
Get ARICH FEB cooling system (v2) geometry parameters.
const ARICHGeoMirrors & getMirrors() const
Get mirrors geometry configuration.
const ARICHGeoHAPD & getHAPDGeometry() const
Get HAPD geometry parameters.
const ARICHGeoDetectorPlane & getDetectorPlane() const
Get geometry configuration of HAPD plane.
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
GeoARICHCreator()
Constructor of the GeoARICHCreator class.
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.
double sqrt(double a)
sqrt for double
Common code concerning the geometry representation of the detector.
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 indicating 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)
std::string material
material
double rotation[3]
rotation coordinates
double position[3]
position coordinates
double size[3]
size coordinates
Structure which holds apexes of the tessellation volumes.
std::vector< std::vector< double > > posV1
x, y, z of apex1.
std::vector< std::vector< double > > posV3
x, y, z of apex3.
std::vector< std::vector< double > > posV2
x, y, z of apex2.
unsigned int nCells
number of cells