OscProb
EarthModelBinned.cxx
Go to the documentation of this file.
1/*************************************************************************
2 * EarthModelBinned.cxx
3 * Implements a 3D earth model (binned in depth, latitude, and longitude)
4 * for the programming library OscProb
5 * Created by Rebekah Pestes (last modified: 4/4/23)
6 *************************************************************************/
7
8#include <cmath>
9#include <fstream>
10#include <iostream>
11
12#include "EarthModelBinned.h"
13#include "prem_default.hpp"
14
15using namespace std;
16
17using namespace OscProb;
18
19//.............................................................................
27void TrajConstants::UpdateNuAngles(double cosTheta, double phi)
28{
29 cosT = cosTheta;
30 sinSqT = 1 - cosT * cosT;
31 sinT = sqrt(sinSqT);
32
33 cosA = cos(phi);
34 sinA = sin(phi);
35
36 sinTsinA = sinT * sinA;
37 sinTcosA = sinT * cosA;
38}
39
40//.............................................................................
49void TrajConstants::UpdateDetPos(double rDet, double DetLat, double DetLon)
50{
51 sinDetLat = sin(DetLat);
52 cosDetLat = cos(DetLat);
53 cosDetLon = cos(DetLon);
54 sinDetLon = sin(DetLon);
55 DetRadius = rDet;
56
59}
60
61//.............................................................................
67{
78 maxSinSqLat = 1 - pow(sinA * cosDetLat, 2);
79 if(beta == 0) { xlatextreme = 0; }
80 else { xlatextreme = cosA * rDetCosDetLat / beta; }
81}
82
83//.............................................................................
95{
96 SetDetPos(6368, 0, 0);
97 LoadModel(filename);
99 fLonError = 0;
100}
101
102//.............................................................................
107
108//.............................................................................
114vector<EarthBin> EarthModelBinned::GetEarthBins() { return fEarthBins; }
115
116//.............................................................................
121{
122 fnDepthBins = 0;
123 fnLonBins = 0;
124 fnLatBins = 0;
125 fEarthBins.clear();
126}
127
128//.............................................................................
142void EarthModelBinned::SetDetPos(double rad, double lat, double lon)
143{
144 SetDetectorCoordinates(rad, lat, lon);
146}
147
148//.............................................................................
160void EarthModelBinned::AddBin(double radius_out, double radius_in,
161 double latitude, double longitude, double density,
162 double zoa, double index)
163{
164 fEarthBins.push_back(EarthBin(radius_out, radius_in, latitude, longitude,
165 density, zoa, index));
166}
167
168//.............................................................................
187void EarthModelBinned::LoadModel(string filename)
188{
189 // Clear the current model
190 ClearModel();
191 double EarthRadius = 6371.0;
192
193 // Use default if no file provided
194 if (filename == "") { filename = PREM3D_DEFAULT; }
195 cout << "Loading Earth model table from " << filename << "..." << endl;
196
197 // Open the file
198 ifstream fin;
199 fin.open(filename.c_str());
200 if (!fin) {
201 cerr << "ERROR: File " << filename << " not found!" << endl;
202 return;
203 }
204
205 // Variables for storing table rows
206 float depth, latitude, longitude, density, zoa, index;
207
208 // Keep track of previous depth/latitude/longitude
209 double radius_prev = 0;
210 double lat_prev = -90.0;
211 double lon_prev = 0;
212
213 // Hold onto previous different depth, so we have depth maximum for bin
214 double radius_min = radius_prev;
215
216 // Initialize max region index
217 fmaxRegIndex = -1;
218
219 // Loop over table rows
220 while (fin >> longitude >> latitude >> depth >> density >> zoa >> index) {
221 double outer_radius = EarthRadius - depth;
222
223 // Move minimum depth (and reset latitude/longitude) if depth has changed
224 // from previous one
225 if (outer_radius > radius_prev) {
226 radius_min = radius_prev;
227 lat_prev = -90.0;
228 lon_prev = 0.0;
229 fnDepthBins++;
230 }
231 else if (outer_radius <
232 radius_prev) { // Depths must be ordered in model file
233 cerr << "ERROR: Depths are not sorted in decreasing order in the model "
234 "file "
235 << "(or depth is greater than " << EarthRadius << " km)." << endl;
236 ClearModel();
237 return;
238 }
239 else if (longitude > lon_prev) { // Reset latitude if longitude has changed
240 // from previous one
241 lat_prev = -90.0;
242 fnLonBins++;
243 }
244 else if (longitude < lon_prev) { // Longitudes must be ordered in model file
245 // (after depths)
246 cerr << "ERROR: Longitudes are not sorted in increasing order (after "
247 "depths) in the model file."
248 << endl;
249 ClearModel();
250 return;
251 }
252 else if (latitude < lat_prev) { // Latitudes must be ordered in model file
253 // (after longitudes)
254 cerr << "ERROR: Latitudes are not sorted in increasing order (after "
255 "longitudes) in the model file."
256 << endl;
257 ClearModel();
258 return;
259 }
260
261 // Add this bin to the model
262 AddBin(outer_radius, radius_min, latitude, longitude, density, zoa, index);
263
264 // Check region index
265 if (index > fmaxRegIndex) { fmaxRegIndex = index; }
266
267 // Set previous coordinates for next bin
268 radius_prev = outer_radius;
269 lat_prev = latitude;
270 lon_prev = longitude;
271 }
272
273 // Set Outermost Radius
274 fRadiusMax = radius_prev;
275
276 // Modify number of longitude bins to how many there actually are (instead of
277 // how many times we changed the longitude bin without changing the depth bin
278 // = nLonBins-1 times per depth bin)
280 fInvLonBinWidth = 0.5 * fnLonBins / M_PI; // in radians^(-1)
281 fHalfLonBinWidth = M_PI / fnLonBins; // in radians
282
283 // Calculate number of latitude bins
285 fInvLatBinWidth = fnLatBins / M_PI; // in radians^(-1)
286 fHalfLatBinWidth = 0.5 * M_PI / fnLatBins; // in radians
287
288 // Error if first latitude bin center deviates from about half of the
289 // calculated latitude bin width
290 if (abs(fHalfLatBinWidth - (fEarthBins[0].latitude + 0.5 * M_PI)) >
291 fHalfLatBinWidth * 0.01) { // Warn if first latitude bin center isn't about
292 // half of the latitude bin width
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 "
295 << 2 * fHalfLatBinWidth << " rad, as calculated from having "
296 << fnLatBins << " latitude bins." << endl;
297 ClearModel();
298 return;
299 }
300
301 cout << "\t...done (" << fEarthBins.size() << " bins: " << fnDepthBins
302 << " depth, " << fnLatBins << " latitude, and " << fnLonBins
303 << " longitude)." << endl;
304}
305
306//.............................................................................
316void EarthModelBinned::SetRegionZoA(int index, double zoa)
317{
318 if (index > fmaxRegIndex) {
319 cerr << "WARNING: Index " << index << " does not exist in model "
320 << "(max index = " << fmaxRegIndex << ")." << endl
321 << "Doing nothing." << endl;
322 return;
323 }
324
325 int nbins = fEarthBins.size();
326
327 // Loop over all bins and change the ones
328 // with the given index
329 for (int i = 0; i < nbins; i++) {
330 if (fEarthBins[i].index != index) continue;
331
332 fEarthBins[i].zoa = zoa;
333 }
334}
335
336//.............................................................................
346{
347 if (index > fmaxRegIndex) {
348 cerr << "ERROR: Index " << index << " does not exist in model "
349 << "(max index = " << fmaxRegIndex << "). Returning 0" << endl;
350 return 0;
351 }
352
353 int nbins = fEarthBins.size();
354
355 for (int i = 0; i < nbins; i++) {
356 if (fEarthBins[i].index != index)
357 continue;
358
359 else
360 return fEarthBins[i].zoa;
361 }
362
363 // End of vector reached without finding index
364 cerr << "ERROR: Index " << index << " not found! Returning 0" << endl;
365 return 0;
366}
367
368//.............................................................................
376void EarthModelBinned::ScaleRegionDensity(int index, double factor)
377{
378 if (index > fmaxRegIndex) {
379 cerr << "WARNING: Index " << index << " does not exist in model "
380 << "(max index = " << fmaxRegIndex << ")." << endl
381 << "Doing nothing." << endl;
382 return;
383 }
384
385 int nbins = fEarthBins.size();
386
387 // Loop over all bins and change the ones
388 // with the given index
389 for (int i = 0; i < nbins; i++) {
390 if (fEarthBins[i].index != index) continue;
391
392 double density_init = fEarthBins[i].density;
393 fEarthBins[i].density = factor * density_init;
394 }
395}
396
397//.............................................................................
406void EarthModelBinned::AddPath(double length, EarthBin bin)
407{
408 AddPathSegment(length, bin.density, bin.zoa, bin.index);
409}
410
411//.............................................................................
430{
431 // Find next lat bin boundary (bin center +/- 1/2-binwidth)
432 double NewLat = fEarthBins[cur_index].latitude + L.sign * L.dLat;
433 // Turn around if lat reaches +/- 90 degrees (or close enough)
434 if (abs(NewLat) - 0.5 * M_PI > -1.0e-14) {
435 if (L.maxreached) return -1; // Only turn around once
436 L.maxreached = true;
437// cout << "Max latitude reached..." << endl;
438 L.sign = -L.sign;
439 NewLat = fEarthBins[cur_index].latitude + L.sign * L.dLat;
440 if (abs(NewLat) - 0.5 * M_PI > -1.0e-14)
441 return -1; // This would happen if there's only one latitude bin...
442 }
443
444 // Calculate parts of answer
445 double sinNewLat = sin(NewLat);
446 double NsinSqNewLat = -sinNewLat * sinNewLat;
447 double radicand = fC.maxSinSqLat + NsinSqNewLat; //1-[sin(NewLat)]^2-[sin(phi)cos(DetLat)]^2
448 // Turn around if the radicand is 0 (close enough) or less
449 if (radicand < 1.0e-14) {
450 if (L.maxreached) return -1; // Only turn around once
451 L.maxreached = true;
452// cout << "Max latitude reached..." << endl;
453 L.sign = -L.sign;
454 NewLat = fEarthBins[cur_index].latitude + L.sign * L.dLat;
455 sinNewLat = sin(NewLat);
456 NsinSqNewLat = -sinNewLat * sinNewLat;
457 radicand = fC.maxSinSqLat + NsinSqNewLat;
458 if (radicand < 1.0e-14)
459 return -1; // The rest of the track is contained in this lat bin
460 }
461 double denominator = fC.gammaSq + NsinSqNewLat;
462
463 // Calculate distance from the detector at next lat bin boundary
464 double answer;
465 if (denominator == 0) {
466 answer =
468 //There is a "possible" case where answer would be 0:
469 // if the detector is at the center of the Earth... just don't...
470 }
471 else {
472 answer = -(fC.rDetCosT * NsinSqNewLat + fC.rDetGammaSinDetLat +
473 L.sign * fC.rDetSinT * sinNewLat * sqrt(radicand)) /
474 denominator;
475 }
476
477 // Check to see if going to the edge of the bin jumped to an invalid
478 // part of the function (cosA*rDetCosDetLat/beta = x at max lat)
479 if (L.maxreached && answer >= fC.xlatextreme) {
480 return -1; // The rest of the track is contained in this lat bin
481 }
482
483 return answer;
484}
485
486//.............................................................................
500{
501 double twoPi = 2 * M_PI;
502 // Increment to next bin in direction dLon
503 double lon = prev_lon + L.dLon;
504 if (lon < 0 || lon >= twoPi) { lon -= floor(lon / twoPi) * twoPi; }
505 if (L.dLon > 0) {
506 L.nextBin = L.bin + 1;
507 if (L.nextBin >= fnLonBins) {
508 // cross from 2pi to 0
509 L.nextBin = 0;
510 }
511 }
512 else {
513 L.nextBin = L.bin - 1;
514 if (L.nextBin < 0) {
515 // cross from 0 to 2pi
516 L.nextBin = fnLonBins - 1;
517 }
518 }
519
520 // Check if lon is outside of range covered by neutrino's trajectory
521 if (L.max < L.min) {
522 if (0 > lon - L.min && L.max - lon < 0) return -1;
523 }
524 else {
525 if (0 > lon - L.min || L.max - lon < 0) return -1;
526 }
527
528 // Parts of the answer
529 double cosNewLon = cos(lon);
530 double sinNewLon = sin(lon);
531 double expression = fC.sinDetLon * cosNewLon - sinNewLon * fC.cosDetLon;
532 double denominator = fC.alpha * expression +
533 fC.sinTsinAcosDetLon * cosNewLon +
534 fC.sinTsinAsinDetLon * sinNewLon;
535
536 // Calculate & return detector distance
537 if (denominator == 0) { // Is there ever a case when this is true???
538 // Error message will be printed at the end of the FillPath function
539 L.err_message.assign("Longitude along neutrino trajectory = " +
540 std::to_string(lon));
541 L.error = -1;
542 return -1;
543 }
544 return fC.rDetCosDetLat * expression / denominator;
545}
546
547//.............................................................................
560 double& DetDist, int& index,
561 LatBinInfo& latI,
562 LonBinInfo& lonI)
563{
564 //Keep going as long as there is a lat or lon bin crossing before
565 //the next depth bin crossing
566 while (detDist_nextDbin < latI.detDist_nextBin ||
567 detDist_nextDbin < lonI.detDist_nextBin) {
568 if (latI.detDist_nextBin > lonI.detDist_nextBin) { //if next lat bin crossing is before next lon bin crossing
569 // Add segment to next lat bin to path
570 AddPath(DetDist - latI.detDist_nextBin, fEarthBins[index]);
571 double latitude_crossing = fEarthBins[index].latitude + latI.sign * latI.dLat;
572
573 // Move lat bins
574 DetDist = latI.detDist_nextBin;
575 index += latI.nextBin - latI.bin;
576 latI.bin = latI.nextBin;
577// cout << "Latitude bin crossing at x=" << DetDist << "km,lat=" << latitude_crossing << "rad...now in Earth bin " << index << " = (r" << floor(index/(fnLonBins*fnLatBins)) << ", lon" << lonI.bin << ", lat" << latI.bin << ")" << endl;
578
579 // Find next lat bin
580 if (latI.dLat == 0) { //Only 1 lat bin crossing along entire neutrino trajectory
581 latI.detDist_nextBin = -1;
582 }
583 else {
584 latI.detDist_nextBin = DetDistForNextLatBin(index, latI);
585 latI.nextBin = latI.bin + latI.sign;
586 }
587 }
588 else { //if next lon bin crossing is before (or simultaneous with) next lat bin corssing
589 // Add segment to next lon bin to path
590 AddPath(DetDist - lonI.detDist_nextBin, fEarthBins[index]);
591
592 // Move lon bins
593 DetDist = lonI.detDist_nextBin;
594 index += (lonI.nextBin - lonI.bin) * fnLatBins;
595 lonI.bin = lonI.nextBin;
596// cout << "Longitude bin crossing at x=" << DetDist << "km...now in Earth bin " << index << " = (r" << floor(index/(fnLonBins*fnLatBins)) << ", lon" << lonI.bin << ", lat" << latI.bin << ")" << endl;
597
598 // Find next lon bin
599 if (lonI.dLon == 0) { //Only 1 lon bin crossing along entire neutrino trajectory
600 lonI.detDist_nextBin = -1;
601 }
602 else {
603 lonI.detDist_nextBin =
604 DetDistForNextLonBin(fEarthBins[index].longitude, lonI);
605 }
606 }
607 }
608}
609
610//.............................................................................
616int EarthModelBinned::LonBinIndex(double longitude)
617{
618 // Find difference between longitude and beginning of first lon bin
619 double londiff = longitude - (fEarthBins[0].longitude - fHalfLonBinWidth);
620
621 // Shift londiff to be between 0 and 2pi
622 if (londiff < 0 || londiff >= 2 * M_PI)
623 londiff -= floor(londiff / (2 * M_PI));
624
625 // Number of binwidths after from first lon bin
626 return floor(londiff * fInvLonBinWidth);
627}
628
629//.............................................................................
652int EarthModelBinned::FillPath(double cosT, double phi)
653{
654 // Clear current path sequence
655 fNuPath.clear();
656
657 // Do nothing if cosine is unphysical
658 if (fabs(cosT) > 1) return 0;
659
660 // Calculate useful combinations of variables
661 double Az = phi / 180.0 * M_PI; // convert from degrees to radians
662 fC.UpdateNuAngles(cosT, Az);
663 fC.Recalculate();
664 double rDetSqSinSqT = pow(fC.rDetSinT, 2);
665 double distEdgeToMin =
666 sqrt(fRadiusMax * fRadiusMax -
667 rDetSqSinSqT); // distance from point where neutrino enters to
668 // minimum depth (neglecting stopping at the detector)
669 double baseline = distEdgeToMin - fC.rDetCosT; // total baseline
670
671 // Define the maximum depth (minimum radius) along the path (detector
672 // depth/radius, if cosT is non-negative)
673 double minRadius = fDetRadius;
674 if (cosT < 0) { minRadius = fC.rDetSinT; }
675
676 // Starting latitude
677/* cout << "Pieces of init_lat calculation:" << endl
678 << "\trDetSinT = " << fC.rDetSinT << endl
679 << "\tbeta = " << fC.beta << endl
680 << "\tgamma = " << fC.gamma << endl
681 << "\tdistEdgeToMin = " << distEdgeToMin << endl
682 << "\tRadiusMax = " << fRadiusMax << endl; */
683 double init_lat = asin((fC.rDetSinT * fC.beta + fC.gamma * distEdgeToMin) /
684 fRadiusMax); // in radians
685
686 // Starting longitude
687 double init_lon = atan2(
689 baseline * (fC.alpha * fC.sinDetLon + fC.sinTsinAcosDetLon),
691 baseline *
693 fC.alpha * fC.cosDetLon)); // in radians (between -M_PI and M_PI)
694 if (init_lon < 0) { init_lon += 2 * M_PI; }
695
696 // Get initial Earth bin and # of bins per depth layer
697 LatBinInfo latinfo;
698 LonBinInfo loninfo;
699 int binsPerDepth = fEarthBins.size() / fnDepthBins;
700 int init_lonBin = LonBinIndex(init_lon);
701 int init_latBin = floor((init_lat + M_PI / 2.0) * fInvLatBinWidth);
702 int index =
703 fEarthBins.size() - binsPerDepth + init_lonBin * fnLatBins + init_latBin;
704
705 latinfo.bin = init_latBin;
706 loninfo.bin = init_lonBin;
707// cout << "Neutrino starting at (lat,lon)=(" << init_lat << "rad," << init_lon << "rad) in Earth bin " << index << " = (r" << floor(index/binsPerDepth) << ", lon" << loninfo.bin << ", lat" << latinfo.bin << ")" << endl;
708
709 /* Find detector distances for 1st latitude/longitude bin changes */
710 latinfo.dLat = fHalfLatBinWidth; // change in lat from bin center to next bin
711 // (0 if no more than 1 lat bin change)
712 // Condition calculation for starting sign in x(lat) equation
713 latinfo.sign = 1; //+ => lat incr., - => lat decr. (with decr. x)
714 latinfo.maxreached = false; // this changes to true if past the lat func transition
715 if (fC.beta < 0) latinfo.sign = -1;
716 if (fC.beta == 0) {
717 if (fC.cosA > 0) latinfo.sign = -1;
718 }
719 else if (baseline < fC.xlatextreme) {
720 latinfo.sign = -(latinfo.sign);
721 latinfo.maxreached = true;
722 }
723 // Condition calculation for incr./decr. Longitude (with decr. x)
724 loninfo.dLon =
725 fHalfLonBinWidth; // change in lon from bin center to next bin (includes
726 // direction; 0 if no more than 1 lon bin change)
727 loninfo.min = init_lon; // initial lon if lon is inc.
728 loninfo.max = fDetLon; // detector lon if lon is inc.
729 if (fC.sinA < 0) {
730 loninfo.dLon = -(loninfo.dLon);
731 loninfo.min = loninfo.max;
732 loninfo.max = init_lon;
733 // Switch max/min if dec., instead of inc.
734 loninfo.max = init_lon;
735 loninfo.min = fDetLon;
736 }
737 // Remainder of detDist (and nextBin) calculations
738 if (fC.sinT == 0) {
739 // both latitude and logitude flip at center of the Earth
740 loninfo.detDist_nextBin =
741 -fC.rDetCosT; // formula is divided by cosT, but cosT = +-1
742 loninfo.nextBin = LonBinIndex(fDetLon);
743 loninfo.dLon = 0;
744 latinfo.detDist_nextBin = loninfo.detDist_nextBin;
745 latinfo.nextBin = floor((fDetLat + 0.5 * M_PI) * fInvLatBinWidth);
746 latinfo.dLat = 0;
747 }
748 else {
749 if (fC.sinA == 0) {
750 if (fC.alpha == 0) { // crosses "at" infinity
751 loninfo.detDist_nextBin = -1;
752 }
753 else { // longitude flips at center of the Earth
755 loninfo.nextBin = LonBinIndex(fDetLon);
756 }
757 loninfo.dLon = 0;
758 }
759 else if (fC.cosDetLat == 0) {
760 loninfo.detDist_nextBin = -1;
761 }
762 else {
763 // x(lon) calculation
765 fEarthBins[index].longitude, loninfo); // also sets loninfo.nextBin
766 }
767 // x(lat) calculation
768 latinfo.detDist_nextBin = DetDistForNextLatBin(index, latinfo);
769 latinfo.nextBin = init_latBin + latinfo.sign;
770 }
771
772 // Get initial Detector Distance
773 double prev_DetDistance = baseline;
774
775 /* Start at the top layer of Earth model and go down to minimum (not including
776 * minimum), looping over depth bins */
777 int dBin = 0; // depth bin index
778 for (dBin = 0; dBin < fnDepthBins - 1; dBin++) {
779 // Check if minimum radius is contained in depth bin
780 double r_in = fEarthBins[index].radius_in; // inner-most radius
781 if (r_in < minRadius) break;
782
783 // Distance from detector at inner-most radius
784 double DetDistance = -fC.rDetCosT + sqrt(r_in * r_in - rDetSqSinSqT);
785
786 // Check for latitude/longitude bin crossings
787 RecordLatLonBinCrossings(DetDistance, prev_DetDistance, index, latinfo,
788 loninfo);
789
790 // Add Segment to next depth bin to path
791 AddPath(prev_DetDistance - DetDistance, fEarthBins[index]);
792
793 // Reset variables for next depth bin
794 prev_DetDistance = DetDistance;
795 index -= binsPerDepth;
796// cout << "Depth bin crossing at x=" << DetDistance << "km...now in Earth bin " << index << " = (r" << floor(index/binsPerDepth) << ", lon" << loninfo.bin << ", lat" << latinfo.bin << ")" << endl;
797 }
798
799 /* Do minimum depth bin and then go up to the detector */
800 int index2 = index;
801 for (index2 = index; fEarthBins[index2].radius_out < fDetRadius;
802 index2 += binsPerDepth) {
803 double r_out = fEarthBins[index2].radius_out; // outer-most radius
804
805 // Distance from detector at outer-most radius
806 double DetDistance = -fC.rDetCosT - sqrt(r_out * r_out - rDetSqSinSqT);
807
808 // Check for latitude/longitude bin crossings
809 RecordLatLonBinCrossings(DetDistance, prev_DetDistance, index2, latinfo,
810 loninfo);
811
812 // Add Segment in depth bin to path
813 AddPath(prev_DetDistance - DetDistance, fEarthBins[index2]);
814
815 // Reset variables for "previous" depth bin
816 prev_DetDistance = DetDistance;
817// cout << "Depth bin crossing at x=" << DetDistance << "km...now in Earth bin " << index2 << " = (r" << floor((index2+binsPerDepth)/binsPerDepth) << ", lon" << loninfo.bin << ", lat" << latinfo.bin << ")" << endl;
818 }
819
820 /* Do path to detector */
821 // Check for latitude/longitude bin crossings
822 RecordLatLonBinCrossings(0, prev_DetDistance, index2, latinfo, loninfo);
823 // Add the path segment within the detector bin
824 AddPath(prev_DetDistance, fEarthBins[index2]);
825
826 // Longitude calculation error message, if needed
827 if (loninfo.error < 0) {
828 cerr
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) = "
832 << "0."
833 << " Send the following message to rpestes@apc.in2p3.fr:" << endl
834 << 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 << ", "
838 << fDetLat << ", " << fDetLon << ")" << endl
839 << "\tcos(Zenith Angle) = " << cosT << endl
840 << "\tAzimuthal Angle = " << phi << " deg" << endl
841 << "\t" << loninfo.err_message << endl
842 << "Please fix this ASAP!" << endl;
843 return -1;
844 }
845
846 // Return the number of path segments
847 return fNuPath.size();
848}
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.
Definition: Absorption.h:6
Definition: EigenPoint.h:44
double zoa
The effective Z/A value of the matter in the bin.
int index
Region index.
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.
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 rDetCosT
rDet*cosT
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)