File indexing completed on 2026-04-10 07:50:30
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 #include "G4ThreeVector.hh"
0077
0078 #include "IPMTAccessor.h"
0079 #include "Layr.h"
0080 #include "U4Touchable.h"
0081
0082 struct CustomART
0083 {
0084 int count ;
0085 double zlocal ;
0086 double lposcost ;
0087
0088 const IPMTAccessor* accessor ;
0089
0090 G4double& theTransmittance ;
0091 G4double& theReflectivity ;
0092 G4double& theEfficiency ;
0093
0094 const G4ThreeVector& theGlobalPoint ;
0095 const G4ThreeVector& OldMomentum ;
0096 const G4ThreeVector& OldPolarization ;
0097 const G4ThreeVector& theRecoveredNormal ;
0098 const G4double& thePhotonMomentum ;
0099
0100 CustomART(
0101 const IPMTAccessor* accessor,
0102 G4double& theTransmittance,
0103 G4double& theReflectivity,
0104 G4double& theEfficiency,
0105 const G4ThreeVector& theGlobalPoint,
0106 const G4ThreeVector& OldMomentum,
0107 const G4ThreeVector& OldPolarization,
0108 const G4ThreeVector& theRecoveredNormal,
0109 const G4double& thePhotonMomentum
0110 );
0111
0112
0113 double local_z( const G4Track& aTrack );
0114 void doIt(const G4Track& aTrack, const G4Step& aStep );
0115 };
0116
0117 inline CustomART::CustomART(
0118 const IPMTAccessor* accessor_,
0119 G4double& theTransmittance_,
0120 G4double& theReflectivity_,
0121 G4double& theEfficiency_,
0122 const G4ThreeVector& theGlobalPoint_,
0123 const G4ThreeVector& OldMomentum_,
0124 const G4ThreeVector& OldPolarization_,
0125 const G4ThreeVector& theRecoveredNormal_,
0126 const G4double& thePhotonMomentum_
0127 )
0128 :
0129 count(0),
0130 zlocal(-1.),
0131 lposcost(-2.),
0132 accessor(accessor_),
0133 theTransmittance(theTransmittance_),
0134 theReflectivity(theReflectivity_),
0135 theEfficiency(theEfficiency_),
0136 theGlobalPoint(theGlobalPoint_),
0137 OldMomentum(OldMomentum_),
0138 OldPolarization(OldPolarization_),
0139 theRecoveredNormal(theRecoveredNormal_),
0140 thePhotonMomentum(thePhotonMomentum_)
0141 {
0142 }
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 inline double CustomART::local_z( const G4Track& aTrack )
0163 {
0164 const G4AffineTransform& transform = aTrack.GetTouchable()->GetHistory()->GetTopTransform();
0165 G4ThreeVector localPoint = transform.TransformPoint(theGlobalPoint);
0166 zlocal = localPoint.z() ;
0167 lposcost = localPoint.cosTheta() ;
0168 return zlocal ;
0169 }
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 inline void CustomART::doIt(const G4Track& aTrack, const G4Step& aStep )
0202 {
0203 G4double minus_cos_theta = OldMomentum*theRecoveredNormal ;
0204
0205 G4double energy = thePhotonMomentum ;
0206 G4double wavelength = twopi*hbarc/energy ;
0207 G4double energy_eV = energy/eV ;
0208 G4double wavelength_nm = wavelength/nm ;
0209
0210 const G4VTouchable* touch = aTrack.GetTouchable();
0211 int pmtid = U4Touchable::ReplicaNumber(touch);
0212
0213 int pmtcat = accessor->get_pmtcat( pmtid ) ;
0214 double _qe = minus_cos_theta > 0. ? 0.0 : accessor->get_pmtid_qe( pmtid, energy ) ;
0215
0216
0217 std::array<double,16> a_spec ;
0218 accessor->get_stackspec(a_spec, pmtcat, energy_eV );
0219 StackSpec<double,4> spec ;
0220 spec.import( a_spec );
0221
0222 bool dump = false ;
0223
0224 if(dump) std::cerr << "CustomART::doIt" << " spec " << std::endl << spec << std::endl ;
0225
0226
0227
0228
0229 Stack<double,4> stack(wavelength_nm, minus_cos_theta, spec );
0230
0231 const double _si = stack.ll[0].st.real() ;
0232 const double _si2 = sqrtf( 1. - minus_cos_theta*minus_cos_theta );
0233
0234 double E_s2 = _si > 0. ? (OldPolarization*OldMomentum.cross(theRecoveredNormal))/_si : 0. ;
0235 E_s2 *= E_s2;
0236
0237
0238
0239
0240 double one = 1.0 ;
0241 double S = E_s2 ;
0242 double P = one - S ;
0243
0244 if(dump) std::cerr
0245 << "CustomART::doIt"
0246 << " count " << count
0247 << " pmtid " << pmtid
0248 << " _si " << std::fixed << std::setw(10) << std::setprecision(5) << _si
0249 << " _si2 " << std::fixed << std::setw(10) << std::setprecision(5) << _si2
0250 << " theRecoveredNormal " << theRecoveredNormal
0251 << " OldPolarization*OldMomentum.cross(theRecoveredNormal) " << OldPolarization*OldMomentum.cross(theRecoveredNormal)
0252 << " E_s2 " << std::fixed << std::setw(10) << std::setprecision(5) << E_s2
0253 << std::endl
0254 ;
0255
0256 double T = S*stack.art.T_s + P*stack.art.T_p ;
0257 double R = S*stack.art.R_s + P*stack.art.R_p ;
0258 double A = one - (T+R);
0259
0260 theTransmittance = T ;
0261 theReflectivity = R ;
0262
0263 if(dump) std::cerr
0264 << "CustomART::doIt"
0265 << " count " << count
0266 << " S " << std::fixed << std::setw(10) << std::setprecision(5) << S
0267 << " P " << std::fixed << std::setw(10) << std::setprecision(5) << P
0268 << " T " << std::fixed << std::setw(10) << std::setprecision(5) << T
0269 << " R " << std::fixed << std::setw(10) << std::setprecision(5) << R
0270 << " A " << std::fixed << std::setw(10) << std::setprecision(5) << A
0271 << std::endl
0272 ;
0273
0274
0275 Stack<double,4> stackNormal(wavelength_nm, -1. , spec );
0276
0277 double An = one - (stackNormal.art.T + stackNormal.art.R) ;
0278 double D = _qe/An;
0279
0280 theEfficiency = D ;
0281
0282 bool expect = D <= 1. ;
0283 if(!expect) std::cerr
0284 << "CustomART::doIt"
0285 << " FATAL "
0286 << " ERR: D > 1. : " << D
0287 << " _qe " << _qe
0288 << " An " << An
0289 << std::endl
0290 ;
0291
0292 assert( expect );
0293 }
0294
0295