13#include "prem_default.hpp"
27void TrajConstants::UpdateNuAngles(
double cosTheta,
double phi)
161 double latitude,
double longitude,
double density,
162 double zoa,
double index)
165 density, zoa, index));
191 double EarthRadius = 6371.0;
194 if (filename ==
"") { filename = PREM3D_DEFAULT; }
195 cout <<
"Loading Earth model table from " << filename <<
"..." << endl;
199 fin.open(filename.c_str());
201 cerr <<
"ERROR: File " << filename <<
" not found!" << endl;
206 float depth, latitude, longitude, density, zoa, index;
209 double radius_prev = 0;
210 double lat_prev = -90.0;
214 double radius_min = radius_prev;
220 while (fin >> longitude >> latitude >> depth >> density >> zoa >> index) {
221 double outer_radius = EarthRadius - depth;
225 if (outer_radius > radius_prev) {
226 radius_min = radius_prev;
231 else if (outer_radius <
233 cerr <<
"ERROR: Depths are not sorted in decreasing order in the model "
235 <<
"(or depth is greater than " << EarthRadius <<
" km)." << endl;
239 else if (longitude > lon_prev) {
244 else if (longitude < lon_prev) {
246 cerr <<
"ERROR: Longitudes are not sorted in increasing order (after "
247 "depths) in the model file."
252 else if (latitude < lat_prev) {
254 cerr <<
"ERROR: Latitudes are not sorted in increasing order (after "
255 "longitudes) in the model file."
262 AddBin(outer_radius, radius_min, latitude, longitude, density, zoa, index);
268 radius_prev = outer_radius;
270 lon_prev = longitude;
293 cerr <<
"ERROR: Latitude of 1st bin center (" <<
fEarthBins[0].latitude
294 <<
") is not in the middle of the first bin, whose size should be "
296 <<
fnLatBins <<
" latitude bins." << endl;
303 <<
" longitude)." << endl;
319 cerr <<
"WARNING: Index " << index <<
" does not exist in model "
321 <<
"Doing nothing." << endl;
329 for (
int i = 0; i < nbins; i++) {
348 cerr <<
"ERROR: Index " << index <<
" does not exist in model "
349 <<
"(max index = " <<
fmaxRegIndex <<
"). Returning 0" << endl;
355 for (
int i = 0; i < nbins; i++) {
364 cerr <<
"ERROR: Index " << index <<
" not found! Returning 0" << endl;
379 cerr <<
"WARNING: Index " << index <<
" does not exist in model "
381 <<
"Doing nothing." << endl;
389 for (
int i = 0; i < nbins; i++) {
393 fEarthBins[i].density = factor * density_init;
434 if (abs(NewLat) - 0.5 * M_PI > -1.0e-14) {
440 if (abs(NewLat) - 0.5 * M_PI > -1.0e-14)
445 double sinNewLat = sin(NewLat);
446 double NsinSqNewLat = -sinNewLat * sinNewLat;
449 if (radicand < 1.0e-14) {
455 sinNewLat = sin(NewLat);
456 NsinSqNewLat = -sinNewLat * sinNewLat;
458 if (radicand < 1.0e-14)
461 double denominator =
fC.
gammaSq + NsinSqNewLat;
465 if (denominator == 0) {
501 double twoPi = 2 * M_PI;
503 double lon = prev_lon + L.
dLon;
504 if (lon < 0 || lon >= twoPi) { lon -= floor(lon / twoPi) * twoPi; }
522 if (0 > lon - L.
min && L.
max - lon < 0)
return -1;
525 if (0 > lon - L.
min || L.
max - lon < 0)
return -1;
529 double cosNewLon = cos(lon);
530 double sinNewLon = sin(lon);
532 double denominator =
fC.
alpha * expression +
537 if (denominator == 0) {
539 L.
err_message.assign(
"Longitude along neutrino trajectory = " +
540 std::to_string(lon));
560 double& DetDist,
int& index,
580 if (latI.
dLat == 0) {
599 if (lonI.
dLon == 0) {
622 if (londiff < 0 || londiff >= 2 * M_PI)
623 londiff -= floor(londiff / (2 * M_PI));
658 if (fabs(cosT) > 1)
return 0;
661 double Az = phi / 180.0 * M_PI;
665 double distEdgeToMin =
669 double baseline = distEdgeToMin -
fC.
rDetCosT;
687 double init_lon = atan2(
694 if (init_lon < 0) { init_lon += 2 * M_PI; }
705 latinfo.
bin = init_latBin;
706 loninfo.
bin = init_lonBin;
727 loninfo.
min = init_lon;
731 loninfo.
min = loninfo.
max;
732 loninfo.
max = init_lon;
734 loninfo.
max = init_lon;
773 double prev_DetDistance = baseline;
781 if (r_in < minRadius)
break;
784 double DetDistance = -
fC.
rDetCosT + sqrt(r_in * r_in - rDetSqSinSqT);
794 prev_DetDistance = DetDistance;
795 index -= binsPerDepth;
802 index2 += binsPerDepth) {
806 double DetDistance = -
fC.
rDetCosT - sqrt(r_out * r_out - rDetSqSinSqT);
816 prev_DetDistance = DetDistance;
827 if (loninfo.
error < 0) {
829 <<
"ERROR: Oops... It turns out that I was wrong about the denominator"
830 <<
" of the x(long) equation never being 0 apart from the cases where "
831 <<
"sin(Zenith) = 0, sin(Azimuthal) = 0, or cos(Detector Longitude) = "
833 <<
" Send the following message to rpestes@apc.in2p3.fr:" << endl
835 <<
"You were wrong about the denominator of x(long)... "
836 <<
"Here are the values of the variables that broke it:" << endl
837 <<
"\tDetector Coordinates (r,lat,lon) = (" <<
fDetRadius <<
", "
839 <<
"\tcos(Zenith Angle) = " << cosT << endl
840 <<
"\tAzimuthal Angle = " << phi <<
" deg" << endl
842 <<
"Please fix this ASAP!" << endl;
double fRadiusMax
Maximum radius in Earth model (in km)
double fDetLat
The latitude (in rad) where the detector sits.
double fDetLon
The longitude (in rad) where the detector sits.
virtual void SetRemoveSmallPaths(bool rp=true)
Set tag to remove small paths.
virtual void AddPathSegment(double length, double density, double zoa, int index)
Add a path segment to the sequence.
std::vector< NuPath > fNuPath
The current neutrino path sequence.
double fDetRadius
The radius where the detector sits (in km)
virtual void SetDetectorCoordinates(double rad, double lat, double lon)
virtual double GetRegionZoA(int index)
Get Z/A of all bins with specified region index.
virtual double DetDistForNextLonBin(double prev_lon, LonBinInfo &L)
std::vector< EarthBin > fEarthBins
The bins in the earth model.
virtual void ClearModel()
Clear the earth model information.
double fInvLonBinWidth
1/binwidth for each longitude bin
virtual void AddPath(double length, EarthBin bin)
Add a path segment to the sequence.
virtual ~EarthModelBinned()
Destructor.
int fnDepthBins
Total number of depth bins.
int FillPath(double cosT, double phi=0)
virtual std::vector< EarthBin > GetEarthBins()
virtual void LoadModel(std::string filename)
Load an earth model from a file.
EarthModelBinned(std::string filename="")
Constructor.
virtual void RecordLatLonBinCrossings(double detDist_nextDbin, double &DetDist, int &index, LatBinInfo &latI, LonBinInfo &lonI)
double fHalfLonBinWidth
Half-width of each longitude bin.
void SetDetPos(double rad, double lat=0, double lon=0)
virtual void SetRegionZoA(int index, double zoa)
Set Z/A of all bins with specified region index.
int fnLatBins
Total number of latitude bins.
virtual void AddBin(double radius_out, double radius_in, double latitude, double longitude, double density, double zoa, double layer)
Add a bin to the model (angles in degrees)
double fHalfLatBinWidth
Half-width of each latitude bin.
double fInvLatBinWidth
1/binwidth for each latitude bin
virtual int LonBinIndex(double longitude)
Find lon bin index containing longitude.
TrajConstants fC
Useful constants for the trajectory.
int fmaxRegIndex
Largest region index in model.
virtual void ScaleRegionDensity(int index, double scalingfactor)
virtual double DetDistForNextLatBin(int cur_index, LatBinInfo &L)
int fnLonBins
Total number of longitude bins.
Some useful general definitions.
double zoa
The effective Z/A value of the matter in the bin.
double density
The density of the matter in the bin in g/cm^3.
A struct holding information about upcoming latitude bin crossings along the neutrino's trajectory.
int nextBin
Index of next latitude bin.
int bin
Index of current latitude bin.
A struct holding information about upcoming longitude bin crossings along the neutrino's trajectory.
int nextBin
Index of next longitude bin.
int bin
Index of current longitude bin.
double min
"Minimum" longitude
double max
"Maximum" longitude
std::string err_message
Part of error message specific to piece of path.
double cosTcosDetLat
cosT*cos(DetLat)
double sinTsinA
sin(T)*sin(phi)
double cosDetLon
cos(DetLon)
double beta
sin(T)*sin(DetLat)-cos(phi)*cosT*cos(DetLat)
double gammaSq
[sin(T)*cos(phi)*cos(DetLat)+cosT*sin(DetLat)]^2
double sinDetLat
sin(DetLat)
double rDetSinT
rDet*sin(T)
double xlatextreme
rDet*cos(phi)*cos(DetLat)/[sin(T)*sin(DetLat)-cos(phi)*cosT*cos(DetLat)], unless the denominator is 0...
double sinTcosA
sin(T)*cos(phi)
double alpha
sin(T)*cos(phi)*sin(DetLat)-cosT*cos(DetLat)
double rDetGammaSinDetLat
rDet*sin(DetLat)*[sin(T)*cos(phi)*cos(DetLat)+cosT*sin(DetLat)]
double sinSqT
sin^2(T) = 1 - (cosT)^2
double sinDetLon
sin(DetLon)
double sinTsinAsinDetLon
sin(T)*sin(phi)*sin(DetLon)
void UpdateDetPos(double rDet, double DetLat, double DetLon)
double gamma
sin(T)*cos(phi)*cos(DetLat)+cosT*sin(DetLat)
double maxSinSqLat
1 - [sin(phi)*cos(DetLat)]^2
void UpdateNuAngles(double cosTheta, double phi)
double rDetSinDetLat
rDet*sin(DetLat)
double rDetCosDetLat
rDet*cos(DetLat)
double cosDetLat
cos(DetLat)
double sinT
sin(T) = sqrt(sinSqT)
double sinTsinAcosDetLon
sin(T)*sin(phi)*cos(DetLon)