Belle II Software development
GeoARICHCreator Class Reference

The creator for the ARICH geometry of the Belle II detector. More...

#include <GeoARICHCreator.h>

Inheritance diagram for GeoARICHCreator:
CreatorBase

Public Member Functions

 GeoARICHCreator ()
 Constructor of the GeoARICHCreator class.
 
virtual ~GeoARICHCreator ()
 The destructor of the GeoARICHreator class.
 
virtual void create (const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
 Creates the ROOT Objects for the ARICH geometry.
 
virtual void createPayloads (const GearDir &content, const IntervalOfValidity &iov) override
 creates DB payload for ARICHGeometryConfig class
 
virtual void createFromDB (const std::string &name, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
 Create the geometry from the Database.
 
 BELLE2_DEFINE_EXCEPTION (DBNotImplemented, "Cannot create geometry from Database.")
 Exception that will be thrown in createFromDB if member is not yet implemented by creator.
 

Private Member Functions

ARICHGeometryConfig createConfiguration (const GearDir &param)
 Reads ARICH geometry parameters from the xml files and createst DB class ARICHGeometryConfig.
 
void createGeometry (G4LogicalVolume &topVolume, geometry::GeometryTypes type)
 Create detector geometry.
 
G4LogicalVolume * buildHAPD (const ARICHGeoHAPD &hapdPar)
 build the HAPD modules
 
G4LogicalVolume * buildMerger (const ARICHGeoMerger &mergerGeo)
 build the merger PCB logical volume
 
G4LogicalVolume * buildMergerEnvelope (const ARICHGeoMerger &mergerGeo, int type)
 build single merger and merger cooling body envelope logical volume
 
G4LogicalVolume * buildCables (const ARICHGeoCablesEnvelope &cablesGeo)
 build the cables envelop with effective material describing cables
 
G4LogicalVolume * buildMirror (const ARICHGeometryConfig &detectorGeo)
 build mirrors
 
G4LogicalVolume * buildDetectorPlane (const ARICHGeometryConfig &detectorGeo)
 build detector plane
 
G4LogicalVolume * buildMergerPCBEnvelopePlane (const ARICHGeometryConfig &detectorGeo)
 build merger PCB assembly envelope plane
 
G4LogicalVolume * buildCoolingEnvelopePlane (const ARICHGeoCooling &coolingGeo)
 build cooling system assembly envelope plane
 
G4LogicalVolume * buildCoolingTube (const unsigned i_volumeID, const ARICHGeoCooling &coolingGeo)
 build cooling tube (G4Tubs)
 
G4LogicalVolume * buildCoolingTorus (const unsigned i_volumeID, const ARICHGeoCooling &coolingGeo)
 build cooling tube (G4Torus)
 
G4LogicalVolume * buildCoolingTestPlate (const ARICHGeoCooling &coolingGeo)
 build cooling test plates
 
G4LogicalVolume * buildFEBCoolingBody (const ARICHGeoFEBCooling &coolingv2Geo)
 build FEB cooling bodies (cooling system update after phase 2)
 
G4LogicalVolume * buildMergerCooling (unsigned iType)
 build merger cooling bodies (cooling system update after phase 2)
 
G4LogicalVolume * buildAerogelPlane (const ARICHGeometryConfig &detectorGeo)
 build aerogel plane
 
G4LogicalVolume * buildAerogelPlaneAveragedOverLayers (const ARICHGeometryConfig &detectorGeo)
 build aerogel plane with average properties of aerogel per layer
 
G4LogicalVolume * buildAerogelPlaneWithIndividualTilesProp (const ARICHGeometryConfig &detectorGeo)
 with individual properties of aerogel tiles
 
G4LogicalVolume * buildSimpleAerogelPlane (const ARICHGeometryConfig &detectorGeo)
 build simple aerogel plane (for cosmic test)
 
G4LogicalVolume * buildDetectorSupportPlate (const ARICHGeometryConfig &detectorGeo)
 build detector support plate
 
void makeJoint (G4Material *supportMaterial, const std::vector< double > &pars, G4AssemblyVolume *assemblyWedge)
 build joints of the ARICH support structure
 
double getAvgRINDEX (G4Material *material)
 get refractive index of the material
 

Private Attributes

ARICHGeometryConfig m_config
 geometry configuration
 
SensitiveDetectorm_sensitive
 pointer to sensitive detector
 
SensitiveAerom_sensitiveAero
 pointer to sensitive aerogel - used instead of tracking
 
int m_isBeamBkgStudy
 flag the beam background study
 
DBObjPtr< ARICHModulesInfom_modInfo
 information on installed modules from the DB
 
OptionalDBObjPtr< ARICHGeoMergerCoolingm_mergerCooling
 merger cooling bodies geometry from the DB
 

Detailed Description

The creator for the ARICH geometry of the Belle II detector.

Definition at line 40 of file GeoARICHCreator.h.

Constructor & Destructor Documentation

◆ GeoARICHCreator()

Constructor of the GeoARICHCreator class.

Definition at line 67 of file GeoARICHCreator.cc.

67 : m_isBeamBkgStudy(0)
68 {
69 m_sensitive = NULL;
70 m_sensitiveAero = NULL;
71 }

◆ ~GeoARICHCreator()

~GeoARICHCreator ( )
virtual

The destructor of the GeoARICHreator class.

Definition at line 73 of file GeoARICHCreator.cc.

74 {
75 delete m_sensitive;
76 delete m_sensitiveAero;
77 G4LogicalSkinSurface::CleanSurfaceTable();
78
79 }

Member Function Documentation

◆ buildAerogelPlane()

G4LogicalVolume * buildAerogelPlane ( const ARICHGeometryConfig & detectorGeo)
private

build aerogel plane

Definition at line 491 of file GeoARICHCreator.cc.

492 {
493 if (detectorGeo.getAerogelPlane().getFullAerogelMaterialDescriptionKey() == 0)
494 return buildAerogelPlaneAveragedOverLayers(detectorGeo);
495 else if (detectorGeo.getAerogelPlane().getFullAerogelMaterialDescriptionKey() == 1)
496 return buildAerogelPlaneWithIndividualTilesProp(detectorGeo);
497 else
498 B2ERROR("GeoARICHCreator::buildAerogelPlane --> getFullAerogelMaterialDescriptionKey() is wrong");
499 return NULL;
500 }

◆ buildAerogelPlaneAveragedOverLayers()

G4LogicalVolume * buildAerogelPlaneAveragedOverLayers ( const ARICHGeometryConfig & detectorGeo)
private

build aerogel plane with average properties of aerogel per layer

Definition at line 502 of file GeoARICHCreator.cc.

503 {
504
505 //cout<<"GeoARICHCreator::buildAerogelPlaneAveragedOverLayers(const ARICHGeometryConfig& detectorGeo)"<<endl;
506
507 const ARICHGeoAerogelPlane& aeroGeo = detectorGeo.getAerogelPlane();
508
509 // support plane
510 double rin = aeroGeo.getSupportInnerR();
511 double rout = aeroGeo.getSupportOuterR();
512 double thick = aeroGeo.getSupportThickness();
513 double wallThick = aeroGeo.getWallThickness();
514 double wallHeight = aeroGeo.getWallHeight();
515 string supportMat = aeroGeo.getSupportMaterial();
516 G4Material* supportMaterial = Materials::get(supportMat);
517 G4Material* gapMaterial = Materials::get("Air"); // Air without refractive index (to kill photons, to mimic black paper around tile)
518 G4Material* imgMaterial = Materials::get("ARICH_Air");
519 // master volume
520
521 //double imgTubeLen = 0.5; // if changed, change position of aerogel plane also in main function!!
522 double imgTubeLen = aeroGeo.getImgTubeThickness();
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");
525
526 // support plate
527 G4Tubs* supportTube = new G4Tubs("aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
528 G4LogicalVolume* supportTubeLV = new G4LogicalVolume(supportTube, supportMaterial, "ARICH.AerogelSupportPlate");
529 //supportTubeLV->SetSensitiveDetector(m_sensitiveAero);
530
531 // imaginary tube after aerogel layers (used as volume to which tracks are extrapolated by ext module)
532 G4Tubs* imgTube = new G4Tubs("imgTube", rin, rout, imgTubeLen / 2., 0, 2 * M_PI);
533 G4LogicalVolume* imgTubeLV = new G4LogicalVolume(imgTube, imgMaterial, "ARICH.AerogelImgPlate");
534 imgTubeLV->SetSensitiveDetector(m_sensitiveAero);
535
536
537 // read radiuses of aerogel slot aluminum walls
538 std::vector<double> wallR;
539 unsigned nRing = aeroGeo.getNRings();
540 for (unsigned iRing = 1; iRing < nRing + 1; iRing++) {
541 wallR.push_back(aeroGeo.getRingRadius(iRing));
542 }
543
544 unsigned nLayer = aeroGeo.getNLayers();
545 double tileGap = aeroGeo.getTileGap();
546 G4Transform3D transform = G4Translate3D(0., 0., (thick - imgTubeLen) / 2.);
547
548 for (unsigned iRing = 0; iRing < nRing; iRing++) {
549
550 // aluminum walls between tile rings (r wall)
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());
555
556 new G4PVPlacement(transform, supportWallLV, string("ARICH.") + wallName.str().c_str(), aerogelPlaneLV, false, 0);
557
558 if (iRing == 0) continue;
559
560 // place phi aluminum walls
561 double dphi = aeroGeo.getRingDPhi(iRing);
562
563 wallName.str("");
564 wallName << "supportWallPhi_" << iRing + 1;
565 G4Box* wall = new G4Box(wallName.str(), (wallR[iRing] - wallR[iRing - 1] - wallThick) / 2. - 1., thick / 2., wallHeight / 2.);
566 [[clang::suppress]]
567 G4LogicalVolume* wallLV = new G4LogicalVolume(wall, supportMaterial, string("ARICH.") + wallName.str());
568 double r = (wallR[iRing - 1] + wallThick + wallR[iRing]) / 2.;
569 double zLayer = 0;
570
571 // loop over layers
572 int iSlot = 1;
573 for (unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
574 double iphi = 0;
575 double layerThick = aeroGeo.getLayerThickness(iLayer);
576
577 std::stringstream tileName;
578 tileName << "aerogelTile_" << iRing << "_" << iLayer;
579
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]);
582
583 G4Material* aeroMaterial = Materials::get(aeroGeo.getLayerMaterial(iLayer));
584 [[clang::suppress]]
585 G4LogicalVolume* tileLV = new G4LogicalVolume(tileShape, aeroMaterial, string("ARICH.") + tileName.str());
586
587 while (iphi < 2 * M_PI - 0.0001) {
588 G4ThreeVector trans(r * cos(iphi), r * sin(iphi), (thick - imgTubeLen) / 2.);
589 G4RotationMatrix Ra;
590 Ra.rotateZ(iphi);
591
592 if (iLayer == 1) new G4PVPlacement(G4Transform3D(Ra, trans), wallLV, string("ARICH.") + wallName.str(), aerogelPlaneLV, false,
593 iSlot);
594
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);
597 iphi += dphi;
598 iSlot++;
599 }
600 zLayer += layerThick;
601 }
602 }
603
604 new G4PVPlacement(G4Translate3D(0., 0., -(wallHeight + imgTubeLen) / 2.), supportTubeLV, "ARICH.AerogelSupportPlate",
605 aerogelPlaneLV,
606 false, 1);
607
608 new G4PVPlacement(G4Translate3D(0., 0., (wallHeight + thick) / 2.), imgTubeLV, "ARICH.AerogelImgPlate", aerogelPlaneLV, false, 1);
609
610 return aerogelPlaneLV;
611
612 }

