7 #include "earthmodel.hh" 13 #include "position.hh" 14 #include "Primaries.h" 19 #include "EnvironmentVariable.h" 21 #include "icemc_random.h" 34 const string ICEMC_DATA_DIR = ICEMC_SRC_DIR+
"/data/";
37 #ifdef ICEMODEL_DEBUG_TREE 40 static TFile * debugfile = 0;
41 static TTree * debugtree = 0;
46 static void write_the_tree()
56 static void setupTree()
61 debugfile =
new TFile(Form(
"icemodel_debug_%d.root",getpid()),
"RECREATE");
62 debugtree =
new TTree(
"debug",
"debug");
63 debugtree->Branch(
"dbg",dbg);
64 atexit(write_the_tree);
72 class FillTreeOnReturn
76 FillTreeOnReturn(TFile * cdto, TTree * tree) : f(cdto), t(tree) { ; }
78 TDirectory * tmp = gDirectory;
91 static bool inHistBounds(
double x,
double y,
const TH2 & h)
93 if (x < h.GetXaxis()->GetXmin())
return false;
94 if (y < h.GetYaxis()->GetXmin())
return false;
95 if (x > h.GetXaxis()->GetXmax())
return false;
96 if (y > h.GetYaxis()->GetXmax())
return false;
104 IceModel::IceModel(
int model,
int earth_model,
int WEIGHTABSORPTION_SETTING) :
EarthModel(earth_model,WEIGHTABSORPTION_SETTING)
107 bedmap_R = scale_factor*bedmap_c_0 * pow(( (1 + eccentricity*sin(71*RADDEG)) / (1 - eccentricity*sin(71*RADDEG)) ),eccentricity/2) * tan((PI/4) - (71*RADDEG)/2);
108 bedmap_nu = bedmap_R / cos(71*RADDEG);
114 xLowerLeft_ice=-3000000;
115 yLowerLeft_ice=-2500000;
118 xLowerLeft_ground=-2661600;
119 yLowerLeft_ground=-2149967;
122 xLowerLeft_water=-3000000;
123 yLowerLeft_water=-2500000;
126 h_ice_thickness.SetTitle(
"BEDMAP Ice Thickness; Easting (m), Northing (m)");
128 h_ground_elevation.SetTitle(
"BEDMAP Ground Elevation; Easting (m), Northing (m)");
130 h_water_depth.SetTitle(
"BEDMAP Water Depth; Easting (m), Northing (m)");
136 DEPTH_DEPENDENT_N = (int) (model / 10);
137 ice_model -= DEPTH_DEPENDENT_N * 10;
140 if (ice_model != 0 && ice_model != 1) {
141 cout<<
"Error! Unknown ice model requested! Defaulting to Crust 2.0.\n";
144 else if (ice_model==1) {
152 ifstream sheetup((ICEMC_DATA_DIR+
"/icesheet_attenlength_up.txt").c_str());
155 cerr <<
"Failed to open icesheet_attenlength_up.txt" << endl;
160 while(sheetup>>d_sheetup[i]>>l_sheetup[i])
166 ifstream shelfup((ICEMC_DATA_DIR+
"/iceshelf_attenlength_up.txt").c_str());
169 cerr <<
"Failed to open iceshelf_attenlength_up.txt" << endl;
174 while(shelfup>>d_shelfup[i]>>l_shelfup[i])
180 ifstream westlandup((ICEMC_DATA_DIR+
"/westland_attenlength_up.txt").c_str());
182 if(westlandup.fail())
183 {cerr <<
"Failed to open westland_attenlength_up.txt";
187 while(westlandup>>d_westlandup[i]>>l_westlandup[i])
195 ifstream sheetdown((ICEMC_DATA_DIR+
"/icesheet_attenlength_down.txt").c_str());
198 cerr <<
"Failed to open icesheet_attenlength_down.txt" << endl;
203 while(sheetdown>>d_sheetdown[i]>>l_sheetdown[i])
209 ifstream shelfdown((ICEMC_DATA_DIR+
"/iceshelf_attenlength_down.txt").c_str());
212 cerr <<
"Failed to open iceshelf_attenlength_down.txt" << endl;
217 while(shelfdown>>d_shelfdown[i]>>l_shelfdown[i])
223 ifstream westlanddown((ICEMC_DATA_DIR+
"/westland_attenlength_down.txt").c_str());
224 if(westlanddown.fail())
225 {cerr <<
"Failed to open westland_attenlength_down.txt";
229 while(westlanddown>>d_westlanddown[i]>>l_westlanddown[i])
233 westlanddown.close();
245 IceModel::~IceModel()
247 if (cart_ice_top)
delete cart_ice_top;
248 if (cart_ice_bot)
delete cart_ice_bot;
249 if (cart_ice_file)
delete cart_ice_file;
254 Position IceModel::PickBalloonPosition() {
267 int whichbin_forcrust20=0;
269 double phi=0,theta=0;
275 TRandom * rng = getRNG(RNG_INTERACTION_LOCATION);
318 if (ice_model == 0) {
321 while(vol_bybin/maxvol_inhorizon[ibnposition]<rnd3) {
325 whichbin_forcrust20=(int)(rnd1*(
double)ilat_inhorizon[ibnposition].size());
326 ilat=ilat_inhorizon[ibnposition][whichbin_forcrust20];
328 ilon=ilon_inhorizon[ibnposition][whichbin_forcrust20];
330 vol_bybin=icethkarray[ilon][ilat]*1000.*area[ilat];
332 phi=SmearPhi(ilon, rng->Rndm());
333 theta=SmearTheta(ilat, rng->Rndm());
338 else if (ice_model==1) {
340 while(vol_bybin/maxvol_inhorizon[ibnposition]<rnd3) {
344 which_coord=(int)(rnd1*(
double)easting_inhorizon[ibnposition].size());
346 e_coord=easting_inhorizon[ibnposition][which_coord];
347 n_coord=northing_inhorizon[ibnposition][which_coord];
351 GroundENtoLonLat(e_coord,n_coord,lon,lat);
355 if (e_coord > 1068 || e_coord < 0 || n_coord < 0 || n_coord > 869)
356 cout<<
"Problem in PickDownward: e_coord, n_coord : "<<e_coord<<
" , "<<n_coord<<endl;
357 vol_bybin=IceThickness(lon,lat)*Area(lat);
360 phi=LongtoPhi_0is180thMeridian(lon);
366 Vector posnu=PickPosnuForaLonLat(lon,lat,theta,phi);
377 const int PICK_RANDOM_SEGMENT = 1;
378 static void sampleLocation(
double len_int_kgm2,
379 std::vector<std::pair<double,double> > & ice_intersections,
385 std::vector<double> interaction_weights(ice_intersections.size());
386 std::vector<double> absorption_weights(ice_intersections.size());
387 double cumulative_prob = 0;
388 std::vector<double> lengths(ice_intersections.size());
389 std::vector<double> cumulative_probs(ice_intersections.size());
390 std::vector<double> chords(ice_intersections.size());
391 std::vector<double> nearthlayers(ice_intersections.size());
392 std::vector<double> total_kgm2(ice_intersections.size());
393 std::vector<int> crust_entered(ice_intersections.size());
394 std::vector<int> mantle_entered(ice_intersections.size());
395 std::vector<int> core_entered(ice_intersections.size());
396 std::vector<Vector> enterices;
397 std::vector<Vector> exitices;
402 interaction1->
r_in = model->WhereDoesItEnter(x + 0.5 * (ice_intersections[0].second + ice_intersections[0].first) * interaction1->
nnu, interaction1->
nnu);
404 double L_ice=len_int_kgm2/Signal::RHOICE;
405 interaction1->pathlength_inice = 0;
411 for (
unsigned i = 0; i < ice_intersections.size(); i++)
413 double this_length = ice_intersections[i].second - ice_intersections[i].first;
414 lengths[i] = this_length;
417 enterices.push_back(x + ice_intersections[i].first * interaction1->
nnu);
418 exitices.push_back( x + ice_intersections[i].second * interaction1->
nnu);
422 model->Getchord(
true,
429 interaction_weights[i],
430 absorption_weights[i],
433 total_kgm2[i], crust_entered[i], mantle_entered[i], core_entered[i]);
436 interaction1->pathlength_inice += this_length;
438 cumulative_prob += interaction_weights[i];
439 cumulative_probs[i] = cumulative_prob;
443 if (PICK_RANDOM_SEGMENT)
445 which = rng->Integer(ice_intersections.size());
450 double p = rng->Uniform(0, cumulative_prob);
451 which = std::upper_bound(cumulative_probs.begin(), cumulative_probs.end(), p) - cumulative_probs.begin();
455 interaction1->
nuexitice = exitices[which];
457 interaction1->nearthlayers = nearthlayers[which];
458 interaction1->crust_entered = crust_entered[which];
459 interaction1->mantle_entered = mantle_entered[which];
460 interaction1->core_entered = core_entered[which];
461 interaction1->
weight_nu = absorption_weights[which];
462 if (PICK_RANDOM_SEGMENT )
464 interaction1->
weight_nu_prob = interaction_weights[which] * ice_intersections.size();
474 double this_length = lengths[which];
478 if (this_length/ L_ice < 1e-3)
480 distance = rng->Rndm() * this_length;
484 distance = -log(rng->Uniform(exp(-this_length/L_ice),1))*L_ice;
491 interaction1->posnu = enterices[which] + distance * interaction1->
nnu;
495 #ifdef ICEMODEL_DEBUG_TREE 496 dbg->sum_weight_probs = cumulative_prob;
497 for (
unsigned i = 0; i < enterices.size(); i++)
499 dbg->abs_weights.push_back(absorption_weights[i]);
500 dbg->weight_probs.push_back(interaction_weights[i]);
501 dbg->lengths.push_back(lengths[i]);
508 int IceModel::PickUnbiasedPointSourceNearBalloon(
Interaction * interaction1,
const Position * balloon_position,
509 double maxdist,
double chord_step,
double len_int_kgm2,
const Vector * force_dir)
512 #ifdef ICEMODEL_DEBUG_TREE 515 FillTreeOnReturn fill (debugfile, debugtree);
525 interaction1->
nnu = *force_dir;
528 TRandom * rng = getRNG(RNG_INTERACTION_LOCATION);
536 Position ref(balloon_position->
Lon()+180, balloon_position->
Lat(), R_EARTH);
543 double x= rng->Uniform(-maxdist*1e3,maxdist*1e3);
544 double y= rng->Uniform(-maxdist*1e3,maxdist*1e3);
545 sample_x =x; sample_y = y;
549 Vector orth = nudir.Orthogonal();
550 Vector orth2 = nudir.Cross(orth);
552 Vector p0 = ref + x*orth + y*orth2;
559 int nintersect = GeoidIntersection(p0, nudir, &int1, &int2);
562 #ifdef ICEMODEL_DEBUG_TREE 563 dbg->balloon.SetXYZ(balloon_position->X(), balloon_position->Y(), balloon_position->Z());
564 dbg->ref.SetXYZ(ref.X(), ref.Y(), ref.Z());
565 dbg->nudir.SetXYZ(nudir.X(), nudir.Y(), nudir.Z());
566 dbg->nintersect = nintersect;
569 dbg->int1.SetXYZ(int1.X(), int1.Y(), int1.Z());
570 dbg->int2.SetXYZ(int2.X(), int2.Y(), int2.Z());
576 #ifdef ICEMODEL_DEBUG_TREE 579 interaction1->neverseesice=1;
580 interaction1->noway = 1;
588 std::vector<std::pair<double,double> > ice_intersections;
589 int n_intersections = GetIceIntersectionsCartesian(int1, nudir, ice_intersections,chord_step);
591 if (n_intersections == 0)
593 #ifdef ICEMODEL_DEBUG_TREE 596 interaction1->pathlength_inice = 0;
597 interaction1->neverseesice = 1;
602 sampleLocation(len_int_kgm2, ice_intersections, interaction1,int1, rng,
this);
606 #ifdef ICEMODEL_DEBUG_TREE 609 dbg->nupos.SetXYZ(interaction1->posnu.X(),interaction1->posnu.Y(),interaction1->posnu.Z());
614 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)>0) {
615 interaction1->toohigh=1;
618 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)+IceThickness(interaction1->posnu)<0) {
619 interaction1->toolow=1;
629 int IceModel::PickUnbiased(
Interaction *interaction1,
double len_int_kgm2,
double & position_weight,
double chord_step,
Vector * force_dir) {
631 TRandom * rng = getRNG(RNG_INTERACTION_LOCATION);
638 interaction1->
nnu = *force_dir;
647 double sinth = rng->Uniform(0, sin(COASTLINE*RADDEG));
648 double phi = rng->Uniform(0,2*TMath::Pi());
650 double costh = sqrt(1-sinth*sinth);
652 const double RMAX = GEOID_MAX + 5500;
653 const double RMIN = GEOID_MIN + 5500;
654 Vector p0(RMAX * cos(phi) * sinth, RMAX * sin(phi) * sinth, RMIN*costh);
659 position_weight = 1./fabs(p0.Unit() * interaction1->
nnu);
665 GeoidIntersection(p0, interaction1->
nnu, &ints[0],&ints[2]);
667 int nabovecoastline = 0;
668 for (
int i =0; i < 2; i++)
670 if (ints[i].Lat() < COASTLINE) nabovecoastline++;
672 assert(nabovecoastline>0);
673 position_weight /= nabovecoastline;
677 std::vector<std::pair<double,double> > ice_intersections;
678 int n_intersections = GetIceIntersectionsCartesian(p0, interaction1->
nnu, ice_intersections,chord_step);
681 if (!n_intersections)
683 interaction1->noway = 1;
684 interaction1->neverseesice=1;
685 interaction1->pathlength_inice = 0;
689 sampleLocation(len_int_kgm2, ice_intersections, interaction1,p0, rng,
this);
692 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)>0) {
693 interaction1->toohigh=1;
697 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)+IceThickness(interaction1->posnu)<0) {
698 interaction1->toolow=1;
708 Vector n_surf = r_out.Unit();
713 double theta=r_out.Theta();
716 GetILonILat(r_out,ilon,ilat);
718 int ilon_previous=ilon-1;
720 ilon_previous=NLON-1;
722 int ilon_next=ilon+1;
726 double r=(geoid[ilat]+surfacer[ilon][ilat])*sin(theta);
728 double slope_phi=(surfacer[ilon_next][ilat]-surfacer[ilon_previous][ilat])/(r*2*phistep);
730 int ilat_previous=ilat-1;
734 int ilat_next=ilat+1;
738 double slope_costheta=(surfacer[ilon][ilat_next]-surfacer[ilon][ilat_previous])/((geoid[ilat]+surfacer[ilon][ilat])*2*thetastep);
741 double angle=atan(slope_costheta);
743 n_surf = n_surf.RotateY(angle);
746 angle=atan(slope_phi);
748 n_surf = n_surf.RotateZ(angle);
750 else if (ice_model==1) {
751 double dist_to_check = 7500;
753 double lon_prev,lon_next;
754 double lat_prev,lat_next;
757 double local_surface_elevation = Surface(lon,lat);
759 lat_next = lat + dist_to_check * (180 / (local_surface_elevation * PI));
760 lat_prev = lat - dist_to_check * (180 / (local_surface_elevation * PI));
762 lon_next = lon + dist_to_check * (180 / (sin(lat*RADDEG) * local_surface_elevation * PI));
763 lon_prev = lon - dist_to_check * (180 / (sin(lat*RADDEG) * local_surface_elevation * PI));
767 lat_next = 90 - (lat_next - 90);
773 if (lon_next > 360) {
777 else if (lon_next < 0) {
781 if (lon_prev > 360) {
785 else if (lon_prev < 0) {
790 double slope_phi=(SurfaceAboveGeoid(lon_next,lat)-SurfaceAboveGeoid(lon_prev,lat))/(2*dist_to_check);
792 double slope_costheta=(SurfaceAboveGeoid(lon,lat_next)-SurfaceAboveGeoid(lon,lat_prev))/(2*dist_to_check);
795 double angle=atan(slope_costheta);
797 n_surf = n_surf.RotateY(angle);
800 angle=atan(slope_phi);
802 n_surf = n_surf.RotateZ(angle);
809 int IceModel::WhereDoesItEnterIce(
const Position &posnu,
826 double x_previous2= x_previous * x_previous;
829 double lon = x.
Lon(),lat = x.
Lat();
830 double lon_old = lon,lat_old = lat;
831 double local_surface = Surface(lon,lat);
832 double rock_previous2= pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
833 double surface_previous2=pow(local_surface,2);
835 double rock2=rock_previous2;
836 double surface2=surface_previous2;
841 while (distance<2*local_surface+1000) {
851 double ice_thickness=IceThickness(lon,lat);
852 if (lon!=lon_old || lat!=lat_old) {
853 local_surface = Surface(lon,lat);
858 rock2=pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
859 surface2=pow(local_surface,2);
862 if ((
int)(lat)==COASTLINE && rock_previous2 < x2 && surface2 > x2)
867 if ((((x_previous2>rock_previous2 && x2<rock2)
868 || (x_previous2<surface_previous2 && x2>surface2)) && ice_thickness>0 && lat<COASTLINE)
875 distance=3*Geoid(lat);
886 if (lon!=lon_old || lat!=lat_old) {
887 rock_previous2 = rock2;
888 surface_previous2 = surface2;
898 int IceModel::WhereDoesItExitIce(
const Position &posnu,
915 double x_previous2= x_previous * x_previous;
918 double lon = x.
Lon(),lat = x.
Lat();
919 double lon_old = lon,lat_old = lat;
920 double local_surface = Surface(lon,lat);
921 double rock_previous2= pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
922 double surface_previous2=pow(local_surface,2);
924 double rock2=rock_previous2;
925 double surface2=surface_previous2;
933 while (distance<2*local_surface+1000) {
944 double ice_thickness=IceThickness(lon,lat);
945 if (lon!=lon_old || lat!=lat_old) {
946 local_surface = Surface(lon,lat);
951 rock2=pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
952 surface2=pow(local_surface,2);
955 if ((
int)(lat)==COASTLINE && rock_previous2 < x2 && surface2 > x2)
960 if ((((x_previous2<rock_previous2 && x2>rock2)
961 || (x_previous2>surface_previous2 && x2<surface2)) && ice_thickness>0 && lat<COASTLINE)
968 distance=3*Geoid(lat);
978 if (lon!=lon_old || lat!=lat_old) {
979 rock_previous2 = rock2;
980 surface_previous2 = surface2;
989 int IceModel::WhereDoesItExitIceForward(
const Position &posnu,
1006 double x_previous2= x_previous * x_previous;
1009 double lon = x.
Lon(),lat = x.
Lat();
1010 double lon_old = lon,lat_old = lat;
1011 double local_surface = Surface(lon,lat);
1012 double rock_previous2= pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
1013 double surface_previous2=pow(local_surface,2);
1015 double rock2=rock_previous2;
1016 double surface2=surface_previous2;
1021 while (distance<2*local_surface+1000) {
1031 double ice_thickness=IceThickness(lon,lat);
1032 if (lon!=lon_old || lat!=lat_old) {
1033 local_surface = Surface(lon,lat);
1038 rock2=pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
1039 surface2=pow(local_surface,2);
1042 if ((
int)(lat)==COASTLINE && rock_previous2 < x2 && surface2 > x2)
1047 if ((((x_previous2<rock_previous2 && x2>rock2)
1048 || (x_previous2>surface_previous2 && x2<surface2)) && ice_thickness>0 && lat<COASTLINE)
1055 distance=3*Geoid(lat);
1065 if (lon!=lon_old || lat!=lat_old) {
1066 rock_previous2 = rock2;
1067 surface_previous2 = surface2;
1078 double IceModel::IceThickness(
double lon,
double lat) {
1080 double ice_thickness=0;
1086 LonLattoEN(lon,lat,E,N);
1087 if (inHistBounds(E,N,h_ice_thickness))
1089 ice_thickness = h_ice_thickness.Interpolate(E,N);
1093 ice_thickness = icethkarray[(int)(lon/2)][(int)(lat/2)]*1000.;
1096 else if (ice_model==0) {
1097 ice_thickness = icethkarray[(int)(lon/2)][(int)(lat/2)]*1000.;
1101 return ice_thickness;
1103 double IceModel::IceThickness(
const Position &pos) {
1106 return IceThickness(pos.
Lon(),pos.
Lat());
1109 double IceModel::SurfaceAboveGeoid(
double lon,
double lat) {
1116 LonLattoEN(lon,lat,E,N);
1118 if (inHistBounds(E,N, h_ground_elevation))
1120 surface = h_ground_elevation.Interpolate(E,N) + h_ice_thickness.Interpolate(E,N) + h_water_depth.Interpolate(E,N);
1124 surface = surfacer[(int)(lon/2)][(int)(lat/2)];
1127 else if (ice_model==0) {
1128 surface = surfacer[(int)(lon/2)][(int)(lat/2)];
1134 double IceModel::SurfaceAboveGeoid(
const Position &pos) {
1137 return SurfaceAboveGeoid(pos.
Lon(),pos.
Lat());
1140 double IceModel::Surface(
double lon,
double lat) {
1141 return (SurfaceAboveGeoid(lon,lat) + Geoid(lat));
1144 double IceModel::Surface(
const Position& pos) {
1145 return Surface(pos.
Lon(),pos.
Lat());
1148 double IceModel::WaterDepth(
double lon,
double lat) {
1150 double water_depth_value=0;
1153 water_depth_value = waterthkarray[(int)(lon/2)][(int)(lat/2)]*1000;
1155 else if (ice_model==1) {
1157 LonLattoEN(lon,lat,E,N);
1158 if (inHistBounds(E,N,h_water_depth))
1160 water_depth_value = h_water_depth.Interpolate(E,N);
1163 water_depth_value = waterthkarray[(int)(lon/2)][(int)(lat/2)]*1000;
1166 return water_depth_value;
1168 double IceModel::WaterDepth(
const Position &pos) {
1171 return WaterDepth(pos.
Lon(),pos.
Lat());
1174 int IceModel::IceOnWater(
const Position &pos) {
1175 if(IceThickness(pos)>0.&&WaterDepth(pos)>0.)
1180 int IceModel::RossIceShelf(
const Position &pos) {
1183 GetILonILat(pos,ilon,ilat);
1185 if ((ilat==2 && ilon>=5 && ilon<=14) ||
1186 (ilat==3 && (ilon>=168 || ilon<=14)) ||
1187 (ilat==4 && (ilon>=168 || ilon<=13)) ||
1188 (ilat==5 && (ilon>=168 || ilon<=14)))
1194 int IceModel::RossExcept(
const Position &pos) {
1196 GetILonILat(pos,ilon,ilat);
1197 if(ilon<=178&&ilon>=174&&ilat>=4&&ilat<=5)
1204 int IceModel::RonneIceShelf(
const Position &pos) {
1207 GetILonILat(pos,ilon,ilat);
1209 if ((ilat==4 && ilon>=52 && ilon<=74) ||
1210 (ilat==5 && ilon>=50 && ilon<=71) ||
1211 (ilat==6 && ilon>=55 && ilon<=64))
1218 int IceModel::WestLand(
const Position &pos) {
1219 double lon = pos.
Lon() , lat = pos.
Lat();
1221 if((lat>=4&&lat<=26)&&((lon>=0&&lon<=180)||lon>=336))
1227 double IceModel::GetBalloonPositionWeight(
int ibnpos) {
1229 if (volume_inhorizon[ibnpos]==0) {
1233 return volume/volume_inhorizon[ibnpos];
1236 int IceModel::OutsideAntarctica(
const Position &pos) {
1237 return (pos.
Lat() >= COASTLINE);
1240 int IceModel::OutsideAntarctica(
double lat) {
1241 return (lat >= COASTLINE);
1244 int IceModel::AcceptableRfexit(
const Vector &nsurf_rfexit,
const Position &rfexit,
const Vector &n_exit2rx) {
1247 if (rfexit.
Lat()>COASTLINE || IceThickness(rfexit)<0.0001) {
1248 cout <<
"latitude is " << rfexit.
Lat() <<
" compared to COASTLINE at " << COASTLINE <<
"\n";
1249 cout <<
"ice thickness is " << IceThickness(rfexit) <<
"\n";
1254 if (nsurf_rfexit*n_exit2rx<0) {
1262 double IceModel::GetN(
double altitude) {
1265 double b1=0.0140157;
1268 if (altitude < FIRNDEPTH)
1270 else if (altitude >= FIRNDEPTH && altitude <=0 && DEPTH_DEPENDENT_N)
1273 n=NFIRN+a1*(1.0-exp(b1*altitude));
1274 else if (altitude > 0)
1275 cout<<
"Error! N requested for position in air!\n";
1276 else if (!DEPTH_DEPENDENT_N)
1282 double IceModel::GetN(
const Position &pos) {
1283 return GetN(pos.Mag() - Surface(pos.
Lon(),pos.
Lat()));
1286 double IceModel::EffectiveAttenuationLength(
Settings *settings1,
const Position &pos,
const int &whichray) {
1287 double localmaxdepth = IceThickness(pos);
1288 double depth = Surface(pos) - pos.Mag();
1291 double attenuation_length=0.0;
1293 if(WestLand(pos) && !CONSTANTICETHICKNESS)
1295 depth_index=int(depth*419.9/localmaxdepth);
1296 if(RossIceShelf(pos) || RonneIceShelf(pos))
1299 attenuation_length=l_shelfup[depth_index];
1300 else if(whichray==1)
1301 attenuation_length=l_shelfdown[depth_index];
1303 cerr <<
" wrong attenuation length " <<endl;
1306 if((depth_index+0.5)!=d_shelfup[depth_index])
1308 cerr <<
"the index of the array l_iceshelfup is wrong!" << endl;
1315 attenuation_length=l_westlandup[depth_index];
1316 else if(whichray==1)
1317 attenuation_length=l_westlanddown[depth_index];
1319 cerr <<
" wrong attenuation length " <<endl;
1322 if(settings1->MOOREBAY)
1323 attenuation_length*=1.717557;
1328 depth_index =int(depth*(2809.9/localmaxdepth));
1332 attenuation_length =l_sheetup[depth_index];
1333 else if(whichray==1)
1334 attenuation_length =l_sheetdown[depth_index];
1336 cerr <<
" wrong attenuation length " <<endl;
1339 return attenuation_length;
1342 double IceModel::Area(
double latitude) {
1344 double lat_rad = (90 - latitude) * RADDEG;
1346 return (pow(cellSize* ((1 + sin(71*RADDEG)) / (1 + sin(lat_rad))),2));
1349 void IceModel::LonLattoEN(
double lon,
double lat,
double& E,
double& N) {
1353 double lon_rad = (lon - 180) * RADDEG;
1354 double lat_rad = (90 - lat) * RADDEG;
1356 bedmap_R = scale_factor*bedmap_c_0 * pow(( (1 + eccentricity*sin(lat_rad)) / (1 - eccentricity*sin(lat_rad)) ),eccentricity/2) * tan((PI/4) - lat_rad/2);
1358 E = bedmap_R * sin(lon_rad);
1359 N = bedmap_R * cos(lon_rad);
1364 void IceModel::ENtoLonLat(
int e_coord,
int n_coord,
double xLowerLeft,
double yLowerLeft,
double& lon,
double& lat) {
1367 double isometric_lat=0;
1368 double easting = xLowerLeft+(cellSize*(e_coord+0.5));
1369 double northing = -(yLowerLeft+(cellSize*(n_coord+0.5)));
1376 lon = atan(easting/northing);
1381 if (easting > 0 && lon < 0)
1383 else if (easting < 0 && lon > 0)
1385 else if (easting == 0 && northing < 0)
1391 bedmap_R = fabs(easting/sin(lon));
1392 else if (easting == 0 && northing != 0)
1393 bedmap_R = fabs(northing);
1400 isometric_lat = (PI/2) - 2*atan(bedmap_R/(scale_factor*bedmap_c_0));
1402 lat = isometric_lat + bedmap_a_bar*sin(2*isometric_lat) + bedmap_b_bar*sin(4*isometric_lat) + bedmap_c_bar*sin(6*isometric_lat) + bedmap_d_bar*sin(8*isometric_lat);
1404 lon = lon * DEGRAD + 180;
1405 lat = 90 - lat*DEGRAD;
1413 void IceModel::IceENtoLonLat(
int e,
int n,
double& lon,
double& lat) {
1416 ENtoLonLat(e,n,xLowerLeft_ice,yLowerLeft_ice,lon,lat);
1418 void IceModel::GroundENtoLonLat(
int e,
int n,
double& lon,
double& lat) {
1420 ENtoLonLat(e,n,xLowerLeft_ground,yLowerLeft_ground,lon,lat);
1422 void IceModel::WaterENtoLonLat(
int e,
int n,
double& lon,
double& lat) {
1424 ENtoLonLat(e,n,xLowerLeft_water,yLowerLeft_water,lon,lat);
1429 void IceModel::GetMAXHORIZON(
Balloon *bn1) {
1435 bn1->
MAXHORIZON=(sqrt((R_EARTH+altitude_inmeters)*(R_EARTH+altitude_inmeters)-R_EARTH*R_EARTH))*1.1;
1436 cout <<
"MAXHORIZON is " << bn1->
MAXHORIZON <<
"\n";
1440 void IceModel::CreateHorizons(
Settings *settings1,
Balloon *bn1,
double theta_bn,
double phi_bn,
double altitude_bn,ofstream &foutput) {
1456 double total_area=0;
1457 int NBALLOONPOSITIONS;
1461 NBALLOONPOSITIONS=(int)((
double)bn1->flightdatachain->GetEntries()/(double)bn1->
REDUCEBALLOONPOSITIONS)+1;
1464 NBALLOONPOSITIONS=NPHI;
1466 NBALLOONPOSITIONS=1;
1468 volume_inhorizon.resize(NBALLOONPOSITIONS);
1469 maxvol_inhorizon.resize(NBALLOONPOSITIONS);
1470 ilon_inhorizon.resize(NBALLOONPOSITIONS);
1471 ilat_inhorizon.resize(NBALLOONPOSITIONS);
1472 easting_inhorizon.resize(NBALLOONPOSITIONS);
1473 northing_inhorizon.resize(NBALLOONPOSITIONS);
1477 double phi_bn_temp=0;
1481 double surface_elevation=0;
1482 double local_ice_thickness=0;
1489 char horizon_file[80];
1490 FILE *bedmap_horizons = 0;
1501 sprintf(horizon_file,
"bedmap_horizons_whichpath%i_weights%i.dat",bn1->
WHICHPATH,settings1->USEPOSITIONWEIGHTS);
1504 if (ice_model==1 && !settings1->WRITE_FILE) {
1505 if(!(bedmap_horizons = fopen(horizon_file,
"r"))) {
1506 printf(
"Error: unable to open %s. Creating new file.\n", horizon_file);
1507 settings1->WRITE_FILE=1;
1510 if (ice_model==1 && settings1->WRITE_FILE) {
1511 if(!(bedmap_horizons = fopen(horizon_file,
"w"))) {
1512 printf(
"Error: unable to open %s\n", horizon_file);
1518 lat=GetLat(theta_bn);
1522 for (
int i=0;i<NBALLOONPOSITIONS;i++) {
1524 maxvol_inhorizon[i]=-1.;
1529 lat=GetLat(theta_bn);
1533 phi_bn_temp*=RADDEG;
1547 theta_bn=(90+(double)bn1->flatitude)*RADDEG;
1548 lat=GetLat(theta_bn);
1549 phi_bn_temp=(-1*(double)bn1->flongitude+90.);
1552 phi_bn_temp*=RADDEG;
1554 altitude_bn=(double)bn1->faltitude;
1558 phi_bn_temp=dGetPhi(i);
1567 lon=GetLon(phi_bn_temp);
1571 surface_elevation = this->Surface(lon,lat);
1572 r_bn_temp =
Vector(sin(theta_bn)*cos(phi_bn_temp)*(surface_elevation+altitude_bn),
1573 sin(theta_bn)*sin(phi_bn_temp)*(surface_elevation+altitude_bn),
1574 cos(theta_bn)*(surface_elevation+altitude_bn));
1580 for (
int j=0;j<NLON;j++) {
1581 for (
int k=0;k<ILAT_COASTLINE;k++) {
1584 r_bin =
Vector(sin(dGetTheta(k))*cos(dGetPhi(j))*(geoid[k]+surfacer[j][k]),
1585 sin(dGetTheta(k))*sin(dGetPhi(j))*(geoid[k]+surfacer[j][k]),
1586 cos(dGetTheta(k))*(geoid[k]+surfacer[j][k]));
1590 volume += icethkarray[j][k]*1000*area[k];
1591 if (!volume_found && icethkarray[j][k] > 0)
1592 total_area += area[k];
1601 || !settings1->USEPOSITIONWEIGHTS) {
1605 ilat_inhorizon[i].push_back(k);
1606 ilon_inhorizon[i].push_back(j);
1610 volume_inhorizon[i]+=icethkarray[j][k]*1000*area[k];
1614 if (icethkarray[j][k]*1000*area[k]>maxvol_inhorizon[i]) {
1615 maxvol_inhorizon[i]=icethkarray[j][k]*1000.*area[k];
1627 int ilat_bn,ilon_bn;
1628 GetILonILat(r_bn_temp,ilon_bn,ilat_bn);
1630 if (ilat_inhorizon[i].size()==0 || ilon_inhorizon[i].size()==0) {
1631 maxvol_inhorizon[i]=icethkarray[ilon_bn][ilat_bn]*1000.*area[ilat_bn];
1632 volume_inhorizon[i]=icethkarray[ilon_bn][ilat_bn]*1000.*area[ilat_bn];
1635 if (ilat_inhorizon[i].size()==0)
1636 ilat_inhorizon[i].push_back(ilat_bn);
1638 if (ilon_inhorizon[i].size()==0)
1639 ilon_inhorizon[i].push_back(ilon_bn);
1645 else if (ice_model==1 && !settings1->WRITE_FILE) {
1646 fgets(line,200,bedmap_horizons);
1647 while(line[0] !=
'X') {
1648 e_coord = atoi(strtok(line,
","));
1649 n_coord = atoi(strtok(NULL,
","));
1650 easting_inhorizon[i].push_back(e_coord);
1651 northing_inhorizon[i].push_back(n_coord);
1652 fgets(line,200,bedmap_horizons);
1655 volume_inhorizon[i] = atof(strtok(NULL,
","));
1656 maxvol_inhorizon[i] = atof(strtok(NULL,
","));
1658 if (!volume_found) {
1659 total_area = atof(fgets(line,200,bedmap_horizons));
1660 volume = atof(fgets(line,200,bedmap_horizons));
1664 else if (ice_model==1 && settings1->WRITE_FILE) {
1666 for (
int n_coord=0;n_coord<nRows_ground;n_coord++) {
1667 for (
int e_coord=0;e_coord<nCols_ground;e_coord++) {
1669 GroundENtoLonLat(e_coord,n_coord,lon,lat);
1671 theta = lat * RADDEG;
1672 phi=LongtoPhi_0is180thMeridian(lon);
1674 surface_elevation = this->Surface(lon,lat);
1675 local_ice_thickness = this->IceThickness(lon,lat);
1678 r_bin =
Vector(sin(theta)*cos(phi)*surface_elevation,
1679 sin(theta)*sin(phi)*surface_elevation,
1680 cos(theta)*surface_elevation);
1683 volume += local_ice_thickness*Area(lat);
1684 if (!volume_found && local_ice_thickness > 5)
1685 total_area += Area(lat);
1686 if ((settings1->USEPOSITIONWEIGHTS && r_bn_temp.
Distance(r_bin)<bn1->
MAXHORIZON) || !settings1->USEPOSITIONWEIGHTS) {
1687 fprintf(bedmap_horizons,
"%i,%i,\n",e_coord,n_coord);
1689 easting_inhorizon[i].push_back(e_coord);
1690 northing_inhorizon[i].push_back(n_coord);
1693 GroundENtoLonLat(e_coord,n_coord,lon,lat);
1696 volume_inhorizon[i]+=local_ice_thickness*Area(lat);
1699 if (local_ice_thickness*Area(lat)>maxvol_inhorizon[i]) {
1700 maxvol_inhorizon[i]=local_ice_thickness*Area(lat);
1706 fprintf(bedmap_horizons,
"X,%f,%f,\n",volume_inhorizon[i],maxvol_inhorizon[i]);
1707 if (!volume_found) {
1708 fprintf(bedmap_horizons,
"%f\n",total_area);
1709 fprintf(bedmap_horizons,
"%f\n",volume);
1715 if (!volume_found) {
1716 cout<<
"Total surface area covered with ice (in m^2) is : "<<total_area<<endl;
1722 if (bedmap_horizons)
1723 fclose(bedmap_horizons);
1725 volume_inhorizon_average=0;
1727 for (
int i=0;i<NBALLOONPOSITIONS;i++) {
1728 volume_inhorizon_average+=volume_inhorizon[i];
1731 volume_inhorizon_average/=(double)NBALLOONPOSITIONS;
1736 foutput <<
"Average volume of ice within a horizon is " << volume_inhorizon_average <<
"\n";
1738 foutput <<
"Average thickness of ice within horizon, averages over balloon positions " << volume_inhorizon_average/PI/pow(bn1->
MAXHORIZON,2) <<
"\n";
1742 void IceModel::ReadIceThickness() {
1745 ifstream IceThicknessFile((ICEMC_DATA_DIR+
"/icethic.asc").c_str());
1746 if(!IceThicknessFile) {
1747 cerr <<
"Couldn't open: $ICEMC_DATA_DIR/icethic.asc" << endl;
1751 cout<<
"Reading in BEDMAP data on ice thickness.\n";
1759 int temp1,temp2,temp3,temp4,temp5,temp6;
1761 IceThicknessFile >> tempBuf1 >> temp1 >> tempBuf2 >> temp2
1762 >> tempBuf3 >> temp3 >> tempBuf4 >> temp4
1763 >> tempBuf5 >> temp5 >> tempBuf6 >> temp6;
1765 if(tempBuf1 ==
string(
"ncols")) {
1768 if(tempBuf2 ==
string(
"nrows")) {
1771 if(tempBuf3 ==
string(
"xllcorner")) {
1772 xLowerLeft_ice=temp3;
1774 if(tempBuf4 ==
string(
"yllcorner")) {
1775 yLowerLeft_ice=temp4;
1777 if(tempBuf5 ==
string(
"cellsize")) {
1780 if(tempBuf6 ==
string(
"NODATA_value")) {
1786 assert(nRows_ice == 1000 && nCols_ice==1200);
1788 h_ice_thickness.SetBins(nCols_ice, xLowerLeft_ice, xLowerLeft_ice + nCols_ice*cellSize,
1789 nRows_ice, yLowerLeft_ice, yLowerLeft_ice+nRows_ice*cellSize);
1794 max_icevol_perbin=0.;
1795 max_icethk_perbin=0.;
1796 double lon_tmp,lat_tmp;
1797 for(
int rowNum=0;rowNum<nRows_ice;rowNum++) {
1798 for(
int colNum=0;colNum<nCols_ice;colNum++) {
1799 IceENtoLonLat(colNum,rowNum,lon_tmp,lat_tmp);
1800 IceThicknessFile >> theValue;
1801 if(theValue==NODATA)
1805 h_ice_thickness.SetBinContent(1+colNum, nRows_ice-rowNum, theValue);
1806 volume+=theValue*Area(lat_tmp);
1808 ice_area+=Area(lat_tmp);
1809 if (theValue*Area(lat_tmp)>max_icevol_perbin)
1810 max_icevol_perbin=theValue*Area(lat_tmp);
1811 if (theValue>max_icethk_perbin)
1812 max_icethk_perbin=theValue;
1816 IceThicknessFile.close();
1820 void IceModel::ReadGroundBed() {
1822 ifstream GroundBedFile((ICEMC_DATA_DIR+
"/groundbed.asc").c_str());
1823 if(!GroundBedFile) {
1824 cerr <<
"Couldn't open: ICEMC_DATA_DIR/groundbed.asc" << endl;
1828 cout<<
"Reading in BEDMAP data on elevation of ground.\n";
1836 int temp1,temp2,temp3,temp4,temp5,temp6;
1838 GroundBedFile >> tempBuf1 >> temp1 >> tempBuf2 >> temp2
1839 >> tempBuf3 >> temp3 >> tempBuf4 >> temp4
1840 >> tempBuf5 >> temp5 >> tempBuf6 >> temp6;
1842 if(tempBuf1 ==
string(
"ncols")) {
1845 if(tempBuf2 ==
string(
"nrows")) {
1848 if(tempBuf3 ==
string(
"xllcorner")) {
1849 xLowerLeft_ground=temp3;
1851 if(tempBuf4 ==
string(
"yllcorner")) {
1852 yLowerLeft_ground=temp4;
1854 if(tempBuf5 ==
string(
"cellsize")) {
1857 if(tempBuf6 ==
string(
"NODATA_value")) {
1860 assert(nRows_ground == 869 && nCols_ground==1068);
1862 h_ground_elevation.SetBins(nCols_ground, xLowerLeft_ground, xLowerLeft_ground + nCols_ground*cellSize,
1863 nRows_ground, yLowerLeft_ground, yLowerLeft_ground + nRows_ground*cellSize);
1869 for(
int rowNum=0;rowNum<nRows_ground;rowNum++) {
1870 for(
int colNum=0;colNum<nCols_ground;colNum++) {
1871 GroundBedFile >> theValue;
1873 if(theValue==NODATA)
1875 h_ground_elevation.SetBinContent(colNum+1,nRows_ground-rowNum,
double(theValue));
1881 GroundBedFile.close();
1885 void IceModel::ReadWaterDepth() {
1887 ifstream WaterDepthFile((ICEMC_DATA_DIR+
"/water.asc").c_str());
1888 if(!WaterDepthFile) {
1889 cerr <<
"Couldn't open: ICEMC_DATA_DIR/water.asc" << endl;
1893 cout<<
"Reading in BEDMAP data on water depth.\n";
1901 int temp1,temp2,temp3,temp4,temp5,temp6;
1903 WaterDepthFile >> tempBuf1 >> temp1 >> tempBuf2 >> temp2
1904 >> tempBuf3 >> temp3 >> tempBuf4 >> temp4
1905 >> tempBuf5 >> temp5 >> tempBuf6 >> temp6;
1907 if(tempBuf1 ==
string(
"ncols")) {
1910 if(tempBuf2 ==
string(
"nrows")) {
1913 if(tempBuf3 ==
string(
"xllcorner")) {
1914 xLowerLeft_water=temp3;
1916 if(tempBuf4 ==
string(
"yllcorner")) {
1917 yLowerLeft_water=temp4;
1919 if(tempBuf5 ==
string(
"cellsize")) {
1922 if(tempBuf6 ==
string(
"NODATA_value")) {
1929 assert(nRows_water == 1000 && nCols_water==1200);
1931 h_water_depth.SetBins(nCols_water, xLowerLeft_water, xLowerLeft_water + nCols_water*cellSize,
1932 nRows_water, yLowerLeft_water, yLowerLeft_water+nRows_water*cellSize);
1934 for(
int rowNum=0;rowNum<nRows_water;rowNum++) {
1935 for(
int colNum=0;colNum<nCols_water;colNum++) {
1936 WaterDepthFile >> theValue;
1938 if(theValue==NODATA)
1940 h_water_depth.SetBinContent(1+colNum,nRows_water-rowNum,
double(theValue));
1944 WaterDepthFile.close();
1955 void IceModel::CreateCartesianTopAndBottom(
int resolution,
bool force)
1959 if (resolution == cart_resolution)
1964 cart_resolution = resolution;
1966 if (cart_ice_file)
delete cart_ice_file;
1968 fname.Form(
"%s/cartesian_icemodel_%d_%d.root", getenv(
"ICEMC_SRC_DIR")?:
".", ice_model , resolution);
1970 TDirectory * olddir = gDirectory;
1975 cart_ice_file =
new TFile(fname);
1977 if (!cart_ice_file->IsOpen())
1979 delete cart_ice_file;
1983 cart_ice_top = (TH2*) cart_ice_file->Get(
"top");
1984 cart_ice_bot = (TH2*) cart_ice_file->Get(
"bot");
1986 if (!cart_ice_top || !cart_ice_bot)
1988 delete cart_ice_file;
2000 cart_ice_file =
new TFile(fname,
"RECREATE");
2003 printf(
"Creating new cartesian ice file at %s...\n", cart_ice_file->GetName());
2005 double bound = ceil(6371000/2/resolution)*resolution;
2006 int nbins = (2*bound)/resolution;
2009 hname.Form(
"icetop_%d_%d", ice_model, resolution);
2011 htitle.Form(
"Ice Top (model=%d, res=%d m)", ice_model, resolution);
2012 cart_ice_top =
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
2014 hname.Form(
"icebot_%d_%d", ice_model, resolution);
2015 htitle.Form(
"Ice Bottom (model=%d, res=%d m)", ice_model, resolution);
2016 cart_ice_bot=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
2019 hname.Form(
"ice_bot_r_%d_%d",ice_model, resolution);
2020 htitle.Form(
"Ice Bottom (r) (model=%d, res=%d m)", ice_model, resolution);
2022 TH2 * r_bot=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
2024 hname.Form(
"ice_top_r_%d_%d",ice_model, resolution);
2025 htitle.Form(
"Ice top (r) (model=%d, res=%d m)", ice_model, resolution);
2027 TH2 * r_top=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
2029 hname.Form(
"ice_bot_alt_%d_%d",ice_model, resolution);
2030 htitle.Form(
"Ice Bottom (alt) (model=%d, res=%d m)", ice_model, resolution);
2032 TH2 * alt_bot=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
2034 hname.Form(
"ice_top_alt_%d_%d",ice_model, resolution);
2035 htitle.Form(
"Ice top (alt) (model=%d, res=%d m)", ice_model, resolution);
2037 TH2 * alt_top=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
2040 for (
int j = 1; j <= nbins; j++)
2042 double y = cart_ice_top->GetYaxis()->GetBinCenter(j);
2043 for (
int i = 1; i <= nbins; i++)
2045 double x = cart_ice_top->GetXaxis()->GetBinCenter(i);
2047 double r2 = x*x+y*y;
2048 const double a = 6378137;
2049 const double a2 = a*a;
2050 if (r2 > a2)
continue;
2051 const double b = 6356752.314245; ;
2052 const double b2 = b*b;
2053 double z_geoid = sqrt((1-r2/a2)*b2);
2056 double lon = p.Lon();
2057 double lat = p.Lat();
2058 double ice_depth = IceThickness(lon,lat);
2061 double surface_above_geoid = SurfaceAboveGeoid(lon,lat);
2062 double geoid = Geoid(lat);
2063 double surface = surface_above_geoid+geoid;
2066 Position bot(lon,lat,surface-ice_depth);
2068 cart_ice_top->SetBinContent(i,j,top.Z());
2069 cart_ice_bot->SetBinContent(i,j,bot.Z());
2071 r_top->SetBinContent(i,j,surface);
2072 r_bot->SetBinContent(i,j,surface-ice_depth);
2074 alt_top->SetBinContent(i,j,surface_above_geoid);
2075 alt_bot->SetBinContent(i,j,surface_above_geoid-ice_depth);
2080 cart_ice_top->Write(
"top");
2081 cart_ice_bot->Write(
"bot");
2082 r_top->Write(
"r_top");
2083 r_bot->Write(
"r_bot");
2084 alt_top->Write(
"alt_top");
2085 alt_bot->Write(
"alt_bot");
2086 cart_ice_file->Flush();
2087 printf(
"...Done!\n");
2093 bool IceModel::CartesianIsInIce(
double x,
double y,
double z)
2095 const TH2 * htop = GetCartesianTop();
2096 if (z > cart_max_z)
return false;
2097 if (z < cart_min_z)
return false;
2098 if (x < htop->GetXaxis()->GetXmin())
return false;
2099 if (x > htop->GetXaxis()->GetXmax())
return false;
2100 if (y < htop->GetYaxis()->GetXmin())
return false;
2101 if (y > htop->GetYaxis()->GetXmax())
return false;
2103 double top = ((TH2*)htop)->Interpolate(x,y);
2104 if (!top)
return false;
2106 return z < top && z > ((TH2*)GetCartesianBottom())->Interpolate(x,y);
2109 int IceModel::GetIceIntersectionsCartesian(
const Position & posnu,
const Vector & nnu_in,
2110 std::vector<std::pair<double,double> > & intersection_points,
2111 double start_step,
int map_resolution)
2113 if (map_resolution!= cart_resolution) CreateCartesianTopAndBottom(map_resolution);
2115 if (cart_max_z == -1)
2117 cart_max_z = GetCartesianTop()->GetMaximum();
2119 cart_min_z = cart_max_z;
2121 const TH2 * hbot = GetCartesianBottom();
2123 for (
int j = 1; j <= hbot->GetNbinsY(); j++)
2125 for (
int i = 1; i <= hbot->GetNbinsX(); i++)
2127 double val = hbot->GetBinContent(i,j);
2128 if (val > 0 && val < cart_min_z) cart_min_z = val;
2134 std::vector<double> boundaries;
2138 bool start_in_ice = CartesianIsInIce(posnu.X(), posnu.Y(), posnu.Z());
2140 Vector nnu = nnu_in.Unit();
2142 for (
int dir = -1; dir <=1 ; dir+=2)
2146 bool was_in_ice = start_in_ice;
2150 double displacement = 0;
2151 bool jumped =
false;
2152 bool just_jumped =
false;
2156 displacement += start_step*dir;
2157 x = posnu + displacement*nnu;
2158 double mag2 = x.X()*x.X() + x.Y()*x.Y() + x.Z()*x.Z();
2160 if (mag2 > (7000e3*7000e3))
2162 printf(
"wtf: [%g,%g,%g], %g\n", x.X(), x.Y(), x.Z(), mag2);
2165 if (mag2 > (6365e3*6365e3))
2171 if (mag2 < (6355.5e3*6355.5e3) && !jumped && !was_in_ice)
2175 GeoidIntersection(x,dir*nnu, 0,0,-1000,ds);
2177 displacement = (ds[0] > 0 ? ds[0] : ds[1])*dir;
2184 bool is_in_ice = CartesianIsInIce(x.X(),x.Y(),x.Z());
2188 if (just_jumped && is_in_ice)
2190 displacement -= dir*(500+start_step);
2194 just_jumped =
false;
2196 if (was_in_ice!=is_in_ice)
2201 double step = -start_step*dir/2;
2202 bool search_was_in_ice = is_in_ice;
2203 double boundary_displacement = displacement;
2205 while (fabs(step) > 1)
2207 boundary_displacement+=step;
2208 xsearch = posnu + boundary_displacement * nnu;
2209 bool search_is_in_ice = CartesianIsInIce(xsearch.X(),xsearch.Y(),xsearch.Z());
2212 if (search_is_in_ice!=search_was_in_ice) step*=-1;
2213 search_was_in_ice = search_is_in_ice;
2217 boundaries.push_back(boundary_displacement);
2219 was_in_ice = is_in_ice;
2223 std::sort(boundaries.begin(), boundaries.end());
2225 if (boundaries.size() % 2)
2227 fprintf(stderr,
"Uh oh, have an odd number of boundaries (%lu) . That means there's a bug...\n", boundaries.size());
2228 for (
unsigned i = 0; i < boundaries.size(); i++) printf(
" %g ", boundaries[i]);
2234 for (
unsigned i = 0; i < boundaries.size()/2; i++)
2236 intersection_points.push_back(std::pair<double,double>(boundaries[2*i], boundaries[2*i+1]));
2239 return boundaries.size()/2;
int WHICHPATH
0=fixed balloon position,1=randomized,2=ANITA-lite GPS data,3=banana plot
double Distance(const Position &second) const
Returns chord distance (direct distance between two vectors)
double MAXHORIZON
pick the interaction within this distance from the balloon so that it is within the horizon ...
int REDUCEBALLOONPOSITIONS
only take every 100th entry in the flight data file
const char * ICEMC_SRC_DIR()
double altitude_bn_anitalite[100000]
same for altitude
double BN_LATITUDE
balloon latitude for fixed balloon location
double weight_nu
Weight for neutrino that survives to posnu.
double Lat() const
Returns latitude, where the +z direction is at 0 latitude.
Reads in and stores input settings for the run.
int NPOINTS
number of GPS positions we're picking from.
double BN_ALTITUDE
pick balloon altitude
This class is a 3-vector that represents a position on the Earth's surface.
Stores everything about a particular neutrino interaction. Interaction.
double longitude_bn_anitalite[100000]
same for longitude
double total_kgm2
number of earth layers traversed
Position r_in
position where neutrino enters the earth
Shape of the earth, ice thicknesses, profiles of earth layers, densities, neutrino absorption...
double weight_nu_prob
Weight for neutrino that survives to posnu and interacts in the ice.
void PickAnyDirection()
Constructor.
double latitude_bn_anitalite[100000]
latitude at times along flightpath, equally distributed among gps data. This is filled with anita or ...
Handles everything related to balloon positions, payload orientation over the course of a flight...
Position nuexitice
place where neutrino would have left the ice
This class represents a three-vector. Operators are overloaded to provide for the familiar operations...
Position r_enterice
position where neutrino enters the ice
double Lon() const
Returns longitude.
Ice thicknesses and water depth.
Vector nnu
direction of neutrino (+z in south pole direction)