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 38 ClassImp(icemodel_debug);
40 static TFile * debugfile = 0;
41 static TTree * debugtree = 0;
43 static icemodel_debug * dbg =
new icemodel_debug;
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);
376 static void sampleLocation(
double len_int_kgm2,
377 std::vector<std::pair<double,double> > & ice_intersections,
381 std::vector<double> cumulative_dists(ice_intersections.size());
382 interaction1->pathlength_inice = 0;
383 for (
unsigned i = 0; i < ice_intersections.size(); i++)
385 double this_distance = ice_intersections[i].second - ice_intersections[i].first;
386 interaction1->pathlength_inice += this_distance;
387 cumulative_dists[i] = interaction1->pathlength_inice;
392 double distance = -1;
393 double L_ice=len_int_kgm2/Signal::RHOICE;
395 if (interaction1->pathlength_inice / L_ice < 1e-3)
397 distance = rng->Rndm() * interaction1->pathlength_inice;
401 distance = -log(rng->Uniform(exp(-interaction1->pathlength_inice/L_ice),1))*L_ice;
408 for (which= 0; which < cumulative_dists.size(); which++)
410 if (distance < cumulative_dists[which])
414 Vector enterice = x + ice_intersections[which].first * interaction1->
nnu;
415 Vector exitice = x + ice_intersections[which].second * interaction1->
nnu;
416 interaction1->posnu = enterice + (which == 0 ? distance : distance-cumulative_dists[which-1]) * interaction1->
nnu;
421 int IceModel::PickUnbiasedPointSourceNearBalloon(
Interaction * interaction1,
const Position * balloon_position,
422 double maxdist,
double chord_step,
double len_int_kgm2,
const Vector * force_dir)
425 #ifdef ICEMODEL_DEBUG_TREE 428 FillTreeOnReturn fill (debugfile, debugtree);
438 interaction1->
nnu = *force_dir;
441 TRandom * rng = getRNG(RNG_INTERACTION_LOCATION);
449 Position ref(balloon_position->
Lon()+180, balloon_position->
Lat(), R_EARTH);
456 double x= rng->Uniform(-maxdist*1e3,maxdist*1e3);
457 double y= rng->Uniform(-maxdist*1e3,maxdist*1e3);
458 sample_x =x; sample_y = y;
462 Vector orth = nudir.Orthogonal();
463 Vector orth2 = nudir.Cross(orth);
465 Vector p0 = ref + x*orth + y*orth2;
475 #ifdef ICEMODEL_DEBUG_TREE 476 dbg->balloon.SetXYZ(balloon_position->X(), balloon_position->Y(), balloon_position->Z());
477 dbg->ref.SetXYZ(ref.X(), ref.Y(), ref.Z());
478 dbg->nudir.SetXYZ(nudir.X(), nudir.Y(), nudir.Z());
479 dbg->nintersect = nintersect;
482 dbg->int1.SetXYZ(int1.X(), int1.Y(), int1.Z());
483 dbg->int2.SetXYZ(int2.X(), int2.Y(), int2.Z());
489 #ifdef ICEMODEL_DEBUG_TREE 492 interaction1->neverseesice=1;
493 interaction1->noway = 1;
501 std::vector<std::pair<double,double> > ice_intersections;
502 int n_intersections = GetIceIntersectionsCartesian(int1, nudir, ice_intersections,chord_step);
504 if (n_intersections == 0)
506 #ifdef ICEMODEL_DEBUG_TREE 509 interaction1->pathlength_inice = 0;
510 interaction1->neverseesice = 1;
515 sampleLocation(len_int_kgm2, ice_intersections, interaction1,int1, rng);
519 #ifdef ICEMODEL_DEBUG_TREE 520 dbg->exitice.SetXYZ(exitice.X(),exitice.Y(),exitice.Z());
521 dbg->enterice.SetXYZ(enterice.X(),enterice.Y(),enterice.Z());
522 dbg->nupos.SetXYZ(interaction1->posnu.X(),interaction1->posnu.Y(),interaction1->posnu.Z());
527 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)>0) {
528 interaction1->toohigh=1;
531 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)+IceThickness(interaction1->posnu)<0) {
532 interaction1->toolow=1;
542 int IceModel::PickUnbiased(
Interaction *interaction1,
double len_int_kgm2,
double & position_weight,
double chord_step,
Vector * force_dir) {
544 TRandom * rng = getRNG(RNG_INTERACTION_LOCATION);
551 interaction1->
nnu = *force_dir;
560 double sinth = rng->Uniform(0, sin(COASTLINE*RADDEG));
561 double phi = rng->Uniform(0,2*TMath::Pi());
563 double costh = sqrt(1-sinth*sinth);
565 const double RMAX = GEOID_MAX + 5500;
566 const double RMIN = GEOID_MIN + 5500;
567 Vector p0(RMAX * cos(phi) * sinth, RMAX * sin(phi) * sinth, RMIN*costh);
572 position_weight = 1./fabs(p0.Unit() * interaction1->
nnu);
580 int nabovecoastline = 0;
581 for (
int i =0; i < 2; i++)
583 if (ints[i].Lat() < COASTLINE) nabovecoastline++;
585 assert(nabovecoastline>0);
586 position_weight /= nabovecoastline;
590 std::vector<std::pair<double,double> > ice_intersections;
591 int n_intersections = GetIceIntersectionsCartesian(p0, interaction1->
nnu, ice_intersections,chord_step);
594 if (!n_intersections)
596 interaction1->noway = 1;
597 interaction1->neverseesice=1;
598 interaction1->pathlength_inice = 0;
602 sampleLocation(len_int_kgm2, ice_intersections, interaction1,p0, rng);
605 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)>0) {
606 interaction1->toohigh=1;
610 if (interaction1->posnu.Mag()-Surface(interaction1->posnu)+IceThickness(interaction1->posnu)<0) {
611 interaction1->toolow=1;
621 Vector n_surf = r_out.Unit();
626 double theta=r_out.Theta();
629 GetILonILat(r_out,ilon,ilat);
631 int ilon_previous=ilon-1;
633 ilon_previous=NLON-1;
635 int ilon_next=ilon+1;
639 double r=(geoid[ilat]+surfacer[ilon][ilat])*sin(theta);
641 double slope_phi=(surfacer[ilon_next][ilat]-surfacer[ilon_previous][ilat])/(r*2*phistep);
643 int ilat_previous=ilat-1;
647 int ilat_next=ilat+1;
651 double slope_costheta=(surfacer[ilon][ilat_next]-surfacer[ilon][ilat_previous])/((geoid[ilat]+surfacer[ilon][ilat])*2*thetastep);
654 double angle=atan(slope_costheta);
656 n_surf = n_surf.RotateY(angle);
659 angle=atan(slope_phi);
661 n_surf = n_surf.RotateZ(angle);
663 else if (ice_model==1) {
664 double dist_to_check = 7500;
666 double lon_prev,lon_next;
667 double lat_prev,lat_next;
670 double local_surface_elevation = Surface(lon,lat);
672 lat_next = lat + dist_to_check * (180 / (local_surface_elevation * PI));
673 lat_prev = lat - dist_to_check * (180 / (local_surface_elevation * PI));
675 lon_next = lon + dist_to_check * (180 / (sin(lat*RADDEG) * local_surface_elevation * PI));
676 lon_prev = lon - dist_to_check * (180 / (sin(lat*RADDEG) * local_surface_elevation * PI));
680 lat_next = 90 - (lat_next - 90);
686 if (lon_next > 360) {
690 else if (lon_next < 0) {
694 if (lon_prev > 360) {
698 else if (lon_prev < 0) {
703 double slope_phi=(SurfaceAboveGeoid(lon_next,lat)-SurfaceAboveGeoid(lon_prev,lat))/(2*dist_to_check);
705 double slope_costheta=(SurfaceAboveGeoid(lon,lat_next)-SurfaceAboveGeoid(lon,lat_prev))/(2*dist_to_check);
708 double angle=atan(slope_costheta);
710 n_surf = n_surf.RotateY(angle);
713 angle=atan(slope_phi);
715 n_surf = n_surf.RotateZ(angle);
722 int IceModel::WhereDoesItEnterIce(
const Position &posnu,
739 double x_previous2= x_previous * x_previous;
742 double lon = x.
Lon(),lat = x.
Lat();
743 double lon_old = lon,lat_old = lat;
744 double local_surface = Surface(lon,lat);
745 double rock_previous2= pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
746 double surface_previous2=pow(local_surface,2);
748 double rock2=rock_previous2;
749 double surface2=surface_previous2;
754 while (distance<2*local_surface+1000) {
764 double ice_thickness=IceThickness(lon,lat);
765 if (lon!=lon_old || lat!=lat_old) {
766 local_surface = Surface(lon,lat);
771 rock2=pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
772 surface2=pow(local_surface,2);
775 if ((
int)(lat)==COASTLINE && rock_previous2 < x2 && surface2 > x2)
780 if ((((x_previous2>rock_previous2 && x2<rock2)
781 || (x_previous2<surface_previous2 && x2>surface2)) && ice_thickness>0 && lat<COASTLINE)
788 distance=3*Geoid(lat);
799 if (lon!=lon_old || lat!=lat_old) {
800 rock_previous2 = rock2;
801 surface_previous2 = surface2;
811 int IceModel::WhereDoesItExitIce(
const Position &posnu,
828 double x_previous2= x_previous * x_previous;
831 double lon = x.
Lon(),lat = x.
Lat();
832 double lon_old = lon,lat_old = lat;
833 double local_surface = Surface(lon,lat);
834 double rock_previous2= pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
835 double surface_previous2=pow(local_surface,2);
837 double rock2=rock_previous2;
838 double surface2=surface_previous2;
846 while (distance<2*local_surface+1000) {
857 double ice_thickness=IceThickness(lon,lat);
858 if (lon!=lon_old || lat!=lat_old) {
859 local_surface = Surface(lon,lat);
864 rock2=pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
865 surface2=pow(local_surface,2);
868 if ((
int)(lat)==COASTLINE && rock_previous2 < x2 && surface2 > x2)
873 if ((((x_previous2<rock_previous2 && x2>rock2)
874 || (x_previous2>surface_previous2 && x2<surface2)) && ice_thickness>0 && lat<COASTLINE)
881 distance=3*Geoid(lat);
891 if (lon!=lon_old || lat!=lat_old) {
892 rock_previous2 = rock2;
893 surface_previous2 = surface2;
902 int IceModel::WhereDoesItExitIceForward(
const Position &posnu,
919 double x_previous2= x_previous * x_previous;
922 double lon = x.
Lon(),lat = x.
Lat();
923 double lon_old = lon,lat_old = lat;
924 double local_surface = Surface(lon,lat);
925 double rock_previous2= pow((local_surface - IceThickness(lon,lat) - WaterDepth(lon,lat)),2);
926 double surface_previous2=pow(local_surface,2);
928 double rock2=rock_previous2;
929 double surface2=surface_previous2;
934 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;
991 double IceModel::IceThickness(
double lon,
double lat) {
993 double ice_thickness=0;
999 LonLattoEN(lon,lat,E,N);
1000 if (inHistBounds(E,N,h_ice_thickness))
1002 ice_thickness = h_ice_thickness.Interpolate(E,N);
1006 ice_thickness = icethkarray[(int)(lon/2)][(int)(lat/2)]*1000.;
1009 else if (ice_model==0) {
1010 ice_thickness = icethkarray[(int)(lon/2)][(int)(lat/2)]*1000.;
1014 return ice_thickness;
1016 double IceModel::IceThickness(
const Position &pos) {
1019 return IceThickness(pos.
Lon(),pos.
Lat());
1022 double IceModel::SurfaceAboveGeoid(
double lon,
double lat) {
1029 LonLattoEN(lon,lat,E,N);
1031 if (inHistBounds(E,N, h_ground_elevation))
1033 surface = h_ground_elevation.Interpolate(E,N) + h_ice_thickness.Interpolate(E,N) + h_water_depth.Interpolate(E,N);
1037 surface = surfacer[(int)(lon/2)][(int)(lat/2)];
1040 else if (ice_model==0) {
1041 surface = surfacer[(int)(lon/2)][(int)(lat/2)];
1047 double IceModel::SurfaceAboveGeoid(
const Position &pos) {
1050 return SurfaceAboveGeoid(pos.
Lon(),pos.
Lat());
1053 double IceModel::Surface(
double lon,
double lat) {
1054 return (SurfaceAboveGeoid(lon,lat) + Geoid(lat));
1057 double IceModel::Surface(
const Position& pos) {
1058 return Surface(pos.
Lon(),pos.
Lat());
1061 double IceModel::WaterDepth(
double lon,
double lat) {
1063 double water_depth_value=0;
1066 water_depth_value = waterthkarray[(int)(lon/2)][(int)(lat/2)]*1000;
1068 else if (ice_model==1) {
1070 LonLattoEN(lon,lat,E,N);
1071 if (inHistBounds(E,N,h_water_depth))
1073 water_depth_value = h_water_depth.Interpolate(E,N);
1076 water_depth_value = waterthkarray[(int)(lon/2)][(int)(lat/2)]*1000;
1079 return water_depth_value;
1081 double IceModel::WaterDepth(
const Position &pos) {
1084 return WaterDepth(pos.
Lon(),pos.
Lat());
1087 int IceModel::IceOnWater(
const Position &pos) {
1088 if(IceThickness(pos)>0.&&WaterDepth(pos)>0.)
1093 int IceModel::RossIceShelf(
const Position &pos) {
1096 GetILonILat(pos,ilon,ilat);
1098 if ((ilat==2 && ilon>=5 && ilon<=14) ||
1099 (ilat==3 && (ilon>=168 || ilon<=14)) ||
1100 (ilat==4 && (ilon>=168 || ilon<=13)) ||
1101 (ilat==5 && (ilon>=168 || ilon<=14)))
1107 int IceModel::RossExcept(
const Position &pos) {
1109 GetILonILat(pos,ilon,ilat);
1110 if(ilon<=178&&ilon>=174&&ilat>=4&&ilat<=5)
1117 int IceModel::RonneIceShelf(
const Position &pos) {
1120 GetILonILat(pos,ilon,ilat);
1122 if ((ilat==4 && ilon>=52 && ilon<=74) ||
1123 (ilat==5 && ilon>=50 && ilon<=71) ||
1124 (ilat==6 && ilon>=55 && ilon<=64))
1131 int IceModel::WestLand(
const Position &pos) {
1132 double lon = pos.
Lon() , lat = pos.
Lat();
1134 if((lat>=4&&lat<=26)&&((lon>=0&&lon<=180)||lon>=336))
1140 double IceModel::GetBalloonPositionWeight(
int ibnpos) {
1142 if (volume_inhorizon[ibnpos]==0) {
1146 return volume/volume_inhorizon[ibnpos];
1149 int IceModel::OutsideAntarctica(
const Position &pos) {
1150 return (pos.
Lat() >= COASTLINE);
1153 int IceModel::OutsideAntarctica(
double lat) {
1154 return (lat >= COASTLINE);
1157 int IceModel::AcceptableRfexit(
const Vector &nsurf_rfexit,
const Position &rfexit,
const Vector &n_exit2rx) {
1160 if (rfexit.
Lat()>COASTLINE || IceThickness(rfexit)<0.0001) {
1161 cout <<
"latitude is " << rfexit.
Lat() <<
" compared to COASTLINE at " << COASTLINE <<
"\n";
1162 cout <<
"ice thickness is " << IceThickness(rfexit) <<
"\n";
1167 if (nsurf_rfexit*n_exit2rx<0) {
1175 double IceModel::GetN(
double altitude) {
1178 double b1=0.0140157;
1181 if (altitude < FIRNDEPTH)
1183 else if (altitude >= FIRNDEPTH && altitude <=0 && DEPTH_DEPENDENT_N)
1186 n=NFIRN+a1*(1.0-exp(b1*altitude));
1187 else if (altitude > 0)
1188 cout<<
"Error! N requested for position in air!\n";
1189 else if (!DEPTH_DEPENDENT_N)
1195 double IceModel::GetN(
const Position &pos) {
1196 return GetN(pos.Mag() - Surface(pos.
Lon(),pos.
Lat()));
1199 double IceModel::EffectiveAttenuationLength(
Settings *settings1,
const Position &pos,
const int &whichray) {
1200 double localmaxdepth = IceThickness(pos);
1201 double depth = Surface(pos) - pos.Mag();
1204 double attenuation_length=0.0;
1206 if(WestLand(pos) && !CONSTANTICETHICKNESS)
1208 depth_index=int(depth*419.9/localmaxdepth);
1209 if(RossIceShelf(pos) || RonneIceShelf(pos))
1212 attenuation_length=l_shelfup[depth_index];
1213 else if(whichray==1)
1214 attenuation_length=l_shelfdown[depth_index];
1216 cerr <<
" wrong attenuation length " <<endl;
1219 if((depth_index+0.5)!=d_shelfup[depth_index])
1221 cerr <<
"the index of the array l_iceshelfup is wrong!" << endl;
1228 attenuation_length=l_westlandup[depth_index];
1229 else if(whichray==1)
1230 attenuation_length=l_westlanddown[depth_index];
1232 cerr <<
" wrong attenuation length " <<endl;
1235 if(settings1->MOOREBAY)
1236 attenuation_length*=1.717557;
1241 depth_index =int(depth*(2809.9/localmaxdepth));
1245 attenuation_length =l_sheetup[depth_index];
1246 else if(whichray==1)
1247 attenuation_length =l_sheetdown[depth_index];
1249 cerr <<
" wrong attenuation length " <<endl;
1252 return attenuation_length;
1255 double IceModel::Area(
double latitude) {
1257 double lat_rad = (90 - latitude) * RADDEG;
1259 return (pow(cellSize* ((1 + sin(71*RADDEG)) / (1 + sin(lat_rad))),2));
1262 void IceModel::LonLattoEN(
double lon,
double lat,
double& E,
double& N) {
1266 double lon_rad = (lon - 180) * RADDEG;
1267 double lat_rad = (90 - lat) * RADDEG;
1269 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);
1271 E = bedmap_R * sin(lon_rad);
1272 N = bedmap_R * cos(lon_rad);
1277 void IceModel::ENtoLonLat(
int e_coord,
int n_coord,
double xLowerLeft,
double yLowerLeft,
double& lon,
double& lat) {
1280 double isometric_lat=0;
1281 double easting = xLowerLeft+(cellSize*(e_coord+0.5));
1282 double northing = -(yLowerLeft+(cellSize*(n_coord+0.5)));
1289 lon = atan(easting/northing);
1294 if (easting > 0 && lon < 0)
1296 else if (easting < 0 && lon > 0)
1298 else if (easting == 0 && northing < 0)
1304 bedmap_R = fabs(easting/sin(lon));
1305 else if (easting == 0 && northing != 0)
1306 bedmap_R = fabs(northing);
1313 isometric_lat = (PI/2) - 2*atan(bedmap_R/(scale_factor*bedmap_c_0));
1315 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);
1317 lon = lon * DEGRAD + 180;
1318 lat = 90 - lat*DEGRAD;
1326 void IceModel::IceENtoLonLat(
int e,
int n,
double& lon,
double& lat) {
1329 ENtoLonLat(e,n,xLowerLeft_ice,yLowerLeft_ice,lon,lat);
1331 void IceModel::GroundENtoLonLat(
int e,
int n,
double& lon,
double& lat) {
1333 ENtoLonLat(e,n,xLowerLeft_ground,yLowerLeft_ground,lon,lat);
1335 void IceModel::WaterENtoLonLat(
int e,
int n,
double& lon,
double& lat) {
1337 ENtoLonLat(e,n,xLowerLeft_water,yLowerLeft_water,lon,lat);
1342 void IceModel::GetMAXHORIZON(
Balloon *bn1) {
1344 double altitude_inmeters=bn1->
BN_ALTITUDE*12.*CMINCH/100.;
1348 bn1->
MAXHORIZON=(sqrt((R_EARTH+altitude_inmeters)*(R_EARTH+altitude_inmeters)-R_EARTH*R_EARTH))*1.1;
1349 cout <<
"MAXHORIZON is " << bn1->
MAXHORIZON <<
"\n";
1353 void IceModel::CreateHorizons(
Settings *settings1,
Balloon *bn1,
double theta_bn,
double phi_bn,
double altitude_bn,ofstream &foutput) {
1369 double total_area=0;
1370 int NBALLOONPOSITIONS;
1374 NBALLOONPOSITIONS=(int)((
double)bn1->flightdatachain->GetEntries()/(double)bn1->
REDUCEBALLOONPOSITIONS)+1;
1377 NBALLOONPOSITIONS=NPHI;
1379 NBALLOONPOSITIONS=1;
1381 volume_inhorizon.resize(NBALLOONPOSITIONS);
1382 maxvol_inhorizon.resize(NBALLOONPOSITIONS);
1383 ilon_inhorizon.resize(NBALLOONPOSITIONS);
1384 ilat_inhorizon.resize(NBALLOONPOSITIONS);
1385 easting_inhorizon.resize(NBALLOONPOSITIONS);
1386 northing_inhorizon.resize(NBALLOONPOSITIONS);
1390 double phi_bn_temp=0;
1394 double surface_elevation=0;
1395 double local_ice_thickness=0;
1402 char horizon_file[80];
1403 FILE *bedmap_horizons =
new FILE();
1408 sprintf(horizon_file,
"bedmap_horizons_whichpath%i_weights%i.dat",bn1->
WHICHPATH,settings1->USEPOSITIONWEIGHTS);
1410 if (ice_model==1 && !settings1->WRITE_FILE) {
1411 if(!(bedmap_horizons = fopen(horizon_file,
"r"))) {
1412 printf(
"Error: unable to open %s. Creating new file.\n", horizon_file);
1413 settings1->WRITE_FILE=1;
1416 if (ice_model==1 && settings1->WRITE_FILE) {
1417 if(!(bedmap_horizons = fopen(horizon_file,
"w"))) {
1418 printf(
"Error: unable to open %s\n", horizon_file);
1424 lat=GetLat(theta_bn);
1428 for (
int i=0;i<NBALLOONPOSITIONS;i++) {
1430 maxvol_inhorizon[i]=-1.;
1435 lat=GetLat(theta_bn);
1439 phi_bn_temp*=RADDEG;
1454 theta_bn=(90+(double)bn1->flatitude)*RADDEG;
1455 lat=GetLat(theta_bn);
1456 phi_bn_temp=(-1*(double)bn1->flongitude+90.);
1459 phi_bn_temp*=RADDEG;
1461 altitude_bn=(double)bn1->faltitude;
1465 phi_bn_temp=dGetPhi(i);
1474 lon=GetLon(phi_bn_temp);
1478 surface_elevation = this->Surface(lon,lat);
1479 r_bn_temp =
Vector(sin(theta_bn)*cos(phi_bn_temp)*(surface_elevation+altitude_bn),
1480 sin(theta_bn)*sin(phi_bn_temp)*(surface_elevation+altitude_bn),
1481 cos(theta_bn)*(surface_elevation+altitude_bn));
1487 for (
int j=0;j<NLON;j++) {
1488 for (
int k=0;k<ILAT_COASTLINE;k++) {
1491 r_bin =
Vector(sin(dGetTheta(k))*cos(dGetPhi(j))*(geoid[k]+surfacer[j][k]),
1492 sin(dGetTheta(k))*sin(dGetPhi(j))*(geoid[k]+surfacer[j][k]),
1493 cos(dGetTheta(k))*(geoid[k]+surfacer[j][k]));
1497 volume += icethkarray[j][k]*1000*area[k];
1498 if (!volume_found && icethkarray[j][k] > 0)
1499 total_area += area[k];
1508 || !settings1->USEPOSITIONWEIGHTS) {
1512 ilat_inhorizon[i].push_back(k);
1513 ilon_inhorizon[i].push_back(j);
1517 volume_inhorizon[i]+=icethkarray[j][k]*1000*area[k];
1521 if (icethkarray[j][k]*1000*area[k]>maxvol_inhorizon[i]) {
1522 maxvol_inhorizon[i]=icethkarray[j][k]*1000.*area[k];
1534 int ilat_bn,ilon_bn;
1535 GetILonILat(r_bn_temp,ilon_bn,ilat_bn);
1537 if (ilat_inhorizon[i].size()==0 || ilon_inhorizon[i].size()==0) {
1538 maxvol_inhorizon[i]=icethkarray[ilon_bn][ilat_bn]*1000.*area[ilat_bn];
1539 volume_inhorizon[i]=icethkarray[ilon_bn][ilat_bn]*1000.*area[ilat_bn];
1542 if (ilat_inhorizon[i].size()==0)
1543 ilat_inhorizon[i].push_back(ilat_bn);
1545 if (ilon_inhorizon[i].size()==0)
1546 ilon_inhorizon[i].push_back(ilon_bn);
1552 else if (ice_model==1 && !settings1->WRITE_FILE) {
1553 fgets(line,200,bedmap_horizons);
1554 while(line[0] !=
'X') {
1555 e_coord = atoi(strtok(line,
","));
1556 n_coord = atoi(strtok(NULL,
","));
1557 easting_inhorizon[i].push_back(e_coord);
1558 northing_inhorizon[i].push_back(n_coord);
1559 fgets(line,200,bedmap_horizons);
1562 volume_inhorizon[i] = atof(strtok(NULL,
","));
1563 maxvol_inhorizon[i] = atof(strtok(NULL,
","));
1565 if (!volume_found) {
1566 total_area = atof(fgets(line,200,bedmap_horizons));
1567 volume = atof(fgets(line,200,bedmap_horizons));
1571 else if (ice_model==1 && settings1->WRITE_FILE) {
1573 for (
int n_coord=0;n_coord<nRows_ground;n_coord++) {
1574 for (
int e_coord=0;e_coord<nCols_ground;e_coord++) {
1576 GroundENtoLonLat(e_coord,n_coord,lon,lat);
1578 theta = lat * RADDEG;
1579 phi=LongtoPhi_0is180thMeridian(lon);
1581 surface_elevation = this->Surface(lon,lat);
1582 local_ice_thickness = this->IceThickness(lon,lat);
1585 r_bin =
Vector(sin(theta)*cos(phi)*surface_elevation,
1586 sin(theta)*sin(phi)*surface_elevation,
1587 cos(theta)*surface_elevation);
1590 volume += local_ice_thickness*Area(lat);
1591 if (!volume_found && local_ice_thickness > 5)
1592 total_area += Area(lat);
1593 if ((settings1->USEPOSITIONWEIGHTS && r_bn_temp.
Distance(r_bin)<bn1->
MAXHORIZON) || !settings1->USEPOSITIONWEIGHTS) {
1594 fprintf(bedmap_horizons,
"%i,%i,\n",e_coord,n_coord);
1596 easting_inhorizon[i].push_back(e_coord);
1597 northing_inhorizon[i].push_back(n_coord);
1600 GroundENtoLonLat(e_coord,n_coord,lon,lat);
1603 volume_inhorizon[i]+=local_ice_thickness*Area(lat);
1606 if (local_ice_thickness*Area(lat)>maxvol_inhorizon[i]) {
1607 maxvol_inhorizon[i]=local_ice_thickness*Area(lat);
1613 fprintf(bedmap_horizons,
"X,%f,%f,\n",volume_inhorizon[i],maxvol_inhorizon[i]);
1614 if (!volume_found) {
1615 fprintf(bedmap_horizons,
"%f\n",total_area);
1616 fprintf(bedmap_horizons,
"%f\n",volume);
1621 if (!volume_found) {
1622 cout<<
"Total surface area covered with ice (in m^2) is : "<<total_area<<endl;
1629 volume_inhorizon_average=0;
1631 for (
int i=0;i<NBALLOONPOSITIONS;i++) {
1632 volume_inhorizon_average+=volume_inhorizon[i];
1635 volume_inhorizon_average/=(double)NBALLOONPOSITIONS;
1640 foutput <<
"Average volume of ice within a horizon is " << volume_inhorizon_average <<
"\n";
1642 foutput <<
"Average thickness of ice within horizon, averages over balloon positions " << volume_inhorizon_average/PI/pow(bn1->
MAXHORIZON,2) <<
"\n";
1646 void IceModel::ReadIceThickness() {
1649 ifstream IceThicknessFile((ICEMC_DATA_DIR+
"/icethic.asc").c_str());
1650 if(!IceThicknessFile) {
1651 cerr <<
"Couldn't open: $ICEMC_DATA_DIR/icethic.asc" << endl;
1655 cout<<
"Reading in BEDMAP data on ice thickness.\n";
1663 int temp1,temp2,temp3,temp4,temp5,temp6;
1665 IceThicknessFile >> tempBuf1 >> temp1 >> tempBuf2 >> temp2
1666 >> tempBuf3 >> temp3 >> tempBuf4 >> temp4
1667 >> tempBuf5 >> temp5 >> tempBuf6 >> temp6;
1669 if(tempBuf1 ==
string(
"ncols")) {
1672 if(tempBuf2 ==
string(
"nrows")) {
1675 if(tempBuf3 ==
string(
"xllcorner")) {
1676 xLowerLeft_ice=temp3;
1678 if(tempBuf4 ==
string(
"yllcorner")) {
1679 yLowerLeft_ice=temp4;
1681 if(tempBuf5 ==
string(
"cellsize")) {
1684 if(tempBuf6 ==
string(
"NODATA_value")) {
1690 assert(nRows_ice == 1000 && nCols_ice==1200);
1692 h_ice_thickness.SetBins(nCols_ice, xLowerLeft_ice, xLowerLeft_ice + nCols_ice*cellSize,
1693 nRows_ice, yLowerLeft_ice, yLowerLeft_ice+nRows_ice*cellSize);
1698 max_icevol_perbin=0.;
1699 max_icethk_perbin=0.;
1700 double lon_tmp,lat_tmp;
1701 for(
int rowNum=0;rowNum<nRows_ice;rowNum++) {
1702 for(
int colNum=0;colNum<nCols_ice;colNum++) {
1703 IceENtoLonLat(colNum,rowNum,lon_tmp,lat_tmp);
1704 IceThicknessFile >> theValue;
1705 if(theValue==NODATA)
1709 h_ice_thickness.SetBinContent(1+colNum, nRows_ice-rowNum, theValue);
1710 volume+=theValue*Area(lat_tmp);
1712 ice_area+=Area(lat_tmp);
1713 if (theValue*Area(lat_tmp)>max_icevol_perbin)
1714 max_icevol_perbin=theValue*Area(lat_tmp);
1715 if (theValue>max_icethk_perbin)
1716 max_icethk_perbin=theValue;
1720 IceThicknessFile.close();
1724 void IceModel::ReadGroundBed() {
1726 ifstream GroundBedFile((ICEMC_DATA_DIR+
"/groundbed.asc").c_str());
1727 if(!GroundBedFile) {
1728 cerr <<
"Couldn't open: ICEMC_DATA_DIR/groundbed.asc" << endl;
1732 cout<<
"Reading in BEDMAP data on elevation of ground.\n";
1740 int temp1,temp2,temp3,temp4,temp5,temp6;
1742 GroundBedFile >> tempBuf1 >> temp1 >> tempBuf2 >> temp2
1743 >> tempBuf3 >> temp3 >> tempBuf4 >> temp4
1744 >> tempBuf5 >> temp5 >> tempBuf6 >> temp6;
1746 if(tempBuf1 ==
string(
"ncols")) {
1749 if(tempBuf2 ==
string(
"nrows")) {
1752 if(tempBuf3 ==
string(
"xllcorner")) {
1753 xLowerLeft_ground=temp3;
1755 if(tempBuf4 ==
string(
"yllcorner")) {
1756 yLowerLeft_ground=temp4;
1758 if(tempBuf5 ==
string(
"cellsize")) {
1761 if(tempBuf6 ==
string(
"NODATA_value")) {
1764 assert(nRows_ground == 869 && nCols_ground==1068);
1766 h_ground_elevation.SetBins(nCols_ground, xLowerLeft_ground, xLowerLeft_ground + nCols_ground*cellSize,
1767 nRows_ground, yLowerLeft_ground, yLowerLeft_ground + nRows_ground*cellSize);
1773 for(
int rowNum=0;rowNum<nRows_ground;rowNum++) {
1774 for(
int colNum=0;colNum<nCols_ground;colNum++) {
1775 GroundBedFile >> theValue;
1777 if(theValue==NODATA)
1779 h_ground_elevation.SetBinContent(colNum+1,nRows_ground-rowNum,
double(theValue));
1785 GroundBedFile.close();
1789 void IceModel::ReadWaterDepth() {
1791 ifstream WaterDepthFile((ICEMC_DATA_DIR+
"/water.asc").c_str());
1792 if(!WaterDepthFile) {
1793 cerr <<
"Couldn't open: ICEMC_DATA_DIR/water.asc" << endl;
1797 cout<<
"Reading in BEDMAP data on water depth.\n";
1805 int temp1,temp2,temp3,temp4,temp5,temp6;
1807 WaterDepthFile >> tempBuf1 >> temp1 >> tempBuf2 >> temp2
1808 >> tempBuf3 >> temp3 >> tempBuf4 >> temp4
1809 >> tempBuf5 >> temp5 >> tempBuf6 >> temp6;
1811 if(tempBuf1 ==
string(
"ncols")) {
1814 if(tempBuf2 ==
string(
"nrows")) {
1817 if(tempBuf3 ==
string(
"xllcorner")) {
1818 xLowerLeft_water=temp3;
1820 if(tempBuf4 ==
string(
"yllcorner")) {
1821 yLowerLeft_water=temp4;
1823 if(tempBuf5 ==
string(
"cellsize")) {
1826 if(tempBuf6 ==
string(
"NODATA_value")) {
1833 assert(nRows_water == 1000 && nCols_water==1200);
1835 h_water_depth.SetBins(nCols_water, xLowerLeft_water, xLowerLeft_water + nCols_water*cellSize,
1836 nRows_water, yLowerLeft_water, yLowerLeft_water+nRows_water*cellSize);
1838 for(
int rowNum=0;rowNum<nRows_water;rowNum++) {
1839 for(
int colNum=0;colNum<nCols_water;colNum++) {
1840 WaterDepthFile >> theValue;
1842 if(theValue==NODATA)
1844 h_water_depth.SetBinContent(1+colNum,nRows_water-rowNum,
double(theValue));
1848 WaterDepthFile.close();
1859 void IceModel::CreateCartesianTopAndBottom(
int resolution,
bool force)
1863 if (resolution == cart_resolution)
1868 cart_resolution = resolution;
1870 if (cart_ice_file)
delete cart_ice_file;
1872 fname.Form(
"%s/cartesian_icemodel_%d_%d.root", getenv(
"ICEMC_SRC_DIR")?:
".", ice_model , resolution);
1874 TDirectory * olddir = gDirectory;
1879 cart_ice_file =
new TFile(fname);
1881 if (!cart_ice_file->IsOpen())
1883 delete cart_ice_file;
1887 cart_ice_top = (TH2*) cart_ice_file->Get(
"top");
1888 cart_ice_bot = (TH2*) cart_ice_file->Get(
"bot");
1890 if (!cart_ice_top || !cart_ice_bot)
1892 delete cart_ice_file;
1904 cart_ice_file =
new TFile(fname,
"RECREATE");
1907 printf(
"Creating new cartesian ice file at %s...\n", cart_ice_file->GetName());
1909 double bound = ceil(6371000/2/resolution)*resolution;
1910 int nbins = (2*bound)/resolution;
1913 hname.Form(
"icetop_%d_%d", ice_model, resolution);
1915 htitle.Form(
"Ice Top (model=%d, res=%d m)", ice_model, resolution);
1916 cart_ice_top =
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
1918 hname.Form(
"icebot_%d_%d", ice_model, resolution);
1919 htitle.Form(
"Ice Bottom (model=%d, res=%d m)", ice_model, resolution);
1920 cart_ice_bot=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
1923 hname.Form(
"ice_bot_r_%d_%d",ice_model, resolution);
1924 htitle.Form(
"Ice Bottom (r) (model=%d, res=%d m)", ice_model, resolution);
1926 TH2 * r_bot=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
1928 hname.Form(
"ice_top_r_%d_%d",ice_model, resolution);
1929 htitle.Form(
"Ice top (r) (model=%d, res=%d m)", ice_model, resolution);
1931 TH2 * r_top=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
1933 hname.Form(
"ice_bot_alt_%d_%d",ice_model, resolution);
1934 htitle.Form(
"Ice Bottom (alt) (model=%d, res=%d m)", ice_model, resolution);
1936 TH2 * alt_bot=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
1938 hname.Form(
"ice_top_alt_%d_%d",ice_model, resolution);
1939 htitle.Form(
"Ice top (alt) (model=%d, res=%d m)", ice_model, resolution);
1941 TH2 * alt_top=
new TH2D(hname.Data(), htitle.Data(), nbins,-bound,bound,nbins,-bound,bound);
1944 for (
int j = 1; j <= nbins; j++)
1946 double y = cart_ice_top->GetYaxis()->GetBinCenter(j);
1947 for (
int i = 1; i <= nbins; i++)
1949 double x = cart_ice_top->GetXaxis()->GetBinCenter(i);
1951 double r2 = x*x+y*y;
1952 const double a = 6378137;
1953 const double a2 = a*a;
1954 if (r2 > a2)
continue;
1955 const double b = 6356752.314245; ;
1956 const double b2 = b*b;
1957 double z_geoid = sqrt((1-r2/a2)*b2);
1960 double lon = p.Lon();
1961 double lat = p.Lat();
1962 double ice_depth = IceThickness(lon,lat);
1965 double surface_above_geoid = SurfaceAboveGeoid(lon,lat);
1966 double geoid = Geoid(lat);
1967 double surface = surface_above_geoid+geoid;
1970 Position bot(lon,lat,surface-ice_depth);
1972 cart_ice_top->SetBinContent(i,j,top.Z());
1973 cart_ice_bot->SetBinContent(i,j,bot.Z());
1975 r_top->SetBinContent(i,j,surface);
1976 r_bot->SetBinContent(i,j,surface-ice_depth);
1978 alt_top->SetBinContent(i,j,surface_above_geoid);
1979 alt_bot->SetBinContent(i,j,surface_above_geoid-ice_depth);
1984 cart_ice_top->Write(
"top");
1985 cart_ice_bot->Write(
"bot");
1986 r_top->Write(
"r_top");
1987 r_bot->Write(
"r_bot");
1988 alt_top->Write(
"alt_top");
1989 alt_bot->Write(
"alt_bot");
1990 cart_ice_file->Flush();
1991 printf(
"...Done!\n");
1997 bool IceModel::CartesianIsInIce(
double x,
double y,
double z)
1999 const TH2 * htop = GetCartesianTop();
2000 if (z > cart_max_z)
return false;
2001 if (z < cart_min_z)
return false;
2002 if (x < htop->GetXaxis()->GetXmin())
return false;
2003 if (x > htop->GetXaxis()->GetXmax())
return false;
2004 if (y < htop->GetYaxis()->GetXmin())
return false;
2005 if (y > htop->GetYaxis()->GetXmax())
return false;
2007 double top = ((TH2*)htop)->Interpolate(x,y);
2008 if (!top)
return false;
2010 return z < top && z > ((TH2*)GetCartesianBottom())->Interpolate(x,y);
2013 int IceModel::GetIceIntersectionsCartesian(
const Position & posnu,
const Vector & nnu_in,
2014 std::vector<std::pair<double,double> > & intersection_points,
2015 double start_step,
int map_resolution)
2017 if (map_resolution!= cart_resolution) CreateCartesianTopAndBottom(map_resolution);
2019 if (cart_max_z == -1)
2021 cart_max_z = GetCartesianTop()->GetMaximum();
2023 cart_min_z = cart_max_z;
2025 const TH2 * hbot = GetCartesianBottom();
2027 for (
int j = 1; j <= hbot->GetNbinsY(); j++)
2029 for (
int i = 1; i <= hbot->GetNbinsX(); i++)
2031 double val = hbot->GetBinContent(i,j);
2032 if (val > 0 && val < cart_min_z) cart_min_z = val;
2038 std::vector<double> boundaries;
2042 bool start_in_ice = CartesianIsInIce(posnu.X(), posnu.Y(), posnu.Z());
2044 Vector nnu = nnu_in.Unit();
2046 for (
int dir = -1; dir <=1 ; dir+=2)
2050 bool was_in_ice = start_in_ice;
2054 double displacement = 0;
2055 bool jumped =
false;
2056 bool just_jumped =
false;
2060 displacement += start_step*dir;
2061 x = posnu + displacement*nnu;
2062 double mag2 = x.X()*x.X() + x.Y()*x.Y() + x.Z()*x.Z();
2064 if (mag2 > (7000e3*7000e3))
2066 printf(
"wtf: [%g,%g,%g], %g\n", x.X(), x.Y(), x.Z(), mag2);
2069 if (mag2 > (6365e3*6365e3))
2075 if (mag2 < (6355.5e3*6355.5e3) && !jumped && !was_in_ice)
2081 displacement = (ds[0] > 0 ? ds[0] : ds[1])*dir;
2088 bool is_in_ice = CartesianIsInIce(x.X(),x.Y(),x.Z());
2092 if (just_jumped && is_in_ice)
2094 displacement -= dir*(500+start_step);
2098 just_jumped =
false;
2100 if (was_in_ice!=is_in_ice)
2105 double step = -start_step*dir/2;
2106 bool search_was_in_ice = is_in_ice;
2107 double boundary_displacement = displacement;
2109 while (fabs(step) > 1)
2111 boundary_displacement+=step;
2112 xsearch = posnu + boundary_displacement * nnu;
2113 bool search_is_in_ice = CartesianIsInIce(xsearch.X(),xsearch.Y(),xsearch.Z());
2116 if (search_is_in_ice!=search_was_in_ice) step*=-1;
2117 search_was_in_ice = search_is_in_ice;
2121 boundaries.push_back(boundary_displacement);
2123 was_in_ice = is_in_ice;
2127 std::sort(boundaries.begin(), boundaries.end());
2129 if (boundaries.size() % 2)
2131 fprintf(stderr,
"Uh oh, have an odd number of boundaries (%lu) . That means there's a bug...\n", boundaries.size());
2132 for (
unsigned i = 0; i < boundaries.size(); i++) printf(
" %g ", boundaries[i]);
2138 for (
unsigned i = 0; i < boundaries.size()/2; i++)
2140 intersection_points.push_back(std::pair<double,double>(boundaries[2*i], boundaries[2*i+1]));
2143 return boundaries.size()/2;
int WHICHPATH
0=fixed balloon position,1=randomized,2=ANITA-lite GPS data,3=banana plot
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
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
double Lat() const
Returns latitude, where the +z direction is at 0 latitude.
This class is a 3-vector that represents a position on the Earth's surface.
int GeoidIntersection(Vector x0, Vector p0, Position *int1, Position *int2, double extra_height=5500, double *ds=0) const
Stores everything about a particular neutrino interaction. Interaction.
double longitude_bn_anitalite[100000]
same for longitude
Shape of the earth, ice thicknesses, profiles of earth layers, densities, neutrino absorption...
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...
double Distance(const Position &second) const
Returns chord distance (direct distance between two vectors)
Position r_enterice
position where neutrino enters the ice
double Lon() const
Returns longitude.
Vector nnu
direction of neutrino (+z in south pole direction)