◆ buildAerogelPlaneWithIndividualTilesProp()

G4LogicalVolume * buildAerogelPlaneWithIndividualTilesProp ( const ARICHGeometryConfig & detectorGeo)
private

with individual properties of aerogel tiles

Definition at line 614 of file GeoARICHCreator.cc.

615 {
616
617 //cout << "GeoARICHCreator::buildAerogelPlaneWithIndividualTilesProp(const ARICHGeometryConfig& detectorGeo)" << endl;
618
619 const ARICHGeoAerogelPlane& aeroGeo = detectorGeo.getAerogelPlane();
620
621 // support plane
622 double rin = aeroGeo.getSupportInnerR();
623 double rout = aeroGeo.getSupportOuterR();
624 double thick = aeroGeo.getSupportThickness();
625 double wallThick = aeroGeo.getWallThickness();
626 // Maximum total (up and down) thickness of the aerogel tiles
627 double maxTotalAerogelThick = aeroGeo.getMaximumTotalTileThickness();
628 //cout<<"maxTotalAerogelThick "<<maxTotalAerogelThick<<endl
629 // <<"wallHeight "<<wallHeight<<endl;
630 // In case of individual thickness of the tiles we need to define compensation
631 // volume with ARICH air. This volume situated between aerogel tile and image plane (imgTube).
632 // Minimum thickness of the compensation volume with ARICH air
633 double compensationARICHairVolumeThick_min = aeroGeo.getCompensationARICHairVolumeThick_min(); // mm
634 // Please note redefinition of wallHeight value
635 double wallHeight = maxTotalAerogelThick + compensationARICHairVolumeThick_min;
636
637 string supportMat = aeroGeo.getSupportMaterial();
638 G4Material* supportMaterial = Materials::get(supportMat);
639
640 G4Material* gapMaterial =
641 Materials::get("Air"); // Air without refractive index (to kill photons, to mimic black paper around tile)
642 G4Material* imgMaterial = Materials::get("ARICH_Air"); // Air with defined optical properties to propagate cherenkov photons
643
644 // master volume
645 double imgTubeLen = aeroGeo.getImgTubeThickness(); // if changed, change position of aerogel plane also in main function!!
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");
648
649 // support plate
650 G4Tubs* supportTube = new G4Tubs("aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
651 G4LogicalVolume* supportTubeLV = new G4LogicalVolume(supportTube, supportMaterial, "ARICH.AerogelSupportPlate");
652 //supportTubeLV->SetSensitiveDetector(m_sensitiveAero);
653
654 // imaginary tube after aerogel layers (used as volume to which tracks are extrapolated by ext module)
655 G4Tubs* imgTube = new G4Tubs("imgTube", rin, rout, imgTubeLen / 2., 0, 2 * M_PI);
656 G4LogicalVolume* imgTubeLV = new G4LogicalVolume(imgTube, imgMaterial, "ARICH.AerogelImgPlate");
657 imgTubeLV->SetSensitiveDetector(m_sensitiveAero);
658
659 // read radiuses of aerogel slot aluminum walls
660 std::vector<double> wallR;
661 unsigned nRing = aeroGeo.getNRings();
662 for (unsigned iRing = 1; iRing < nRing + 1; iRing++) {
663 wallR.push_back(aeroGeo.getRingRadius(iRing));
664 }
665
666 unsigned nLayer = aeroGeo.getNLayers();
667 double tileGap = aeroGeo.getTileGap();
668 G4Transform3D transform = G4Translate3D(0., 0., (thick - imgTubeLen) / 2.);
669
670 for (unsigned iRing = 0; iRing < nRing; iRing++) {
671
672 // Aluminum walls between tile rings (r wall)
673 std::stringstream wallName;
674 wallName << "supportWallR_" << iRing + 1;
675 //cout<<"wallName = "<<wallName.str().c_str()<<endl;
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);
680
681 // There are only 4 rings of aerogel - the first one is only for mechanical support
682 if (iRing == 0) continue;
683
684 // dphi - distance between centers of two consecutive aluminum walls (diaphragm) in one ring
685 double dphi = aeroGeo.getRingDPhi(iRing);
686
687 // Aluminum walls (diaphragm) between two neighboring tile in one ring (phi wall)
688 wallName.str("");
689 wallName << "supportWallPhi_" << iRing + 1;
690 G4Box* wall = new G4Box(wallName.str(), (wallR[iRing] - wallR[iRing - 1] - wallThick) / 2. - 1., thick / 2., wallHeight / 2.);
691 [[clang::suppress]]
692 G4LogicalVolume* wallLV = new G4LogicalVolume(wall, supportMaterial, string("ARICH.") + wallName.str());
693 double r = (wallR[iRing - 1] + wallThick + wallR[iRing]) / 2.;
695
696 // loop over layers
697 int icopyNumber = 0;
698 for (unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
699 //int iSlot = 1;
700 double iphi = 0;
701
702 int iicolumn = 0;
703 // loop over phi (over tile slots from same ring)
704 while (iphi < 2 * M_PI - 0.0001) {
705
706 // Define layer thickness as -1 in case it will not be defined
707 // below in the code with a appropriate value - Geant4 will trigger error
708 double layerThick = -1.0;
709 double tileUpThick = -1.0;
710 double tileDownThick = -1.0;
711 //cout<<" double layerThick = aeroGeo.getLayerThickness(iLayer) = "<<layerThick<<endl;
712
713 // Define material and thickness
714 G4Material* aeroMaterial = NULL;
715 int ati_ring = iRing;
716 int ati_column = iicolumn + 1;
717 int ati_layerN = iLayer - 1;
718
719 //cout<<setw(5)<<ati_layerN<<setw(5)<<ati_ring<<setw(5)<<ati_column<<endl;
720 if (detectorGeo.getAerogelPlane().getFullAerogelMaterialDescriptionKey() == 1) {
721 aeroMaterial = Materials::get(aeroGeo.getTileMaterialName(ati_ring, ati_column, ati_layerN).c_str());
722 } else {
723 B2ERROR("GeoARICHCreator::buildAerogelPlaneWithIndividualTilesProp --> getFullAerogelMaterialDescriptionKey() is wrong");
724 }
725 //cout<<"-----------------"<<endl
726 // <<"iLayer = "<<iLayer<<endl
727 // <<aeroMaterial->GetName()<<endl;
728 //cout<<setw(5)<<ati_layerN<<setw(5)<<ati_ring<<setw(5)<<ati_column<<endl;
729 //aeroMaterial->GetMaterialPropertiesTable()->DumpTable();
730 //zcout<<"ooooooooooooooooo"<<endl;
731 layerThick = aeroGeo.getTileThickness(ati_ring, ati_column, ati_layerN);
732 tileUpThick = aeroGeo.getTileThickness(ati_ring, ati_column, 0);
733 tileDownThick = aeroGeo.getTileThickness(ati_ring, ati_column, 1);
734
735 // Placement of the aluminum walls (diaphragm) between two neighboring tile in one ring (phi wall)
736 // please note that we place single wall for two aerogel layers
737 G4ThreeVector trans(r * cos(iphi), r * sin(iphi), (thick - imgTubeLen) / 2.);
738 G4RotationMatrix Ra;
739 Ra.rotateZ(iphi);
740 if (iLayer == 1) {
741 new G4PVPlacement(G4Transform3D(Ra, trans), //transformation
742 wallLV, //its logical
743 string("ARICH.") + wallName.str(), //name
744 aerogelPlaneLV, //mother logical
745 false, //always false
746 icopyNumber); //should be set to 0 for the first volume of a given type.
748
749 // In case of individual thickness
750 // (if aeroGeo.getFullAerogelMaterialDescriptionKey() == 1) or
751 // (if aeroGeo.getFullAerogelMaterialDescriptionKey() == 2)
752 // of the tiles we need to define compensation volume with ARICH air.
753 // This volume situated between aerogel tile and image plane (imgTube).
754 // This volume have same shape as earogel tile but different thickness.
755 // Build Compensation tiles only one time
756 // Compensation tile shape
757 double compTileUpThick = wallHeight - tileUpThick - tileDownThick;
758 std::stringstream compTileName;
759 //compTileName << "aerogelCompTile_" << ati_layerN << "_" << ati_ring << "_" << ati_column;
760 // In the end of the name we have Layer(L), Ring(R), Slot/Column(S) id's
761 // L : 1-2
762 // R : 1-4
763 // S : 1-22 @ R = 1
764 // S : 1-28 @ R = 2
765 // S : 1-34 @ R = 3
766 // S : 1-40 @ R = 4
767 compTileName << "aerogelCompTile_" << iLayer << "_" << ati_ring << "_" << ati_column;
768 //cout<<compTileName.str()<<endl;
769 G4Tubs* compTileShape = new G4Tubs(compTileName.str(), //name
770 wallR[iRing - 1] + wallThick + tileGap, //Rmin
771 wallR[iRing] - tileGap, //Rmax
772 compTileUpThick / 2.0, //Thickness
773 (tileGap + wallThick / 2.0) / wallR[iRing], //phi start
774 dphi - (2.0 * tileGap + wallThick) / wallR[iRing]); //delta phi
775
776 // Logical volume of the compensation tiles
777 G4LogicalVolume* compTileLV = new G4LogicalVolume(compTileShape, //Its solid
778 imgMaterial, //G4 material
779 string("ARICH.") + compTileName.str()); //name
780
781 // Placement of the compensation tiles
782 G4ThreeVector transCompTile(0, 0, (thick + wallHeight - compTileUpThick - imgTubeLen) / 2.0);
783 G4RotationMatrix compRa;
784 compRa.rotateZ(iphi);
785 new G4PVPlacement(G4Transform3D(compRa, transCompTile), //transformation
786 compTileLV, //its logical
787 string("ARICH.") + compTileName.str(), //name
788 aerogelPlaneLV, //mother logical
789 false, //always false
790 0); //should be set to 0 for the first volume of a given type.
791 }
792
793 // Tile shape
794 std::stringstream tileName;
795 tileName << "aerogelTile_" << iLayer << "_" << ati_ring << "_" << ati_column;
796 //cout<<tileName.str()<<endl;
797 G4Tubs* tileShape = new G4Tubs(tileName.str(), //name
798 wallR[iRing - 1] + wallThick + tileGap, //Rmin
799 wallR[iRing] - tileGap, //Rmax
800 layerThick / 2.0, //Thickness
801 (tileGap + wallThick / 2.0) / wallR[iRing], //phi start
802 dphi - (2.0 * tileGap + wallThick) / wallR[iRing]); //delta phi
803
804 // Logical volume of the aerogel tiles
805 G4LogicalVolume* tileLV = new G4LogicalVolume(tileShape, //Its solid
806 aeroMaterial, //G4 material
807 string("ARICH.") + tileName.str()); //name
808
809 // Placement of the aerogel tiles
810 double zLayer = 0.0;
811 if (iLayer == 2)
812 zLayer = tileUpThick;
813 G4ThreeVector transTile(0, 0, (thick + layerThick - wallHeight - imgTubeLen) / 2.0 + zLayer);
814 new G4PVPlacement(G4Transform3D(Ra, transTile), //transformation
815 tileLV, //its logical
816 string("ARICH.") + tileName.str(), //name
817 aerogelPlaneLV, //mother logical
818 false, //always false
819 0); //should be set to 0 for the first volume of a given type.
821
822 iphi += dphi;
823 //iSlot++;
824 icopyNumber++;
825 iicolumn++;
826 }
827 }
828 }
829
830 // Placement of the support tube
831 new G4PVPlacement(G4Translate3D(0., 0., -(wallHeight + imgTubeLen) / 2.), //transformation
832 supportTubeLV, //its logical
833 "ARICH.AerogelSupportPlate", //name
834 aerogelPlaneLV, //mother logical
835 false, //always false
836 0); //should be set to 0 for the first volume of a given type.
837
838 // Placement of the imaginary tube after aerogel layers (used as volume to which tracks are extrapolated by ext module)
839 new G4PVPlacement(G4Translate3D(0., 0., (wallHeight + thick) / 2.), //transformation
840 imgTubeLV, //its logical
841 "ARICH.AerogelImgPlate", //name
842 aerogelPlaneLV, //mother logical
843 false, //always false
844 0); //should be set to 0 for the first volume of a given type.
845
846 return aerogelPlaneLV;
847
848 }

