Open spradlin opened 1 year ago
In running overlap checks for the new IWCD geometries, an overlap in the construction of the individual PMT revealed that the reflector construction is rife with hard-coded dimensions. Very undesirable and obviously fragile.
Why did this not show up in previous testing? Under what conditions are reflectors constructed?
The PMT construction is performed by one of the two overloaded methods WCSimDetectorConstruction::ConstructPMT()
that are defined in WCSimConstructPMT.cc
:
G4LogicalVolume* WCSimDetectorConstruction::ConstructPMT(G4String, G4String, G4String, G4int)
G4LogicalVolume* WCSimDetectorConstruction::ConstructPMT(G4String, G4String, G4String, bool)
The reflector construction only happens in 1. The WLS construction only happens in 2.
The condition for constructing a reflector is in L346-L347:
346 if(id_reflector_height > 0.1*CLHEP::mm
347 && (reflectorRadius-radius) > -5*CLHEP::mm){
:
385 }
For existing detector configurations, id_reflector_height
defaults to 0. Geometries that have non-trivial id_reflector_height
include
HyperK_HybridFake
NuPRISM_mPMT
NuPRISMBeamTest_mPMT
NuPRISMShort_mPMT
TestSinglemPMT
Cylinder_60x74_3inchmPMT_14perCent
Cylinder_60x74_3inchmPMT_40perCent
None of these are the canonical configurations that i have looked at in the past. Oh, well. It's broken and needs to be fixed.
The containing volume for the PMT is either
Although it appears that reflectors can be constructed for either, the present overlap occurs in the context of 1, so focus on that, for now.
To do: Check that reflectors can be constructed without problems for single PMTs.
The code segment is L95-L111:
95 //All components of the PMT are now contained in a single logical volume logicWCPMT.
96 //Origin is on the blacksheet, faces positive z-direction.
97
98 G4double PMTHolderZ[2] = {0, std::max(expose,id_reflector_height+id_reflector_z_offset)};
99 G4double PMTHolderR[2] = {std::max(radius,reflectorRadius) + reflectorThickness,
100 std::max(radius,reflectorRadius) + reflectorThickness};
101 G4double PMTHolderr[2] = {0,0};
102
103
104 solidWCPMT =
105 new G4Polycone("WCPMT",
106 0.0*deg,
107 360.0*deg,
108 2,
109 PMTHolderZ,
110 PMTHolderr, // R Inner
111 PMTHolderR);// R Outer
The height of the cylindrical plug is large enough to contain both the expose height of the PMT face and the reflector height. Note that the maximum z in L98 does not include allowance for the reflector thickness. Will need to check that assumption.
The outer radius of the cylindrical plug is one reflectorThickness
larger than the larger of the PMT radius and the reflectorRadius
. The reflectorThickness
is a hard-coded dimension that would be more appropriately a class data member and part of the detector configuration. Worse, it can be automatically modified without warning.
The reflectorRadius
is a local variable computed from the PMT radius and two other class data-member configuration parameters
71 G4double reflectorRadius = radius + id_reflector_height * tan(id_reflector_angle); // PMT radius+ r = h * tan (theta)
The reflector is a cone of shame:
349 /* Some details:
350 * 1.1mm is the gap between reflector and PMT for mechanical construction
351 * (KM3NeT support matrix value)
352 * three degrees of freedom: height, z position and opening angle
353 */
354 G4Cons* reflectorCone =
355 new G4Cons("WCPMT_reflect",
356 radius - 4.715*CLHEP::mm, //rmin
357 radius - 4.715*CLHEP::mm + reflectorThickness, //rmax
358 reflectorRadius - 4.715*CLHEP::mm, //Rmin
359 reflectorRadius - 4.715*CLHEP::mm + reflectorThickness, //Rmax
360 id_reflector_height/2, //z/2
361 0, 2*CLHEP::pi);
The radius
in the code is the PMT radius. Why is the inner radius of the narrow end of the cone smaller than the PMT radius? What does 4.715*CLHEP::mm
represent? Hopefully this becomes clearer in the context of the placement relative to the PMT glass face.
The PMT glass face is a segment of a spherical shell with the 'back' flattened. In the local coordinates of the glass face volume, the origin is at the center of the spherical shell. The back of the face is at z = +PMTOffset
.
When placed in the containing volume, the placement vector is G4ThreeVector(0, 0, -1.0*PMTOffset+position_z_offset)
. The local variable position_z_offset
is 0 for mPMT PMTs, so the center of the flat back of the PMT face is coincident with the origin of the containing volume.
The origin of a G4Cons
is at the center of the symmetry axis of the truncated cone. When placed in the PMT containing volume, the placement vector is G4ThreeVector(0, 0, id_reflector_z_offset+id_reflector_height/2+position_z_offset)
. The position_z_offset
term preserves a relative z alignment to the glass face. The +id_reflector_height/2
term alone would put the narrow end of the reflector cone on the same plane as the back of the glass face. So, if the id_reflector_z_offset
term is > 0, then the entire reflector will be above/in front of the back of the glass face.
So the reflector is a funnel that should be entirely in front of the PMT glass face. My previous visualization of the PMT makes sense with this interpretation. There is a potential overlap between the glass face and the cone, which can be adjusted with class data member id_reflector_z_offset
.
Take the comments in L349-L353 as describing the way in which the reflector should be specified:
349 /* Some details:
350 * 1.1mm is the gap between reflector and PMT for mechanical construction
351 * (KM3NeT support matrix value)
352 * three degrees of freedom: height, z position and opening angle
353 */
There are three values to be specified by the user and, presumably, a fixed 1.1mm margin between the reflector and the PMT glass face. (There is actually a fourth degree of freedom that is the width of the reflector.)
I tried to sketch the geometry:
I expect the inner radius of the narrow end of the reflector cone to be the cylindrical radius of the PMT glass face at z = PMTOffset + id_reflector_z_offset
plus the 1.1mm gap,
z_rf_bot = PMTOffset + id_reflector_z_offset
= (sphereRadius - expose) + id_reflector_z_offset
= ((expose*expose + radius*radius)/(2*expose) - expose) + id_reflector_z_offset
= (radius*radius - expose*expose)/(2*expose) + id_reflector_z_offset
= (40mm * 40mm - 20mm * 20mm) / (2*20mm) + 6.12mm
= 36.12mm
sphereRadius = (expose*expose + radius*radius)/(2*expose)
= (40mm*40mm + 20mm*20mm)/(2*20mm)
= 50mm
rho_rf_bot = sqrt(sphereRadius*sphereRadius - z_rf_bot*z_rf_bot) + 1.1mm
= sqrt(50mm*50mm - 36.12mm*36.12mm) + 1.1mm
= 35.674mm
The PMT dimensions are from the definition of PMT3inchR12199_02
.
The actual dimension is
radius - 4.715mm = 40mm - 4.715mm = 35.285mm
which is about 0.4mm smaller than what i calculated. If there are no erros in my calculations, it looks like the constructed gap between the PMT and reflector in the horizontal plane is about 0.7mm rather than 1.1mm. Could the difference be a projection, say, if the gap is measured along the angle of the cone?
1.1mm * sin(46.5deg) = 0.798
It is not a precise result, but it might be plausible.
Although i have not precisely reproduced the magic number, i think that this can be a prescription for replacing the magic number with a value derived from PMT dimensions and the configured reflector dimensions.
Ugh, the dimensions of
WCPMTsupport2
are hardcoded.The comments above the hardcoded values appear to define relations from which the values can be derived from configuration variables. Will need to check and update.
Ugh, there are hardcoded magic numbers throughout the PMT reflector construction. This will take some effort to understand and properly generalize.
Originally posted by @spradlin in https://github.com/spradlin/WCSim/issues/32#issuecomment-1653585424