// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // #include "DetectorConstruction.hh" #include "globals.hh" #include "G4Element.hh" #include "G4Material.hh" #include "G4PVPlacement.hh" #include "G4LogicalVolume.hh" #include "G4Tubs.hh" #include "G4Box.hh" //#include "G4SubtractionSolid.hh" #include "G4FieldManager.hh" #include "G4TransportationManager.hh" #include "G4ChordFinder.hh" #include "G4Colour.hh" #include "G4VisAttributes.hh" #include "SensitiveDetector.hh" #include "G4SDManager.hh" #include "G4UserLimits.hh" #include "Randomize.hh" #include "G4ThreeVector.hh" #include "G4GeometryTolerance.hh" #include "G4GeometryManager.hh" #include "G4SystemOfUnits.hh" #include "G4NistManager.hh" DetectorConstruction::DetectorConstruction(AnalysisManager* analysis_manager) { analysis = analysis_manager; } DetectorConstruction::~DetectorConstruction(){ } G4VPhysicalVolume* DetectorConstruction::Construct() { //-------------------------------------------------------- //--------------------- MATERIALS ------------------------ //-------------------------------------------------------- G4NistManager * nistMan = G4NistManager::Instance(); //Define Water G4Material* water = nistMan->FindOrBuildMaterial("G4_WATER"); //Define Polyethylene //G4Material* poly = nistMan->FindOrBuildMaterial("G4_POLYETHYLENE"); //Define PMMA //G4Material* perspex = nistMan->FindOrBuildMaterial("G4_PLEXIGLASS"); //Default 1.19g //Define Air G4Material* Air = nistMan->FindOrBuildMaterial("G4_AIR"); //Define Aluminium G4Material* Aluminium = nistMan->FindOrBuildMaterial("G4_Al"); //Define Silicon G4Material* silicon = nistMan->FindOrBuildMaterial("G4_Si"); //Define Aluminium Oxide (this is acting as the ceremic) //G4Material* AlOx = nistMan->FindOrBuildMaterial("G4_ALUMINUM_OXIDE"); //Define SiO G4Material* SiO2 = nistMan->FindOrBuildMaterial("G4_SILICON_DIOXIDE"); //Define Pyrex Glass //G4Material* PyrexGlass = nistMan->FindOrBuildMaterial("G4_Pyrex_Glass"); //-------------------------------------------------------- //-------------------- Vis Attributes -------------------- //-------------------------------------------------------- G4VisAttributes* wireFrameWhiteAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0)); wireFrameWhiteAtt -> SetVisibility(true); wireFrameWhiteAtt -> SetForceWireframe(true); G4VisAttributes* wireFramePinkAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 1.0)); wireFramePinkAtt -> SetVisibility(true); wireFramePinkAtt -> SetForceWireframe(true); G4VisAttributes* wireFrameRedAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0)); wireFrameRedAtt -> SetVisibility(true); wireFrameRedAtt -> SetForceWireframe(true); G4VisAttributes* wireFrameBlueAtt = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0)); wireFrameBlueAtt -> SetVisibility(true); wireFrameBlueAtt -> SetForceWireframe(true); G4VisAttributes* solidGreyAtt = new G4VisAttributes(G4Colour(0.5, .5, .5)); solidGreyAtt -> SetVisibility(true); solidGreyAtt -> SetForceSolid(true); G4VisAttributes* solidRedAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0)); solidRedAtt -> SetVisibility(true); solidRedAtt -> SetForceSolid(true); G4VisAttributes* solidGreenAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0)); solidGreenAtt -> SetVisibility(true); solidGreenAtt -> SetForceSolid(true); G4VisAttributes* solidYellowAtt = new G4VisAttributes(G4Colour(1.0, 1.0, 0.0)); solidYellowAtt -> SetVisibility(true); solidYellowAtt -> SetForceSolid(true); G4VisAttributes* solidBlueAtt = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0)); solidBlueAtt -> SetVisibility(true); solidBlueAtt -> SetForceSolid(true); //-------------------------------------------------------- //----------------------- Volumes ------------------------ //-------------------------------------------------------- // World volume has size 1cm G4double worldx = 1 * m; //half length!!!! G4double worldy = 1 * m; G4double worldz = 1 * m; // World volume, containing all geometry G4Box* world = new G4Box("world_box", worldx, worldy, worldz); G4LogicalVolume* logical_world = new G4LogicalVolume(world, Air, "world_log", 0,0,0); //set the logical world volume invisible //logical_world -> SetVisAttributes(G4VisAttributes::GetInvisible()); G4VPhysicalVolume* physical_world = new G4PVPlacement(0, G4ThreeVector(), logical_world, "world_phys", 0, false, 0, true); //Create 30 cm^3 water phantom to go in the world G4double phantomX = 30. * cm; G4double phantomY = 30. * cm; G4double phantomZ = 30. * cm; G4Box* phantom = new G4Box("phantom_box", phantomX/2. , phantomY/2., phantomZ/2.); G4LogicalVolume* logicalPhantom = new G4LogicalVolume(phantom, water, "Phantom_log", 0,0,0); new G4PVPlacement(0, G4ThreeVector(0,0,0), logicalPhantom, "Phantom_Phys", logical_world, false, 0, true); G4VisAttributes* phantomAtt = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0)); // blue phantomAtt -> SetVisibility(true); phantomAtt -> SetForceWireframe(true); logicalPhantom -> SetVisAttributes(phantomAtt); //logicalPhantom -> SetVisAttributes(solidBlueAtt); G4Region* phantomRegion = new G4Region("phantomLog"); logicalPhantom -> SetRegion(phantomRegion); phantomRegion -> AddRootLogicalVolume(logicalPhantom); //------------------Detector Mother Volume Size------------------ G4double SVheight = 10.*micrometer; G4double insulationThickness = 1.*micrometer; G4double SiOoverlayerBottomThickness = 1.7*micrometer; G4double AlOverlayerThickness = 1.7*micrometer; G4double AlOverlayerRadius = 4.*micrometer; G4double SiOoverlayerTopThickness = 1.43*micrometer; G4double SiOoverlayerTopRadius = 10.5/2. * micrometer; G4double overLayerThickness = AlOverlayerThickness + SiOoverlayerTopThickness; G4double baseSiThickness = 300.*micrometer; G4double detectorHeight = (SVheight + baseSiThickness + insulationThickness + SiOoverlayerBottomThickness + AlOverlayerThickness + SiOoverlayerTopThickness); G4double SVwidth = 30.*micrometer; G4double pitch = 20.*micrometer; //distance between the odd and even rows G4double bridgingWidth = 20.*micrometer; G4double bridgingLength = 15.*micrometer; G4double bridingHeight = SVheight; G4double numberOfRows = 59; G4double numberOfColumns = (24*3); G4double SVareaWidth = (numberOfColumns * (SVwidth + bridgingWidth)) - 1.*bridgingWidth; G4double SVareaLength = numberOfRows*(SVwidth + pitch) - 1.*pitch; G4double bufferWidth = 100.*micrometer; G4double detectorWidth = SVareaWidth + bufferWidth; G4double detectorLength = SVareaLength + bufferWidth; G4RotationMatrix* rotMat = new G4RotationMatrix; rotMat->rotateZ(M_PI*1.5*rad); //------------------Cut Region------------------------------------- G4double cutHeight = detectorHeight + 2.*mm; G4double cutWidth = detectorWidth + 2.*mm; G4double cutLength = detectorLength + 2.*mm; G4Box* cutBox = new G4Box("cutBox", cutWidth/2., cutHeight/2., cutLength/2.); G4LogicalVolume* logicalcutReg = new G4LogicalVolume(cutBox, water, "cutReg_log", 0,0,0); new G4PVPlacement(rotMat, G4ThreeVector(-128,0,0), logicalcutReg, "cutRegPhys", logicalPhantom, false, 0, true); logicalcutReg -> SetVisAttributes(wireFrameBlueAtt); //detector position in mm, 0 is in the center of phantom G4Region* cutRegion = new G4Region("cutLog"); logicalcutReg -> SetRegion(cutRegion); cutRegion -> AddRootLogicalVolume(logicalcutReg); //------------------StepLimit Region------------------------------------- G4double stepLimitHeight = detectorHeight + 150.*micrometer; G4double stepLimitWidth = detectorWidth + 150.*micrometer; G4double stepLimitLength = detectorLength + 150.*micrometer; G4Box* stepLimitBox = new G4Box("stepLimitBox", stepLimitWidth/2., stepLimitHeight/2., stepLimitLength/2.); G4LogicalVolume* logicalstepLimitReg = new G4LogicalVolume(stepLimitBox, water, "stepLimitReg_log", 0,0,0); new G4PVPlacement(0, G4ThreeVector(0,0,0), logicalstepLimitReg, "stepLimitRegPhys", logicalcutReg, false, 0, true); logicalstepLimitReg -> SetVisAttributes(wireFrameRedAtt); //G4Region* stepLimitRegion = new G4Region("stepLimitLog"); //logicalstepLimitReg -> SetRegion(stepLimitRegion); //tepLimitRegion -> AddRootLogicalVolume(logicalcutReg); G4double stepLimitValue = 1*micrometer; logicalstepLimitReg -> SetUserLimits(new G4UserLimits(stepLimitValue)); //------------------Detector Mother Volume------------------ G4Box* detectorBox = new G4Box("detectorBox", detectorWidth/2., detectorHeight/2., detectorLength/2.); G4LogicalVolume* logicalDetectorReg = new G4LogicalVolume(detectorBox, Air, "detectorReg_log", 0,0,0); new G4PVPlacement(0, G4ThreeVector(0,0,0), logicalDetectorReg, "detectorRegPhys", logicalstepLimitReg , false, 0, true); logicalDetectorReg -> SetVisAttributes(wireFrameWhiteAtt); //------------------Detector Cut Region------------------------------------- G4Region* detectorRegion = new G4Region("detectorLog"); logicalDetectorReg -> SetRegion(detectorRegion); detectorRegion -> AddRootLogicalVolume(logicalDetectorReg); //------------------Base Silicon Volume---------------------- G4Box* basSiBox = new G4Box("baseSiBox", detectorWidth/2., baseSiThickness/2., detectorLength/2.); G4LogicalVolume* logicalbaseSi = new G4LogicalVolume(basSiBox, silicon, "baseSi_log", 0,0,0); new G4PVPlacement(0, G4ThreeVector(0,(-detectorHeight/2. + baseSiThickness/2.),0), logicalbaseSi, "baseSiPhys", logicalDetectorReg, false, 0, true); logicalbaseSi -> SetVisAttributes(wireFrameWhiteAtt); //---------------------Insulation Volume---------------------- G4Box* SiOBox = new G4Box("SiOBox", detectorWidth/2., insulationThickness/2., detectorLength/2.); G4LogicalVolume* logicalSoI = new G4LogicalVolume(SiOBox, SiO2, "SoI_log", 0,0,0); new G4PVPlacement(0, G4ThreeVector(0,(detectorHeight/2. -overLayerThickness - SVheight - insulationThickness/2.),0), logicalSoI, "SoIPhys", logicalDetectorReg, false, 0, true); logicalSoI -> SetVisAttributes(solidGreyAtt); //----------------Sensitive Volume Region--------------------- //This volume encapsulates the SVs and the "bridging" volumes G4Box* SVregBox = new G4Box("SVregBox", detectorWidth/2., SVheight/2., detectorLength/2.); G4LogicalVolume* logicalSVreg = new G4LogicalVolume(SVregBox, Air, "SVreg_log", 0,0,0); new G4PVPlacement(0, G4ThreeVector(0,(detectorHeight/2. - overLayerThickness - SVheight/2.),0), logicalSVreg, "SVregPhys", logicalDetectorReg, false, 0, true); logicalSVreg -> SetVisAttributes(wireFrameWhiteAtt); //----------------------Bridging Volume---------------------- //This volume connects or "bridges" the main sensitive volumes //together but effectively act as additional sensitive volumes G4Box* bridgeVolBox = new G4Box("bridgeVolBox", bridgingWidth/2., bridingHeight/2., bridgingLength/2.); G4LogicalVolume* logicalBridgeVol = new G4LogicalVolume(bridgeVolBox, silicon, "bridgeVol_log", 0,0,0); logicalBridgeVol -> SetVisAttributes(solidRedAtt); //---------------------SiO Bottom Overlayer------------------ G4Box* SiObotLayerBox = new G4Box("SiObotLayerBox", SVwidth/2., SiOoverlayerBottomThickness/2., SVwidth/2.); G4LogicalVolume* logicalSiObotLayer = new G4LogicalVolume(SiObotLayerBox, SiO2, "logicalSiObotLayer", 0,0,0); logicalSiObotLayer -> SetVisAttributes(solidGreenAtt); //--------------SiO Bottom Overlayer Bridging Vol------------- G4Box* SiObotLayerBridgeBox = new G4Box("SiObotLayerBridgeBox", bridgingWidth/2., SiOoverlayerBottomThickness/2., bridgingLength/2.); G4LogicalVolume* logicalSiObotLayerBridge = new G4LogicalVolume(SiObotLayerBridgeBox, SiO2, "logicalSiObotLayer", 0,0,0); logicalSiObotLayerBridge -> SetVisAttributes(solidGreenAtt); //-----------------------Al contact --------------------------- G4Box* AlContactBox = new G4Box("AlContactBox", AlOverlayerRadius, AlOverlayerThickness/2., AlOverlayerRadius); G4LogicalVolume* logicalAlContact = new G4LogicalVolume(AlContactBox, Aluminium, "logicalAlContact", 0,0,0); logicalAlContact -> SetVisAttributes(solidYellowAtt); //----------------------SiO Top Overlayer---------------------- G4Box* SiOtopLayerBox = new G4Box("SiOtopLayerBox", SiOoverlayerTopRadius, SiOoverlayerTopThickness/2., SiOoverlayerTopRadius); G4LogicalVolume* logicalSiOtopLayer = new G4LogicalVolume(SiOtopLayerBox, SiO2, "logicalSiOtopLayer", 0,0,0); logicalSiOtopLayer -> SetVisAttributes(solidBlueAtt); //--------------------Sensitive Volume-------------------------- G4Box* sensitiveBridgeVolume = new G4Box("water_region_sphere", SVwidth/2., SVheight/2., SVwidth/2.); G4LogicalVolume* SV_log = new G4LogicalVolume(sensitiveBridgeVolume, silicon, "SV_log", 0,0,0); SV_log -> SetVisAttributes(solidYellowAtt); //---Placing SVs, 30x30 volumes and "bridging" volumes between them G4bool checkSVoverlap = false; //Placing "odd" SV rows/columns G4int globalCount = 100000; for (G4double j = -SVareaLength/2.; j <= SVareaLength/2.; j+=2.*(SVwidth + bridgingWidth)) //creates each row { for (G4double i = -SVareaWidth/2.; i <= SVareaWidth/2.; i+=(SVwidth + bridgingWidth)) //goes through each odd row { //G4cout << "x: " << i/um << " z: " << j/um << G4endl; new G4PVPlacement(0, G4ThreeVector(i,0,j), SV_log , "physSensitiveBridgeVolume", logicalSVreg, false, globalCount, checkSVoverlap); new G4PVPlacement(0, G4ThreeVector(i,((detectorHeight/2. -overLayerThickness + SiOoverlayerBottomThickness/2.)),j), logicalSiObotLayer, "physSiObotLayer", logicalDetectorReg, false, globalCount, checkSVoverlap); new G4PVPlacement(0, G4ThreeVector(i,((detectorHeight/2. -overLayerThickness + SiOoverlayerBottomThickness + SiOoverlayerTopThickness/2.)),j), logicalSiOtopLayer, "physSiOtopLayer", logicalDetectorReg, false, globalCount, checkSVoverlap); globalCount++; } } //Placing "even" SV rows/columns globalCount = 200000; for (G4double j = (-SVareaLength/2. + SVwidth + bridgingWidth); j <= SVareaLength/2.; j+=2.*(SVwidth + bridgingWidth)) //creates each row { for (G4double i = -SVareaWidth/2.; i <= SVareaWidth/2.; i+=(SVwidth + bridgingWidth)) //goes through each odd row { //G4cout << "x: " << i/micrometer << " z: " << j/micrometer << G4endl; new G4PVPlacement(0, G4ThreeVector(i,0,j), SV_log , "physSensitiveBridgeVolume", logicalSVreg, false, globalCount, checkSVoverlap); new G4PVPlacement(0, G4ThreeVector(i,((detectorHeight/2. -overLayerThickness + SiOoverlayerBottomThickness/2.)),j), logicalSiObotLayer, "physSiObotLayer", logicalDetectorReg, false, globalCount, checkSVoverlap); new G4PVPlacement(0, G4ThreeVector(i,((detectorHeight/2. -overLayerThickness + SiOoverlayerBottomThickness + SiOoverlayerTopThickness/2.)),j), logicalSiOtopLayer, "physSiOtopLayer", logicalDetectorReg, false, globalCount, checkSVoverlap); globalCount++; } } //Placing "odd" bridging volumes rows/columns globalCount = 300000; for (G4double j = -SVareaLength/2.; j < SVareaLength/2.; j+=2.*(SVwidth + bridgingWidth)) //creates each row { for (G4double i = -SVareaWidth/2.; i < SVareaWidth/2.; i+=(SVwidth + bridgingWidth)) //goes through each odd row { if ( (i + (SVwidth + bridgingWidth)) < SVareaWidth/2.) { //G4cout << globalCount << G4endl; new G4PVPlacement(0, G4ThreeVector((i + SVwidth/2. + bridgingWidth/2.),0,(j+ bridgingLength/2.)), logicalBridgeVol , "sen_bridge", logicalSVreg, false, globalCount, checkSVoverlap); new G4PVPlacement(0, G4ThreeVector((i + SVwidth/2. + bridgingWidth/2.),((detectorHeight/2. -overLayerThickness + SiOoverlayerBottomThickness/2.)),(j+ bridgingLength/2.)), logicalSiObotLayerBridge, "physSiObotLayerBridge", logicalDetectorReg, false, globalCount, checkSVoverlap); //G4cout << "x: " << (i + SVwidth/2. + bridgingWidth/2.)/micrometer << " z: " << j/micrometer << G4endl; globalCount++; } } } //Placing "even" bridging rows/columns globalCount = 400000; for (G4double j = (-SVareaLength/2. + SVwidth + bridgingWidth); j < SVareaLength/2.; j+=2.*(SVwidth + bridgingWidth)) //creates each row { for (G4double i = -SVareaWidth/2.; i < SVareaWidth/2.; i+=(SVwidth + bridgingWidth)) //goes through each odd row { if ( (i+ (SVwidth + bridgingWidth)) < SVareaWidth/2.) { //G4cout << globalCount << G4endl; new G4PVPlacement(0, G4ThreeVector((i + SVwidth/2. + bridgingWidth/2.),0,(j+ bridgingLength/2.)), logicalBridgeVol , "sen_bridge", logicalSVreg, false, globalCount, checkSVoverlap); //G4cout << "x: " << (i + SVwidth/2. + bridgingWidth/2.)/micrometer << " z: " << j/micrometer << G4endl; new G4PVPlacement(0, G4ThreeVector((i + SVwidth/2. + bridgingWidth/2.),((detectorHeight/2. -overLayerThickness + SiOoverlayerBottomThickness/2.)),(j+ bridgingLength/2.)), logicalSiObotLayerBridge, "physSiObotLayerBridge", logicalDetectorReg, false, globalCount, checkSVoverlap); globalCount++; } } } //---------------------------------------- new G4PVPlacement(0, G4ThreeVector(0,0,0), logicalAlContact, "physAlContact", logicalSiObotLayer, false, 0, 1); return physical_world; } void DetectorConstruction::ConstructSDandField() { SensitiveDetector* SD = new SensitiveDetector("SD", "DetectorHitsCollection", analysis); G4SDManager::GetSDMpointer()->AddNewDetector(SD); SetSensitiveDetector("bridgeVol_log", SD); }