◆ buildCables()

G4LogicalVolume * buildCables ( const ARICHGeoCablesEnvelope & cablesGeo)
private

build the cables envelop with effective material describing cables

Definition at line 1168 of file GeoARICHCreator.cc.

1169 {
1170
1171 G4Tubs* cablesEnvelope_solid = new G4Tubs("cablesEnvelope_solid",
1172 cablesGeo.getEnvelopeInnerRadius(),
1173 cablesGeo.getEnvelopeOuterRadius(),
1174 cablesGeo.getEnvelopeThickness() / 2.0,
1175 0.0,
1176 2.0 * M_PI);
1177 G4LogicalVolume* cablesEnvelope_logical = new G4LogicalVolume(cablesEnvelope_solid,
1178 Materials::get(cablesGeo.getCablesEffectiveMaterialName()),
1179 "ARICH.cablesEnvelope");
1180
1181 return cablesEnvelope_logical;
1182
1183 }

◆ buildCoolingEnvelopePlane()

G4LogicalVolume * buildCoolingEnvelopePlane ( const ARICHGeoCooling & coolingGeo)
private

build cooling system assembly envelope plane

Definition at line 1336 of file GeoARICHCreator.cc.

1337 {
1338
1339 G4Tubs* coolingEnvelope_solid = new G4Tubs("coolingEnvelope_solid",
1340 coolingGeo.getEnvelopeInnerRadius(),
1341 coolingGeo.getEnvelopeOuterRadius(),
1342 coolingGeo.getEnvelopeThickness() / 2.0,
1343 0.0,
1344 2.0 * M_PI);
1345 G4LogicalVolume* coolingEnvelope_logical = new G4LogicalVolume(coolingEnvelope_solid,
1346 Materials::get("Air"),
1347 "ARICH.coolingEnvelope");
1348
1349 unsigned nComponents = coolingGeo.getCoolingGeometryID().size();
1350
1351 for (unsigned i = 0; i < nComponents; i++) {
1352 double r = coolingGeo.getCoolingPosR().at(i) * mm;
1353 double phi = coolingGeo.getCoolingPosPhi().at(i) * deg;
1354 G4ThreeVector Ta;
1355 G4RotationMatrix Ra;
1356 G4LogicalVolume* coolingComponentLV;
1357 if (coolingGeo.getCoolingGeometryID().at(i) == 1) {
1358 //<!-- 1 -> G4Tubs --> build a tube
1359 Ta.set(r * cos(phi), r * sin(phi), 0);
1360 //First need to rotate around y axis
1361 //to make the tube parallel with x axis
1362 Ra.rotateY(90.0 * deg);
1363 Ra.rotateZ(coolingGeo.getCoolinRotationAngle().at(i) * deg);
1364 coolingComponentLV = buildCoolingTube(i, coolingGeo);
1365 } else if (coolingGeo.getCoolingGeometryID().at(i) == 2) {
1366 //<!-- 2 -> G4Torus --> build a torus
1367 coolingComponentLV = buildCoolingTorus(i, coolingGeo);
1368 } else {
1369 B2FATAL("ARICH cooling geometry component ID is wrong");
1370 }
1371 new G4PVPlacement(G4Transform3D(Ra, Ta), //Transformation
1372 coolingComponentLV, //its logical volume
1373 "ARICH.cooling", //its name
1374 coolingEnvelope_logical, //its mother volume
1375 false, //no boolean operation
1376 i); //copy number
1377 }
1378
1379 return coolingEnvelope_logical;
1380
1381 }

◆ buildCoolingTestPlate()

G4LogicalVolume * buildCoolingTestPlate ( const ARICHGeoCooling & coolingGeo)
private

build cooling test plates

Definition at line 1383 of file GeoARICHCreator.cc.

1384 {
1385
1386 G4Box* coolingTestPlateEnvelop_solid = new G4Box("coolingTestPlateEnvelop_solid",
1387 coolingGeo.getCoolingTestPlateslengths().X() / 2.0 * mm,
1388 coolingGeo.getCoolingTestPlateslengths().Y() / 2.0 * mm,
1389 coolingGeo.getCoolingTestPlateslengths().Z() / 2.0 * mm);
1390 G4LogicalVolume* coolingTestPlateEnvelop_logical = new G4LogicalVolume(coolingTestPlateEnvelop_solid, Materials::get("Air"),
1391 "ARICH.coolingTestPlateEnvelop");
1392
1393 G4Box* coolingTestPlate_solid = new G4Box("coolingTestPlate_solid",
1394 coolingGeo.getCoolingTestPlateslengths().X() / 2.0 * mm,
1395 coolingGeo.getCoolingTestPlateslengths().Y() / 2.0 * mm,
1396 coolingGeo.getCoolingTestPlateslengths().Z() / 2.0 * mm);
1397
1398 // Volume to subtract
1399 G4VSolid* coldTubeSubtracted_solid = new G4Tubs("coldTubeSubtracted_solid",
1400 0.0,
1401 coolingGeo.getColdTubeSubtractedR() * mm,
1402 (coolingGeo.getCoolingTestPlateslengths().X() + 1) / 2.0 * mm,
1403 0, 360.0 * deg);
1404
1405 // Volume to add (cold tube)
1406 G4VSolid* coldTube_solid = new G4Tubs("coldTube_solid",
1407 (coolingGeo.getColdTubeR() - coolingGeo.getColdTubeWallThickness()) * mm,
1408 coolingGeo.getColdTubeR() * mm,
1409 coolingGeo.getCoolingTestPlateslengths().X() / 2.0 * mm,
1410 0, 360.0 * deg);
1411 [[clang::suppress]]
1412 G4LogicalVolume* coldTube_logical = new G4LogicalVolume(coldTube_solid, Materials::get(coolingGeo.getColdTubeMaterialName()),
1413 "ARICH.coldTube");
1414
1415 G4RotationMatrix Ra_sub;
1416 G4ThreeVector Ta_sub;
1417 G4Transform3D Tr_sub;
1418 Ta_sub.setX(0.0);
1419 Ta_sub.setY((coolingGeo.getCoolingTestPlateslengths().Y() / 2.0 - coolingGeo.getColdTubeSpacing()) * mm);
1420 Ta_sub.setZ((coolingGeo.getCoolingTestPlateslengths().Z() / 2.0 - coolingGeo.getDepthColdTubeInPlate()) * mm);
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);
1425 for (int i = 1; i < coolingGeo.getColdTubeNumber(); i++) {
1426 Ta_sub.setX(0.0);
1427 Ta_sub.setY((coolingGeo.getCoolingTestPlateslengths().Y() / 2.0 - coolingGeo.getColdTubeSpacing() - coolingGeo.getColdTubeSpacing()
1428 * 2 * i) * mm);
1429 Ta_sub.setZ((coolingGeo.getCoolingTestPlateslengths().Z() / 2.0 - coolingGeo.getDepthColdTubeInPlate()) * mm);
1430 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1431 substraction_solid = new G4SubtractionSolid("substraction_solid", substraction_solid, coldTubeSubtracted_solid, Tr_sub);
1432 }
1433
1434 G4LogicalVolume* coolingTestPlate_logical = new G4LogicalVolume(substraction_solid,
1435 Materials::get(coolingGeo.getCoolingTestPlateMaterialName()), "ARICH.coolingTestPlate");
1436
1437 new G4PVPlacement(G4Transform3D(), //Transformation
1438 coolingTestPlate_logical, //its logical volume
1439 "ARICH.coolingTestPlate", //its name
1440 coolingTestPlateEnvelop_logical, //its mother volume
1441 false, //no boolean operation
1442 0); //copy number
1443 //Add cold tubes
1444 G4RotationMatrix Ra;
1445 G4ThreeVector Ta;
1446 G4Transform3D Tr;
1447 Ra.rotateY(90.0 * deg);
1448 for (int i = 0; i < coolingGeo.getColdTubeNumber(); i++) {
1449 Ta.setX(0.0);
1450 Ta.setY((coolingGeo.getCoolingTestPlateslengths().Y() / 2.0 - coolingGeo.getColdTubeSpacing() - coolingGeo.getColdTubeSpacing() *
1451 2 * i) * mm);
1452 Ta.setZ((coolingGeo.getCoolingTestPlateslengths().Z() / 2.0 - coolingGeo.getDepthColdTubeInPlate()) * mm);
1453 Tr = G4Transform3D(Ra, Ta);
1454 new G4PVPlacement(Tr, //Transformation
1455 coldTube_logical, //its logical volume
1456 "ARICH.coldTube", //its name
1457 coolingTestPlateEnvelop_logical, //its mother volume
1458 false, //no boolean operation
1459 0); //copy number
1460 }
1461
1462 return coolingTestPlateEnvelop_logical;
1463
1464 }

◆ buildCoolingTorus()

G4LogicalVolume * buildCoolingTorus ( const unsigned i_volumeID,
const ARICHGeoCooling & coolingGeo )
private

build cooling tube (G4Torus)

Definition at line 1314 of file GeoARICHCreator.cc.

1315 {
1316
1317 B2ASSERT("ARICH cooling geometry ID (G4Torus) is wrong : coolingGeo.getCoolingGeometryID.at(i_volumeID) != 2",
1318 coolingGeo.getCoolingGeometryID().at(i_volumeID) == 2);
1319
1320 double pSPhi = coolingGeo.getCoolingPosPhi().at(i_volumeID) * deg - coolingGeo.getCoolingL().at(
1321 i_volumeID) / coolingGeo.getCoolingPosR().at(i_volumeID) / 2.0;
1322 //double pDPhi = coolingGeo.getCoolingPosPhi().at(i_volumeID)*deg + coolingGeo.getCoolingL().at(i_volumeID) / coolingGeo.getCoolingPosR().at(i_volumeID) / 2.0;
1323 double pDPhi = coolingGeo.getCoolingL().at(i_volumeID) / coolingGeo.getCoolingPosR().at(i_volumeID);
1324
1325 G4Torus* coolingTorus_solid = new G4Torus("coolingTorus_solid", // name
1326 coolingGeo.getRmin(), // pRmin
1327 coolingGeo.getRmax(), // pRmax
1328 coolingGeo.getCoolingPosR().at(i_volumeID), // pRtor
1329 pSPhi, // pSPhi
1330 pDPhi); // pDPhi
1331
1332 return new G4LogicalVolume(coolingTorus_solid, Materials::get(coolingGeo.getCoolingPipeMaterialName()), "ARICH.coolingTorus");
1333
1334 }

