#include #include #include #include #include #include #include #include #include #include using namespace CLHEP; using namespace RAT; BucketConstructor::BucketConstructor( const std::string& prefix, const BucketConstructorParams& params ) : fBucketParameters( params ) { fPrefix = prefix + std::string("_bucket"); fBucketLogic = NULL; } void BucketConstructor::Construct() { // Some G4 quirk requires this method const G4int nPoints = fBucketParameters.fEdgeZCoord.size(); G4double *rInner = new G4double[nPoints]; G4double *zCoord = new G4double[nPoints]; G4double *rOuter = new G4double[nPoints]; G4int iLoop; for( iLoop=0; iLoop < nPoints; iLoop++ ) { rInner[iLoop] = fBucketParameters.fInnerEdgeRhoCoord[iLoop]; zCoord[iLoop] = fBucketParameters.fEdgeZCoord[iLoop]; rOuter[iLoop] = fBucketParameters.fOuterEdgeRhoCoord[iLoop] - 2.0 * PMTGeo::kFaceGap; } zCoord[0] -= 2.0 * PMTGeo::kFaceGap; zCoord[nPoints-1] += 2.0 * PMTGeo::kFaceGap; const G4int numHexEdges = 6; // Create a hex shell that is the majority of the bucket/panel-sub-part G4Polyhedra* bucketOuter = new G4Polyhedra( fPrefix + "_outer", 0, twopi, numHexEdges, nPoints, zCoord, rInner, rOuter ); delete[] rInner; delete[] zCoord; delete[] rOuter; G4VSolid* topHoleSolid = NULL; if( fBucketParameters.fTopHexRadius == 0.0 ) // Then circular opening { // Create a solid that represents the top hole (Conc opening) topHoleSolid = new G4Tubs( "_top_hole", 0.0, fBucketParameters.fTopHoleRadius, fBucketParameters.fTopHoleDepth, 0.0, twopi); } else if( fBucketParameters.fTopHoleRadius == 0.0 ) // Then hex opening { G4double zCoord[] = { fBucketParameters.fTopHoleDepth, -fBucketParameters.fTopHoleDepth }; G4double rInner[] = { 0.0, 0.0 }; G4double rOuter[] = { fBucketParameters.fTopHexRadius, fBucketParameters.fTopHexRadius }; topHoleSolid = new G4Polyhedra( "_top_hole", pi / 18.0 * rad, twopi, fBucketParameters.fNumPetals, 2, zCoord, rInner, rOuter ); } else Log::Die("BucketConstructor::BucketConstructor: Unclear top opening type."); // Create a solid that represents the bottom hole (PMT base opening) G4Tubs *bottomHoleSolid = new G4Tubs( "_bottom_hole", 0.0, fBucketParameters.fBottomHoleRadius, fBucketParameters.fBottomHoleDepth, 0.0, twopi); // Remove the top hole G4SubtractionSolid *bucketTopSolid = new G4SubtractionSolid( "_top_temp", bucketOuter, topHoleSolid, 0, G4ThreeVector (0, 0, fBucketParameters.fEdgeZCoord.front() ) ); // Remove the bottom hole G4SubtractionSolid *bucketSolid = new G4SubtractionSolid( fPrefix + "_solid", bucketTopSolid, bottomHoleSolid, 0, G4ThreeVector (0, 0, fBucketParameters.fEdgeZCoord.back() ) ); fBucketLogic = new G4LogicalVolume( bucketSolid, fBucketParameters.fBulkMaterial, fPrefix + "_logic" ); // ------------ Vis Attributes ------------- fBucketLogic->SetVisAttributes( fBucketParameters.fVisAttributes ); } G4LogicalVolume* BucketConstructor::GetLogicalVolume() { if( fBucketLogic == NULL ) Log::Die("BucketConstructor::GetLogicalVolume: Construct has not been called."); return fBucketLogic; } G4double BucketConstructor::GetMaxHeight() { //Above PMT equator, order of EdgeZCoord matters return fBucketParameters.fEdgeZCoord.front() - 2.0 * PMTGeo::kFaceGap; } G4double BucketConstructor::GetMaxDepth() { //Below PMT equator, order of EdgeZCoord matters return fBucketParameters.fEdgeZCoord.back() + 2.0 * PMTGeo::kFaceGap; } G4double BucketConstructor::GetHexRadius() { // Radius is assumed constant return fBucketParameters.fOuterEdgeRhoCoord.front() - 2.0 * PMTGeo::kFaceGap; } G4double BucketConstructor::GetOffset() { return fBucketParameters.fOffset; }