#include #include #include #include #include #include using namespace RAT; #include #include using namespace CLHEP; using namespace std; CylindricalPMTConstructor::CylindricalPMTConstructor( const std::string& prefix, const PMTConstructorParams& params ) : PMTConstructor( prefix, params ) { } void CylindricalPMTConstructor::ConstructLogical() { const bool overlapRegion = fPMTParameters.fPCMirrorOverlapTop != fPMTParameters.fPCMirrorOverlapBottom; const G4double wall = fPMTParameters.fGlassThickness; // Construct the glass body G4Tubs* bodySolid = new G4Tubs( fPrefix + "_body_solid", 0.0, fPMTParameters.fRadius, fPMTParameters.fHeight / 2.0, 0.0, twopi ); // Now construct the solids const double inner1Height = fPMTParameters.fHeight / 2.0 - fPMTParameters.fPCMirrorOverlapTop - wall; G4Tubs* inner1Solid = new G4Tubs( fPrefix + "_inner1_solid", 0.0, fPMTParameters.fRadius - wall, inner1Height / 2.0, 0.0, twopi ); const double inner2Height = fPMTParameters.fPCMirrorOverlapTop - fPMTParameters.fPCMirrorOverlapBottom; G4Tubs* inner2Solid = NULL; if( overlapRegion ) inner2Solid = new G4Tubs( fPrefix + "_inner2_solid", 0.0, fPMTParameters.fRadius - wall, inner2Height / 2.0, 0.0, twopi ); const double inner3Height = fPMTParameters.fPCMirrorOverlapBottom + fPMTParameters.fHeight / 2.0 - wall; G4Tubs* inner3Solid = new G4Tubs( fPrefix + "_inner3_solid", 0.0, fPMTParameters.fRadius - wall, inner3Height / 2.0, 0.0, twopi ); // Construct the dynode volume double dynodeHeight = fPMTParameters.fDynodeTopZCoord + fPMTParameters.fHeight / 2.0 - wall; G4Tubs* dynodeSolid = new G4Tubs( fPrefix + "_dynode_solid", 0.0, fPMTParameters.fDynodeRadius, dynodeHeight / 2.0, 0.0, twopi ); // Construct the logical volumes fBodyLogic = new G4LogicalVolume( bodySolid, fPMTParameters.fGlassMaterial, fPrefix + "_body_logic" ); fInner1Logic = new G4LogicalVolume( inner1Solid, fPMTParameters.fVacuumMaterial, fPrefix + "_inner1_logic" ); fInner2Logic = NULL; if( overlapRegion ) fInner2Logic = new G4LogicalVolume( inner2Solid, fPMTParameters.fVacuumMaterial, fPrefix + "_inner2_logic"); fInner3Logic = new G4LogicalVolume( inner3Solid, fPMTParameters.fVacuumMaterial, fPrefix + "_inner3_logic"); fDynode1Logic = new G4LogicalVolume( dynodeSolid, fPMTParameters.fDynodeMaterial, fPrefix + "_dynode_logic" ); // Place the inner solids in the body solid to produce the physical volumes fInner1Phys = new G4PVPlacement( 0, G4ThreeVector( 0.0, 0.0, fPMTParameters.fPCMirrorOverlapTop + inner1Height / 2.0 ), fInner1Logic, fPrefix + "_inner1", fBodyLogic, false, 0 ); fInner2Phys = NULL; if( overlapRegion ) fInner2Phys = new G4PVPlacement( 0, G4ThreeVector( 0.0, 0.0, fPMTParameters.fPCMirrorOverlapBottom + inner2Height / 2.0 ), fInner2Logic, fPrefix + "_inner2", fBodyLogic, false, 0 ); double inner3posZ = fPMTParameters.fPCMirrorOverlapBottom - inner3Height / 2.0; fInner3Phys = new G4PVPlacement( 0, G4ThreeVector( 0.0, 0.0, inner3posZ ), fInner3Logic, fPrefix + "_inner3", fBodyLogic, false, 0 ); new G4PVPlacement( 0, G4ThreeVector( 0.0, 0.0, fPMTParameters.fDynodeTopZCoord - dynodeHeight / 2.0 - inner3posZ ), fDynode1Logic, fPrefix + "_dynode", fInner3Logic, false, 0 ); // Set the colour etc... SetAttributes(); } G4double CylindricalPMTConstructor::GetMaxHeight() { return fPMTParameters.fHeight / 2.0; } G4double CylindricalPMTConstructor::GetMaxDepth() { return -fPMTParameters.fHeight / 2.0; } G4double CylindricalPMTConstructor::GetHexRadius() { return fPMTParameters.fRadius; }