◆ buildCoolingTube()

G4LogicalVolume * buildCoolingTube ( const unsigned i_volumeID,
const ARICHGeoCooling & coolingGeo )
private

build cooling tube (G4Tubs)

Definition at line 1299 of file GeoARICHCreator.cc.

1300 {
1301
1302 B2ASSERT("ARICH cooling geometry ID (G4Tube) is wrong : coolingGeo.getCoolingGeometryID.at(i_volumeID) != 1",
1303 coolingGeo.getCoolingGeometryID().at(i_volumeID) == 1);
1304 G4Tubs* coolingTube_solid = new G4Tubs("coolingTube_solid",
1305 coolingGeo.getRmin() * mm,
1306 coolingGeo.getRmax() * mm,
1307 coolingGeo.getCoolingL().at(i_volumeID) * mm / 2.0,
1308 0.0,
1309 2.0 * M_PI);
1310 return new G4LogicalVolume(coolingTube_solid, Materials::get(coolingGeo.getCoolingPipeMaterialName()), "ARICH.coolingTube");
1311
1312 }

◆ buildDetectorPlane()

G4LogicalVolume * buildDetectorPlane ( const ARICHGeometryConfig & detectorGeo)
private

build detector plane

Definition at line 945 of file GeoARICHCreator.cc.

946 {
947
948 const ARICHGeoHAPD& hapdGeo = detectorGeo.getHAPDGeometry();
949 G4LogicalVolume* hapdLV = buildHAPD(hapdGeo);
950
951 const ARICHGeoDetectorPlane& detGeo = detectorGeo.getDetectorPlane();
952
953 G4Tubs* detTube = new G4Tubs("detTube", detGeo.getRingR(1) - hapdGeo.getSizeX() * 1.4 / 2.,
954 detGeo.getRingR(detGeo.getNRings()) + hapdGeo.getSizeX() * 1.4 / 2., hapdGeo.getModuleSizeZ() / 2., 0, 2 * M_PI);
955 G4LogicalVolume* detPlaneLV = new G4LogicalVolume(detTube, Materials::get("ARICH_Air"), "ARICH.detectorPlane");
956
957 unsigned nSlots = detGeo.getNSlots();
958
959 for (unsigned iSlot = 1; iSlot < nSlots + 1; iSlot++) {
960 if (!m_modInfo->isInstalled(iSlot)) continue;
961 double r = detGeo.getSlotR(iSlot);
962 double phi = detGeo.getSlotPhi(iSlot);
963 G4ThreeVector trans(r * cos(phi), r * sin(phi), 0);
964 G4RotationMatrix Ra;
965 Ra.rotateZ(phi);
966 G4ThreeVector trans1(r * cos(phi), r * sin(phi), 0.0);
967 new G4PVPlacement(G4Transform3D(Ra, trans1), hapdLV, "ARICH.HAPDModule", detPlaneLV, false, iSlot);
968 }
969
970 return detPlaneLV;
971
972 }

◆ buildDetectorSupportPlate()

G4LogicalVolume * buildDetectorSupportPlate ( const ARICHGeometryConfig & detectorGeo)
private

build detector support plate

Definition at line 1466 of file GeoARICHCreator.cc.

1467 {
1468
1469 const ARICHGeoDetectorPlane& detGeo = detectorGeo.getDetectorPlane();
1470
1471 G4Tubs* supportTube = new G4Tubs("supportTube", detGeo.getSupportInnerR(), detGeo.getSupportOuterR(),
1472 (detGeo.getSupportThickness() + detGeo.getSupportBackWallHeight()) / 2., 0, 2 * M_PI);
1473 G4Material* supportMaterial = Materials::get(detGeo.getSupportMaterial());
1474 G4LogicalVolume* detSupportLV = new G4LogicalVolume(supportTube, supportMaterial, "ARICH.detectorSupportPlate");
1475
1476 G4Tubs* supportPlate = new G4Tubs("supportPlate", detGeo.getSupportInnerR(), detGeo.getSupportOuterR(),
1477 detGeo.getSupportThickness() / 2., 0, 2 * M_PI);
1478
1479 G4Box* hole = new G4Box("hole", detGeo.getModuleHoleSize() / 2., detGeo.getModuleHoleSize() / 2.,
1480 detGeo.getSupportThickness() / 2.); // +1 for thickness for subtraction solid
1481 [[clang::suppress]]
1482 G4LogicalVolume* holeLV = new G4LogicalVolume(hole, Materials::get("Air"), "ARICH.detectorSupportHole");
1483
1484 int nRings = detGeo.getNRings();
1485 std::vector<G4LogicalVolume*> hapdBackRadialWallLV;
1486 double backWallThick = detGeo.getSupportBackWallThickness();
1487 double backWallHeight = detGeo.getSupportBackWallHeight();
1488
1489 [[clang::suppress]]
1490 G4LogicalVolume* hapdSupportPlateLV = new G4LogicalVolume(supportPlate, supportMaterial, "hapdSupport");
1491
1492 std::vector<double> wallR;
1493 wallR.assign(nRings + 1, 0);
1494 std::vector<double> thickR;
1495 thickR.assign(nRings + 1, 0);
1496
1497 for (int i = 1; i < nRings; i++) {
1498 double rm1 = detGeo.getRingR(i);
1499 double rp1 = detGeo.getRingR(i + 1);
1500 wallR[i] = (rp1 + rm1) / 2.;
1501 if (i == 1) {
1502 wallR[0] = rm1 - (rp1 - rm1) / 2.;
1503 }
1504 if (i == nRings - 1) {
1505 wallR[i + 1] = rp1 + (rp1 - rm1) / 2.;
1506 }
1507 }
1508
1509 for (int i = 0; i < nRings + 1; i++) {
1510 std::stringstream ringName1;
1511 ringName1 << "backWall_" << i;
1512 thickR[i] = backWallThick;
1513 if (i == nRings) {
1514 thickR[i] = 2.*backWallThick;
1515 wallR[i] = detGeo.getSupportOuterR() - thickR[i] / 2.;
1516 }
1517 G4Tubs* backTube = new G4Tubs("hapdBackRing", wallR[i] - thickR[i] / 2., wallR[i] + thickR[i] / 2., backWallHeight / 2., 0,
1518 2 * M_PI);
1519 G4LogicalVolume* hapdBackTubeLV = new G4LogicalVolume(backTube, supportMaterial, "backTube");
1520 G4Transform3D transform3 = G4Translate3D(0., 0., detGeo.getSupportThickness() / 2.);
1521 new G4PVPlacement(transform3, hapdBackTubeLV, "backTube", detSupportLV, false, 1);
1522 if (i == 0) continue;
1523
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()));
1527 }
1528
1529 G4SubtractionSolid* substraction = NULL;
1530 unsigned nSlots = detGeo.getNSlots();
1531
1532 if (nSlots > detectorGeo.getFEBCoolingGeometry().getFebcoolingv2GeometryID().size()) {
1533 B2WARNING("GeoARICHCreator: No FEB colling body geometry available so they will not be placed (ARICHGeometryConfig with ClasDef>4 is needed).");
1534 return detSupportLV;
1535 }
1536
1537 // drill holes in support plate
1538 // add FEB cooling bodies
1539 for (unsigned iSlot = 1; iSlot < nSlots + 1; iSlot++) {
1540 unsigned iRing = detGeo.getSlotRing(iSlot);
1541 double r = (wallR[iRing] + wallR[iRing - 1]) / 2. - (thickR[iRing] - thickR[iRing - 1]) / 2.;
1542
1543 double phi = detGeo.getSlotPhi(iSlot);
1544 G4ThreeVector trans(r * cos(phi), r * sin(phi), 0);
1545 G4RotationMatrix Ra;
1546 Ra.rotateZ(phi);
1547
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));
1551
1552 phi = phi + detGeo.getRingDPhi(iRing) / 2.;
1553 G4ThreeVector transBack(r * cos(phi), r * sin(phi), detGeo.getSupportThickness() / 2.);
1554 G4RotationMatrix RaBack;
1555 RaBack.rotateZ(phi);
1556 new G4PVPlacement(G4Transform3D(RaBack, transBack), hapdBackRadialWallLV[iRing - 1], "hapdBack", detSupportLV, false, iSlot);
1557
1558 // add FEB cooling bodies
1559 G4ThreeVector febCoolingTa;
1560 G4Transform3D febCoolingTr;
1561 febCoolingTa.setX(r * cos(detGeo.getSlotPhi(iSlot)));
1562 febCoolingTa.setY(r * sin(detGeo.getSlotPhi(iSlot)));
1563
1564 double supportTube_envelope_dZ = (detGeo.getSupportThickness() + detGeo.getSupportBackWallHeight());
1565 double febCooling_envelope_dZ = (detectorGeo.getFEBCoolingGeometry().getBigSquareThickness() +
1566 detectorGeo.getFEBCoolingGeometry().getRectangleThickness());
1567 double febCooling_envelope_Z0 = -supportTube_envelope_dZ / 2.0 + febCooling_envelope_dZ / 2.0 + detGeo.getSupportThickness();
1568 febCoolingTa.setZ(febCooling_envelope_Z0);
1569
1570 int febcoolingv2GeometryID = detectorGeo.getFEBCoolingGeometry().getFebcoolingv2GeometryID().at(iSlot - 1);
1571
1572 if (febcoolingv2GeometryID == 2) Ra.rotateZ(90.0 * deg);
1573
1574 febCoolingTr = G4Transform3D(Ra, febCoolingTa);
1575
1576 if (febcoolingv2GeometryID != 0) {
1577 G4LogicalVolume* febCoolingLV = buildFEBCoolingBody(detectorGeo.getFEBCoolingGeometry());
1578
1579 new G4PVPlacement(febCoolingTr, //Transformation
1580 febCoolingLV, //its logical volume
1581 "febCoolingLV", //its name
1582 detSupportLV, //its mother volume
1583 false, //no boolean operation
1584 iSlot); //copy number
1585 }
1586 }
1587
1588 // G4LogicalVolume* hapdSupportPlateLV = new G4LogicalVolume(substraction, supportMaterial, "hapdSupport");
1589
1590 G4Transform3D transform3 = G4Translate3D(0., 0., - backWallHeight / 2.);
1591 new G4PVPlacement(transform3, hapdSupportPlateLV, "supportPlate", detSupportLV, false, 1);
1592
1593 // place electronics side neutron shield - for now hardcoded here, pending for more proper implementation!
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;
1604 rot.rotateZ(phi);
1605 G4ThreeVector trans(r1 * cos(phi), r1 * sin(phi), detGeo.getSupportThickness() / 2.);
1606 G4ThreeVector trans1(r2 * cos(phi), r2 * sin(phi), detGeo.getSupportThickness() / 2.);
1607 new G4PVPlacement(G4Transform3D(rot, trans), shield1, "ARICH.FWDShield1", detSupportLV, false, i);
1608 new G4PVPlacement(G4Transform3D(rot, trans1), shield2, "ARICH.FWDShield2", detSupportLV, false, i);
1609 }
1610
1611 return detSupportLV;
1612 }

◆ buildFEBCoolingBody()

G4LogicalVolume * buildFEBCoolingBody ( const ARICHGeoFEBCooling & coolingv2Geo)
private

build FEB cooling bodies (cooling system update after phase 2)

Definition at line 1185 of file GeoARICHCreator.cc.

