//********************************** // author: Aizat Daribayeva *** // *** // GEANT4 MRPC Simulation *** //********************************** #include #include #include #include #include #include #include #include #include "G4Region.hh" #include "G4RegionStore.hh" #include "G4ProductionCuts.hh" #include "G4VisAttributes.hh" #include using namespace det::G4Utilities; using namespace CLHEP; // necessary G4 ver.10 namespace det { void G4MRPC::BuildMRPC(G4LogicalVolume* const logicalWorld, const std::vector& sensitiveDetectors, const bool checkOverlaps) { const Detector& detector = Detector::GetInstance(); const MRPC& mrpc = detector.GetMRPC(); const MRPCWall& mRPCWall = mrpc.GetWall(TOFConst::EId::eMRPCL); const MRPCStaticInfo& geoStaticInfo = mrpc.GetMRPCStaticInfo(); const G4MaterialBuilder& materialBuilder = G4MaterialBuilder::GetInstance(); typedef TOFConst::MRPCConst::EType EType; utl::CoordinateSystemPtr detectorCoord = detector.GetDetectorCoordinateSystem(); //############## WALL GEOMETRY ################################### G4Material* wallMaterial = materialBuilder.GetMaterial("Aluminium"); G4Material* mRPCGas = materialBuilder.GetMaterial("RPCGas"); // RPCGas double wallWidth = 0.5 * geoStaticInfo.GetWallWidth(); double wallHeight = 0.5 * geoStaticInfo.GetWallHeight(); double wallThickness = 0.5 * geoStaticInfo.GetWallThickness(); G4VSolid* wallSV = new G4Box("", wallWidth / utl::cm * cm, wallHeight / utl::cm * cm, wallThickness / utl::cm * cm); G4LogicalVolume* wallLV = new G4LogicalVolume(wallSV, wallMaterial, ""); new G4PVPlacement(0, G4ThreeVector(253 / utl::cm * cm, -59 / utl::cm * cm, 807 / utl::cm * cm), wallLV, "", logicalWorld, false, 0, checkOverlaps); //Inner G4VSolid* wallSV1 = new G4Box("", (wallWidth-1*mm) / utl::cm * cm, (wallHeight-1*mm) / utl::cm * cm, (wallThickness-1*mm) / utl::cm * cm); G4LogicalVolume* wallLV1 = new G4LogicalVolume(wallSV1, mRPCGas, ""); new G4PVPlacement(0, G4ThreeVector(), wallLV1, "", wallLV, false, 0, checkOverlaps); //############ PLANES ############################################# double planeWidth = 0.5 * geoStaticInfo.GetPlaneWidth(); double planeHeight = 0.5 * geoStaticInfo.GetPlaneHeight(); double planeThickness = 0.5 * geoStaticInfo.GetPlaneThickness(); double smallPlaneHeight = 0.5 * geoStaticInfo.GetSmallPlaneHeight(); G4RotationMatrix* planeRotation = new G4RotationMatrix(); planeRotation->rotateY(172.5*deg); // Large /////// G4VSolid* lPlaneSV = new G4Box("", planeWidth / utl::cm * cm, planeHeight / utl::cm * cm, planeThickness / utl::cm * cm); G4LogicalVolume* lPlaneLV = new G4LogicalVolume(lPlaneSV, mRPCGas, ""); // Small /////// G4VSolid* sPlaneSV = new G4Box("", planeWidth / utl::cm * cm, smallPlaneHeight / utl::cm * cm, planeThickness / utl::cm * cm); G4LogicalVolume* sPlaneLV = new G4LogicalVolume(sPlaneSV, mRPCGas, ""); //############ STRIPS ############################################## double stripWidth = 0.5 * geoStaticInfo.GetStripWidth(); double stripThickness = 0.5 * geoStaticInfo.GetStripThickness(); // Large ////// G4VSolid* lStripSV = new G4Box("", stripWidth / utl::cm * cm, planeHeight / utl::cm * cm, stripThickness / utl::cm * cm); G4LogicalVolume* lStripLV = new G4LogicalVolume(lStripSV, mRPCGas, ""); lStripLV->SetVisAttributes(G4VisAttributes(G4Colour::Yellow())); // Small ////// G4VSolid* sStripSV = new G4Box("", stripWidth / utl::cm * cm, smallPlaneHeight / utl::cm * cm, stripThickness / utl::cm * cm); G4LogicalVolume* sStripLV = new G4LogicalVolume(sStripSV, mRPCGas, ""); sStripLV->SetVisAttributes(G4VisAttributes(G4Colour::Yellow())); //############ KAPTON ############################################# double glassWidth = 0.5 * geoStaticInfo.GetGlassWidth(); double glassHeight = 0.5 * geoStaticInfo.GetGlassHeight(); double glassThickness = 0.5 * geoStaticInfo.GetGlassThickness(); double smallGlassHeight = 0.5 * geoStaticInfo.GetSmallGlassHeight(); G4Material* kapton = materialBuilder.GetMaterial("Kapton"); double kaptonThickness = 0.5 * geoStaticInfo.GetKaptonThickness(); double kaptonZPos = stripThickness + kaptonThickness; // Large ////// G4VSolid* lKaptonSV = new G4Box("", glassWidth / utl::cm * cm, glassHeight / utl::cm * cm, kaptonThickness / utl::cm * cm); G4LogicalVolume* lKaptonLV = new G4LogicalVolume(lKaptonSV, kapton, ""); lKaptonLV->SetVisAttributes(G4VisAttributes(G4Colour::Brown())); // Small ////// G4VSolid* sKaptonSV = new G4Box("", glassWidth / utl::cm * cm, smallGlassHeight / utl::cm * cm, kaptonThickness / utl::cm * cm); G4LogicalVolume* sKaptonLV = new G4LogicalVolume(sKaptonSV, kapton, ""); sKaptonLV->SetVisAttributes(G4VisAttributes(G4Colour::Brown())); //############ GLASS ############################################## G4Material* glass = materialBuilder.GetMaterial("Glass"); double glassZPos = kaptonZPos + kaptonThickness + glassThickness; // Large /////// G4VSolid* lGlassSV = new G4Box("", glassWidth / utl::cm * cm, glassHeight / utl::cm * cm, glassThickness / utl::cm * cm); G4LogicalVolume* lGlassLV = new G4LogicalVolume(lGlassSV, glass, ""); lGlassLV->SetVisAttributes(G4VisAttributes(G4Colour::Blue())); // Small /////// G4VSolid* sGlassSV = new G4Box("", glassWidth / utl::cm * cm, smallGlassHeight / utl::cm * cm, glassThickness / utl::cm * cm); G4LogicalVolume* sGlassLV = new G4LogicalVolume(sGlassSV, glass, ""); sGlassLV->SetVisAttributes(G4VisAttributes(G4Colour::Blue())); //############ COPPER LAYER ######################################### G4Material* copper = materialBuilder.GetMaterial("Copper"); double copperThickness = 0.5 * geoStaticInfo.GetCopperThickness(); double copperZPos = glassZPos + glassThickness + copperThickness; // Large ////// G4VSolid* lCopperSV = new G4Box("", planeWidth / utl::cm * cm, planeHeight / utl::cm * cm, copperThickness / utl::cm * cm); G4LogicalVolume* lCopperLV = new G4LogicalVolume(lCopperSV, copper, ""); //lCopperLV->SetVisAttributes(G4VisAttributes(G4Colour::Yellow())); // Small ////// G4VSolid* sCopperSV = new G4Box("", planeWidth / utl::cm * cm, smallPlaneHeight / utl::cm * cm, copperThickness / utl::cm * cm); G4LogicalVolume* sCopperLV = new G4LogicalVolume(sCopperSV, copper, ""); //sCopperLV->SetVisAttributes(G4VisAttributes(G4Colour::Yellow())); //############ HONEYCOMB + PCB ######################################### G4Material* honeycombPCB = materialBuilder.GetMaterial("honeycombPCB"); double honeycombPCBThickness = 0.5 * geoStaticInfo.GetHoneycombPCBThickness(); double honeycombPCBZPos = copperZPos + copperThickness + honeycombPCBThickness; // Large /////// G4VSolid* lHoneycombPCBSV = new G4Box("", glassWidth / utl::cm * cm, glassHeight / utl::cm * cm, honeycombPCBThickness / utl::cm * cm); G4LogicalVolume* lHoneycombPCBLV = new G4LogicalVolume(lHoneycombPCBSV, honeycombPCB, ""); lHoneycombPCBLV->SetVisAttributes(G4VisAttributes(G4Colour::Green())); // Small /////// G4VSolid* sHoneycombPCBSV = new G4Box("", glassWidth / utl::cm * cm, smallGlassHeight / utl::cm * cm, honeycombPCBThickness / utl::cm * cm); G4LogicalVolume* sHoneycombPCBLV = new G4LogicalVolume(sHoneycombPCBSV, honeycombPCB, ""); sHoneycombPCBLV->SetVisAttributes(G4VisAttributes(G4Colour::Green())); //############ PLACEMENT OF ALL OBJECTS ################################### for (unsigned int planeId = 0; planeId < mRPCWall.GetNPlanes(); planeId++) { const MRPCPlane& plane = mRPCWall.GetPlane(planeId); const utl::Point planePosition = plane.GetPlanePosition(); EType planeType = plane.GetType(); //*************** LARGE OBJECTS ************************** if (planeType == EType::eWide) { //Planes new G4PVPlacement(planeRotation, G4ThreeVector(planePosition.GetX() / utl::cm * cm, planePosition.GetY() / utl::cm * cm, planePosition.GetZ() / utl::cm * cm), lPlaneLV, "", wallLV1, false, planeId, checkOverlaps); //Strips for (unsigned int stripId = 0; stripId < 48; stripId++) { const MRPCStrip& strip = plane.GetStrip(stripId); const utl::Point stripPosition = strip.GetStripPosition(); new G4PVPlacement(0, G4ThreeVector(stripPosition.GetX() / utl::cm * cm, stripPosition.GetY() / utl::cm * cm, stripPosition.GetZ() / utl::cm * cm), lStripLV, "", lPlaneLV, false, stripId, checkOverlaps); } //Other layers inside plane for (int i = 0; i < 2; i++) { //Kapton layers double zPosKapton = kaptonZPos - i * (kaptonZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPosKapton / utl::cm * cm), lKaptonLV, "", lPlaneLV, false, i, checkOverlaps); //Glass layers double zPozGlass = glassZPos - i * (glassZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPozGlass / utl::cm * cm), lGlassLV, "", lPlaneLV, false, i, checkOverlaps); //Copper layers double zPosCopper = copperZPos - i * (copperZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPosCopper / utl::cm * cm), lCopperLV, "", lPlaneLV, false, i, checkOverlaps); //HoneycombPCB layers double zPosHoneycombPCB = honeycombPCBZPos - i * (honeycombPCBZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPosHoneycombPCB / utl::cm * cm), lHoneycombPCBLV, "", lPlaneLV, false, i, checkOverlaps); } } //********** SMALL OBJECTS ***************************** if (planeType == EType::eNarrow) { //Planes new G4PVPlacement(planeRotation, G4ThreeVector(planePosition.GetX() / utl::cm * cm, planePosition.GetY() / utl::cm * cm, planePosition.GetZ() / utl::cm * cm), sPlaneLV, "", wallLV1, false, planeId, checkOverlaps); //Strips for (unsigned int stripId = 0; stripId < 48; stripId++) { const MRPCStrip& strip = plane.GetStrip(stripId); const utl::Point stripPosition = strip.GetStripPosition(); new G4PVPlacement(0, G4ThreeVector(stripPosition.GetX() / utl::cm * cm, stripPosition.GetY() / utl::cm * cm, stripPosition.GetZ() / utl::cm * cm), sStripLV, "", sPlaneLV, false, stripId, checkOverlaps); } //Other layers inside plane for (int i = 0; i < 2; i++) { //Kapton layers double zPosKapton = kaptonZPos - i * (kaptonZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPosKapton / utl::cm * cm), sKaptonLV, "", sPlaneLV, false, i, checkOverlaps); //Glass layers double zPozGlass = glassZPos - i * (glassZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPozGlass / utl::cm * cm), sGlassLV, "", sPlaneLV, false, i, checkOverlaps); //Copper layers double zPosCopper = copperZPos - i * (copperZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPosCopper / utl::cm * cm), sCopperLV, "", sPlaneLV, false, i, checkOverlaps); //HoneycombPCB layers double zPosHoneycombPCB = honeycombPCBZPos - i * (honeycombPCBZPos * 2); new G4PVPlacement(0, G4ThreeVector(0, 0, zPosHoneycombPCB / utl::cm * cm), sHoneycombPCBLV, "", sPlaneLV, false, i, checkOverlaps); } } } //end loop over planes //############ Set sensitive and regions ################################# G4SensitiveDetector* wallSD = new G4SensitiveDetector("MRPCL"); bool buildSensitiveMRPC = false; for (auto i : sensitiveDetectors) { if (i == "MRPCL") buildSensitiveMRPC = true; } if (buildSensitiveMRPC) { G4SDManager::GetSDMpointer()->AddNewDetector(wallSD); lStripLV->SetSensitiveDetector(wallSD); sStripLV->SetSensitiveDetector(wallSD); } /*G4String lPlaneRegionName = "lPlaneRegion"; G4Region* lPlaneRegion; lPlaneRegion = (G4RegionStore::GetInstance())->FindOrCreateRegion(lPlaneRegionName); lPlaneLV->SetRegion(lPlaneRegion); lPlaneRegion->AddRootLogicalVolume(lPlaneLV); G4String sPlaneRegionName = "sPlaneRegion"; G4Region* sPlaneRegion; sPlaneRegion = (G4RegionStore::GetInstance())->FindOrCreateRegion(sPlaneRegionName); sPlaneLV->SetRegion(sPlaneRegion); sPlaneRegion->AddRootLogicalVolume(sPlaneLV);*/ return; }//end of buildMRPC }//end of namespace det