// #define STRETCH struct ice { double la; // absorption length double ls; // scattering length double le; // effective scattering length double g; // double wv; // light wavelength double np; // phase refractive index double ng; // group refractive index double c; // speed of light in vacuum double cm; // speed of light in medium double na; // average propagation refractive index double coschr, sinchr; // cos and sin of the cherenkov angle int size; // size of kurt table double dh, rdh, hmin, hmax; // step, 1/step, min and max depth double *abs, *sca; // arrays of absorption and scattering values double *rabs, *rsca; // inverse of these arrays double *abs_sum, *sca_sum; // arrays of absorption and scattering depth-integrated values bool kurt; // whether kurt table is used bool accl; // accelerate lookup for large ice tables bool first; double A, B, D, E, a, k; double Ae, Be, De, Ee, ae, ke; vector dp, be, ba, td; #ifdef STRETCH double stretch(double x, double mean, double factor){ return mean+factor*(x-mean); } #endif void init(){ // initialize ice parameters first=true; kurt=false; bool flag=true; ifstream inFile; inFile.open((dir+"icemodel.par").c_str(), ifstream::in); if(flag=!inFile.fail()){ if(flag) flag=(inFile >> a >> ae); if(flag) flag=(inFile >> k >> ke); if(flag) flag=(inFile >> A >> Ae); if(flag) flag=(inFile >> B >> Be); if(flag) flag=(inFile >> D >> De); if(flag) flag=(inFile >> E >> Ee); if(!flag) cerr << "File icemodel.par found, but is corrupt, falling back to bulk ice" << endl; inFile.close(); if(!flag) return; } else return; inFile.open((dir+"icemodel.dat").c_str(), ifstream::in); if(!inFile.fail()){ size=0; double dpa, bea, baa, tda; while(inFile >> dpa >> bea >> baa >> tda){ #ifdef STRETCH if(dpa<2090){ bea=stretch(bea, 0.047, 2); baa=stretch(baa, 0.041, 2); } else{ bea=stretch(bea, 0.029, 2); baa=stretch(baa, 0.017, 2); } #endif dp.push_back(dpa); be.push_back(bea); ba.push_back(baa); td.push_back(tda); size++; } if(size<2){ cerr << "File icemodel.dat found, but is corrupt, falling back to bulk ice" << endl; return; } inFile.close(); } else return; dh=dp[1]-dp[0]; rdh=1/dh; if(dh<=0){ cerr << "Ice table does not use increasing depth spacing, falling back to bulk ice" << endl; return; } for(int i=0; i0) if(fabs(dp[i]-dp[i-1]-dh)>dh*1.e-10){ cerr << "Ice table does not use uniform depth spacing, falling back to bulk ice" << endl; return; } } hmin=dp[0]-dh/2; hmax=dp[size-1]+dh/2; kurt=true; } void init(double wv){ this->wv=wv; if(kurt){ if(wv<0.2) wv=0.2; else if(wv>0.8) wv=0.8; double wva=wv*1.e3; double wv0=400; double l_a=pow(wva/wv0, -a); double l_k=pow(wva, -k); double ABl=A*exp(-B/wva); if(first){ abs = new double[size]; sca = new double[size]; rabs = new double[size]; rsca = new double[size]; } double abs_a=0, sca_a=0; for(int i=0; i