1186 {
1187
1188 //FEB aluminum cooling envelope for single object
1189 double feb_alcooling_singleObjectEnvelope_sizeX = (2 * coolingv2Geo.getSmallSquareSize() + coolingv2Geo.getBigSquareSize() + 2.0) *
1190 mm;
1191 double feb_alcooling_singleObjectEnvelope_sizeY = feb_alcooling_singleObjectEnvelope_sizeX * mm;
1192 double feb_alcooling_singleObjectEnvelope_sizeZ = (coolingv2Geo.getSmallSquareThickness() + coolingv2Geo.getRectangleThickness()) *
1193 mm;
1194
1195 double feb_alcooling_box1_sizeX = coolingv2Geo.getSmallSquareSize() * mm;
1196 double feb_alcooling_box1_sizeY = feb_alcooling_box1_sizeX;
1197 double feb_alcooling_box1_sizeZ = coolingv2Geo.getSmallSquareThickness() * mm;
1198
1199 double feb_alcooling_box2_sizeX = coolingv2Geo.getBigSquareSize() * mm;
1200 double feb_alcooling_box2_sizeY = feb_alcooling_box2_sizeX;
1201 double feb_alcooling_box2_sizeZ = coolingv2Geo.getBigSquareThickness() * mm;
1202
1203 double feb_alcooling_box3_sizeX = coolingv2Geo.getRectangleW() * mm;
1204 double feb_alcooling_box3_sizeY = coolingv2Geo.getRectangleL() * mm;
1205 double feb_alcooling_box3_sizeZ = coolingv2Geo.getRectangleThickness() * mm;
1206
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;
1210
1211 //double feb_alcooling_box2_X0 = 0.0*mm;
1212 //double feb_alcooling_box2_Y0 = 0.0*mm;
1213 //double feb_alcooling_box2_Z0 = 0.0*mm;
1214
1215 double feb_alcooling_box3_X0 = coolingv2Geo.getRectangleDistanceFromCenter() / sqrt(2.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;
1219
1220 G4RotationMatrix Ra;
1221 G4ThreeVector Ta;
1222 G4Transform3D Tr;
1223
1224 //
1225 // Define single FEB aluminum cooling envelope
1226 //
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");
1233
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);
1240
1241 //
1242 //Box 1 A
1243 //
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);
1250 //
1251 //Box 1 B
1252 //
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);
1259 //
1260 //Box 3 A
1261 //
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);
1270 //
1271 //Box 3 B
1272 //
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);
1281
1282 G4LogicalVolume* feb_alcooling_assembly_logical = new G4LogicalVolume(feb_alcooling_assembly_solid, Materials::get("Al"),
1283 "feb_alcooling_assembly_logical");
1284 Ta.setX(0.0);
1285 Ta.setY(0.0);
1286 Ta.setZ(-feb_alcooling_box3_sizeZ / 2.0);
1287
1288 Tr = G4Transform3D(Ra, Ta);
1289 new G4PVPlacement(Tr, //Transformation
1290 feb_alcooling_assembly_logical, //its logical volume
1291 "feb_alcooling_assembly", //its name
1292 feb_alcoolingEnvelope_logical, //its mother volume
1293 false, //no boolean operation
1294 0); //copy number
1295
1296 return feb_alcoolingEnvelope_logical;
1297 }
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28

◆ buildHAPD()

G4LogicalVolume * buildHAPD ( const ARICHGeoHAPD & hapdPar)
private

build the HAPD modules

Definition at line 850 of file GeoARICHCreator.cc.

851 {
852
853 // get module materials
854 string wallMat = hapdGeo.getWallMaterial();
855 string winMat = hapdGeo.getWinMaterial();
856 string apdMat = hapdGeo.getAPDMaterial();
857 string fillMat = hapdGeo.getFillMaterial();
858 string febMat = hapdGeo.getFEBMaterial();
859 G4Material* wallMaterial = Materials::get(wallMat);
860 G4Material* windowMaterial = Materials::get(winMat);
861 G4Material* apdMaterial = Materials::get(apdMat);
862 G4Material* fillMaterial = Materials::get(fillMat);
863 G4Material* febMaterial = Materials::get(febMat);
864 G4Material* moduleFill = Materials::get("ARICH_Air");
865
866 // check that module window material has specified refractive index
867 double wref = getAvgRINDEX(windowMaterial);
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.");
870
871 // get module dimensions
872 const double hapdSizeX = hapdGeo.getSizeX();
873 const double hapdSizeY = hapdGeo.getSizeY();
874 const double hapdSizeZ = hapdGeo.getSizeZ();
875 const double wallThick = hapdGeo.getWallThickness();
876 const double winThick = hapdGeo.getWinThickness();
877 const double apdSizeX = hapdGeo.getAPDSizeX();
878 const double apdSizeY = hapdGeo.getAPDSizeY();
879 const double apdSizeZ = hapdGeo.getAPDSizeZ();
880 const double botThick = wallThick;
881 const double modHeight = hapdGeo.getModuleSizeZ();
882
883 // module master volume
884 G4Box* moduleBox = new G4Box("moduleBox", hapdSizeX / 2., hapdSizeY / 2., modHeight / 2.);
885 G4LogicalVolume* lmoduleBox = new G4LogicalVolume(moduleBox, moduleFill, "ARICH.HAPDModule");
886
887 // build HAPD box
888 G4Box* hapdBox = new G4Box("hapdBox", hapdSizeX / 2., hapdSizeY / 2., hapdSizeZ / 2.);
889 G4LogicalVolume* lhapdBox = new G4LogicalVolume(hapdBox, fillMaterial, "ARICH.HAPD");
890
891 // build HAPD walls
892 G4Box* tempBox2 = new G4Box("tempBox2", hapdSizeX / 2. - wallThick, hapdSizeY / 2. - wallThick,
893 hapdSizeZ / 2. + 0.1); // Don't care about "+0.1", needs to be there.
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);
898
899 // build HAPD window
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)");
903 lmoduleWin->SetSensitiveDetector(m_sensitive);
904 G4Transform3D transform = G4Translate3D(0., 0., (-hapdSizeZ + winThick) / 2.);
905 new G4PVPlacement(transform, lmoduleWin, "ARICH.HAPDWindow", lhapdBox, false, 1);
906
907 // build module bottom
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);
913
914 // build apd
915 G4Box* apdBox = new G4Box("apdBox", apdSizeX / 2., apdSizeY / 2., apdSizeZ / 2.);
916 G4LogicalVolume* lApd = new G4LogicalVolume(apdBox, apdMaterial, "ARICH.HAPDApd");
917 if (m_isBeamBkgStudy) lApd->SetSensitiveDetector(new BkgSensitiveDetector("ARICH", 1));
918
919 // add APD surface optical properties
920 Materials& materials = Materials::getInstance();
921
922 G4OpticalSurface* optSurf = materials.createOpticalSurface(hapdGeo.getAPDSurface());
923
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);
927
928 // build FEB
929 double febSizeX = hapdGeo.getFEBSizeX();
930 double febSizeY = hapdGeo.getFEBSizeY();
931 double febSizeZ = hapdGeo.getFEBSizeZ();
932 G4Box* febBox = new G4Box("febBox", febSizeX / 2., febSizeY / 2., febSizeZ / 2.);
933 G4LogicalVolume* lfeb = new G4LogicalVolume(febBox, febMaterial, "ARICH.HAPDFeb");
934 if (m_isBeamBkgStudy) lfeb->SetSensitiveDetector(new BkgSensitiveDetector("ARICH"));
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);
940
941 return lmoduleBox;
942
943 }
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.
Definition utilities.cc:100

◆ buildMerger()

G4LogicalVolume * buildMerger ( const ARICHGeoMerger & mergerGeo)
private

build the merger PCB logical volume

Definition at line 974 of file GeoARICHCreator.cc.

975 {
976
977 // This is a screw hole on the merger board.
978 // This high precision of the geometry description is needed
979 // only for the correct placement of the merger cooling bodies.
980 // Volume to subtract (screw hole on the merger board)
981 double screwholeR = mergerGeo.getMergerPCBscrewholeR() * mm;
982 double screwholedY = mergerGeo.getMergerPCBscrewholePosdY() * mm;
983 double screwholedX1 = mergerGeo.getMergerPCBscrewholePosdX1() * mm;
984 double screwholedX2 = mergerGeo.getMergerPCBscrewholePosdX2() * mm;
985
986 G4VSolid* screwHoleTubeSubtracted_solid = new G4Tubs("screwHoleTubeSubtracted_solid",
987 0.0,
988 screwholeR,
989 mergerGeo.getThickness() * mm / 2.0,
990 0, 360.0 * deg);
991
992 // Volume to add (merger box)
993 G4Box* merger_solid = new G4Box("merger_solid",
994 mergerGeo.getSizeW() * mm / 2.0,
995 mergerGeo.getSizeL() * mm / 2.0,
996 mergerGeo.getThickness() * mm / 2.0);
997
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);
1003 Ta_sub.setZ(0.0);
1004 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1005 G4SubtractionSolid* substraction_solid = new G4SubtractionSolid("substraction_solid", merger_solid, screwHoleTubeSubtracted_solid,
1006 Tr_sub);
1007 Ta_sub.setX(mergerGeo.getSizeW() * mm / 2.0 - screwholedX2);
1008 Ta_sub.setY(mergerGeo.getSizeL() * mm / 2.0 - screwholedY);
1009 Ta_sub.setZ(0.0);
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);
1014 Ta_sub.setZ(0.0);
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);
1019 Ta_sub.setZ(0.0);
1020 Tr_sub = G4Transform3D(Ra_sub, Ta_sub);
1021 substraction_solid = new G4SubtractionSolid("substraction_solid", substraction_solid, screwHoleTubeSubtracted_solid, Tr_sub);
1022
1023 return new G4LogicalVolume(substraction_solid, Materials::get(mergerGeo.getMergerPCBMaterialName()), "ARICH.mergerPCB");
1024 }

◆ buildMergerCooling()

G4LogicalVolume * buildMergerCooling ( unsigned iType)
private

build merger cooling bodies (cooling system update after phase 2)

Definition at line 1027 of file GeoARICHCreator.cc.

1028 {
1029
1030 if (!m_mergerCooling) {
1031 B2WARNING("ARICH geometry: no data available for merger " << iType << " cooling body geometry. Cooling body will not be placed.");
1032 return NULL;
1033 }
1034
1035 std::stringstream shpName;
1036 shpName << "TessellatedSolid_" << + iType;
1037
1038 G4TessellatedSolid* volume_solid = new G4TessellatedSolid(shpName.str().c_str());
1039
1040 G4ThreeVector point_1;
1041 G4ThreeVector point_2;
1042 G4ThreeVector point_3;
1043
1044 tessellatedSolidStr mergerCoolingStr = m_mergerCooling->getMergerCoolingBodiesInfo(iType);
1045
1046 if (mergerCoolingStr.nCells == 0) {
1047 B2WARNING("ARICH geometry: no data available for merger " << iType << " cooling body geometry. Cooling body will not be placed.");
1048 return NULL;
1049 }
1050
1051 for (unsigned int i = 0; i < mergerCoolingStr.nCells; i++) {
1052 //
1053 point_1.setX(mergerCoolingStr.posV1[0][i]);
1054 point_1.setY(mergerCoolingStr.posV1[1][i]);
1055 point_1.setZ(mergerCoolingStr.posV1[2][i]);
1056 //
1057 point_2.setX(mergerCoolingStr.posV2[0][i]);
1058 point_2.setY(mergerCoolingStr.posV2[1][i]);
1059 point_2.setZ(mergerCoolingStr.posV2[2][i]);
1060 //
1061 point_3.setX(mergerCoolingStr.posV3[0][i]);
1062 point_3.setY(mergerCoolingStr.posV3[1][i]);
1063 point_3.setZ(mergerCoolingStr.posV3[2][i]);
1064 //
1065 G4TriangularFacet* facet = new G4TriangularFacet(point_1, point_2, point_3, ABSOLUTE);
1066 volume_solid->AddFacet((G4VFacet*) facet);
1067 delete facet;
1068 }
1069
1070 volume_solid->SetSolidClosed(true);
1071 std::stringstream volName;
1072 volName << "ARICH.mergerCooling_" << + iType;
1073 G4LogicalVolume* volume_logical = new G4LogicalVolume(volume_solid,
1074 Materials::get(m_mergerCooling->getMergerCoolingBodiesMaterialName()), volName.str().c_str());
1075
1076 setColor(*volume_logical, "rgb(0.6,0.0,0.2,1.0)"); //From the top (farther from IP, downstream)
1077
1078 return volume_logical;
1079 }

