98 assert(
abs(za) <= 180);
107 assert(
abs(a_za) <= 180);
108 assert(r >= ppc -
RTOL);
112 if (
abs(a_za) > 90) {
143 assert(
abs(za) <= 180);
151 assert(
abs(za0) <= 180);
152 assert(
abs(za) <= 180);
153 assert((za0 >= 0 && za >= 0) || (za0 < 0 && za < 0));
155 return lat0 + za0 - za;
160 assert(r >= ppc -
RTOL);
163 return sqrt(r * r - ppc * ppc);
185 return sqrt(l * l + ppc * ppc);
205 assert(
abs(za0) <= 180);
206 assert((za0 >= 0 && lat >= lat0) || (za0 <= 0 && lat <= lat0));
209 const Numeric za = za0 + lat0 - lat;
245 const bool& tanpoint,
272 lstep = (l2 - l1) / (
Numeric)n;
357 dy = sin(aarad) *
dx;
358 dx = cos(aarad) *
dx;
378 assert(R.
ncols() == 3);
379 assert(R.
nrows() == 3);
380 assert(vrot.
nelem() == 3);
383 sqrt(vrot[0] * vrot[0] + vrot[1] * vrot[1] + vrot[2] * vrot[2]);
395 R(0, 0) = u2 + (v2 + w2) * c;
396 R(0, 1) = u * v * (1 - c) - w * s;
397 R(0, 2) = u * w * (1 - c) + v * s;
398 R(1, 0) = u * v * (1 - c) + w * s;
399 R(1, 1) = v2 + (u2 + w2) * c;
400 R(1, 2) = v * w * (1 - c) - u * s;
401 R(2, 0) = u * w * (1 - c) - v * s;
402 R(2, 1) = v * w * (1 - c) + u * s;
403 R(2, 2) = w2 + (u2 + v2) * c;
418 zaaa2cart(xyz[0], xyz[1], xyz[2], 90, aa0);
431 zaaa2cart(xyz[0], xyz[1], xyz[2], 90 + dza, aa0 + daa);
454 assert(za != 0 && za != 180);
458 zaaa2cart(xyz[0], xyz[1], xyz[2], za0, aa0);
471 zaaa2cart(xyz[0], xyz[1], xyz[2], za, aa);
482 cart2zaaa(za_tmp, aa_tmp, u[0], u[1], u[2]);
508 const Numeric& refr_index_air) {
510 assert(
abs(za) <= 180);
512 return r * refr_index_air * sin(
DEG2RAD *
abs(za));
516 assert(lon6 >= lon5);
518 if (lon < lon5 && lon + 180 <= lon6) {
520 }
else if (lon > lon6 && lon - 180 >= lon5) {
528 while (it < ppath.
np - 1 && ppath.
pos(it + 1, 0) < zmin) {
530 zmin = ppath.
pos(it, 0);
532 if (it == 0 || it == ppath.
np - 1) {
539 bool below =
false, above =
false;
543 if (p.
pos(
i, 0) < alt) {
544 if (above)
return i - 1;
547 if (below)
return i - 1;
559 if (signfac * (ppath.
pos(
i, 0) - ppath.
pos(
i - 1, 0)) < 0)
561 "A propagation path of limb character found. Such " 562 "viewing geometries are not supported by this method. " 563 "Propagation paths must result in strictly " 564 "increasing or decreasing altitudes.");
592 return r1 + (lat - lat1) * (r3 - r1) / (lat3 - lat1);
603 const Numeric r2 =
refell2r(refellipsoid, lat_grid[i1 + 1]) + z_surf[i1 + 1];
605 c1 = (r2 - r1) / (lat_grid[i1 + 1] - lat_grid[i1]);
629 c1 = (r2 - r1) / (lat2 - lat1);
639 assert(
abs(za) <= 180);
642 if (za > (90 - tilt) || za < (-90 - tilt)) {
678 assert(
abs(za_start) <= 180);
679 assert(r_start >= ppc);
685 if ((r_start >= r_hit && absza <= 90) || ppc > r_hit) {
692 if (absza > 90 && r_start <= r_hit) {
749 assert(zaabs != 180);
774 p0[0] = r0s - rp * sv;
776 p0[2] = -r0s / 2 + cc;
777 p0[3] = -r0c / 6 - cs / 2;
778 p0[4] = r0s / 24 - cc / 6;
779 p0[5] = r0c / 120 + cs / 24;
780 p0[6] = -r0s / 720 + cc / 120;
787 if (
abs(90 - zaabs) > 89.9) {
789 }
else if (
abs(90 - zaabs) > 75) {
795 int solutionfailure = 1;
797 while (solutionfailure) {
800 p = p0[
Range(0, n + 1)];
802 if (solutionfailure) {
811 if (
abs(r0 - rp) < 1e-9)
820 if (roots(
i, 1) == 0 && roots(
i, 0) > dmin && roots(
i, 0) < dlat) {
885 assert(absza <= 180);
886 assert(lat_start >= lat1 && lat_start <= lat3);
897 l =
max(1e-9, r - r_start0);
902 else if (absza > 180 -
ANGTOL) {
906 l =
max(1e-9, r_start0 - r);
920 if (rmax - rmin < 1e-6) {
925 if (r_start < rmax) {
929 if (r_start > rmin) {
937 if (lat > lat3 || lat < lat1) {
948 if (r_start < rmin) {
952 if (r_start > rmax) {
960 if (r_start > rmax) {
963 }
else if (r_start < rmin) {
974 if (lat < lat1 || lat > lat3) {
983 const Numeric rpl = r1 + cpl * (lat - lat1);
999 za = lat_start + za_start - lat;
1008 if (lat < lat1 || lat > lat3) {
1015 r = rpl + cpl * dlat;
1018 za = lat_start + za_start - lat;
1021 if (absza > 90 &&
abs(za) < 90) {
1069 return r15 + (lon - lon5) * (r16 - r15) / (lon6 - lon5);
1070 }
else if (lat == lat3) {
1071 return r35 + (lon - lon5) * (r36 - r35) / (lon6 - lon5);
1072 }
else if (lon == lon5) {
1073 return r15 + (lat - lat1) * (r35 - r15) / (lat3 - lat1);
1074 }
else if (lon == lon6) {
1075 return r16 + (lat - lat1) * (r36 - r16) / (lat3 - lat1);
1077 const Numeric fdlat = (lat - lat1) / (lat3 - lat1);
1078 const Numeric fdlon = (lon - lon5) / (lon6 - lon5);
1079 return (1 - fdlat) * (1 - fdlon) * r15 + fdlat * (1 - fdlon) * r35 +
1080 (1 - fdlat) * fdlon * r16 + fdlat * fdlon * r36;
1098 if (r15 == r35 && r15 == r36 && r15 == r16 && r35 == r36 && r35 == r16 &&
1107 rsurf_at_latlon(lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat, lon);
1120 lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat2, lon2) -
1127 lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat2, lon2) -
1131 c1 = 0.5 * (4 * dr1 - dr2);
1132 c2 = (dr1 - c1) / (dang * dang);
1178 if (lat_grid[llat] >
POLELAT) {
1181 throw runtime_error(
1182 "The upper latitude end of the atmosphere " 1183 "reached, that is not allowed.");
1187 if (ilon >= lon_grid.
nelem() - 1) {
1191 throw runtime_error(
1192 "The upper longitude end of the atmosphere " 1193 "reached, that is not allowed.");
1201 lat =
interp(itw, lat_grid, gp_lat);
1203 lon =
interp(itw, lon_grid, gp_lon);
1206 const Numeric lat1 = lat_grid[ilat];
1207 const Numeric lat3 = lat_grid[ilat + 1];
1208 const Numeric lon5 = lon_grid[ilon];
1209 const Numeric lon6 = lon_grid[ilon + 1];
1212 const Numeric r15 = re1 + z_surf(ilat, ilon);
1213 const Numeric r35 = re3 + z_surf(ilat + 1, ilon);
1214 const Numeric r36 = re3 + z_surf(ilat + 1, ilon + 1);
1215 const Numeric r16 = re1 + z_surf(ilat, ilon + 1);
1218 c1, c2, lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat, lon, aa);
1266 p0[0] = r0s - rp * sv;
1268 p0[2] = -r0s / 2 + c1c + c2s;
1269 p0[3] = -r0c / 6 - c1s / 2 + c2c;
1270 p0[4] = r0s / 24 - c1c / 6 - c2s / 2;
1271 p0[5] = r0c / 120 + c1s / 24 - c2c / 6;
1272 p0[6] = -r0s / 720 + c1c / 120 + c2s / 24;
1280 if (
abs(90 - za) > 89.9) {
1282 }
else if (
abs(90 - za) > 75) {
1288 int solutionfailure = 1;
1290 while (solutionfailure) {
1293 p = p0[
Range(0, n + 1)];
1295 if (solutionfailure) {
1313 if (roots(
i, 1) == 0 && roots(
i, 0) > dmin && roots(
i, 0) < dlat) {
1321 dlat = RAD2DEG * dlat;
1375 assert(za_start >= 0);
1376 assert(za_start <= 180);
1380 if ((r_start >= r_hit && za_start <= 90) || ppc > r_hit) {
1388 if (za_start < ANGTOL || za_start > 180 -
ANGTOL) {
1389 l =
abs(r_hit - r_start);
1395 const Numeric p = x * dx + y * dy + z * dz;
1397 const Numeric q = x * x + y * y + z * z - r_hit * r_hit;
1416 lat =
RAD2DEG * asin((z + dz * l) / r_hit);
1417 lon =
RAD2DEG * atan2(y + dy * l, x + dx * l);
1427 const Index& atmosphere_dim,
1430 assert(atmosphere_dim >= 1);
1431 assert(atmosphere_dim <= 3);
1433 ppath.
dim = atmosphere_dim;
1454 ppath.
gp_p.resize(np);
1455 if (atmosphere_dim >= 2) {
1457 if (atmosphere_dim == 3) {
1489 os <<
"Case number " << case_nr <<
" is not defined.";
1490 throw runtime_error(os.
str());
1501 }
else if (ppath.
background ==
"cloud box level") {
1503 }
else if (ppath.
background ==
"cloud box interior") {
1505 }
else if (ppath.
background ==
"transmitter") {
1510 <<
" is not a valid background case.";
1511 throw runtime_error(os.
str());
1523 assert(ppath1.
np >= n);
1537 if (n == ppath1.
np) {
1555 if (ppath1.
dim >= 2) {
1559 if (ppath1.
dim == 3) {
1597 ppath1.
pos(i1, 0) = ppath2.
pos(i, 0);
1598 ppath1.
pos(i1, 1) = ppath2.
pos(i, 1);
1599 ppath1.
los(i1, 0) = ppath2.
los(i, 0);
1600 ppath1.
r[i1] = ppath2.
r[i];
1605 if (ppath1.
dim >= 2) {
1609 if (ppath1.
dim == 3) {
1610 ppath1.
pos(i1, 2) = ppath2.
pos(i, 2);
1611 ppath1.
los(i1, 1) = ppath2.
los(i, 1);
1645 const Ppath& ppath) {
1647 const Index imax = ppath.
np - 1;
1650 r_start = ppath.
r[imax];
1651 lat_start = ppath.
pos(imax, 1);
1652 za_start = ppath.
los(imax, 0);
1680 const Index& endface,
1691 const Numeric r1 = refellipsoid[0] + z_field[ip];
1692 const Numeric dr = z_field[ip + 1] - z_field[ip];
1695 ppath.
r[
i] = r_v[
i];
1696 ppath.
pos(
i, 0) = r_v[
i] - refellipsoid[0];
1697 ppath.
pos(
i, 1) = lat_v[
i];
1698 ppath.
los(
i, 0) = za_v[
i];
1702 ppath.
gp_p[
i].idx = ip;
1703 ppath.
gp_p[
i].fd[0] = (r_v[
i] - r1) / dr;
1704 ppath.
gp_p[
i].fd[1] = 1 - ppath.
gp_p[
i].fd[0];
1708 ppath.
lstep[
i - 1] = lstep[
i - 1];
1719 else if (endface <= 4) {
1753 const Index imax = ppath.
np - 1;
1756 r_start = ppath.
r[imax];
1757 lat_start = ppath.
pos(imax, 1);
1758 za_start = ppath.
los(imax, 0);
1765 lat1 = lat_grid[ilat];
1766 lat3 = lat_grid[ilat + 1];
1779 r1a = re1 + z_field(ip, ilat);
1780 r3a = re3 + z_field(ip, ilat + 1);
1781 r3b = re3 + z_field(ip + 1, ilat + 1);
1782 r1b = re1 + z_field(ip + 1, ilat);
1812 r1a = re1 + z_field(ip, ilat);
1813 r3a = re3 + z_field(ip, ilat + 1);
1823 r3b = re3 + z_field(ip + 1, ilat + 1);
1824 r1b = re1 + z_field(ip + 1, ilat);
1830 rsurface1 = re1 + z_surface[ilat];
1831 rsurface3 = re3 + z_surface[ilat + 1];
1856 const Index& endface,
1860 const Index imax = np - 1;
1869 const Numeric dlat = lat_grid[ilat + 1] - lat_grid[ilat];
1870 const Numeric z1low = z_field(ip, ilat);
1871 const Numeric z1upp = z_field(ip + 1, ilat);
1872 const Numeric dzlow = z_field(ip, ilat + 1) - z1low;
1873 const Numeric dzupp = z_field(ip + 1, ilat + 1) - z1upp;
1875 const Numeric r1low = re + z1low;
1876 const Numeric r1upp = re + z1upp;
1877 re =
refell2r(refellipsoid, lat_grid[ilat + 1]);
1878 const Numeric drlow = re + z_field(ip, ilat + 1) - r1low;
1879 const Numeric drupp = re + z_field(ip + 1, ilat + 1) - r1upp;
1882 ppath.
r[
i] = r_v[
i];
1883 ppath.
pos(
i, 1) = lat_v[
i];
1884 ppath.
los(
i, 0) = za_v[
i];
1889 Numeric w = (lat_v[
i] - lat_grid[ilat]) / dlat;
1892 const Numeric rlow = r1low + w * drlow;
1893 const Numeric rupp = r1upp + w * drupp;
1896 const Numeric zlow = z1low + w * dzlow;
1897 const Numeric zupp = z1upp + w * dzupp;
1899 ppath.
gp_p[
i].idx = ip;
1900 ppath.
gp_p[
i].fd[0] = (r_v[
i] - rlow) / (rupp - rlow);
1901 ppath.
gp_p[
i].fd[1] = 1 - ppath.
gp_p[
i].fd[0];
1904 ppath.
pos(
i, 0) = zlow + ppath.
gp_p[
i].fd[0] * (zupp - zlow);
1907 ppath.
gp_lat[
i].fd[0] = (lat_v[
i] - lat_grid[ilat]) / dlat;
1912 ppath.
lstep[
i - 1] = lstep[
i - 1];
1925 if (endface == 1 || endface == 3) {
1927 }
else if (endface == 2 || endface == 4) {
1933 if (ppath.
gp_p[imax].fd[0] < 0 || ppath.
gp_p[imax].fd[1] < 0) {
1936 if (ppath.
gp_lat[imax].fd[0] < 0 || ppath.
gp_lat[imax].fd[1] < 0) {
1982 const Index imax = ppath.
np - 1;
1985 r_start = ppath.
r[imax];
1986 lat_start = ppath.
pos(imax, 1);
1987 lon_start = ppath.
pos(imax, 2);
1988 za_start = ppath.
los(imax, 0);
1989 aa_start = ppath.
los(imax, 1);
2000 if (lat_start == 90) {
2003 gridpos(gp_tmp, lon_grid, aa_start);
2004 if (aa_start < 180) {
2009 }
else if (lat_start == -90) {
2012 gridpos(gp_tmp, lon_grid, aa_start);
2013 if (aa_start < 180) {
2019 if (lat_start > 0) {
2024 if (lon_start < lon_grid[nlon - 1]) {
2031 lat1 = lat_grid[ilat];
2032 lat3 = lat_grid[ilat + 1];
2033 lon5 = lon_grid[ilon];
2034 lon6 = lon_grid[ilon + 1];
2047 r15a = re1 + z_field(ip, ilat, ilon);
2048 r35a = re3 + z_field(ip, ilat + 1, ilon);
2049 r36a = re3 + z_field(ip, ilat + 1, ilon + 1);
2050 r16a = re1 + z_field(ip, ilat, ilon + 1);
2051 r15b = re1 + z_field(ip + 1, ilat, ilon);
2052 r35b = re3 + z_field(ip + 1, ilat + 1, ilon);
2053 r36b = re3 + z_field(ip + 1, ilat + 1, ilon + 1);
2054 r16b = re1 + z_field(ip + 1, ilat, ilon + 1);
2061 if (fabs(za_start - 90) <= 10)
2087 r15a = re1 + z_field(ip, ilat, ilon);
2088 r35a = re3 + z_field(ip, ilat + 1, ilon);
2089 r36a = re3 + z_field(ip, ilat + 1, ilon + 1);
2090 r16a = re1 + z_field(ip, ilat, ilon + 1);
2116 r15b = re1 + z_field(ip + 1, ilat, ilon);
2117 r35b = re3 + z_field(ip + 1, ilat + 1, ilon);
2118 r36b = re3 + z_field(ip + 1, ilat + 1, ilon + 1);
2119 r16b = re1 + z_field(ip + 1, ilat, ilon + 1);
2125 rsurface15 = re1 + z_surface(ilat, ilon);
2126 rsurface35 = re3 + z_surface(ilat + 1, ilon);
2127 rsurface36 = re3 + z_surface(ilat + 1, ilon + 1);
2128 rsurface16 = re1 + z_surface(ilat, ilon + 1);
2157 const Index& endface,
2161 const Index imax = np - 1;
2170 const Numeric lat1 = lat_grid[ilat];
2171 const Numeric lat3 = lat_grid[ilat + 1];
2172 const Numeric lon5 = lon_grid[ilon];
2173 const Numeric lon6 = lon_grid[ilon + 1];
2176 const Numeric r15a = re1 + z_field(ip, ilat, ilon);
2177 const Numeric r35a = re3 + z_field(ip, ilat + 1, ilon);
2178 const Numeric r36a = re3 + z_field(ip, ilat + 1, ilon + 1);
2179 const Numeric r16a = re1 + z_field(ip, ilat, ilon + 1);
2180 const Numeric r15b = re1 + z_field(ip + 1, ilat, ilon);
2181 const Numeric r35b = re3 + z_field(ip + 1, ilat + 1, ilon);
2182 const Numeric r36b = re3 + z_field(ip + 1, ilat + 1, ilon + 1);
2183 const Numeric r16b = re1 + z_field(ip + 1, ilat, ilon + 1);
2184 const Numeric dlat = lat3 - lat1;
2185 const Numeric dlon = lon6 - lon5;
2190 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_v[
i], lon_v[i]);
2192 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_v[i], lon_v[i]);
2195 ppath.
r[i] = r_v[i];
2196 ppath.
pos(i, 1) = lat_v[i];
2197 ppath.
pos(i, 2) = lon_v[i];
2198 ppath.
los(i, 0) = za_v[i];
2199 ppath.
los(i, 1) = aa_v[i];
2200 ppath.
nreal[i] = n_v[i];
2201 ppath.
ngroup[i] = ng_v[i];
2204 ppath.
gp_p[i].idx = ip;
2205 ppath.
gp_p[i].fd[0] = (r_v[i] - rlow) / (rupp - rlow);
2206 ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
2211 lat1, lat3, lon5, lon6, re1, re3, re3, re1, lat_v[i], lon_v[i]);
2212 const Numeric zlow = rlow - re;
2213 const Numeric zupp = rupp - re;
2215 ppath.
pos(i, 0) = zlow + ppath.
gp_p[i].fd[0] * (zupp - zlow);
2218 ppath.
gp_lat[i].idx = ilat;
2219 ppath.
gp_lat[i].fd[0] = (lat_v[i] - lat1) / dlat;
2229 ppath.
gp_lon[i].idx = ilon;
2230 ppath.
gp_lon[i].fd[0] = (lon_v[i] - lon5) / dlon;
2235 ppath.
gp_lon[i].fd[0] = 0;
2236 ppath.
gp_lon[i].fd[1] = 1;
2240 ppath.
lstep[i - 1] = lstep[i - 1];
2251 if (endface == 1 || endface == 3) {
2253 }
else if (endface == 2 || endface == 4) {
2255 }
else if (endface == 5 || endface == 6) {
2261 if (ppath.
gp_p[imax].fd[0] < 0 || ppath.
gp_p[imax].fd[1] < 0) {
2264 if (ppath.
gp_lat[imax].fd[0] < 0 || ppath.
gp_lat[imax].fd[1] < 0) {
2267 if (ppath.
gp_lon[imax].fd[0] < 0 || ppath.
gp_lon[imax].fd[1] < 0) {
2316 assert(r_start >= ra -
RTOL);
2317 assert(r_start <= rb +
RTOL);
2322 }
else if (r_start > rb) {
2327 bool tanpoint =
false;
2331 if (za_start <= 90) {
2338 if (ra > rsurface && ra > ppc) {
2344 else if (rsurface > ppc) {
2357 assert(endface > 0);
2378 Numeric r_start, lat_start, za_start;
2414 refellipsoid[0] + z_field[ip],
2415 refellipsoid[0] + z_field[ip + 1],
2416 refellipsoid[0] + z_surface);
2460 Numeric lat_start = lat_start0;
2465 assert(lat_start >= lat1 - LATLONTOL);
2466 assert(lat_start <= lat3 + LATLONTOL);
2469 if (lat_start < lat1) {
2471 }
else if (lat_start > lat3) {
2480 assert(r_start >= rlow -
RTOL);
2481 assert(r_start <= rupp +
RTOL);
2484 if (r_start < rlow) {
2486 }
else if (r_start > rupp) {
2492 poslos2cart(x, z, dx, dz, r_start, lat_start, za_start);
2495 bool unsafe =
false;
2496 bool do_surface =
false;
2502 Numeric r_end, lat_end, l_end;
2509 l_end = rupp - r_start;
2514 else if (absza > 180 -
ANGTOL) {
2516 rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_start);
2518 if (rlow > rsurface) {
2519 l_end = r_start - rlow;
2522 l_end = r_start - rsurface;
2535 cart2pol(r_corr, lat_corr, x, z, lat_start, za_start);
2538 lat_corr -= lat_start;
2553 l_end = 2 * (rupp - rlow);
2556 Numeric l_in = 0, l_out = l_end;
2557 bool ready =
false, startup =
true;
2559 if (rsurface1 +
RTOL >= r1a || rsurface3 +
RTOL >= r3a) {
2565 r_end, lat_end, x + dx * l_end, z + dz * l_end, lat_start, za_start);
2567 lat_end -= lat_corr;
2575 rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_end);
2576 if (r_surface >= rlow && r_end <= r_surface) {
2583 if (lat_end < lat1) {
2586 }
else if (lat_end > lat3) {
2589 }
else if (r_end < rlow) {
2607 l_end = (l_out + l_in) / 2;
2617 if ((l_out - l_in) <
LACC) {
2620 l_end = (l_out + l_in) / 2;
2631 n =
Index(ceil(
abs(l_end / lmax)));
2642 lat_v[0] = lat_start;
2649 for (
Index j = 1; j <= n; j++) {
2675 rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_v[j]);
2677 if (r_v[j] < r_test) {
2681 }
else if (r_v[j] < rlow) {
2687 if (r_v[j] > rupp) {
2699 }
else if (endface == 2) {
2701 }
else if (endface == 3) {
2703 }
else if (endface == 4) {
2705 }
else if (endface == 7) {
2706 r_v[n] =
rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_v[n]);
2743 Numeric r_start, lat_start, za_start;
2749 Numeric lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
2861 Numeric lat_start = lat_start0;
2862 Numeric lon_start = lon_start0;
2867 assert(lat_start >= lat1 - LATLONTOL);
2868 assert(lat_start <= lat3 + LATLONTOL);
2869 assert(!(
abs(lat_start) <
POLELAT && lon_start < lon5 - LATLONTOL));
2870 assert(!(
abs(lat_start) <
POLELAT && lon_start > lon6 + LATLONTOL));
2873 assert(
abs(ppc - r_start0 * sin(
DEG2RAD * za_start)) < 0.1);
2876 if (lat_start < lat1) {
2878 }
else if (lat_start > lat3) {
2881 if (lon_start < lon5) {
2883 }
else if (lon_start > lon6) {
2889 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_start, lon_start);
2891 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_start, lon_start);
2894 assert(r_start >= rlow -
RTOL);
2895 assert(r_start <= rupp +
RTOL);
2898 if (r_start < rlow) {
2900 }
else if (r_start > rupp) {
2907 x, y, z, dx, dy, dz, r_start, lat_start, lon_start, za_start, aa_start);
2910 bool unsafe =
false;
2911 bool do_surface =
false;
2917 Numeric r_end, lat_end, lon_end, l_end;
2923 l_end = rupp - r_start;
2928 else if (za_start > 180 -
ANGTOL) {
2940 if (rlow > rsurface) {
2941 l_end = r_start - rlow;
2944 l_end = r_start - rsurface;
2955 Numeric r_corr, lat_corr, lon_corr;
2969 lat_corr -= lat_start;
2970 lon_corr -= lon_start;
2985 l_end = 2 * (rupp - rlow);
2988 Numeric l_in = 0, l_out = l_end;
2989 bool ready =
false, startup =
true;
2991 if (rsurface15 +
RTOL >= r15a || rsurface35 +
RTOL >= r35a ||
2992 rsurface36 +
RTOL >= r36a || rsurface16 +
RTOL >= r16a) {
3008 lat_end -= lat_corr;
3009 lon_end -= lon_corr;
3015 lon_end = lon_start;
3021 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_end, lon_end);
3034 if (r_surface >= rlow && r_end <= r_surface) {
3041 if (lat_end < lat1) {
3044 }
else if (lat_end > lat3) {
3047 }
else if (lon_end < lon5) {
3050 }
else if (lon_end > lon6) {
3053 }
else if (r_end < rlow) {
3058 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_end, lon_end);
3072 l_end = (l_out + l_in) / 2;
3082 if ((l_out - l_in) <
LACC) {
3085 l_end = (l_out + l_in) / 2;
3096 n =
Index(ceil(
abs(l_end / lmax)));
3109 lat_v[0] = lat_start;
3110 lon_v[0] = lon_start;
3118 for (
Index j = 1; j <= n; j++) {
3154 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_v[j], lon_v[j]);
3167 if (r_v[j] < r_test) {
3171 }
else if (r_v[j] < rlow) {
3177 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_v[j], lon_v[j]);
3178 if (r_v[j] > rupp) {
3190 }
else if (endface == 2) {
3201 }
else if (endface == 3) {
3203 }
else if (endface == 4) {
3214 }
else if (endface == 5) {
3216 }
else if (endface == 6) {
3218 }
else if (endface == 7) {
3278 Numeric r_start, lat_start, lon_start, za_start, aa_start;
3281 Index ip, ilat, ilon;
3285 Numeric lat1, lat3, lon5, lon6;
3286 Numeric r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
3287 Numeric rsurface15, rsurface35, rsurface36, rsurface16;
3331 Vector r_v, lat_v, lon_v, za_v, aa_v;
3447 const Agenda& refr_index_air_agenda,
3459 Numeric refr_index_air, refr_index_air_group;
3462 refr_index_air_group,
3463 refr_index_air_agenda,
3471 r_array.push_back(r);
3472 lat_array.push_back(lat);
3473 za_array.push_back(za);
3474 n_array.push_back(refr_index_air);
3475 ng_array.push_back(refr_index_air_group);
3479 Numeric lstep, lcum = 0, dlat;
3499 assert(r_v.
nelem() == 2);
3507 if (lstep <= lraytrace) {
3509 dlat = lat_v[1] - lat;
3520 za_flagside = 180 - za_flagside;
3528 dlat = lat_new - lat;
3538 refr_index_air_group,
3540 refr_index_air_agenda,
3554 za += (
RAD2DEG * lstep / refr_index_air) * (-sin(za_rad) * dndr);
3559 }
else if (za > 180) {
3564 if (ready || (lmax > 0 && lcum + lraytrace > lmax)) {
3565 r_array.push_back(r);
3566 lat_array.push_back(lat);
3567 za_array.push_back(za);
3568 n_array.push_back(refr_index_air);
3569 ng_array.push_back(refr_index_air_group);
3570 l_array.push_back(lcum);
3586 const Agenda& refr_index_air_agenda,
3587 const String& rtrace_method,
3590 Numeric r_start, lat_start, za_start;
3605 Numeric refr_index_air, refr_index_air_group;
3608 refr_index_air_group,
3609 refr_index_air_agenda,
3626 Array<Numeric> r_array, lat_array, za_array, l_array, n_array, ng_array;
3629 if (rtrace_method ==
"linear_basic") {
3653 refr_index_air_agenda,
3655 refellipsoid[0] + z_surface,
3656 refellipsoid[0] + z_field(ip, 0, 0),
3657 refellipsoid[0] + z_field(ip + 1, 0, 0),
3669 Vector r_v(np), lat_v(np), za_v(np), l_v(np - 1), n_v(np), ng_v(np);
3671 r_v[
i] = r_array[
i];
3672 lat_v[
i] = lat_array[
i];
3673 za_v[
i] = za_array[
i];
3674 n_v[
i] = n_array[
i];
3675 ng_v[
i] = ng_array[
i];
3677 l_v[
i] = l_array[
i];
3688 z_field(
joker, 0, 0),
3754 const Agenda& refr_index_air_agenda,
3771 Numeric refr_index_air, refr_index_air_group;
3774 refr_index_air_group,
3775 refr_index_air_agenda,
3785 r_array.push_back(r);
3786 lat_array.push_back(lat);
3787 za_array.push_back(za);
3788 n_array.push_back(refr_index_air);
3789 ng_array.push_back(refr_index_air_group);
3793 Numeric lstep, lcum = 0, dlat;
3820 assert(r_v.
nelem() == 2);
3828 if (lstep <= lraytrace) {
3830 dlat = lat_v[1] - lat;
3836 if (
abs(za) <= 90) {
3842 za_flagside =
sign(za) * 180 - za_flagside;
3850 dlat = lat_new - lat;
3859 }
else if (lat > lat3) {
3868 refr_index_air_group,
3871 refr_index_air_agenda,
3887 za += (
RAD2DEG * lstep / refr_index_air) *
3888 (-sin(za_rad) * dndr + cos(za_rad) * dndlat);
3893 }
else if (za > 180) {
3899 if (lat == lat1 && za < 0) {
3902 }
else if (lat == lat3 && za > 0) {
3908 if (ready || (lmax > 0 && lcum + lraytrace > lmax)) {
3909 r_array.push_back(r);
3910 lat_array.push_back(lat);
3911 za_array.push_back(za);
3912 n_array.push_back(refr_index_air);
3913 ng_array.push_back(refr_index_air_group);
3914 l_array.push_back(lcum);
3931 const Agenda& refr_index_air_agenda,
3932 const String& rtrace_method,
3935 Numeric r_start, lat_start, za_start;
3941 Numeric lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
3969 Array<Numeric> r_array, lat_array, za_array, l_array, n_array, ng_array;
3972 if (rtrace_method ==
"linear_basic") {
3989 refr_index_air_agenda,
4010 Vector r_v(np), lat_v(np), za_v(np), l_v(np - 1), n_v(np), ng_v(np);
4012 r_v[
i] = r_array[
i];
4013 lat_v[
i] = lat_array[
i];
4014 za_v[
i] = za_array[
i];
4015 n_v[
i] = n_array[
i];
4016 ng_v[
i] = ng_array[
i];
4018 l_v[
i] = l_array[
i];
4114 const Agenda& refr_index_air_agenda,
4141 Numeric refr_index_air, refr_index_air_group;
4144 refr_index_air_group,
4145 refr_index_air_agenda,
4157 r_array.push_back(r);
4158 lat_array.push_back(lat);
4159 lon_array.push_back(lon);
4160 za_array.push_back(za);
4161 aa_array.push_back(aa);
4162 n_array.push_back(refr_index_air);
4163 ng_array.push_back(refr_index_air_group);
4166 Vector r_v, lat_v, lon_v, za_v, aa_v;
4207 assert(r_v.
nelem() == 2);
4212 if (lstep <= lraytrace) {
4222 Numeric x, y, z,
dx, dy, dz, lat_new, lon_new;
4224 poslos2cart(x, y, z, dx, dy, dz, r, lat, lon, za, aa);
4258 refr_index_air_group,
4262 refr_index_air_agenda,
4279 const Numeric sinza = sin(za_rad);
4280 const Numeric sinaa = sin(aa_rad);
4281 const Numeric cosaa = cos(aa_rad);
4287 if (za < ANGTOL || za > 180 -
ANGTOL) {
4288 los[0] += aterm * (cos(za_rad) * (cosaa * dndlat + sinaa * dndlon));
4289 los[1] =
RAD2DEG * atan2(dndlon, dndlat);
4291 los[0] += aterm * (-sinza * dndr +
4292 cos(za_rad) * (cosaa * dndlat + sinaa * dndlon));
4293 los[1] += aterm * sinza * (cosaa * dndlon - sinaa * dndlat);
4304 if (za > 0 && za < 180) {
4305 if (lon == lon5 && aa < 0) {
4308 }
else if (lon == lon6 && aa > 0) {
4311 }
else if (lat == lat1 && lat != -90 &&
abs(aa) > 90) {
4314 }
else if (lat == lat3 && lat != 90 &&
abs(aa) < 90) {
4321 if (ready || (lmax > 0 && lcum + lraytrace > lmax)) {
4322 r_array.push_back(r);
4323 lat_array.push_back(lat);
4324 lon_array.push_back(lon);
4325 za_array.push_back(za);
4326 aa_array.push_back(aa);
4327 n_array.push_back(refr_index_air);
4328 ng_array.push_back(refr_index_air_group);
4329 l_array.push_back(lcum);
4347 const Agenda& refr_index_air_agenda,
4348 const String& rtrace_method,
4351 Numeric r_start, lat_start, lon_start, za_start, aa_start;
4354 Index ip, ilat, ilon;
4358 Numeric lat1, lat3, lon5, lon6;
4359 Numeric r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
4360 Numeric rsurface15, rsurface35, rsurface36, rsurface16;
4400 Array<Numeric> r_array, lat_array, lon_array, za_array, aa_array;
4404 if (rtrace_method ==
"linear_basic") {
4424 refr_index_air_agenda,
4455 Vector r_v(np), lat_v(np), lon_v(np), za_v(np), aa_v(np), l_v(np - 1);
4456 Vector n_v(np), ng_v(np);
4458 r_v[
i] = r_array[
i];
4459 lat_v[
i] = lat_array[
i];
4460 lon_v[
i] = lon_array[
i];
4461 za_v[
i] = za_array[
i];
4462 aa_v[
i] = aa_array[
i];
4463 n_v[
i] = n_array[
i];
4464 ng_v[
i] = ng_array[
i];
4466 l_v[
i] = l_array[
i];
4496 const Index& atmosphere_dim,
4503 const Index& cloudbox_on,
4505 const bool& ppath_inside_cloudbox_do,
4522 if (atmosphere_dim == 1) {
4524 ppath.
end_pos[0] = rte_pos[0];
4526 ppath.
end_los[0] = rte_los[0];
4529 if (rte_pos[0] < z_field(lp, 0, 0)) {
4531 if ((rte_pos[0] +
RTOL) < z_surface(0, 0)) {
4533 os <<
"The ppath starting point is placed " 4534 << (z_surface(0, 0) - rte_pos[0]) / 1e3 <<
" km below the surface.";
4535 throw runtime_error(os.
str());
4540 ppath.
r[0] = refellipsoid[0] + rte_pos[0];
4549 if (ppath.
pos(0, 0) <= z_surface(0, 0) && ppath.
los(0, 0) > 90) {
4555 if (cloudbox_on && !ppath_inside_cloudbox_do) {
4557 if (fgp >= (
Numeric)cloudbox_limits[0] &&
4558 fgp <= (
Numeric)cloudbox_limits[1]) {
4566 assert(fgp >= (
Numeric)cloudbox_limits[0] &&
4567 fgp <= (
Numeric)cloudbox_limits[1]);
4580 if (rte_los[0] <= 90 ||
4581 ppath.
constant >= refellipsoid[0] + z_field(lp, 0, 0)) {
4582 ppath.
pos(0, 0) = rte_pos[0];
4583 ppath.
pos(0, 1) = 0;
4584 ppath.
r[0] = refellipsoid[0] + rte_pos[0];
4585 ppath.
los(0, 0) = rte_los[0];
4588 out1 <<
" --- WARNING ---, path is totally outside of the " 4589 <<
"model atmosphere\n";
4594 ppath.
r[0] = refellipsoid[0] + z_field(lp, 0, 0);
4595 ppath.
pos(0, 0) = z_field(lp, 0, 0);
4604 ppath.
gp_p[0].idx = lp - 1;
4605 ppath.
gp_p[0].fd[0] = 1;
4606 ppath.
gp_p[0].fd[1] = 0;
4609 if (cloudbox_on && cloudbox_limits[1] == lp) {
4617 else if (atmosphere_dim == 2) {
4619 ppath.
end_pos[0] = rte_pos[0];
4620 ppath.
end_pos[1] = rte_pos[1];
4621 ppath.
end_los[0] = rte_los[0];
4630 bool islatin =
false;
4633 if (rte_pos[1] > lat_grid[0] && rte_pos[1] < lat_grid[llat]) {
4635 gridpos(gp_lat, lat_grid, rte_pos[1]);
4637 z_toa =
interp(itw, z_field(lp,
joker, 0), gp_lat);
4638 r_e =
refell2d(refellipsoid, lat_grid, gp_lat);
4640 r_e =
refell2r(refellipsoid, rte_pos[1]);
4644 if (islatin && rte_pos[0] < z_toa) {
4648 if ((rte_pos[0] +
RTOL) < z_s) {
4650 os <<
"The ppath starting point is placed " << (z_s - rte_pos[0]) / 1e3
4651 <<
" km below the surface.";
4652 throw runtime_error(os.
str());
4657 ppath.
r[0] = r_e + rte_pos[0];
4677 if (ppath.
pos(0, 0) <= z_s) {
4683 z_surface(
joker, 0),
4700 if (cloudbox_on && !ppath_inside_cloudbox_do) {
4703 if (fgp >= (
Numeric)cloudbox_limits[0] &&
4704 fgp <= (
Numeric)cloudbox_limits[1] &&
4705 fgl >= (
Numeric)cloudbox_limits[2] &&
4706 fgl <= (
Numeric)cloudbox_limits[3]) {
4715 assert(fgp >= (
Numeric)cloudbox_limits[0] &&
4716 fgp <= (
Numeric)cloudbox_limits[1] &&
4717 fgl >= (
Numeric)cloudbox_limits[2] &&
4718 fgl <= (
Numeric)cloudbox_limits[3]);
4725 if ((rte_pos[1] <= lat_grid[0] && rte_los[0] <= 0) ||
4726 (rte_pos[1] >= lat_grid[llat] && rte_los[0] >= 0)) {
4728 os <<
"The sensor is outside (or at the limit) of the model " 4729 <<
"atmosphere but\nlooks in the wrong direction (wrong sign " 4730 <<
"for the zenith angle?).\nThis case includes nadir " 4731 <<
"looking exactly at the latitude end points.";
4732 throw runtime_error(os.
str());
4738 const Numeric r_p = r_e + rte_pos[0];
4743 Numeric r_toa_min = 99e99, r_toa_max = -1;
4744 for (
Index ilat = 0; ilat <= llat; ilat++) {
4746 refell2r(refellipsoid, lat_grid[ilat]) + z_field(lp, ilat, 0);
4747 if (r_toa[ilat] < r_toa_min) {
4748 r_toa_min = r_toa[ilat];
4750 if (r_toa[ilat] > r_toa_max) {
4751 r_toa_max = r_toa[ilat];
4754 if (r_p <= r_toa_max) {
4756 os <<
"The sensor is horizontally outside (or at the limit) of " 4757 <<
"the model\natmosphere, but is at a radius smaller than " 4758 <<
"the maximum value of\nthe top-of-the-atmosphere radii. " 4759 <<
"This is not allowed. Make the\nmodel atmosphere larger " 4760 <<
"to also cover the sensor position?";
4761 throw runtime_error(os.
str());
4765 if (
abs(rte_los[0]) <= 90) {
4766 ppath.
pos(0, 0) = rte_pos[0];
4767 ppath.
pos(0, 1) = rte_pos[1];
4768 ppath.
r[0] = r_e + rte_pos[0];
4769 ppath.
los(0, 0) = rte_los[0];
4772 out1 <<
" ------- WARNING -------: path is totally outside of " 4773 <<
"the model atmosphere\n";
4778 bool above =
false, ready =
false, failed =
false;
4788 if (islatin || ppath.
constant > r_toa_min) {
4797 while (!ready && !failed) {
4807 latt, lt, rt, r_p, rte_pos[1], rte_los[0], ppath.
constant);
4811 if (latt < lat_grid[0] || latt > lat_grid[llat]) {
4818 if (
abs(lt - lt_old) <
LACC) {
4824 gridpos(gp_latt, lat_grid, latt);
4826 rt =
interp(itwt, r_toa, gp_latt);
4833 os <<
"The path does not enter the model atmosphere. It " 4834 <<
"reaches the\ntop of the atmosphere " 4835 <<
"altitude around latitude " << latt <<
" deg.";
4836 throw runtime_error(os.
str());
4838 ppath.
pos(0, 0) = rte_pos[0];
4839 ppath.
pos(0, 1) = rte_pos[1];
4840 ppath.
r[0] = r_e + rte_pos[0];
4841 ppath.
los(0, 0) = rte_los[0];
4844 out1 <<
" ------- WARNING -------: path is totally outside " 4845 <<
"of the model atmosphere\n";
4856 ppath.
gp_p[0].idx = lp - 1;
4857 ppath.
gp_p[0].fd[0] = 1;
4858 ppath.
gp_p[0].fd[1] = 0;
4864 if (cloudbox_on && cloudbox_limits[1] == lp) {
4866 if (fgp >= (
Numeric)cloudbox_limits[2] &&
4867 fgp <= (
Numeric)cloudbox_limits[3]) {
4884 resolve_lon(lon2use, lon_grid[0], lon_grid[llon]);
4887 ppath.
end_pos[0] = rte_pos[0];
4888 ppath.
end_pos[1] = rte_pos[1];
4890 ppath.
end_los[0] = rte_los[0];
4891 ppath.
end_los[1] = rte_los[1];
4897 bool islatlonin =
false;
4901 if (rte_pos[1] >= lat_grid[0] && rte_pos[1] <= lat_grid[llat] &&
4902 lon2use >= lon_grid[0] && lon2use <= lon_grid[llon]) {
4904 gridpos(gp_lat, lat_grid, rte_pos[1]);
4905 gridpos(gp_lon, lon_grid, lon2use);
4908 r_e =
refell2d(refellipsoid, lat_grid, gp_lat);
4910 r_e =
refell2r(refellipsoid, rte_pos[1]);
4914 if (islatlonin && rte_pos[0] < z_toa) {
4918 if ((rte_pos[0] +
RTOL) < z_s) {
4920 os <<
"The ppath starting point is placed " << (z_s - rte_pos[0]) / 1e3
4921 <<
" km below the surface.";
4922 throw runtime_error(os.
str());
4927 ppath.
r[0] = r_e + rte_pos[0];
4947 if (ppath.
pos(0, 0) <= z_s) {
4973 if (cloudbox_on && !ppath_inside_cloudbox_do) {
4977 if (fgp >= (
Numeric)cloudbox_limits[0] &&
4978 fgp <= (
Numeric)cloudbox_limits[1] &&
4979 fgl >= (
Numeric)cloudbox_limits[2] &&
4980 fgl <= (
Numeric)cloudbox_limits[3] &&
4981 fgo >= (
Numeric)cloudbox_limits[4] &&
4982 fgo <= (
Numeric)cloudbox_limits[5]) {
4992 assert(fgp >= (
Numeric)cloudbox_limits[0] &&
4993 fgp <= (
Numeric)cloudbox_limits[1] &&
4994 fgl >= (
Numeric)cloudbox_limits[2] &&
4995 fgl <= (
Numeric)cloudbox_limits[3] &&
4996 fgo >= (
Numeric)cloudbox_limits[4] &&
4997 fgo <= (
Numeric)cloudbox_limits[5]);
5006 const Numeric r_p = r_e + rte_pos[0];
5010 Matrix r_toa(llat + 1, llon + 1);
5011 Numeric r_toa_min = 99e99, r_toa_max = -1;
5012 for (
Index ilat = 0; ilat <= llat; ilat++) {
5014 for (
Index ilon = 0; ilon <= llon; ilon++) {
5015 r_toa(ilat, ilon) = r_lat + z_field(lp, ilat, ilon);
5016 if (r_toa(ilat, ilon) < r_toa_min) {
5017 r_toa_min = r_toa(ilat, ilon);
5019 if (r_toa(ilat, ilon) > r_toa_max) {
5020 r_toa_max = r_toa(ilat, ilon);
5025 if (r_p <= r_toa_max) {
5027 os <<
"The sensor is horizontally outside (or at the limit) of " 5028 <<
"the model\natmosphere, but is at a radius smaller than " 5029 <<
"the maximum value of\nthe top-of-the-atmosphere radii. " 5030 <<
"This is not allowed. Make the\nmodel atmosphere larger " 5031 <<
"to also cover the sensor position?";
5032 throw runtime_error(os.
str());
5036 if (rte_los[0] <= 90) {
5037 ppath.
pos(0, 0) = rte_pos[0];
5038 ppath.
pos(0, 1) = rte_pos[1];
5039 ppath.
pos(0, 2) = rte_pos[2];
5040 ppath.
r[0] = r_e + rte_pos[0];
5041 ppath.
los(0, 0) = rte_los[0];
5042 ppath.
los(0, 1) = rte_los[1];
5045 out1 <<
" ------- WARNING -------: path is totally outside of " 5046 <<
"the model atmosphere\n";
5051 bool above =
false, ready =
false, failed =
false;
5061 if (islatlonin || ppath.
constant > r_toa_min) {
5084 while (!ready && !failed) {
5111 if (latt < lat_grid[0] || latt > lat_grid[llat] ||
5112 lont < lon_grid[0] || lont > lon_grid[llon]) {
5119 if (
abs(lt - lt_old) <
LACC) {
5125 gridpos(gp_latt, lat_grid, latt);
5126 gridpos(gp_lont, lon_grid, lont);
5128 rt =
interp(itwt, r_toa, gp_latt, gp_lont);
5135 os <<
"The path does not enter the model atmosphere. It\n" 5136 <<
"reaches the top of the atmosphere altitude around:\n" 5137 <<
" lat: " << latt <<
" deg.\n lon: " << lont <<
" deg.";
5138 throw runtime_error(os.
str());
5140 ppath.
pos(0, 0) = rte_pos[0];
5141 ppath.
pos(0, 1) = rte_pos[1];
5143 ppath.
r[0] = r_e + rte_pos[0];
5144 ppath.
los(0, 0) = rte_los[0];
5145 ppath.
los(0, 1) = rte_los[1];
5148 out1 <<
" ------- WARNING -------: path is totally outside " 5149 <<
"of the model atmosphere\n";
5173 assert(
abs(ppath.
r[0] - rt) <
RTOL);
5181 ppath.
gp_p[0].idx = lp - 1;
5182 ppath.
gp_p[0].fd[0] = 1;
5183 ppath.
gp_p[0].fd[1] = 0;
5190 if (cloudbox_on && cloudbox_limits[1] == lp) {
5193 if (fgp1 >= (
Numeric)cloudbox_limits[2] &&
5194 fgp1 <= (
Numeric)cloudbox_limits[3] &&
5195 fgp2 >= (
Numeric)cloudbox_limits[4] &&
5196 fgp2 <= (
Numeric)cloudbox_limits[5]) {
5208 const Agenda& ppath_step_agenda,
5209 const Index& atmosphere_dim,
5215 const Vector& refellipsoid,
5217 const Index& cloudbox_on,
5222 const Numeric& ppath_lraytrace,
5223 const bool& ppath_inside_cloudbox_do,
5233 if (ppath_inside_cloudbox_do && !cloudbox_on)
5234 throw runtime_error(
5235 "The WSV *ppath_inside_cloudbox_do* can only be set " 5236 "to 1 if also *cloudbox_on* is 1.");
5260 ppath_inside_cloudbox_do,
5310 if (istep > (
Index)1e4)
5311 throw runtime_error(
5312 "10 000 path points have been reached. Is this an infinite loop?");
5319 if (!ppath_inside_cloudbox_do) {
5324 (
abs(ppath_step.
los(n - 1, 0)) < 90 &&
5330 if (atmosphere_dim == 2) {
5334 os <<
"The path exits the atmosphere through the lower " 5335 <<
"latitude end face.\nThe exit point is at an altitude" 5336 <<
" of " << ppath_step.
pos(n - 1, 0) / 1e3 <<
" km.";
5337 throw runtime_error(os.
str());
5341 os <<
"The path exits the atmosphere through the upper " 5342 <<
"latitude end face.\nThe exit point is at an altitude" 5343 <<
" of " << ppath_step.
pos(n - 1, 0) / 1e3 <<
" km.";
5344 throw runtime_error(os.
str());
5347 if (atmosphere_dim == 3) {
5349 if (lat_grid[0] > -90 &&
5352 os <<
"The path exits the atmosphere through the lower " 5353 <<
"latitude end face.\nThe exit point is at an altitude" 5354 <<
" of " << ppath_step.
pos(n - 1, 0) / 1e3 <<
" km.";
5355 throw runtime_error(os.
str());
5357 if (lat_grid[imax_lat] < 90 &&
5360 os <<
"The path exits the atmosphere through the upper " 5361 <<
"latitude end face.\nThe exit point is at an altitude" 5362 <<
" of " << ppath_step.
pos(n - 1, 0) / 1e3 <<
" km.";
5363 throw runtime_error(os.
str());
5370 ppath_step.
los(n - 1, 1) < 0 &&
5371 abs(ppath_step.
pos(n - 1, 1)) < 90) {
5373 if (lon_grid[imax_lon] - lon_grid[0] >= 360) {
5374 ppath_step.
pos(n - 1, 2) = ppath_step.
pos(n - 1, 2) + 360;
5376 ppath_step.
gp_lon[n - 1], lon_grid, ppath_step.
pos(n - 1, 2));
5379 os <<
"The path exits the atmosphere through the lower " 5380 <<
"longitude end face.\nThe exit point is at an " 5381 <<
"altitude of " << ppath_step.
pos(n - 1, 0) / 1e3 <<
" km.";
5382 throw runtime_error(os.
str());
5385 ppath_step.
los(n - 1, 1) > 0 &&
5386 abs(ppath_step.
pos(n - 1, 1)) < 90) {
5388 if (lon_grid[imax_lon] - lon_grid[0] >= 360) {
5389 ppath_step.
pos(n - 1, 2) = ppath_step.
pos(n - 1, 2) - 360;
5391 ppath_step.
gp_lon[n - 1], lon_grid, ppath_step.
pos(n - 1, 2));
5394 os <<
"The path exits the atmosphere through the upper " 5395 <<
"longitude end face.\nThe exit point is at an " 5396 <<
"altitude of " << ppath_step.
pos(n - 1, 0) / 1e3 <<
" km.";
5397 throw runtime_error(os.
str());
5406 if (ipos >=
Numeric(cloudbox_limits[0]) &&
5407 ipos <=
Numeric(cloudbox_limits[1])) {
5408 if (atmosphere_dim == 1) {
5413 if (ipos >=
Numeric(cloudbox_limits[2]) &&
5414 ipos <=
Numeric(cloudbox_limits[3])) {
5415 if (atmosphere_dim == 2) {
5420 if (ipos >=
Numeric(cloudbox_limits[4]) &&
5421 ipos <=
Numeric(cloudbox_limits[5])) {
5441 assert(ipos1 >= (
Numeric)cloudbox_limits[0]);
5442 assert(ipos1 <= (
Numeric)cloudbox_limits[1]);
5443 if (ipos1 <= (
Numeric)cloudbox_limits[0] && ipos1 < ipos2) {
5447 else if (ipos1 >=
Numeric(cloudbox_limits[1]) && ipos1 > ipos2) {
5451 else if (atmosphere_dim > 1) {
5455 assert(ipos1 >= (
Numeric)cloudbox_limits[2]);
5456 assert(ipos1 <= (
Numeric)cloudbox_limits[3]);
5457 if (ipos1 <=
Numeric(cloudbox_limits[2]) && ipos1 < ipos2) {
5461 else if (ipos1 >=
Numeric(cloudbox_limits[3]) && ipos1 > ipos2) {
5465 else if (atmosphere_dim > 2) {
5469 assert(ipos1 >= (
Numeric)cloudbox_limits[4]);
5470 assert(ipos1 <= (
Numeric)cloudbox_limits[5]);
5471 if (ipos1 <=
Numeric(cloudbox_limits[4]) && ipos1 < ipos2) {
5475 else if (ipos1 >=
Numeric(cloudbox_limits[5]) && ipos1 > ipos2) {
5493 ppath_array.push_back(ppath_step);
5540 ppath.
r[
Range(np, n - i1)] = ppath_array[
i].r[
Range(i1, n - i1)];
5547 ppath_array[
i].ngroup[
Range(i1, n - i1)];
5548 ppath.
lstep[
Range(np - i1, n - 1)] = ppath_array[
i].lstep;
5551 for (
Index j = i1; j < n; j++) {
5552 ppath.
gp_p[np + j - i1] = ppath_array[
i].gp_p[j];
5554 if (atmosphere_dim >= 2) {
5555 for (
Index j = i1; j < n; j++) {
5556 ppath.
gp_lat[np + j - i1] = ppath_array[
i].gp_lat[j];
5559 if (atmosphere_dim == 3) {
5560 for (
Index j = i1; j < n; j++) {
5561 ppath.
gp_lon[np + j - i1] = ppath_array[
i].gp_lon[j];
INDEX Index
The type to use for all integer numbers and indices.
void latlon_at_aa(Numeric &lat2, Numeric &lon2, const Numeric &lat1, const Numeric &lon1, const Numeric &aa, const Numeric &ddeg)
latlon_at_aa
void get_refr_index_2d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat)
get_refr_index_2d
ArrayOfGridPos gp_lat
Index position with respect to the latitude grid.
void ppath_calc(Workspace &ws, Ppath &ppath, const Agenda &ppath_step_agenda, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Vector &f_grid, const Vector &refellipsoid, const Matrix &z_surface, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Vector &rte_pos, const Vector &rte_los, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const bool &ppath_inside_cloudbox_do, const Verbosity &verbosity)
This is the core for the WSM ppathStepByStep.
bool is_lon_cyclic(ConstVectorView grid, const Numeric &epsilon)
Check if the given longitude grid is cyclic.
void get_refr_index_3d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat, const Numeric &lon)
Numeric geompath_za_at_r(const Numeric &ppc, const Numeric &a_za, const Numeric &r)
Calculates the zenith angle for a given radius along a geometrical propagation path.
const Numeric LON_NOT_FOUND
Numeric constant
The propagation path constant (only used for 1D)
Index nelem() const
Number of elements.
Declarations having to do with the four output streams.
void zaaa2cart(Numeric &dx, Numeric &dy, Numeric &dz, const Numeric &za, const Numeric &aa)
Converts zenith and azimuth angles to a cartesian unit vector.
Contains the code to determine roots of polynomials.
Numeric refraction_ppc(const Numeric &r, const Numeric &za, const Numeric &refr_index_air)
Calculates the propagation path constant for cases with refraction.
void ppath_copy(Ppath &ppath1, const Ppath &ppath2, const Index &ncopy)
Copy the content in ppath2 to ppath1.
Matrix los
Line-of-sight at each ppath point.
void ppath_start_stepping(Ppath &ppath, const Index &atmosphere_dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstMatrixView z_surface, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const bool &ppath_inside_cloudbox_do, ConstVectorView rte_pos, ConstVectorView rte_los, const Verbosity &verbosity)
Initiates a Ppath structure for calculation of a path with ppath_step.
void raytrace_3d_linear_basic(Workspace &ws, Array< Numeric > &r_array, Array< Numeric > &lat_array, Array< Numeric > &lon_array, Array< Numeric > &za_array, Array< Numeric > &aa_array, Array< Numeric > &l_array, Array< Numeric > &n_array, Array< Numeric > &ng_array, Index &endface, ConstVectorView refellipsoid, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &lmax, const Agenda &refr_index_air_agenda, const Numeric &lraytrace, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &rsurface15, const Numeric &rsurface35, const Numeric &rsurface36, const Numeric &rsurface16, const Numeric &r15a, const Numeric &r35a, const Numeric &r36a, const Numeric &r16a, const Numeric &r15b, const Numeric &r35b, const Numeric &r36b, const Numeric &r16b, Numeric r, Numeric lat, Numeric lon, Numeric za, Numeric aa)
Performs ray tracing for 3D with linear steps.
Numeric geompath_r_at_l(const Numeric &ppc, const Numeric &l)
Calculates the radius for a distance from the tangent point.
void do_gridcell_2d_byltest(Vector &r_v, Vector &lat_v, Vector &za_v, Numeric &lstep, Index &endface, const Numeric &r_start0, const Numeric &lat_start0, const Numeric &za_start, const Numeric &l_start, const Index &icall, const Numeric &ppc, const Numeric &lmax, const Numeric &lat1, const Numeric &lat3, const Numeric &r1a, const Numeric &r3a, const Numeric &r3b, const Numeric &r1b, const Numeric &rsurface1, const Numeric &rsurface3)
Works as do_gridcell_3d_byltest, but downscaled to 2D.
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
Vector end_pos
End position.
void raytrace_2d_linear_basic(Workspace &ws, Array< Numeric > &r_array, Array< Numeric > &lat_array, Array< Numeric > &za_array, Array< Numeric > &l_array, Array< Numeric > &n_array, Array< Numeric > &ng_array, Index &endface, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &lmax, const Agenda &refr_index_air_agenda, const Numeric &lraytrace, const Numeric &lat1, const Numeric &lat3, const Numeric &rsurface1, const Numeric &rsurface3, const Numeric &r1a, const Numeric &r3a, const Numeric &r3b, const Numeric &r1b, Numeric r, Numeric lat, Numeric za)
Performs ray tracing for 2D with linear steps.
Index dim
Atmospheric dimensionality.
void find_tanpoint(Index &it, const Ppath &ppath)
Identifies the tangent point of a propagation path.
void ppath_step_refr_2d(Workspace &ws, Ppath &ppath, ConstVectorView p_grid, ConstVectorView lat_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, ConstVectorView refellipsoid, ConstVectorView z_surface, const Numeric &lmax, const Agenda &refr_index_air_agenda, const String &rtrace_method, const Numeric &lraytrace)
Calculates 2D propagation path steps, with refraction, using a simple and fast ray tracing scheme...
void ppath_step_agendaExecute(Workspace &ws, Ppath &ppath_step, const Numeric ppath_lmax, const Numeric ppath_lraytrace, const Vector &f_grid, const Agenda &input_agenda)
Vector lstep
The length between ppath points.
void rotationmat3D(Matrix &R, ConstVectorView vrot, const Numeric &a)
Creates a 3D rotation matrix.
void ppath_step_geom_3d(Ppath &ppath, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstMatrixView z_surface, const Numeric &lmax)
Calculates 3D geometrical propagation path steps.
void cart2zaaa(Numeric &za, Numeric &aa, const Numeric &dx, const Numeric &dy, const Numeric &dz)
Converts a cartesian directional vector to zenith and azimuth.
void ppath_end_2d(Ppath &ppath, ConstVectorView r_v, ConstVectorView lat_v, ConstVectorView za_v, ConstVectorView lstep, ConstVectorView n_v, ConstVectorView ng_v, ConstVectorView lat_grid, ConstMatrixView z_field, ConstVectorView refellipsoid, const Index &ip, const Index &ilat, const Index &endface, const Numeric &ppc)
Internal help function for 2D path calculations.
invlib::Vector< ArtsVector > Vector
invlib wrapper type for ARTS vectors.
Numeric fractional_gp(const GridPos &gp)
fractional_gp
cmplx FADDEEVA() w(cmplx z, double relerr)
Matrix pos
The distance between start pos and the last position in pos.
void plevel_slope_3d(Numeric &c1, Numeric &c2, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15, const Numeric &r35, const Numeric &r36, const Numeric &r16, const Numeric &lat, const Numeric &lon, const Numeric &aa)
Vector ngroup
The group index of refraction.
void raytrace_1d_linear_basic(Workspace &ws, Array< Numeric > &r_array, Array< Numeric > &lat_array, Array< Numeric > &za_array, Array< Numeric > &l_array, Array< Numeric > &n_array, Array< Numeric > &ng_array, Index &endface, ConstVectorView p_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &lmax, const Agenda &refr_index_air_agenda, const Numeric &lraytrace, const Numeric &rsurface, const Numeric &r1, const Numeric &r3, Numeric r, Numeric lat, Numeric za)
Performs ray tracing for 1D with linear steps.
Numeric refell2d(ConstVectorView refellipsoid, ConstVectorView lat_grid, const GridPos gp)
refell2d
Index gridpos2gridrange(const GridPos &gp, const bool &upwards)
gridpos2gridrange
Vector start_pos
Start position.
Vector r
Radius of each ppath point.
Numeric rslope_crossing3d(const Numeric &rp, const Numeric &za, const Numeric &r0, Numeric c1, Numeric c2)
3D version of rslope_crossing2d.
const Numeric LAT_NOT_FOUND
void get_refr_index_1d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r)
get_refr_index_1d
Numeric geompath_lat_at_za(const Numeric &za0, const Numeric &lat0, const Numeric &za)
Calculates the latitude for a given zenith angle along a geometrical propagation path.
bool is_gridpos_at_index_i(const GridPos &gp, const Index &i, const bool &strict)
is_gridpos_at_index_i
void resolve_lon(Numeric &lon, const Numeric &lon5, const Numeric &lon6)
Resolves which longitude angle that shall be used.
Index nelem() const
Returns the number of elements.
Numeric geometrical_ppc(const Numeric &r, const Numeric &za)
Calculates the propagation path constant for pure geometrical calculations.
Structure to store a grid position.
A constant view of a Tensor4.
Index ppath_what_background(const Ppath &ppath)
Returns the case number for the radiative background.
Numeric end_lstep
The distance between end pos and the first position in pos.
Numeric sign(const Numeric &x)
sign
const Numeric L_NOT_FOUND
This file contains the definition of Array.
void gridpos_check_fd(GridPos &gp)
gridpos_check_fd
void plevel_slope_2d(Numeric &c1, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstVectorView z_surf, const GridPos &gp, const Numeric &za)
Calculates the radial slope of the surface or a pressure level for 2D.
Vector end_los
End line-of-sight.
void diff_za_aa(Numeric &dza, Numeric &daa, const Numeric &za0, const Numeric &aa0, const Numeric &za, const Numeric &aa)
Takes the difference of zenith and azimuth angles.
Index ncols() const
Returns the number of columns.
void ppath_set_background(Ppath &ppath, const Index &case_nr)
Sets the background field of a Ppath structure.
String background
Radiative background.
Numeric rslope_crossing2d(const Numeric &rp, const Numeric &za, const Numeric &r0, Numeric c1)
Calculates the angular distance to a crossing with a level having a radial slope. ...
void do_gridrange_1d(Vector &r_v, Vector &lat_v, Vector &za_v, Numeric &lstep, Index &endface, const Numeric &r_start0, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc, const Numeric &lmax, const Numeric &ra, const Numeric &rb, const Numeric &rsurface)
Calculates the geometrical path through a 1D grid range.
void geompath_from_r1_to_r2(Vector &r, Vector &lat, Vector &za, Numeric &lstep, const Numeric &ppc, const Numeric &r1, const Numeric &lat1, const Numeric &za1, const Numeric &r2, const bool &tanpoint, const Numeric &lmax)
Determines radii, latitudes and zenith angles between two points of a propagation path...
_CS_string_type str() const
void ppath_end_1d(Ppath &ppath, ConstVectorView r_v, ConstVectorView lat_v, ConstVectorView za_v, ConstVectorView lstep, ConstVectorView n_v, ConstVectorView ng_v, ConstVectorView z_field, ConstVectorView refellipsoid, const Index &ip, const Index &endface, const Numeric &ppc)
Internal help function for 1D path calculations.
const Numeric ANGTOL
Width of zenith and nadir directions.
void ppath_end_3d(Ppath &ppath, ConstVectorView r_v, ConstVectorView lat_v, ConstVectorView lon_v, ConstVectorView za_v, ConstVectorView aa_v, ConstVectorView lstep, ConstVectorView n_v, ConstVectorView ng_v, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, const Index &ip, const Index &ilat, const Index &ilon, const Index &endface, const Numeric &ppc)
Internal help function for 3D path calculations.
void do_gridcell_3d_byltest(Vector &r_v, Vector &lat_v, Vector &lon_v, Vector &za_v, Vector &aa_v, Numeric &lstep, Index &endface, const Numeric &r_start0, const Numeric &lat_start0, const Numeric &lon_start0, const Numeric &za_start, const Numeric &aa_start, const Numeric &l_start, const Index &icall, const Numeric &ppc, const Numeric &lmax, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15a, const Numeric &r35a, const Numeric &r36a, const Numeric &r16a, const Numeric &r15b, const Numeric &r35b, const Numeric &r36b, const Numeric &r16b, const Numeric &rsurface15, const Numeric &rsurface35, const Numeric &rsurface36, const Numeric &rsurface16)
See ATD for a description of the algorithm.
Declarations for agendas.
void ppath_init_structure(Ppath &ppath, const Index &atmosphere_dim, const Index &np)
Initiates a Ppath structure to hold the given number of points.
void cart2poslos(Numeric &r, Numeric &lat, Numeric &za, const Numeric &x, const Numeric &z, const Numeric &dx, const Numeric &dz, const Numeric &ppc, const Numeric &lat0, const Numeric &za0)
cart2poslos
Numeric start_lstep
Length between sensor and atmospheric boundary.
void add_za_aa(Numeric &za, Numeric &aa, const Numeric &za0, const Numeric &aa0, const Numeric &dza, const Numeric &daa)
Adds up zenith and azimuth angles.
void ppath_append(Ppath &ppath1, const Ppath &ppath2)
Combines two Ppath structures.
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
Index first_pos_before_altitude(const Ppath &p, const Numeric &alt)
Determines ppath position just below an altitude.
void ppath_start_1d(Numeric &r_start, Numeric &lat_start, Numeric &za_start, Index &ip, const Ppath &ppath)
Internal help function for 1D path calculations.
const Numeric R_NOT_FOUND
NUMERIC Numeric
The type to use for all floating point numbers.
Vector nreal
The real part of the refractive index at each path position.
Numeric plevel_angletilt(const Numeric &r, const Numeric &c1)
Calculates the angular tilt of the surface or a pressure level.
void refr_gradients_3d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, Numeric &dndr, Numeric &dndlat, Numeric &dndlon, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat, const Numeric &lon)
refr_gradients_3d
Numeric refell2r(ConstVectorView refellipsoid, const Numeric &lat)
refell2r
void error_if_limb_ppath(const Ppath &ppath)
Throws an error if ppath altitudes not are strictly increasing or decreasing.
void gridpos_copy(GridPos &gp_new, const GridPos &gp_old)
gridpos_copy
bool is_los_downwards(const Numeric &za, const Numeric &tilt)
Determines if a line-of-sight is downwards compared to the angular tilt of the surface or a pressure ...
Header file for special_interp.cc.
Propagation path structure and functions.
void ppath_step_geom_2d(Ppath &ppath, ConstVectorView lat_grid, ConstMatrixView z_field, ConstVectorView refellipsoid, ConstVectorView z_surface, const Numeric &lmax)
Calculates 2D geometrical propagation path steps.
void ppath_step_geom_1d(Ppath &ppath, ConstVectorView z_field, ConstVectorView refellipsoid, const Numeric &z_surface, const Numeric &lmax)
Calculates 1D geometrical propagation path steps.
void mult(ComplexVectorView y, const ConstComplexMatrixView &M, const ConstComplexVectorView &x)
Matrix-Vector Multiplication.
void ppath_start_3d(Numeric &r_start, Numeric &lat_start, Numeric &lon_start, Numeric &za_start, Numeric &aa_start, Index &ip, Index &ilat, Index &ilon, Numeric &lat1, Numeric &lat3, Numeric &lon5, Numeric &lon6, Numeric &r15a, Numeric &r35a, Numeric &r36a, Numeric &r16a, Numeric &r15b, Numeric &r35b, Numeric &r36b, Numeric &r16b, Numeric &rsurface15, Numeric &rsurface35, Numeric &rsurface36, Numeric &rsurface16, Ppath &ppath, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstMatrixView z_surface)
Internal help function for 3D path calculations.
void r_crossing_3d(Numeric &lat, Numeric &lon, Numeric &l, const Numeric &r_hit, const Numeric &r_start, const Numeric &lat_start, const Numeric &lon_start, const Numeric &za_start, const Numeric &ppc, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &dx, const Numeric &dy, const Numeric &dz)
Calculates where a 3D LOS crosses the specified radius.
void r_crossing_2d(Numeric &lat, Numeric &l, const Numeric &r_hit, const Numeric &r_start, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc)
Calculates where a 2D LOS crosses the specified radius.
Header file for logic.cc.
Numeric rsurf_at_latlon(const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15, const Numeric &r35, const Numeric &r36, const Numeric &r16, const Numeric &lat, const Numeric &lon)
Determines the radius of a pressure level or the surface given the radius at the corners of a 3D grid...
This can be used to make arrays out of anything.
void adjust_los(VectorView los, const Index &atmosphere_dim)
Ensures that the zenith and azimuth angles of a line-of-sight vector are inside defined ranges...
Numeric geompath_r_at_lat(const Numeric &ppc, const Numeric &lat0, const Numeric &za0, const Numeric &lat)
Calculates the radius for a given latitude.
void ppath_step_refr_1d(Workspace &ws, Ppath &ppath, ConstVectorView p_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, ConstVectorView refellipsoid, const Numeric &z_surface, const Numeric &lmax, const Agenda &refr_index_air_agenda, const String &rtrace_method, const Numeric &lraytrace)
Calculates 1D propagation path steps including effects of refraction.
void rte_pos2gridpos(GridPos &gp_p, GridPos &gp_lat, GridPos &gp_lon, const Index &atmosphere_dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView rte_pos)
Converts a geographical position (rte_pos) to grid positions for p, lat and lon.
void cart2pol(Numeric &r, Numeric &lat, const Numeric &x, const Numeric &z, const Numeric &lat0, const Numeric &za0)
cart2pol
void resize(Index n)
Resize function.
A constant view of a Tensor3.
A constant view of a Vector.
Index np
Number of points describing the ppath.
ArrayOfGridPos gp_lon
Index position with respect to the longitude grid.
void ppath_start_2d(Numeric &r_start, Numeric &lat_start, Numeric &za_start, Index &ip, Index &ilat, Numeric &lat1, Numeric &lat3, Numeric &r1a, Numeric &r3a, Numeric &r3b, Numeric &r1b, Numeric &rsurface1, Numeric &rsurface3, Ppath &ppath, ConstVectorView lat_grid, ConstMatrixView z_field, ConstVectorView refellipsoid, ConstVectorView z_surface)
Internal help function for 2D path calculations.
void refr_gradients_1d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, Numeric &dndr, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r)
refr_gradients_1d
A constant view of a Matrix.
void refr_gradients_2d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, Numeric &dndr, Numeric &dndlat, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat)
refr_gradients_2d
Vector start_los
Start line-of-sight.
void cart2sph(Numeric &r, Numeric &lat, Numeric &lon, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &lat0, const Numeric &lon0, const Numeric &za0, const Numeric &aa0)
cart2sph
Numeric geompath_r_at_za(const Numeric &ppc, const Numeric &za)
Calculates the zenith angle for a given radius along a geometrical propagation path.
Numeric rsurf_at_lat(const Numeric &lat1, const Numeric &lat3, const Numeric &r1, const Numeric &r3, const Numeric &lat)
Determines the radius of a pressure level or the surface given the radius at the corners of a 2D grid...
The structure to describe a propagation path and releated quantities.
Header file for helper functions for OpenMP.
void ppath_step_refr_3d(Workspace &ws, Ppath &ppath, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, ConstVectorView refellipsoid, ConstMatrixView z_surface, const Numeric &lmax, const Agenda &refr_index_air_agenda, const String &rtrace_method, const Numeric &lraytrace)
Calculates 3D propagation path steps, with refraction, using a simple and fast ray tracing scheme...
void plevel_crossing_2d(Numeric &r, Numeric &lat, Numeric &l, const Numeric &r_start0, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc, const Numeric &lat1, const Numeric &lat3, const Numeric &r1, const Numeric &r3, const bool &above)
Handles the crossing with a geometric ppaths step and a atmospheric grid box level for 2D...
const Numeric POLELAT
Size of north and south poles.
int poly_root_solve(Matrix &roots, Vector &coeffs)
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
void poslos2cart(Numeric &x, Numeric &z, Numeric &dx, Numeric &dz, const Numeric &r, const Numeric &lat, const Numeric &za)
poslos2cart
Index nrows() const
Returns the number of rows.
ArrayOfGridPos gp_p
Index position with respect to the pressure grid.
Numeric geompath_l_at_r(const Numeric &ppc, const Numeric &r)
Calculates the length from the tangent point for the given radius.
void gridpos_force_end_fd(GridPos &gp, const Index &n)
gridpos_force_end_fd
This file contains the definition of String, the ARTS string class.
Declaration of functions in rte.cc.
Numeric sqrt(const Rational r)
Square root.
void resize(Index r, Index c)
Resize function.