#include "construction.hh" #include "crystalSD.hh" #include "G4Material.hh" #include "G4NistManager.hh" #include "G4Box.hh" #include "G4Trd.hh" #include "G4Sphere.hh" #include "G4Tubs.hh" #include "G4IntersectionSolid.hh" #include "G4SubtractionSolid.hh" #include "G4LogicalVolume.hh" #include "G4PVPlacement.hh" #include "G4PVReplica.hh" #include "G4GlobalMagFieldMessenger.hh" #include "G4AutoDelete.hh" #include "G4PVReplica.hh" #include "G4RotationMatrix.hh" #include "G4UnionSolid.hh" #include "G4SDManager.hh" #include "G4VisAttributes.hh" #include "G4Colour.hh" #include "G4PhysicalConstants.hh" #include "G4SystemOfUnits.hh" //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4ThreadLocal G4GlobalMagFieldMessenger* MyDetectorConstruction::fMagFieldMessenger = 0; //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... MyDetectorConstruction::MyDetectorConstruction() : G4VUserDetectorConstruction(), fNumOfCrystal(0), // fNumOfSciCrystal(0), fLogicCrystal(NULL), fCrystalMaterial(NULL), fCheckOverlaps(true) { fNumOfCrystal = 4; //also need to change the fNDet in CloverEventAction.cc fLogicCrystal = new G4LogicalVolume* [fNumOfCrystal]; } MyDetectorConstruction::~MyDetectorConstruction() { delete [] fLogicCrystal; // delete [] fLogicSciCrystal; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4VPhysicalVolume* MyDetectorConstruction::Construct() { // Define materials DefineMaterials(); // Define volumes return DefineVolumes(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void MyDetectorConstruction::DefineMaterials() { // Lead material defined using NIST Manager auto nistManager = G4NistManager::Instance(); // Vacuum new G4Material("Galactic", 1., 1.01*g/mole, universe_mean_density, kStateGas, 2.73*kelvin, 3.e-18*pascal); // Air nistManager->FindOrBuildMaterial("G4_AIR"); // Iron nistManager->FindOrBuildMaterial("G4_Fe"); // Aluminium nistManager->FindOrBuildMaterial("G4_Al"); // Copper nistManager->FindOrBuildMaterial("G4_Cu"); // Ge fCrystalMaterial = nistManager->FindOrBuildMaterial("G4_Ge"); // Print materials G4cout << *(G4Material::GetMaterialTable()) << G4endl; } G4VPhysicalVolume *MyDetectorConstruction::DefineVolumes() { // Get materials auto backgroundMaterial = G4Material::GetMaterial("G4_AIR"); //crystal geometry G4double crystalLength = 4.*cm; G4double crystalRadius = 20.*mm; G4double crystalZPos = 12.*cm + crystalLength/2.; G4double cutXY = 35.0 * mm; // Geometry parameters G4double worldSizeZ = 2*(crystalLength + crystalZPos); G4double worldSizeXY = worldSizeZ; //world volume auto solidWorld = new G4Box("World", worldSizeXY/2, worldSizeXY/2, worldSizeZ); auto logicWorld = new G4LogicalVolume(solidWorld, backgroundMaterial, "World"); auto phyWorld = new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), // at (0,0,0) logicWorld, // its logical volume "World", // its name 0, // its mother volume false, // no boolean operation 0, // copy number fCheckOverlaps); // checking overlaps logicWorld->SetVisAttributes (G4VisAttributes::GetInvisible()); G4VisAttributes * red= new G4VisAttributes( G4Colour(255/255. , 0/255. , 0/255. )); G4VisAttributes* Invisible = new G4VisAttributes(false); // logicWorld -> SetVisAttributes(red); logicWorld -> SetVisAttributes(Invisible); // Crystals G4VisAttributes * crystalVisAtt= new G4VisAttributes(G4Colour(0.5,0.5,1.0)); crystalVisAtt->SetVisibility(true); for( G4int i = 0 ; i < fNumOfCrystal ; i++){ G4String name = "HPGe"+ std::to_string(i); G4cout << " crystal name : " << name << G4endl; G4double phi = 360/fNumOfCrystal * degree; G4double rho = 0; if( fNumOfCrystal == 4 ) rho = (cutXY/2 + 0.3* mm) / sin(phi/2.); G4Tubs * base = new G4Tubs("base", 0, crystalRadius, crystalLength/2., 0, 360*degree); G4Box * cut = new G4Box("cut", cutXY/2. , cutXY/2. , crystalLength/2. * 1.2); G4IntersectionSolid * crystalS = new G4IntersectionSolid("HPGe", base, cut); fLogicCrystal[i] = new G4LogicalVolume(crystalS, fCrystalMaterial, "CrystalLV"); fLogicCrystal[i]->SetVisAttributes(crystalVisAtt); G4ThreeVector pos = G4ThreeVector(rho * cos(i* phi + phi/2.), rho * sin(i * phi + phi/2.), crystalZPos); new G4PVPlacement( 0, // no rotation pos, // its position fLogicCrystal[i], // its logical volume name, // its name logicWorld, // its mother volume false, // no boolean operation i, // copy number fCheckOverlaps); // checking overlaps } //cladding auto nistManager = G4NistManager::Instance(); G4Material* casemat = nistManager->FindOrBuildMaterial("G4_Pb"); G4double shape1_dxa = crystalRadius+ 1*cm, shape1_dxb = crystalRadius+ 3*cm; G4double shape1_dya = crystalRadius+ 1*cm, shape1_dyb = crystalRadius+ 3*cm; G4double shape1_dz = 1*cm; G4double shape1a_dxa = crystalRadius- 1*cm, shape1a_dxb = crystalRadius+ 3*cm; G4double shape1a_dya = crystalRadius- 1*cm, shape1a_dyb = crystalRadius+ 3*cm; G4double shape1a_dz = 2*cm; G4Trd* clad1 = new G4Trd("clad1", shape1_dxa/2, shape1_dxb/2, shape1_dya/2, shape1_dyb/2, shape1_dz/2); G4Trd* clad2 = new G4Trd("clad2", shape1a_dxa/2, shape1a_dxb/2, shape1a_dya/2, shape1a_dyb/2, shape1a_dz/2); G4SubtractionSolid* cladding = new G4SubtractionSolid("cladding", clad1, clad2); G4LogicalVolume* cladLV = new G4LogicalVolume(cladding, casemat, "Cladding"); new G4PVPlacement(0, G4ThreeVector(0, 0,4*cm), cladLV, //it's logic volume "cladding", //its name logicWorld, //its mother volume false, // no boolean 0, //iteration fCheckOverlaps); //overlaps checking // colouring of case cladLV->SetVisAttributes(new G4VisAttributes(G4Colour(1.5,1.5,1.5))); //ACS // G4NistManager *nist = G4NistManager::Instance(); // auto nistManager = G4NistManager::Instance(); G4Material* ACSmat = nistManager->FindOrBuildMaterial("G4_BGO"); G4double shape2_dxa = crystalRadius+3*cm, shape2_dxb = crystalRadius+13*cm; G4double shape2_dya = crystalRadius+3*cm, shape2_dyb = crystalRadius+13*cm; G4double shape2_dz = 15.*cm; G4double shape2_dxa2 = crystalRadius+ 1*cm, shape2_dxb2 = crystalRadius+8*cm; G4double shape2_dya2 = crystalRadius+ 1*cm, shape2_dyb2 = crystalRadius+8*cm; G4double shape2_dz2 = 20.*cm; G4Trd* BGO1 = new G4Trd("BGO1", 0.5*shape2_dxa, 0.5*shape2_dxb,0.5*shape2_dya, 0.5*shape2_dyb, 0.5*shape2_dz); G4Trd* BGO2 = new G4Trd("BGO2", 0.5*shape2_dxa2, 0.5*shape2_dxb2,0.5*shape2_dya2, 0.5*shape2_dyb2, 0.5*shape2_dz2); G4SubtractionSolid* BGO = new G4SubtractionSolid("BGO", BGO1, BGO2); G4LogicalVolume* BGOLV = new G4LogicalVolume(BGO, ACSmat, "BGO"); G4ThreeVector BGOpos = G4ThreeVector( 0,0, 12 *cm ); G4RotationMatrix* DetRotm = new G4RotationMatrix(); new G4PVPlacement( DetRotm, // no rotation BGOpos, // its position BGOLV, // its logical volume "BGOPhysVol", // its name logicWorld, // its mother volume false, // no boolean operation 0, // copy number fCheckOverlaps); // checking overlaps // colouring of case //G4VisAttributes * BGOVisAtt= new G4VisAttributes(G4Colour(0.5,1.0,0.5)); // BGOVisAtt->SetVisibility(true); BGOLV->SetVisAttributes(new G4VisAttributes(G4Colour(0.8,0.0,0.0))); //// Backing G4Material* tarmat = nistManager->FindOrBuildMaterial("G4_Al"); G4Box* BackingL1 = new G4Box("BackingL1", 0.5*(crystalRadius+ 8*cm), 0.5*(crystalRadius+8*cm), 1*cm); G4Box* BackingL2 = new G4Box("BackingL2", 0.5*(crystalRadius+13*cm), 0.5*(crystalRadius+13*cm), 0.5*cm); G4SubtractionSolid* Backing = new G4SubtractionSolid("Backing", BackingL2, BackingL1); G4LogicalVolume* BackingLV = new G4LogicalVolume(Backing, tarmat, "Backing"); new G4PVPlacement(0, G4ThreeVector(0,0,20*cm), BackingLV, "Backing", logicWorld, false, 0, 0); BackingLV->SetVisAttributes(new G4VisAttributes(G4Colour(0.8, 0.8, 0.8))); ///Target Chamber G4NistManager *nist = G4NistManager::Instance(); G4Material *worldVaccume = nist->FindOrBuildMaterial("G4_Galactic"); G4double chamberOuterRadius = 20/2.* mm; G4double chamberInnerRadius = 10/2. * mm; // G4double pipeLength = worldSizeZ ; // G4double pipeZPos = 0.*cm; G4Sphere* targetChamber = new G4Sphere("TargetChamber",chamberInnerRadius, chamberOuterRadius, 0.0 * deg, 360.0 * deg, 0.0 * deg, 180.0 * deg); G4LogicalVolume* chamberLogical = new G4LogicalVolume(targetChamber, worldVaccume, "ChamberLogical"); G4RotationMatrix* chamberRotation = new G4RotationMatrix(); G4ThreeVector chamberPosition(0.0, 0.0, 0.0); new G4PVPlacement(chamberRotation, chamberPosition, chamberLogical, "ChamberPhysical", logicWorld, false,0, fCheckOverlaps); // G4VisAttributes * chamberVisAtt= new G4VisAttributes(G4Colour(1.0,0.5,1.0)); chamberLogical->SetVisAttributes(new G4VisAttributes(G4Colour(0.5,0.5,0.5))); return phyWorld; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void MyDetectorConstruction::ConstructSDandField() { G4cout << "********************* MyDetectorConstruction::ConstructSDandField() " << G4endl; G4SDManager::GetSDMpointer()->SetVerboseLevel(1); // Sensitive detectors crystalSD * CrystalSD = new crystalSD("Crystal", "CrystalHitsCollection", fNumOfCrystal); G4SDManager::GetSDMpointer()->AddNewDetector(CrystalSD); //Set crystalSD to all logical volumn under the same name of "CrystalLV" SetSensitiveDetector("CrystalLV",CrystalSD, true); // Create global magnetic field messenger. // Uniform magnetic field is then created automatically if // the field value is not zero. G4ThreeVector fieldValue; fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue); fMagFieldMessenger->SetVerboseLevel(1); // Register the field messenger for deleting G4AutoDelete::Register(fMagFieldMessenger); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......