/// @file AllPixDetectorConstructionLUCID.cc /// @brief Implementation of the LUCID builder method. #include "AllPixDetectorConstruction.hh" // GEANT4 include statements. #include "G4Box.hh" #include "G4Tubs.hh" #include "G4Sphere.hh" #include "G4IntersectionSolid.hh" #include "G4SubtractionSolid.hh" #include "G4SolidStore.hh" #include "G4Material.hh" #include "G4NistManager.hh" #include "G4LogicalVolume.hh" #include "G4RotationMatrix.hh" #include "G4PVPlacement.hh" void AllPixDetectorConstruction::BuildLUCID(G4int num) { // User-defined materials G4NistManager * nistman = G4NistManager::Instance(); // Elements. G4Element * Si = nistman->FindOrBuildElement("Si"); G4Element * O = nistman->FindOrBuildElement("O"); G4Element * C = nistman->FindOrBuildElement("C"); G4Element * H = nistman->FindOrBuildElement("H"); G4Element * Br = nistman->FindOrBuildElement("Br"); G4Element * Cr = nistman->FindOrBuildElement("Cr"); G4Element * Mn = nistman->FindOrBuildElement("Mn"); G4Element * Fe = nistman->FindOrBuildElement("Fe"); G4Element * Ni = nistman->FindOrBuildElement("Ni"); G4double density, fractionmass; G4int ncomponents; // Epoxy for the PCB, based on type FR4 G4Material * EpoxyFR4 = new G4Material("EpoxyFR4", density=1.7*g/cm3, ncomponents=5); EpoxyFR4->AddElement(Si, fractionmass=0.180774); EpoxyFR4->AddElement(O, fractionmass=0.405633); EpoxyFR4->AddElement(C, fractionmass=0.278042); EpoxyFR4->AddElement(H, fractionmass=0.0684428); EpoxyFR4->AddElement(Br, fractionmass=0.0671091); // Aluminium. G4Material * almat = nistman->FindOrBuildMaterial("G4_Al"); G4RotationMatrix * dummyRot = new G4RotationMatrix; /////////////////////////////////////////////////////////// // Hemi-spherical pseudo-detector /////////////////////////////////////////////////////////// G4VisAttributes * pseudoDetectorVisAtt = new G4VisAttributes(G4Color(1.0, 0.0, 0.0, 0.01)); //invisibleVisAtt->SetForceSolid(false); //pseudoDetectorVisAtt->SetVisibility(true); pseudoDetectorVisAtt->SetVisibility(false); //pseudoDetectorVisAtt->SetForceSolid(true); G4LogicalVolume * m_pseudoDetector_log; G4VPhysicalVolume * m_pseudoDetector_phys; G4Sphere * pseudoDetector_sphere = new G4Sphere( "PseudoDetector", (m_worldRad-0.2)*mm, m_worldRad*mm, 0, 360.*degree, 0, 360.*degree); G4Box * pseudoDetector_box = new G4Box("PseudoDetectorCutBox", m_worldRad*mm, (m_worldRad/2.0)*mm, m_worldRad*mm); G4ThreeVector posPDboxcut(0.0*mm,-(m_worldRad/2.0)*mm,0.0*mm); G4SubtractionSolid * pseudoDetector_hemi = new G4SubtractionSolid( "PDhemi", pseudoDetector_sphere, pseudoDetector_box, dummyRot, posPDboxcut); m_pseudoDetector_log = new G4LogicalVolume( pseudoDetector_hemi, m_Vacuum, "PseudoDetector_log" ); m_pseudoDetector_log->SetVisAttributes(pseudoDetectorVisAtt); m_pseudoDetector_phys = new G4PVPlacement( 0, G4ThreeVector(0.,0.,0.), m_pseudoDetector_log, "PseudoDetector_phys", expHall_log, // mother log false, 0, // copy number true); // check overlap /////////////////////////////////////////////////////////// // The PCB base of LUCID // G4VisAttributes * pcbVisAtt = new G4VisAttributes(G4Color(0.18, 0.48, 0.08, 1.0)); pcbVisAtt->SetLineWidth(2); pcbVisAtt->SetForceSolid(true); pcbVisAtt->SetVisibility(true); // The PCB base. G4LogicalVolume * m_PcbBase_log; G4VPhysicalVolume * m_PcbBase_phys; // G4String PcbBaseName("LucidPcbBase"); G4Box * PcbBase_box = new G4Box( "PcbBase_box", m_worldRad * mm, 1.2*mm, m_worldRad * mm//m_PcbBaseDz // 0.0174*mm ); G4Sphere * PcbBase_sphere = new G4Sphere( "PcbBase_sphere", 0.0*mm, m_worldRad * mm, 0, 360.*degree, 0, 360.*degree); G4Box * PcbBase_cut_box = new G4Box( "PcbBase_cut_box", 12.9 * mm, 10.0 * mm, 9.0 * mm ); //G4ThreeVector yShift(0.0*mm,4.5652*mm,0.0*mm); G4ThreeVector yShift(0.0*mm,0.0*mm,0.0*mm); G4ThreeVector posPcbBase(0.0*mm,-7.6*mm,0.0*mm); posPcbBase += yShift; G4ThreeVector posAlBasePlate(0.0*mm,-1.2*mm,0.0*mm); posAlBasePlate += yShift; G4ThreeVector domeWallPos = G4ThreeVector(0.0*mm,16.5*mm,0.0*mm); domeWallPos += yShift; G4ThreeVector domeTopPos = G4ThreeVector(0.0*mm,33.0*mm,0.0*mm); domeTopPos += yShift; G4ThreeVector cutPos(-3.01,1.2,0.0); G4IntersectionSolid * PcbBase_round = new G4IntersectionSolid( "PcbBase_box*PcbBase_sphere", PcbBase_box, PcbBase_sphere, dummyRot, -posPcbBase); // Make sure the plate is moved down G4SubtractionSolid * PcbBase_cutout = new G4SubtractionSolid( "PcbBase_rount-TPX0_pcb", PcbBase_round, PcbBase_cut_box, dummyRot, cutPos ); // Make sure the plate is moved down m_PcbBase_log = new G4LogicalVolume( // PcbBase_round, PcbBase_cutout, EpoxyFR4, PcbBaseName+"_log" ); m_PcbBase_log->SetVisAttributes(pcbVisAtt); m_PcbBase_phys = new G4PVPlacement( 0, posPcbBase, m_PcbBase_log, PcbBaseName+"_phys", expHall_log, // mother log false, 0, // copy number true ); // check overlap /////////////////////////////////////////////////////////// // Al base plate G4VisAttributes * AlBasePlateVisAtt = new G4VisAttributes(G4Color(0.6, 0.6, 0.6, 1.0)); AlBasePlateVisAtt->SetLineWidth(2); AlBasePlateVisAtt->SetForceSolid(true); AlBasePlateVisAtt->SetVisibility(true); // G4String AlBasePlateName("AlBasePlate"); // The aluminium base plate (top of the LUCID box). G4LogicalVolume * m_AlBasePlate_log; G4VPhysicalVolume * m_AlBasePlate_phys; G4Box * AlBasePlate_box = new G4Box( "AlBasePlate_box", m_worldRad*mm, 1.2*mm, m_worldRad*mm ); G4Sphere * AlBasePlate_sphere = new G4Sphere( "AlBasePlate_sphere", 0.0*mm, m_worldRad*mm, 0, 360.*degree, 0, 360.*degree); G4IntersectionSolid * AlBasePlate_round = new G4IntersectionSolid( "AlBasePlate_box*AlBasePlate_sphere", AlBasePlate_box, AlBasePlate_sphere, dummyRot, -posAlBasePlate); // Make sure the plate is moved down G4Box * AlBasePlate_hole = new G4Box( "AlBasePlate_hole", 17.5*mm, 1.3*mm, 17.5*mm ); G4SubtractionSolid * AlBasePlate_plate = new G4SubtractionSolid( "AlBasePlate_round-AlBasePlate_hole", AlBasePlate_round, AlBasePlate_hole); m_AlBasePlate_log = new G4LogicalVolume( AlBasePlate_plate, almat, AlBasePlateName+"_log" ); m_AlBasePlate_log->SetVisAttributes(AlBasePlateVisAtt); m_AlBasePlate_phys = new G4PVPlacement( 0, posAlBasePlate, m_AlBasePlate_log, AlBasePlateName+"_phys", expHall_log, // mother log false, 0, // copy number true ); // check overlap /////////////////////////////////////////////////////////// // The Aluminium support posts G4VisAttributes * SupportPostVisAtt = new G4VisAttributes(G4Color(0.6, 0.6, 0.6, 1.0)); SupportPostVisAtt->SetLineWidth(2); SupportPostVisAtt->SetForceSolid(true); SupportPostVisAtt->SetVisibility(true); // G4String SupportPostName("SupportPost"); // The Timepix (TPX) support posts. G4LogicalVolume * m_SupportPost_log; G4VPhysicalVolume * m_SupportPost12_phys; G4VPhysicalVolume * m_SupportPost23_phys; G4VPhysicalVolume * m_SupportPost34_phys; G4VPhysicalVolume * m_SupportPost41_phys; G4Box * SupportPost_box = new G4Box( "SupportPost_box", 3.50*mm, 18.25*mm, 3.50*mm ); m_SupportPost_log = new G4LogicalVolume( SupportPost_box, almat, SupportPostName+"_log" ); m_SupportPost_log->SetVisAttributes(SupportPostVisAtt); G4ThreeVector posSP12( 14.0*mm,11.85*mm, 14.0*mm); posSP12 += yShift; G4ThreeVector posSP23( 14.0*mm,11.85*mm,-14.0*mm); posSP23 += yShift; G4ThreeVector posSP34(-14.0*mm,11.85*mm,-14.0*mm); posSP34 += yShift; G4ThreeVector posSP41(-14.0*mm,11.85*mm, 14.0*mm); posSP41 += yShift; m_SupportPost12_phys = new G4PVPlacement( 0, posSP12, m_SupportPost_log, SupportPostName+"12_phys", expHall_log, // mother log false, 1, // copy number true); // check overlap m_SupportPost23_phys = new G4PVPlacement( 0, posSP23, m_SupportPost_log, SupportPostName+"23_phys", expHall_log, // mother log false, 2, // copy number true); // check overlap m_SupportPost34_phys = new G4PVPlacement( 0, posSP34, m_SupportPost_log, SupportPostName+"34_phys", expHall_log, // mother log false, 3, // copy number true); // check overlap m_SupportPost41_phys = new G4PVPlacement( 0, posSP41, m_SupportPost_log, SupportPostName+"41_phys", expHall_log, // mother log false, 4, // copy number true); // check overlap /////////////////////////////////////////////////////////// // The Timepix PCB mounts // G4String TpxPcbName("TpxPcb"); // The TPX PCBs. G4LogicalVolume * m_TpxPcb_log; G4VPhysicalVolume * m_TpxPcb1_phys; G4VPhysicalVolume * m_TpxPcb2_phys; G4VPhysicalVolume * m_TpxPcb3_phys; G4VPhysicalVolume * m_TpxPcb4_phys; G4Box * TpxPcb_box = new G4Box( TpxPcbName+"_box", 15.50*mm, 12.90*mm, 0.80*mm ); G4Box * TpxPcb_box_cut = new G4Box( TpxPcbName+"_box_cut", 9.00*mm, 13.00*mm, // Slightly larger. 1.00*mm // Slightly larger. ); G4SubtractionSolid * TpxPcb_sides = new G4SubtractionSolid( TpxPcbName + "_sides", TpxPcb_box, TpxPcb_box_cut, dummyRot, G4ThreeVector(0.,0.,0.) ); m_TpxPcb_log = new G4LogicalVolume( TpxPcb_sides, EpoxyFR4, TpxPcbName+"_log" ); m_TpxPcb_log->SetVisAttributes(pcbVisAtt); G4ThreeVector posTP1( 0.0*mm, 18.3*mm, 18.3*mm); posTP1 += yShift; G4ThreeVector posTP2( 18.3*mm, 18.3*mm, 0.0*mm); posTP2 += yShift; G4ThreeVector posTP3( 0.0*mm, 18.3*mm,-18.3*mm); posTP3 += yShift; G4ThreeVector posTP4(-18.3*mm, 18.3*mm, 0.0*mm); posTP4 += yShift; // Repeated, rotated geometry G4RotationMatrix * rot0 = new G4RotationMatrix; rot0->rotateX(M_PI/2.*rad); // G4RotationMatrix * rot1 = new G4RotationMatrix; //rot1->rotateY(0.0*rad); // G4RotationMatrix * rot2 = new G4RotationMatrix; rot2->rotateY(-M_PI/2.*rad); // G4RotationMatrix * rot3 = new G4RotationMatrix; rot3->rotateY(M_PI *rad); // G4RotationMatrix * rot4 = new G4RotationMatrix; rot4->rotateY( M_PI/2.*rad); m_TpxPcb1_phys = new G4PVPlacement( rot1, posTP1, m_TpxPcb_log, TpxPcbName+"1_phys", expHall_log, // mother log false, 1, // copy number true); // check overlap m_TpxPcb2_phys = new G4PVPlacement( rot2, posTP2, m_TpxPcb_log, TpxPcbName+"2_phys", expHall_log, // mother log false, 2, // copy number true); // check overlap m_TpxPcb3_phys = new G4PVPlacement( rot3, posTP3, m_TpxPcb_log, TpxPcbName+"3_phys", expHall_log, // mother log false, 3, // copy number true); // check overlap m_TpxPcb4_phys = new G4PVPlacement( rot4, posTP4, m_TpxPcb_log, TpxPcbName+"4_phys", expHall_log, // mother log false, 4, // copy number true); // check overlap if (m_testStructureShieldingThickness[num] > 0.0) { //////////////////////////////////////////////////////////////////////////// // The Dome wall G4VisAttributes * DomeVisAtt = new G4VisAttributes(G4Color(0.6, 0.6, 0.6, 0.1)); DomeVisAtt->SetLineWidth(2); DomeVisAtt->SetForceSolid(true); DomeVisAtt->SetVisibility(false); //DomeVisAtt->SetVisibility(true); // The "dome" wall. G4LogicalVolume * m_DomeWall_log; G4VPhysicalVolume * m_DomeWall_phys; G4String DomeWallName("DomeWall"); G4Tubs * DomeWall_cyl = new G4Tubs( DomeWallName+"_box", 30.00*mm, (30.00 + m_testStructureShieldingThickness[num])*mm, 16.50*mm, 0.000, // Starting point for segment. 2.0*pi // Angle (i.e. full tube). ); m_DomeWall_log = new G4LogicalVolume( DomeWall_cyl, almat, DomeWallName+"_log" ); m_DomeWall_log->SetVisAttributes(DomeVisAtt); G4RotationMatrix * domeWallRot = new G4RotationMatrix; domeWallRot->rotateX(M_PI/2.*rad); m_DomeWall_phys = new G4PVPlacement( domeWallRot, domeWallPos, m_DomeWall_log, DomeWallName+"_phys", expHall_log, false, 0, true); //////////////////////////////////////////////////////////////////////////// // The Dome top G4String DomeTopName("DomeTop"); // The "dome" top. G4LogicalVolume * m_DomeTop_log; G4VPhysicalVolume * m_DomeTop_phys; G4Tubs * DomeTop_cyl = new G4Tubs( DomeTopName+"_box", 0.00*mm, (30.00 + m_testStructureShieldingThickness[num]) * mm, m_testStructureShieldingThickness[num] * mm, 0.000, // Starting point for segment. 2.0*pi // Angle (i.e. full tube). ); m_DomeTop_log = new G4LogicalVolume( DomeTop_cyl, almat, DomeTopName+"_log" ); m_DomeTop_log->SetVisAttributes(DomeVisAtt); G4RotationMatrix * domeTopRot = new G4RotationMatrix; domeTopRot->rotateX(M_PI/2.*rad); domeTopPos += G4ThreeVector(0.0, m_testStructureShieldingThickness[num], 0.0); m_DomeTop_phys = new G4PVPlacement( domeTopRot, domeTopPos, m_DomeTop_log, DomeTopName+"_phys", expHall_log, false, 0, true); // G4PVPlacement * shield_phys = new G4PVPlacement( // m_rotVectorTestStructure[num], // m_posVectorTestStructure[num] + G4ThreeVector(0.0,shlthk/2.,0.0), // shield_log, // "shield_phys", // expHall_log, // false, // 0, // copy number // true // ); }//end of shielding thickness check. }//end of AllPixDetectorConstruction::BuildSourceTestBench method.