◆ buildMergerEnvelope()

G4LogicalVolume * buildMergerEnvelope ( const ARICHGeoMerger & mergerGeo,
int type )
private

build single merger and merger cooling body envelope logical volume

Definition at line 1081 of file GeoARICHCreator.cc.

1082 {
1083 // Volume to add single merger and merger cooling body envelope box
1084 G4Box* singlemergerenvelope_solid = new G4Box("singlemergerenvelope_solid",
1085 mergerGeo.getSingleMergerEnvelopeSizeW() * mm / 2.0,
1086 mergerGeo.getSingleMergerEnvelopeSizeL() * mm / 2.0,
1087 mergerGeo.getSingleMergerEnvelopeThickness() * mm / 2.0);
1088 std::stringstream volName;
1089 volName << "ARICH.singleMergerEnvelope_" << + iType;
1090 return new G4LogicalVolume(singlemergerenvelope_solid, Materials::get("ARICH_Air"), volName.str().c_str());
1091 }

◆ buildMergerPCBEnvelopePlane()

G4LogicalVolume * buildMergerPCBEnvelopePlane ( const ARICHGeometryConfig & detectorGeo)
private

build merger PCB assembly envelope plane

Definition at line 1093 of file GeoARICHCreator.cc.

1094 {
1095
1096 const ARICHGeoMerger& mergerGeo = detectorGeo.getMergerGeometry();
1097
1098 if (mergerGeo.getSingleMergerEnvelopeSizeW() < 1e-9) {
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).");
1100 return NULL;
1101 }
1102
1103 G4Tubs* envelope_solid = new G4Tubs("envelope_solid", mergerGeo.getEnvelopeInnerRadius() * mm,
1104 mergerGeo.getEnvelopeOuterRadius() * mm, mergerGeo.getEnvelopeThickness() * mm / 2.0, 0.0, 2.0 * M_PI);
1105
1106 G4LogicalVolume* envelope_logical = new G4LogicalVolume(envelope_solid, Materials::get("ARICH_Air"), "ARICH.mergerEnvelope");
1107
1108
1109 G4LogicalVolume* merger_logical = buildMerger(mergerGeo);
1110 G4LogicalVolume* mergerCooling_logical[12] = {NULL};
1111 G4LogicalVolume* mergerEnvelope_logical[12] = {NULL};
1112 G4ThreeVector TaPCB(mergerGeo.getSingleMergeEnvelopePosition().X() * mm, mergerGeo.getSingleMergeEnvelopePosition().Y() * mm,
1113 mergerGeo.getSingleMergeEnvelopePosition().Z() * mm);
1114 G4RotationMatrix RaPCB;
1115 G4ThreeVector TaMergerCooling(mergerGeo.getSingleMergeEnvelopePosition().X() * mm,
1116 mergerGeo.getSingleMergeEnvelopePosition().Y() * mm, -mergerGeo.getSingleMergeEnvelopePosition().Z() * mm);
1117 G4RotationMatrix RaMergerCooling;
1118 RaMergerCooling.rotateY(180 * deg);
1119 RaMergerCooling.rotateZ(-90 * deg);
1120
1121 // build 12 different merger+cooling body volumes
1122 for (int iType = 1; iType < 13; iType++) {
1123 mergerCooling_logical[iType - 1] = buildMergerCooling(iType);
1124 mergerEnvelope_logical[iType - 1 ] = buildMergerEnvelope(mergerGeo, iType); //Single merger and merger cooling body envelope box
1125 setColor(*mergerEnvelope_logical[iType - 1], "rgb(0.0,0.0,1.0,1.0)");
1126
1127 new G4PVPlacement(G4Transform3D(RaPCB, TaPCB), //Transformation
1128 merger_logical, //its logical volume
1129 "ARICH.mergerPCB", //its name
1130 mergerEnvelope_logical[iType - 1], //its mother volume
1131 false, //no boolean operation
1132 iType); //copy number
1133
1134 if (mergerCooling_logical[iType - 1] == NULL) continue;
1135
1136 new G4PVPlacement(G4Transform3D(RaMergerCooling, TaMergerCooling), //Transformation
1137 mergerCooling_logical[iType - 1], //its logical volume
1138 "ARICH.mergerCooling", //its name
1139 mergerEnvelope_logical[iType - 1], //its mother volume
1140 false, //no boolean operation
1141 iType); //copy number
1142 }
1143
1144 // place all 72 merger+cooling body packages
1145 for (unsigned iSlot = 0; iSlot < mergerGeo.getMergerSlotID().size(); iSlot++) {
1146
1147 int type = 1; // if no merger cooling is available...
1148 if (m_mergerCooling) type = (int)m_mergerCooling->getMergerCoolingPositionID().at(iSlot);
1149
1150 //Placement of the single volume envelope
1151 G4ThreeVector Ta(mergerGeo.getMergerPosR().at(iSlot) * mm * cos(mergerGeo.getMergerAngle().at(iSlot) * deg),
1152 mergerGeo.getMergerPosR().at(iSlot) * mm * sin(mergerGeo.getMergerAngle().at(iSlot) * deg),
1153 mergerGeo.getSingleMergerenvelopeDeltaZ().at(iSlot) * mm);
1154 G4RotationMatrix Ra;
1155 Ra.rotateZ(mergerGeo.getMergerAngle().at(iSlot) * deg + mergerGeo.getMergerOrientation().at(iSlot) * deg);
1156 new G4PVPlacement(G4Transform3D(Ra, Ta), //Transformation
1157 mergerEnvelope_logical[type - 1], //its logical volume
1158 "ARICH.singleMergerEnvelope", //its name
1159 envelope_logical, //its mother volume
1160 false, //no boolean operation
1161 iSlot); //copy number
1162 }
1163
1164 return envelope_logical;
1165
1166 }

◆ buildMirror()

G4LogicalVolume * buildMirror ( const ARICHGeometryConfig & detectorGeo)
private

build mirrors

Definition at line 1615 of file GeoARICHCreator.cc.

1616 {
1617
1618 const ARICHGeoMirrors& mirrGeo = detectorGeo.getMirrors();
1619
1620 // read m_config
1621 string mirrMat = mirrGeo.getMaterial();
1622 G4Material* mirrorMaterial = Materials::get(mirrMat);
1623
1624 double mThick = mirrGeo.getPlateThickness();
1625 double mLength = mirrGeo.getPlateLength();
1626 double mWidth = mirrGeo.getPlateWidth();
1627
1628 G4Box* mirrPlate = new G4Box("mirrPlate", mThick / 2., mLength / 2., mWidth / 2.);
1629
1630 G4LogicalVolume* lmirror = new G4LogicalVolume(mirrPlate, mirrorMaterial, "ARICH.mirrorPlate");
1631
1632 Materials& materials = Materials::getInstance();
1633
1634 G4OpticalSurface* optSurf = materials.createOpticalSurface(mirrGeo.getMirrorSurface());
1635 new G4LogicalSkinSurface("mirrorSurface", lmirror, optSurf);
1636
1637 return lmirror;
1638
1639 }

◆ buildSimpleAerogelPlane()

G4LogicalVolume * buildSimpleAerogelPlane ( const ARICHGeometryConfig & detectorGeo)
private

build simple aerogel plane (for cosmic test)

Definition at line 438 of file GeoARICHCreator.cc.

439 {
440
441 const ARICHGeoAerogelPlane& aeroGeo = detectorGeo.getAerogelPlane();
442
443 const std::vector<double>& params = aeroGeo.getSimpleParams();
444
445 // support plane
446 double rin = aeroGeo.getSupportInnerR();
447 double rout = aeroGeo.getSupportOuterR();
448 double thick = aeroGeo.getSupportThickness();
449 string supportMat = aeroGeo.getSupportMaterial();
450 double wallHeight = aeroGeo.getWallHeight();
451 G4Material* supportMaterial = Materials::get(supportMat);
452 G4Material* gapMaterial = Materials::get("Air"); // Air without refractive index (to kill photons, to mimic black paper around tile)
453
454 // master volume
455 G4Tubs* aerogelTube = new G4Tubs("aerogelTube", rin, rout, (thick + wallHeight) / 2., 0, 2 * M_PI);
456 G4LogicalVolume* aerogelPlaneLV = new G4LogicalVolume(aerogelTube, gapMaterial, "ARICH.AaerogelPlane");
457
458 // support plate
459 G4Tubs* supportTube = new G4Tubs("aeroSupportTube", rin, rout, thick / 2., 0, 2 * M_PI);
460 G4LogicalVolume* supportTubeLV = new G4LogicalVolume(supportTube, supportMaterial, "ARICH.AerogelSupportPlate");
461 //supportTubeLV->SetSensitiveDetector(m_sensitiveAero);
462
463 unsigned nLayer = aeroGeo.getNLayers();
464
465 // loop over layers
466 double zLayer = 0;
467 for (unsigned iLayer = 1; iLayer < nLayer + 1; iLayer++) {
468 double layerThick = aeroGeo.getLayerThickness(iLayer);
469 std::stringstream tileName;
470 tileName << "aerogelTile_" << iLayer;
471
472 G4Box* tileShape = new G4Box(tileName.str(), params[0] * 10. / 2., params[1] * 10. / 2., layerThick / 2.);
473
474 G4Material* aeroMaterial = Materials::get(aeroGeo.getLayerMaterial(iLayer));
475
476 G4LogicalVolume* tileLV = new G4LogicalVolume(tileShape, aeroMaterial, string("ARICH.") + tileName.str());
477
478 G4ThreeVector transTile(params[2] * 10., params[3] * 10., (thick + layerThick - wallHeight) / 2. + zLayer);
479 G4RotationMatrix Ra;
480 Ra.rotateZ(params[4]);
481 new G4PVPlacement(G4Transform3D(Ra, transTile), tileLV, string("ARICH.") + tileName.str(), aerogelPlaneLV, false, iLayer);
482
483 zLayer += layerThick;
484 }
485
486 new G4PVPlacement(G4Translate3D(0., 0., -wallHeight / 2.), supportTubeLV, "ARICH.AerogelSupportPlate", aerogelPlaneLV, false, 1);
487
488 return aerogelPlaneLV;
489 }

◆ create()

virtual void create ( const GearDir & content,
G4LogicalVolume & topVolume,
geometry::GeometryTypes type )
inlineoverridevirtual

Creates the ROOT Objects for the ARICH geometry.

