File indexing completed on 2025-01-18 09:15:24
0001 #ifndef G4E_CI_DRICH_MODEL_HH
0002 #define G4E_CI_DRICH_MODEL_HH
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <iostream>
0013 #include <functional>
0014 #include <vector>
0015 #include <algorithm>
0016 #include "Geant4/G4Material.hh"
0017 #include "Geant4/G4SystemOfUnits.hh"
0018 #include "Geant4/G4MaterialPropertiesTable.hh"
0019 #include "Geant4/G4OpticalSurface.hh"
0020 #include "Geant4/G4LogicalSkinSurface.hh"
0021 #include "Geant4/G4tgbMaterialMgr.hh"
0022 #include "Geant4/G4tgbVolumeMgr.hh"
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 class g4dRIChOptics {
0033
0034 public:
0035
0036 double *scaledE;
0037 double *scaledN;
0038 double *scaledA;
0039 double *scaledS;
0040
0041 double *scaledSE;
0042 double *scaledSR;
0043 double *scaledIN;
0044
0045
0046
0047
0048
0049 g4dRIChOptics(const G4String matName, const G4String logVolName) {
0050
0051 printf("#=======================================================================\n");
0052 printf("# Set Optical Properties\n");
0053
0054 materialName = matName;
0055 logicalVName = logVolName;
0056
0057 scaledE=NULL;
0058 scaledN=NULL;
0059 scaledA=NULL;
0060 scaledS=NULL;
0061
0062 scaledSE = NULL;
0063 scaledSR = NULL;
0064 scaledIN = NULL;
0065
0066 if (matName != "_NA_") {
0067
0068 printf("# Material %s\n",matName.data());
0069
0070 mat = G4tgbMaterialMgr::GetInstance()->FindBuiltG4Material(matName);
0071
0072 if (mat == NULL) {
0073 pTable = NULL;
0074 printf("# ERROR: Cannot retrieve %s material in ci_DRICH\n",matName.data());
0075
0076 } else {
0077 pTable = mat->GetMaterialPropertiesTable();
0078 }
0079
0080 if (pTable == NULL) {
0081 printf("# No properties table available for %s, allocated a new one\n",matName.data());
0082 pTable = new G4MaterialPropertiesTable();
0083 } else {
0084 pTable->DumpTable();
0085 }
0086 }
0087
0088 if (logVolName != "_NA_") {
0089 printf("# Logical Volume %s\n",logVolName.data());
0090 logVolume = G4tgbVolumeMgr::GetInstance()->FindG4LogVol(logVolName, 0);
0091 if (logVolume == NULL) {
0092 printf("# ERROR: Cannot retrieve %s logical volume in ci_DRICH\n",logVolName.data());
0093
0094 }
0095 }
0096
0097 };
0098
0099 ~g4dRIChOptics() {
0100
0101 if (scaledE !=NULL) delete[] scaledE;
0102 if (scaledN !=NULL) delete[] scaledN;
0103 if (scaledA !=NULL) delete[] scaledA;
0104 if (scaledS !=NULL) delete[] scaledS;
0105
0106 if (scaledSE !=NULL) delete[] scaledSE;
0107 if (scaledSR !=NULL) delete[] scaledSR;
0108 if (scaledIN !=NULL) delete[] scaledIN;
0109
0110 };
0111
0112
0113 virtual int setOpticalParams() { return -1; };
0114 virtual int setOpticalParams(double dvalue) { return -1; };
0115 virtual int setOpticalParams(int ivalue) { return -1; };
0116 virtual int setOpticalParams(int ivalue, double dvalue) { return -1; };
0117 virtual int setOpticalParams(G4String svalue) { return -1; };
0118
0119
0120 G4String getMaterialName() { return materialName; };
0121 G4String getLogicalVName() { return logicalVName; };
0122 G4OpticalSurface *getSurface() { return pOps; };
0123
0124
0125 G4MaterialPropertiesTable *getMaterialPropertyTable() {
0126 auto t = pTable;
0127 if(t==nullptr && pOps!=nullptr) t = pOps->GetMaterialPropertiesTable();
0128 if(t==nullptr) fmt::print(stderr,"ERROR: cannot find material property table for ({},{})\n",materialName,logicalVName);
0129 return t;
0130 }
0131
0132
0133 std::vector<G4String> getMaterialPropertyNames() {
0134 std::vector<G4String> validProps;
0135 auto tab = getMaterialPropertyTable();
0136 if(tab!=nullptr) {
0137 for(const auto& propName : tab->GetMaterialPropertyNames()) {
0138 if(tab->GetProperty(propName)!=nullptr) validProps.push_back(propName);
0139 }
0140 }
0141 return validProps;
0142 }
0143
0144
0145 int getMaterialPropertyTableSize() { return int(getMaterialPropertyNames().size()); }
0146
0147
0148 void loopMaterialPropertyTable(G4String propName, std::function<void(G4double,G4double)> block, bool reverseOrder=false) {
0149 auto tab = getMaterialPropertyTable();
0150 if(tab==nullptr) return;
0151 auto prop = tab->GetProperty(propName);
0152 if(prop==nullptr) return;
0153 if(reverseOrder) {
0154 for(int i=prop->GetVectorLength()-1; i>=0; i--) {
0155 auto energy = prop->Energy(i);
0156 auto value = prop->operator[](i);
0157 block(energy,value);
0158 }
0159 } else {
0160 for(int i=0; i<prop->GetVectorLength(); i++) {
0161 auto energy = prop->Energy(i);
0162 auto value = prop->operator[](i);
0163 block(energy,value);
0164 }
0165 }
0166 }
0167
0168
0169 static double wl2e(double wl) {
0170 return 1239.84193 * eV / (wl/nm);
0171 };
0172
0173 static double e2wl(double e) {
0174 return 1239.84193 *nm / (e / eV);
0175 };
0176
0177
0178 protected:
0179
0180 G4String materialName, logicalVName;
0181 G4Material *mat;
0182 G4OpticalSurface *pOps;
0183 G4LogicalVolume *logVolume;
0184
0185 G4MaterialPropertiesTable *pTable;
0186
0187
0188 void setMatPropTable(int nEntries) {
0189
0190 if (scaledN!=NULL) pTable->AddProperty("RINDEX", scaledE, scaledN, nEntries, false, true);
0191 if (scaledA!=NULL) pTable->AddProperty("ABSLENGTH", scaledE, scaledA, nEntries, false, true);
0192 if (scaledS!=NULL) pTable->AddProperty("RAYLEIGH", scaledE, scaledS, nEntries, false, true);
0193
0194
0195
0196 mat->SetMaterialPropertiesTable(pTable);
0197 printf("# Optical Table for material %s with %d points:\n",materialName.data(),nEntries);
0198 pTable->DumpTable();
0199
0200 };
0201
0202
0203 G4MaterialPropertiesTable *addSkinPropTable(int nE) {
0204
0205 G4MaterialPropertiesTable *pTab = new G4MaterialPropertiesTable();
0206 if (scaledSE !=NULL) pTab->AddProperty("EFFICIENCY", scaledE, scaledSE, nE);
0207 if (scaledSR !=NULL) pTab->AddProperty("REFLECTIVITY", scaledE, scaledSR, nE);
0208 if (scaledN !=NULL) pTab->AddProperty("REALRINDEX", scaledE, scaledN, nE);
0209 if (scaledIN !=NULL) pTab->AddProperty("IMAGINARYRINDEX", scaledE, scaledIN, nE);
0210 printf("# Optical Table for volume %s with %d points:\n",logicalVName.data(),nE);
0211 pTab->DumpTable();
0212
0213 return pTab;
0214
0215 };
0216
0217
0218 double linint(double val, int n, const double* x, const double* y) {
0219 if (val<=x[0]) return y[0];
0220 if (val>=x[n-1]) return y[n-1];
0221 for (int i=0;i<(n-1);i++) {
0222 if ((val>=x[i]) && (val<x[i+1])) {
0223 return (y[i+1]-y[i])/(x[i+1]-x[i])*(val-x[i])+y[i];
0224 }
0225 }
0226 return 0.;
0227 };
0228
0229 };
0230
0231
0232
0233
0234 class g4dRIChAerogel : public g4dRIChOptics {
0235
0236 public:
0237
0238 g4dRIChAerogel(const G4String matName) : g4dRIChOptics(matName, "_NA_") {};
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 int setOpticalParams(int mode) {
0251
0252 const double aeroE[]=
0253 { 1.87855*eV,1.96673*eV,2.05490*eV,2.14308*eV,2.23126*eV, 2.31943*eV,2.40761*eV,2.49579*eV,2.58396*eV,2.67214*eV,
0254 2.76032*eV,2.84849*eV,2.93667*eV,3.02485*eV,3.11302*eV, 3.20120*eV,3.28938*eV,3.37755*eV,3.46573*eV,3.55391*eV,
0255 3.64208*eV,3.73026*eV,3.81844*eV,3.90661*eV,3.99479*eV, 4.08297*eV,4.17114*eV,4.25932*eV,4.34750*eV,4.43567*eV,
0256 4.52385*eV,4.61203*eV,4.70020*eV,4.78838*eV,4.87656*eV, 4.96473*eV,5.05291*eV,5.14109*eV,5.22927*eV,5.31744*eV,
0257 5.40562*eV,5.49380*eV,5.58197*eV,5.67015*eV,5.75833*eV, 5.84650*eV,5.93468*eV,6.02286*eV,6.11103*eV,6.19921*eV };
0258
0259 const double aeroN[]=
0260 { 1.01825,1.01829,1.01834,1.01839,1.01844, 1.01849,1.01854,1.01860,1.01866,1.01872,
0261 1.01878,1.01885,1.01892,1.01899,1.01906, 1.01914,1.01921,1.01929,1.01938,1.01946,
0262 1.01955,1.01964,1.01974,1.01983,1.01993, 1.02003,1.02014,1.02025,1.02036,1.02047,
0263 1.02059,1.02071,1.02084,1.02096,1.02109, 1.02123,1.02137,1.02151,1.02166,1.02181,
0264 1.02196,1.02212,1.02228,1.02244,1.02261, 1.02279,1.02297,1.02315,1.02334,1.02354 };
0265
0266 const double aeroA[]=
0267 { 17.5000*cm,17.7466*cm,17.9720*cm,18.1789*cm,18.3694*cm, 18.5455*cm,18.7086*cm,18.8602*cm,19.0015*cm,19.1334*cm,
0268 19.2569*cm,19.3728*cm,19.4817*cm,19.5843*cm,19.6810*cm, 19.7725*cm,19.8590*cm,19.9410*cm,20.0188*cm,20.0928*cm,
0269 18.4895*cm,16.0174*cm,13.9223*cm,12.1401*cm,10.6185*cm, 9.3147*cm,8.1940*cm,7.2274*cm,6.3913*cm,5.6659*cm,
0270 5.0347*cm,4.4841*cm,4.0024*cm,3.5801*cm,3.2088*cm, 2.8817*cm,2.5928*cm,2.3372*cm,2.1105*cm,1.9090*cm,
0271 1.7296*cm,1.5696*cm,1.4266*cm,1.2986*cm,1.1837*cm, 1.0806*cm,0.9877*cm,0.9041*cm,0.8286*cm,0.7603*cm };
0272
0273 const double aeroS[] =
0274 { 35.1384*cm, 29.24805*cm, 24.5418*cm, 20.7453*cm, 17.6553*cm, 15.1197*cm, 13.02345*cm, 11.2782*cm, 9.81585*cm, 8.58285*cm,
0275 7.53765*cm, 6.6468*cm, 5.88375*cm, 5.22705*cm, 4.6596*cm, 4.167*cm, 3.73785*cm, 3.36255*cm, 3.03315*cm, 2.7432*cm,
0276 2.48700*cm, 2.26005*cm, 2.05845*cm, 1.87875*cm, 1.71825*cm, 1.57455*cm, 1.44555*cm, 1.3296*cm, 1.2249*cm, 1.1304*cm,
0277 1.04475*cm, 0.9672*cm, 0.89655*cm, 0.83235*cm, 0.77385*cm, 0.7203*cm, 0.67125*cm, 0.6264*cm, 0.58515*cm, 0.54735*cm,
0278 0.51255*cm, 0.48045*cm, 0.45075*cm, 0.4233*cm, 0.39795*cm, 0.37455*cm, 0.3528*cm, 0.33255*cm, 0.3138*cm, 0.29625*cm };
0279
0280 const int nEntries = sizeof(aeroE)/sizeof(double);
0281
0282 double density = mat->GetDensity();
0283 printf("# Aerogel Density : %f g/cm3\n",density/(g/cm3));
0284
0285 double refn = density2refIndex(density);
0286 double refwl = 400*nm;
0287
0288 double refee = wl2e(refwl)/eV;
0289 double an0 = linint(refee, nEntries, aeroE, aeroN);
0290
0291
0292
0293 double aa;
0294 double nn;
0295 double ri, a0, wl0, rnscale;
0296 double rho = 0.0;
0297
0298 if (scaledE==NULL) {
0299 scaledE = new double[nEntries];
0300 scaledN = new double[nEntries];
0301 scaledS = new double[nEntries];
0302 scaledA = new double[nEntries];
0303 }
0304
0305 for (int i=0;i<nEntries;i++) {
0306 double ee = aeroE[i];
0307 double wl = e2wl(ee)/nm;
0308
0309 switch (mode) {
0310 case 0:
0311 aa = airFraction(refn, refwl);
0312 nn = aa * riAir(wl) + (1. - aa)*riQuartz(wl);
0313 break;
0314 case 1:
0315 ri = 1.0494;
0316 rho = 0.230;
0317 a0 = 0.09683;
0318 wl0 = 84.13;
0319 rnscale = sqrt(1.+ (a0*refwl*refwl)/(refwl*refwl-a0*a0));
0320 nn = sqrt(1.+ (a0*wl*wl)/(wl*wl-a0*a0))* refn / rnscale;
0321 break;
0322 case 2:
0323 ri = 1.03;
0324 rho = 0.149;
0325 a0 = 0.05639;
0326 wl0 = 84.22;
0327 rnscale = sqrt(1.+ (a0*refwl*refwl)/(refwl*refwl-a0*a0));
0328 nn = sqrt(1.+ (a0*wl*wl)/(wl*wl-a0*a0)) * refn / rnscale;
0329 break;
0330 case 3:
0331 rho = 0.088;
0332 nn = aeroN[i] * refn / an0;
0333 break;
0334 default:
0335 nn = refn;
0336 break;
0337 }
0338
0339 scaledE[i] = ee;
0340 scaledN[i] = nn;
0341 scaledA[i] = aeroA[i] * (rho*g/cm3)/density;
0342 scaledS[i] = aeroS[i] * (rho*g/cm3)/density;
0343
0344 }
0345
0346 printf("# Aerogel Refractive Index, Absorption and Scattering Lengths rescaled to density %.5f g/cm3, method: %d\n", density/g*cm3, mode);
0347
0348 setMatPropTable(nEntries);
0349
0350 return nEntries;
0351
0352 }
0353
0354 private:
0355
0356
0357 double riQuartz(double wl) {
0358 double x = wl / um;
0359 double nn = sqrt(1+0.6961663*x*x/(x*x-pow(0.0684043,2))+0.4079426*x*x/(x*x-pow(0.1162414,2))+0.8974794*x*x/(x*x-pow(9.896161,2)));
0360 if (nn<1.) {
0361 printf("# WARNING: estimated quartz refractive index is %f at wavelength %f nm -> set to 1\n",nn,x);
0362 nn = 1.;
0363 }
0364 return nn;
0365 }
0366
0367
0368 double riAir(double wl) {
0369 double x = wl / um;
0370 double nn = 1.0+(0.05792105/(238.0185-1.0/x/x)+0.00167917/(57.362-1.0/x/x));
0371 if (nn<1.) {
0372 printf("# WARNING: estimated air refractive index is %f at wavelength %f nm -> set to 1\n",nn,x);
0373 nn = 1.;
0374 }
0375 return nn;
0376 }
0377
0378
0379
0380
0381
0382
0383
0384 double airFraction(double rn, double rlambda) {
0385 double rnq = riQuartz(rlambda);
0386 double rna = riAir(rlambda);
0387 double a = (rnq - rn)/(rnq - rna);
0388 return a;
0389 }
0390
0391
0392
0393
0394
0395 double Density(double rn, double rlambda) {
0396 double aa = airFraction(rn, rlambda);
0397 return (aa * 1.1939 * mg/cm3 + (1.- aa ) * 2.32 * g/cm3);
0398 }
0399
0400
0401 double density2refIndex(double rho) {
0402 double nn2 = 1.+0.438*rho/g*cm3;
0403 return sqrt(nn2);
0404 }
0405
0406 };
0407
0408
0409
0410
0411
0412 class g4dRIChFilter : public g4dRIChOptics {
0413
0414 public:
0415
0416 g4dRIChFilter(const G4String matName) : g4dRIChOptics(matName, "_NA_") {};
0417
0418
0419
0420 int setOpticalParams(double wlthr) {
0421
0422 const double acryE[]=
0423 { 1.87855*eV,1.96673*eV,2.05490*eV,2.14308*eV,2.23126*eV, 2.31943*eV,2.40761*eV,2.49579*eV,2.58396*eV,2.67214*eV,
0424 2.76032*eV,2.84849*eV,2.93667*eV,3.02485*eV,3.11302*eV, 3.20120*eV,3.28938*eV,3.37755*eV,3.46573*eV,3.55391*eV,
0425 3.64208*eV,3.73026*eV,3.81844*eV,3.90661*eV,3.99479*eV, 4.08297*eV,4.17114*eV,4.25932*eV,4.34750*eV,4.43567*eV,
0426 4.52385*eV,4.61203*eV,4.70020*eV,4.78838*eV,4.87656*eV, 4.96473*eV,5.05291*eV,5.14109*eV,5.22927*eV,5.31744*eV,
0427 5.40562*eV,5.49380*eV,5.58197*eV,5.67015*eV,5.75833*eV, 5.84650*eV,5.93468*eV,6.02286*eV,6.11103*eV,6.19921*eV };
0428
0429 const double acryN[]=
0430 { 1.4902, 1.4907, 1.4913, 1.4918, 1.4924, 1.4930, 1.4936, 1.4942, 1.4948, 1.4954,
0431 1.4960, 1.4965, 1.4971, 1.4977, 1.4983, 1.4991, 1.5002, 1.5017, 1.5017, 1.5017,
0432 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017,
0433 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017,
0434 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017, 1.5017};
0435
0436 const double acryA[]=
0437 { 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm,
0438 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8495*cm, 14.8494*cm, 14.8486*cm, 14.844*cm,
0439 14.8198*cm, 14.7023*cm, 14.1905*cm, 12.3674*cm, 8.20704*cm, 3.69138*cm, 1.33325*cm, 0.503627*cm, 0.23393*cm, 0.136177*cm,
0440 0.0933192*cm, 0.0708268*cm, 0.0573082*cm, 0.0483641*cm, 0.0420282*cm, 0.0373102*cm, 0.033662*cm, 0.0307572*cm, 0.0283899*cm, 0.0264235*cm,
0441 0.0247641*cm, 0.0233451*cm, 0.0221177*cm, 0.0210456*cm, 0.0201011*cm, 0.0192627*cm, 0.0185134*cm, 0.0178398*cm, 0.0172309*cm, 0.0166779*cm };
0442
0443 const int nEntries = sizeof(acryE)/sizeof(double);
0444
0445 if (scaledE==NULL) {
0446 scaledE = new double[nEntries];
0447 scaledN = new double[nEntries];
0448 scaledS = new double[nEntries];
0449 scaledA = new double[nEntries];
0450 }
0451
0452 double e0 = acryE[24];
0453 double ethr= wl2e(wlthr);
0454
0455 int ithr=-1;
0456 double eshift=0;
0457
0458 for (int i=0;i<(nEntries-1);i++) {
0459 double d1 = ethr-acryE[i];
0460 if (d1>=0) {
0461 ithr = i;
0462 eshift = d1;
0463 }
0464 break;
0465 }
0466 if (ithr==-1) {
0467 fprintf(stderr,"# ERROR filter: wavelength threshold %f nm is out of range\n",wlthr/nm);
0468 return 0;
0469 }
0470
0471 for (int i=0;i<nEntries;i++) {
0472 scaledE[i] = acryE[i]+eshift;
0473 scaledN[i] = linint((scaledE[i] - ethr + e0), nEntries, acryE, acryN);
0474 scaledA[i] = linint((scaledE[i] - ethr + e0), nEntries, acryE, acryA);
0475 scaledS[i] = 100000.*cm;
0476 }
0477
0478 printf("# Acrylic Filter Refractive Index, Absorption and Scattering Lengths rescaled to wavelength threshold %.1f nm\n", wlthr/nm);
0479
0480 setMatPropTable(nEntries);
0481
0482 return nEntries;
0483
0484 };
0485
0486 private:
0487
0488 };
0489
0490
0491
0492
0493
0494 class g4dRIChGas : public g4dRIChOptics {
0495
0496 public:
0497
0498 g4dRIChGas(const G4String matName) : g4dRIChOptics(matName, "_NA_") {
0499
0500 int nel = mat->GetNumberOfElements();
0501 printf("# Gas material number of elements %d\n", nel);
0502
0503 chemFormula="";
0504
0505 for (int i=0;i<nel;i++) {
0506 auto ele = mat->GetElement(i);
0507 printf("# Element %d : Z %f Name %s Atoms %d\n",i,ele->GetZ(),ele->GetSymbol().data(),mat->GetAtomsVector()[i]);
0508 chemFormula = chemFormula + ele->GetSymbol() + std::to_string(mat->GetAtomsVector()[i]);
0509 }
0510 printf("# Chemical Formula : %s\n",chemFormula.data());
0511
0512 };
0513
0514 int setOpticalParams() {
0515
0516
0517 G4String gasType[] = { "C2F6", "CF4", "C4F10" };
0518
0519
0520
0521
0522 const double absLength[] = { 30.*m, 10.*m, 6.*m };
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532 double Ksr[]={ 0.131*cm3/g, 0.122*cm3/g, 0.000*cm3/g };
0533
0534
0535
0536
0537
0538 double Asel[]={0.18994, 0.124523, 0.2375};
0539 double L0sel[]={65.47*nm, 61.88*nm, 73.63*nm};
0540
0541 int igas=0;
0542
0543 for (int i=0;i<3;i++) {
0544 if (chemFormula == gasType[i]) igas=i;
0545 }
0546
0547 printf("# Selected gas index %d for gas %s\n",igas, chemFormula.data());
0548
0549 double density = mat->GetDensity();
0550 double refn = Ksr[igas] * density + 1.;
0551 double wlref = 633*nm;
0552
0553 int nEntries = 16;
0554 double wl0 = 200.*nm;
0555 double wl1 = 1000.*nm;
0556 double dwl = (wl1-wl0)/(nEntries-1.);
0557
0558 if (scaledE==NULL) {
0559 scaledE = new double[nEntries];
0560 scaledN = new double[nEntries];
0561 scaledS = new double[nEntries];
0562 scaledA = new double[nEntries];
0563 }
0564
0565 double l02 = 1./(L0sel[igas]/nm)/(L0sel[igas]/nm);
0566
0567 double rnscale = Asel[igas]/1e6/(l02 - 1./(wlref/nm)/(wlref/nm))+1.;
0568 if(chemFormula=="C4F10") rnscale = refn;
0569
0570 for (int i=0;i<nEntries;i++) {
0571
0572 double wl = wl1 - i*dwl;
0573 double ee = wl2e(wl);
0574
0575 scaledE[i]=ee;
0576 scaledN[i]=(Asel[igas]/1e6/(l02 - 1./(wl/nm)/(wl/nm))+1.) * refn/rnscale;
0577 scaledA[i]=absLength[igas];
0578 scaledS[i]=100000.*cm;
0579 }
0580
0581 printf("# Gas Refractive Index, Absorption and Scattering Lengths rescaled to density %f g/cm3, gas index: %d\n", density/g*cm3, igas);
0582
0583 setMatPropTable(nEntries);
0584
0585 return nEntries;
0586
0587 };
0588
0589 private:
0590
0591 G4String chemFormula;
0592
0593 };
0594
0595
0596
0597
0598
0599 class g4dRIChMirror : public g4dRIChOptics {
0600
0601 public:
0602 g4dRIChMirror(const G4String logName) : g4dRIChOptics("_NA_", logName) { };
0603
0604
0605
0606 int setOpticalParams(G4String pSurfName) {
0607
0608 G4String surfaceName = pSurfName + "mirrorSurf";
0609 G4String skinSurfaceName = pSurfName + "mirrorSkinSurf";
0610
0611 const double mirrorE[] =
0612 { 2.04358*eV, 2.0664*eV, 2.09046*eV, 2.14023*eV, 2.16601*eV, 2.20587*eV, 2.23327*eV, 2.26137*eV,
0613 2.31972*eV, 2.35005*eV, 2.38116*eV, 2.41313*eV, 2.44598*eV, 2.47968*eV, 2.53081*eV, 2.58354*eV,
0614 2.6194*eV, 2.69589*eV, 2.73515*eV, 2.79685*eV, 2.86139*eV, 2.95271*eV, 3.04884*eV, 3.12665*eV,
0615 3.2393*eV, 3.39218*eV, 3.52508*eV, 3.66893*eV, 3.82396*eV, 3.99949*eV, 4.13281*eV, 4.27679*eV,
0616 4.48244*eV, 4.65057*eV, 4.89476*eV, 5.02774*eV, 5.16816*eV, 5.31437*eV, 5.63821*eV, 5.90401*eV,
0617 6.19921*eV };
0618
0619 const double mirrorR[]=
0620 { 0.8678125, 0.8651562, 0.8639063, 0.8637500, 0.8640625, 0.8645313, 0.8643750, 0.8656250,
0621 0.8653125, 0.8650000, 0.8648437, 0.8638281, 0.8635156, 0.8631250, 0.8621875, 0.8617188,
0622 0.8613281, 0.8610156, 0.8610938, 0.8616016, 0.8623047, 0.8637500, 0.8655859, 0.8673828,
0623 0.8700586, 0.8741992, 0.8781055, 0.8825195, 0.8876172, 0.8937207, 0.8981836, 0.9027441,
0624 0.9078369, 0.9102002, 0.9093164, 0.9061743, 0.9004223, 0.8915210, 0.8599536, 0.8208313,
0625 0.7625024
0626 };
0627
0628 const int nEntries = sizeof(mirrorE)/sizeof(double);
0629
0630 if (scaledE==NULL) {
0631 scaledE = new double[nEntries];
0632 scaledSR = new double[nEntries];
0633 }
0634
0635 for (int i=0;i<nEntries;i++) {
0636 scaledE[i] = mirrorE[i];
0637 scaledSR[i] = mirrorR[i];
0638 }
0639
0640 G4MaterialPropertiesTable * pT = addSkinPropTable(nEntries);
0641
0642 pOps = new G4OpticalSurface(surfaceName, unified, polishedfrontpainted, dielectric_dielectric);
0643 pOps->SetMaterialPropertiesTable(pT);
0644 printf("# Surface properties:\n");
0645 pOps->DumpInfo();
0646
0647 new G4LogicalSkinSurface(skinSurfaceName, logVolume, pOps);
0648
0649 return nEntries;
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 };
0665
0666 };
0667
0668
0669
0670
0671
0672 class g4dRIChPhotosensor : public g4dRIChOptics {
0673
0674 public:
0675
0676 g4dRIChPhotosensor(const G4String logName) : g4dRIChOptics("_NA_", logName) { };
0677
0678
0679
0680 int setOpticalParams(G4String pSurfName) {
0681
0682 G4String surfaceName = pSurfName + "phseSurf";
0683 G4String skinSurfaceName = pSurfName + "phseSkinSurf";
0684
0685
0686 std::vector<std::pair<double,double>> QE = {
0687 {315*nm, 0.00},
0688 {325*nm, 0.04},
0689 {340*nm, 0.10},
0690 {350*nm, 0.20},
0691 {370*nm, 0.30},
0692 {400*nm, 0.35},
0693 {450*nm, 0.40},
0694 {500*nm, 0.38},
0695 {550*nm, 0.35},
0696 {600*nm, 0.27},
0697 {650*nm, 0.20},
0698 {700*nm, 0.15},
0699 {750*nm, 0.12},
0700 {800*nm, 0.08},
0701 {850*nm, 0.06},
0702 {900*nm, 0.04},
0703 {1000*nm, 0.00}
0704 };
0705 std::reverse(QE.begin(), QE.end());
0706 const int N_POINTS = QE.size();
0707 double E[N_POINTS], SE[N_POINTS], N[N_POINTS], IN[N_POINTS];
0708 int i_QE = 0;
0709 for(auto [w,q] : QE) {
0710 E[i_QE] = wl2e(w);
0711 SE[i_QE] = q;
0712 N[i_QE] = 1.92;
0713 IN[i_QE] = 1.69;
0714 i_QE++;
0715 }
0716
0717 scaledE = new double[N_POINTS];
0718 scaledSE = new double[N_POINTS];
0719 scaledN = new double[N_POINTS];
0720 scaledIN = new double[N_POINTS];
0721
0722 for (int i=0;i<N_POINTS;i++) {
0723 scaledE[i] = E[i];
0724 scaledSE[i] = SE[i];
0725 scaledN[i] = N[i];
0726 scaledIN[i] = IN[i];
0727 }
0728
0729 G4MaterialPropertiesTable * pT = addSkinPropTable(N_POINTS);
0730
0731 pOps = new G4OpticalSurface(surfaceName, glisur, polished, dielectric_dielectric);
0732 pOps->SetMaterialPropertiesTable(pT);
0733 printf("# Surface properties:\n");
0734 pOps->DumpInfo();
0735
0736 new G4LogicalSkinSurface(skinSurfaceName, logVolume, pOps);
0737
0738 return 2;
0739
0740 };
0741
0742 };
0743
0744 #endif
0745