Parameters
contentA reference to the content part of the parameter description, which should to be used to create the ROOT objects.
topVolumetop volume
typegeometry type

Implements CreatorBase.

Definition at line 70 of file GeoARICHCreator.h.

71 {
72 m_config = createConfiguration(content);
73
74 // override geometry configuration from the DB
75 DBStore::Instance().addConstantOverride("ARICHGeometryConfig", new ARICHGeometryConfig(m_config));
76
77 createGeometry(topVolume, type);
78 }

◆ createConfiguration()

ARICHGeometryConfig createConfiguration ( const GearDir & param)
inlineprivate

Reads ARICH geometry parameters from the xml files and createst DB class ARICHGeometryConfig.

Definition at line 45 of file GeoARICHCreator.h.

46 {
47 ARICHGeometryConfig arichGeometryConfig(param);
48 return arichGeometryConfig;
49 }

◆ createFromDB()

virtual void createFromDB ( const std::string & name,
G4LogicalVolume & topVolume,
geometry::GeometryTypes type )
inlineoverridevirtual

Create the geometry from the Database.

Reimplemented from CreatorBase.

Definition at line 89 of file GeoARICHCreator.h.

90 {
91 DBObjPtr<ARICHGeometryConfig> dbObj;
92 if (!dbObj) {
93 // Check that we found the object and if not report the problem
94 B2FATAL("No configuration for " << name << " found.");
95 }
96 m_config = *dbObj;
97 createGeometry(topVolume, type);
98 }

◆ createGeometry()

void createGeometry ( G4LogicalVolume & topVolume,
geometry::GeometryTypes type )
private

Create detector geometry.

Definition at line 82 of file GeoARICHCreator.cc.

83 {
84
85 m_config.useGeantUnits();
86 m_sensitive = new SensitiveDetector();
87 m_sensitiveAero = new SensitiveAero();
88
89 // print geometry configuration
90 // m_config.print();
91
92 //Build envelope
93 G4Tubs* envelopeTube = new G4Tubs("Envelope", m_config.getMasterVolume().getInnerRadius(),
94 m_config.getMasterVolume().getOuterRadius(), m_config.getMasterVolume().getLength() / 2., 0, 2 * M_PI);
95 G4Material* material = Materials::get(m_config.getMasterVolume().getMaterial());
96
97 // check of material and its refractive index
98 if (!material) { B2FATAL("Material ARICH_Air required for ARICH master volume could not be found");}
99 if (!getAvgRINDEX(material))
100 B2WARNING("Material ARICH_Air required by ARICH master volume has no specified refractive index. Continuing, but no photons in ARICH will be propagated.");
101
102 // create and place
103 G4LogicalVolume* masterLV = new G4LogicalVolume(envelopeTube, material, "ARICH.masterVolume");
104 setVisibility(*masterLV, false);
105
106 // Set up region for production cuts
107 G4Region* aRegion = new G4Region("ARICHEnvelope");
108 masterLV->SetRegion(aRegion);
109 aRegion->AddRootLogicalVolume(masterLV);
110
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();
118
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.");
127 }
128 rotMaster.rotateX(rot_x);
129 rotMaster.rotateY(rot_y);
130 rotMaster.rotateZ(rot_z);
131
132 G4ThreeVector transMaster(tr_x, tr_y, tr_z);
133
134 new G4PVPlacement(G4Transform3D(rotMaster, transMaster), masterLV, "ARICH.MasterVolume", &topVolume, false, 1);
135
136 m_isBeamBkgStudy = m_config.doBeamBackgroundStudy();
137
138 // Z shift for placing volumes in ARICH master volume
139 double zShift = 0;
140
141 // build photon detector logical volume
142 G4LogicalVolume* detPlaneLV = buildDetectorPlane(m_config);
143 G4LogicalVolume* detSupportPlateLV = buildDetectorSupportPlate(m_config);
144
145 // Build merger PCB logical volume
146 G4LogicalVolume* mergerLV = buildMergerPCBEnvelopePlane(m_config);
147
148 // Build the cables envelop with effective material describing cables
149 G4LogicalVolume* cablesLV = buildCables(m_config.getCablesEnvelope());
150
151 // Build cooling system assembly envelope plane
152 //G4LogicalVolume* coolingLV = buildCoolingEnvelopePlane(m_config.getCoolingGeometry());
153
154 // Build aerogel logical volume
155 G4LogicalVolume* aeroPlaneLV;
156 if (!m_config.getAerogelPlane().isSimple()) {
157 aeroPlaneLV = buildAerogelPlane(m_config);
158 } else {
159 B2INFO("GeoARICHCreator: using simple cosmic test geometry.");
160 aeroPlaneLV = buildSimpleAerogelPlane(m_config);
161 }
162
163 G4RotationMatrix rotDetPlane;
164 rotDetPlane.rotateX(m_config.getDetectorPlane().getRotationX());
165 rotDetPlane.rotateY(m_config.getDetectorPlane().getRotationY());
166 rotDetPlane.rotateZ(m_config.getDetectorPlane().getRotationZ());
167
168 //
169 // For the moment rotation of merger PCB board envelope is not foreseen.
170 //
171 G4RotationMatrix rotMergerPlane;
172 rotMergerPlane.rotateX(0.0);
173 rotMergerPlane.rotateY(0.0);
174 rotMergerPlane.rotateZ(0.0);
175
176 //
177 // For the moment rotation of cables envelope is not foreseen.
178 //
179 G4RotationMatrix rotCablesPlane;
180 rotCablesPlane.rotateX(0.0);
181 rotCablesPlane.rotateY(0.0);
182 rotCablesPlane.rotateZ(0.0);
183
184 G4RotationMatrix rotCoolingPlane;
185 rotCoolingPlane.rotateX(0.0);
186 rotCoolingPlane.rotateY(0.0);
187 rotCoolingPlane.rotateZ(0.0);
188
189 G4RotationMatrix rotAeroPlane;
190 rotAeroPlane.rotateX(m_config.getAerogelPlane().getRotationX());
191 rotAeroPlane.rotateY(m_config.getAerogelPlane().getRotationY());
192 rotAeroPlane.rotateZ(m_config.getAerogelPlane().getRotationZ());
193
194 G4ThreeVector transDetPlane(m_config.getDetectorPlane().getPosition().X(), m_config.getDetectorPlane().getPosition().Y(),
195 m_config.getDetectorPlane().getPosition().Z() + zShift);
196
197 G4ThreeVector transDetSupportPlate(m_config.getDetectorPlane().getPosition().X(), m_config.getDetectorPlane().getPosition().Y(),
198 m_config.getDetectorPlane().getSupportZPosition() + zShift);
199
200 G4ThreeVector transMergerPlate(m_config.getMergerGeometry().getEnvelopeCenterPosition().X() * mm,
201 m_config.getMergerGeometry().getEnvelopeCenterPosition().Y() * mm,
202 m_config.getMergerGeometry().getEnvelopeCenterPosition().Z() * mm + zShift);
203
204 G4ThreeVector transCablesPlate(m_config.getCablesEnvelope().getEnvelopeCenterPosition().X(),
205 m_config.getCablesEnvelope().getEnvelopeCenterPosition().Y(),
206 m_config.getCablesEnvelope().getEnvelopeCenterPosition().Z() + zShift);
207
208 G4ThreeVector transCoolingPlate(m_config.getCoolingGeometry().getEnvelopeCenterPosition().X() * mm,
209 m_config.getCoolingGeometry().getEnvelopeCenterPosition().Y() * mm,
210 m_config.getCoolingGeometry().getEnvelopeCenterPosition().Z() * mm + zShift);
211
212 G4ThreeVector transAeroPlane(m_config.getAerogelPlane().getPosition().X(),
213 m_config.getAerogelPlane().getPosition().Y(),
214 m_config.getAerogelPlane().getPosition().Z() + zShift);
215
216
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);
221 //new G4PVPlacement(G4Transform3D(rotCoolingPlane, transCoolingPlate), coolingLV, "ARICH.coolingPlane", masterLV, false, 1);
222 new G4PVPlacement(G4Transform3D(rotAeroPlane, transAeroPlane), aeroPlaneLV, "ARICH.aeroPlane", masterLV, false, 1);
223
224 /*
225 // build and place cooling test plates
226 G4LogicalVolume* coolingTestPlatesLV = buildCoolingTestPlate(m_config.getCoolingGeometry());
227 double coolingTestPlateAngle = 0.0;
228 double coolingTestPlateR = 0.0;
229 for (unsigned i = 0; i < m_config.getCoolingGeometry().getCoolingTestPlatePosR().size(); i++) {
230 coolingTestPlateAngle = m_config.getCoolingGeometry().getCoolingTestPlatePosPhi().at(i) * deg;
231 coolingTestPlateR = m_config.getCoolingGeometry().getCoolingTestPlatePosR().at(i) * mm;
232 G4RotationMatrix rotCoolingTestPlate;
233 rotCoolingTestPlate.rotateZ(coolingTestPlateAngle);
234 G4ThreeVector transCoolingTestPlate(coolingTestPlateR * cos(coolingTestPlateAngle),
235 coolingTestPlateR * sin(coolingTestPlateAngle),
236 m_config.getCoolingGeometry().getCoolingTestPlatePosZ0().at(i) * mm + zShift);
237 new G4PVPlacement(G4Transform3D(rotCoolingTestPlate, transCoolingTestPlate), coolingTestPlatesLV, "ARICH.coolingTestPlates",
238 masterLV, false, i);
239 }
240 */
241
242 // build and place mirrors
243 G4LogicalVolume* mirrorLV = buildMirror(m_config);
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();
248
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++) {
253 double mrot_x = 0;
254 double mrot_y = 0;
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()) {
260 const ARICHPositionElement& displ = m_config.getMirrorDisplacement().getDisplacementElement(i);
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();
267 }
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);
274 angl += dphi;
275 }
276
277 // build additional components of support structure
278
279 const ARICHGeoSupport& supportPar = m_config.getSupportStructure();
280 std::vector<G4LogicalVolume*> shieldLV(2);
281 std::vector<double> shieldZ(2);
282 int nTubes = supportPar.getNTubes();
283 for (int i = 0; i < nTubes; i++) {
284 G4Tubs* tube = new G4Tubs(supportPar.getTubeName(i), supportPar.getTubeInnerR(i), supportPar.getTubeOuterR(i),
285 supportPar.getTubeLength(i) / 2., 0, 2.*M_PI);
286 G4Material* tubeMaterial = Materials::get(supportPar.getTubeMaterial(i));
287
288 if (supportPar.getTubeName(i) == "ARICH.NeutronShield1") {
289 shieldLV[0] = new G4LogicalVolume(tube, tubeMaterial, supportPar.getTubeName(i));
290 shieldZ[0] = supportPar.getTubeZPosition(i) + supportPar.getTubeLength(i) / 2.;
291 continue;
292 } else if (supportPar.getTubeName(i) == "ARICH.NeutronShield2") {
293 shieldLV[1] = new G4LogicalVolume(tube, tubeMaterial, supportPar.getTubeName(i));
294 shieldZ[1] = supportPar.getTubeZPosition(i) + supportPar.getTubeLength(i) / 2.;
295 continue;
296 }
297
298 G4LogicalVolume* tubeLV = new G4LogicalVolume(tube, tubeMaterial, supportPar.getTubeName(i));
299
300 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0,
301 supportPar.getTubeZPosition(i) + supportPar.getTubeLength(i) / 2. + zShift)), tubeLV, supportPar.getTubeName(i), masterLV, false,
302 1);
303 }
304
305 const std::vector<double> wedge1 = supportPar.getWedge(1);
306 const std::vector<double> wedge2 = supportPar.getWedge(2);
307 G4Material* wedge1Material = Materials::get(supportPar.getWedgeMaterial(1));
308 G4Material* wedge2Material = Materials::get(supportPar.getWedgeMaterial(2));
309 G4AssemblyVolume* assemblyWedge1 = new G4AssemblyVolume();
310 G4AssemblyVolume* assemblyWedge2 = new G4AssemblyVolume();
311 makeJoint(wedge1Material, wedge1, assemblyWedge1);
312 makeJoint(wedge2Material, wedge2, assemblyWedge2);
313
314 G4Transform3D Tr;
315 int nWedge = supportPar.getNWedges();
316 for (int i = 0; i < nWedge; i++) {
317 G4RotationMatrix Rx;
318 int wgtype = supportPar.getWedgeType(i);
319 double phi = supportPar.getWedgePhi(i);
320 Rx.rotateZ(phi);
321 double r = supportPar.getWedgeR(i);
322 double z = supportPar.getWedgeZ(i);
323 G4ThreeVector Tb(r * cos(phi), r * sin(phi), z);
324
325 if (shieldLV[0]) {
326 z -= shieldZ[0];
327 Tb.setZ(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);
331 continue;
332 }
333
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!");
338 }
339
340 // place neutron shield volumes
341 if (shieldLV[0])
342 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0, shieldZ[0])), shieldLV[0], "ARICH.NeutronShield1", masterLV,
343 false, 1);
344 if (shieldLV[1])
345 new G4PVPlacement(G4Transform3D(G4RotationMatrix(), G4ThreeVector(0, 0, shieldZ[1])), shieldLV[1], "ARICH.NeutronShield2", masterLV,
346 false, 1);
347
348 // place mirror holders, for now skip
349 /*
350 double mirSupX = 17.;
351 double mirSupY = 14.;
352 double mirSupLen = 131;
353 double mirSupLen1 = 201;
354
355 std::vector<G4TwoVector> polygon;
356 polygon.assign(12, G4TwoVector());
357 polygon[11] = G4TwoVector(-mirSupX / 2., -mirSupY / 2.);
358 polygon[10] = G4TwoVector(-mirSupX / 2., 2.);
359 polygon[9] = G4TwoVector(-mirSupX / 4., 2. - 0.75);
360 polygon[8] = G4TwoVector(-mirSupX / 4., 5. - 0.75);
361 polygon[7] = G4TwoVector(-mirSupX / 2., 5);
362 polygon[6] = G4TwoVector(-mirSupX / 2., mirSupY / 2.);
363 polygon[5] = G4TwoVector(mirSupX / 2., mirSupY / 2.);
364 polygon[4] = G4TwoVector(mirSupX / 2., 6);
365 polygon[3] = G4TwoVector(mirSupX / 4., 6. - 0.75);
366 polygon[2] = G4TwoVector(mirSupX / 4., 2. - 0.75);
367 polygon[1] = G4TwoVector(mirSupX / 2., 2.);
368 polygon[0] = G4TwoVector(mirSupX / 2., -mirSupY / 2.);
369
370 std::vector<G4ExtrudedSolid::ZSection> zsections;
371 zsections.push_back(G4ExtrudedSolid::ZSection(-mirSupLen / 2., G4TwoVector(0, 0), 1));
372 zsections.push_back(G4ExtrudedSolid::ZSection(mirSupLen / 2., G4TwoVector(0, 0), 1));
373
374 G4ExtrudedSolid* shape = new G4ExtrudedSolid("bla", polygon, zsections);
375 G4LogicalVolume* shapeLV = new G4LogicalVolume(shape, wedge1Material, "mirrorsupport");
376
377 G4Box* shape1 = new G4Box("shape1", mirSupX / 2., 2. / 2., mirSupLen1 / 2.);
378 G4LogicalVolume* shape1LV = new G4LogicalVolume(shape1, wedge1Material, "mirrorholder");
379
380 G4AssemblyVolume* mirroHolder = new G4AssemblyVolume();
381 G4RotationMatrix Rh;
382 G4ThreeVector Th(0, 0, 0);
383 Tr = G4Transform3D(Rh, Th);
384 mirroHolder->AddPlacedVolume(shapeLV, Tr);
385
386 Th.setZ(-35.0);
387 Th.setY(-mirSupY / 2. - 1.);
388 Tr = G4Transform3D(Rh, Th);
389 mirroHolder->AddPlacedVolume(shape1LV, Tr);
390
391 double rholder = m_config.getDetectorPlane().getSupportOuterR() - mirSupY / 2.;
392
393 angl = dphi / 2.;
394 for (int i = 1; i < nMirrors + 1; i++) {
395 G4RotationMatrix rotMirror;
396 rotMirror.rotateX(M_PI);
397 rotMirror.rotateZ(-M_PI / 2. + angl);
398 G4ThreeVector transMirror(rholder * cos(angl), rholder * sin(angl), mirZPos + zShift);
399 Tr = G4Transform3D(rotMirror, transMirror);
400 mirroHolder->MakeImprint(masterLV, Tr);
401 angl += dphi;
402 }
403 */
404
405 // temporary for simple cosmic test
406 // if using simple configuration, place scinitilators
407 if (m_config.getAerogelPlane().isSimple()) {
408 int nBoxes = supportPar.getNBoxes();
409 for (int i = 0; i < nBoxes; i++) {
410 ARICHGeoSupport::box box = supportPar.getBox(i);
411 G4Box* scintBox = new G4Box("scintBox", box.size[0] * 10. / 2., box.size[1] * 10. / 2., box.size[2] * 10. / 2.);
412 G4Material* scintMaterial = Materials::get(box.material);
413 G4LogicalVolume* scintLV = new G4LogicalVolume(scintBox, scintMaterial, box.name);
414 scintLV->SetSensitiveDetector(m_sensitiveAero);
415 G4RotationMatrix rotScint;
416 rotScint.rotateX(box.rotation[0]);
417 rotScint.rotateY(box.rotation[1]);
418 rotScint.rotateZ(box.rotation[2]);
419 ROOT::Math::XYZVector transScintTV(box.position[0], box.position[1], box.position[2]);
420 transScintTV = m_config.getMasterVolume().pointToGlobal(transScintTV);
421 B2INFO("GeoARICHCreator: Scintilator " << box.name << " placed at global: " << transScintTV.X() << " " << transScintTV.Y() << " " <<
422 transScintTV.Z());
423 G4ThreeVector transScint(box.position[0] * 10., box.position[1] * 10., box.position[2] * 10.);
424 new G4PVPlacement(G4Transform3D(rotScint, transScint), scintLV, "scintilator", masterLV, false, 1);
425 }
426 }
427
428 m_config.useBasf2Units();
429
430 delete assemblyWedge1;
431 delete assemblyWedge2;
432
433 return;
434
435 }
VXD::SensitiveDetector< PXDSimHit, PXDTrueHit > SensitiveDetector
The PXD Sensitive Detector class.
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
Definition utilities.cc:108

◆ createPayloads()

virtual void createPayloads ( const GearDir & content,
const IntervalOfValidity & iov )
inlineoverridevirtual

creates DB payload for ARICHGeometryConfig class

Reimplemented from CreatorBase.

Definition at line 81 of file GeoARICHCreator.h.

82 {
83 DBImportObjPtr<ARICHGeometryConfig> importObj;
84 importObj.construct(createConfiguration(content));
85 importObj.import(iov);
86 }

◆ getAvgRINDEX()

double getAvgRINDEX ( G4Material * material)
private

get refractive index of the material

Definition at line 1641 of file GeoARICHCreator.cc.

1642 {
1643 G4MaterialPropertiesTable* mTable = material->GetMaterialPropertiesTable();
1644 if (!mTable) return 0;
1645 G4MaterialPropertyVector* mVector = mTable->GetProperty("RINDEX");
1646 if (!mVector) return 0;
1647 G4bool b;
1648 return mVector->GetValue(2 * Unit::eV / Unit::MeV, b);
1649 }

◆ makeJoint()

void makeJoint ( G4Material * supportMaterial,
const std::vector< double > & pars,
G4AssemblyVolume * assemblyWedge )
private

build joints of the ARICH support structure

Definition at line 1651 of file GeoARICHCreator.cc.

1652 {
1653
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);
1660
1661 G4Box* wedgeBox1 = new G4Box("wedgeBox1", thick / 2., lenx / 2., leny / 2.);
1662 G4Box* wedgeBox2 = new G4Box("wedgeBox2", lenz / 2., lenx / 2., thick / 2.);
1663
1664 G4LogicalVolume* wedgeBox1LV = new G4LogicalVolume(wedgeBox1, supportMaterial, "ARICH.supportWedge");
1665 G4LogicalVolume* wedgeBox2LV = new G4LogicalVolume(wedgeBox2, supportMaterial, "ARICH.supportWedge");
1666
1667 G4RotationMatrix Rm;
1668 G4ThreeVector Ta(0, 0, 0);
1669 G4Transform3D Tr;
1670 Tr = G4Transform3D(Rm, Ta);
1671
1672 assemblyWedge->AddPlacedVolume(wedgeBox1LV, Tr);
1673
1674 Ta.setX(lenz / 2. + thick / 2.);
1675 Ta.setZ(leny / 2. - thick / 2.);
1676 Tr = G4Transform3D(Rm, Ta);
1677 assemblyWedge->AddPlacedVolume(wedgeBox2LV, Tr);
1678
1679 if (size == 4) return;
1680 double edge = par.at(4);
1681
1682 G4Box* wedgeBox3 = new G4Box("wedgeBox3", lenz / 2., edge / 2., thick / 2.);
1683 G4LogicalVolume* wedgeBox3LV = new G4LogicalVolume(wedgeBox3, supportMaterial, "ARICH.supportWedge");
1684
1685 Ta.setZ(leny / 2. - thick - thick / 2.);
1686 Tr = G4Transform3D(Rm, Ta);
1687 assemblyWedge->AddPlacedVolume(wedgeBox3LV, Tr);
1688
1689 G4Trap* wedgeBoxTmp = new G4Trap("wedgeBoxTmp", thick, leny - 2 * thick, lenz, edge);
1690 G4LogicalVolume* wedgeBox4LV;
1691 if (size == 8) {
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");
1698
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);
1704
1705 }

Member Data Documentation

◆ m_config

ARICHGeometryConfig m_config
private

geometry configuration

Definition at line 163 of file GeoARICHCreator.h.

◆ m_isBeamBkgStudy

int m_isBeamBkgStudy
private

flag the beam background study

Definition at line 172 of file GeoARICHCreator.h.

◆ m_mergerCooling

OptionalDBObjPtr<ARICHGeoMergerCooling> m_mergerCooling
private

merger cooling bodies geometry from the DB

Definition at line 175 of file GeoARICHCreator.h.

◆ m_modInfo

DBObjPtr<ARICHModulesInfo> m_modInfo
private

information on installed modules from the DB

Definition at line 174 of file GeoARICHCreator.h.

◆ m_sensitive

SensitiveDetector* m_sensitive
private

pointer to sensitive detector

Definition at line 166 of file GeoARICHCreator.h.

◆ m_sensitiveAero

SensitiveAero* m_sensitiveAero
private

pointer to sensitive aerogel - used instead of tracking

Definition at line 169 of file GeoARICHCreator.h.


The documentation for this class was generated from the following files: