113 if (
abs(a_za) > 90) {
154 ARTS_ASSERT((za0 >= 0 && za >= 0) || (za0 < 0 && za < 0));
156 return lat0 + za0 - za;
164 return sqrt(r * r - ppc * ppc);
173 return sqrt(l * l + ppc * ppc);
194 ARTS_ASSERT((za0 >= 0 && lat >= lat0) || (za0 <= 0 && lat <= lat0));
197 const Numeric za = za0 + lat0 - lat;
233 const bool& tanpoint,
260 lstep = (l2 - l1) / (
Numeric)n;
271 for (
Index i = 1; i < n; i++) {
288 for (
Index i = 1; i <= n; i++) {
305 const Numeric r =
sqrt(dx * dx + dy * dy + dz * dz);
323 dy = sin(aarad) * dx;
324 dx = cos(aarad) * dx;
333 aa =
RAD2DEG * atan2( de, dn );
369 sqrt(vrot[0] * vrot[0] + vrot[1] * vrot[1] + vrot[2] * vrot[2]);
381 R(0, 0) = u2 + (v2 + w2) *
c;
382 R(0, 1) =
u *
v * (1 -
c) -
w * s;
383 R(0, 2) =
u *
w * (1 -
c) +
v * s;
384 R(1, 0) =
u *
v * (1 -
c) +
w * s;
385 R(1, 1) = v2 + (u2 + w2) *
c;
386 R(1, 2) =
v *
w * (1 -
c) -
u * s;
387 R(2, 0) =
u *
w * (1 -
c) -
v * s;
388 R(2, 1) =
v *
w * (1 -
c) +
u * s;
389 R(2, 2) = w2 + (u2 + v2) *
c;
404 zaaa2cart(xyz[0], xyz[1], xyz[2], 90, aa0);
417 zaaa2cart(xyz[0], xyz[1], xyz[2], 90 + dza, aa0 + daa);
444 zaaa2cart(xyz[0], xyz[1], xyz[2], za0, aa0);
457 zaaa2cart(xyz[0], xyz[1], xyz[2], za, aa);
494 const Numeric& refr_index_air) {
498 return r * refr_index_air * sin(
DEG2RAD *
abs(za));
504 if (lon < lon5 && lon + 180 <= lon6) {
506 }
else if (lon > lon6 && lon - 180 >= lon5) {
514 while (it < ppath.
np - 1 && ppath.
pos(it + 1, 0) < zmin) {
516 zmin = ppath.
pos(it, 0);
518 if (it == 0 || it == ppath.
np - 1) {
525 bool below =
false, above =
false;
528 for (
Index i = 0; i < p.
np; i++) {
529 if (p.
pos(i, 0) < alt) {
530 if (above)
return i - 1;
533 if (below)
return i - 1;
544 for (
Index i = 2; i < ppath.
np; i++) {
546 "A propagation path of limb character found. Such "
547 "viewing geometries are not supported by this method. "
548 "Propagation paths must result in strictly "
549 "increasing or decreasing altitudes.");
577 return r1 + (lat - lat1) * (r3 - r1) / (lat3 - lat1);
588 const Numeric r2 =
refell2r(refellipsoid, lat_grid[i1 + 1]) + z_surf[i1 + 1];
590 c1 = (r2 - r1) / (lat_grid[i1 + 1] - lat_grid[i1]);
614 c1 = (r2 - r1) / (lat2 - lat1);
627 if (za > (90 - tilt) || za < (-90 - tilt)) {
669 if ((r_start >= r_hit && absza <= 90) || ppc > r_hit) {
676 if (absza > 90 && r_start <= r_hit) {
758 p0[0] = r0s - rp * sv;
760 p0[2] = -r0s / 2 + cc;
761 p0[3] = -r0c / 6 - cs / 2;
762 p0[4] = r0s / 24 - cc / 6;
763 p0[5] = r0c / 120 + cs / 24;
764 p0[6] = -r0s / 720 + cc / 120;
771 if (
abs(90 - zaabs) > 89.9) {
773 }
else if (
abs(90 - zaabs) > 75) {
779 int solutionfailure = 1;
781 while (solutionfailure) {
784 p = p0[
Range(0, n + 1)];
786 if (solutionfailure) {
795 if (
abs(r0 - rp) < 1e-9)
803 for (
Index i = 0; i < n; i++) {
804 if (roots(i, 1) == 0 && roots(i, 0) > dmin && roots(i, 0) < dlat) {
870 ARTS_ASSERT(lat_start >= lat1 && lat_start <= lat3);
881 l =
max(1e-9, r - r_start0);
886 else if (absza > 180 -
ANGTOL) {
890 l =
max(1e-9, r_start0 - r);
904 if (rmax - rmin < 1e-6) {
909 if (r_start < rmax) {
913 if (r_start > rmin) {
921 if (lat > lat3 || lat < lat1) {
932 if (r_start < rmin) {
936 if (r_start > rmax) {
944 if (r_start > rmax) {
947 }
else if (r_start < rmin) {
958 if (lat < lat1 || lat > lat3) {
967 const Numeric rpl = r1 + cpl * (lat - lat1);
983 za = lat_start + za_start - lat;
992 if (lat < lat1 || lat > lat3) {
999 r = rpl + cpl * dlat;
1002 za = lat_start + za_start - lat;
1005 if (absza > 90 &&
abs(za) < 90) {
1053 return r15 + (lon - lon5) * (r16 - r15) / (lon6 - lon5);
1054 }
else if (lat == lat3) {
1055 return r35 + (lon - lon5) * (r36 - r35) / (lon6 - lon5);
1056 }
else if (lon == lon5) {
1057 return r15 + (lat - lat1) * (r35 - r15) / (lat3 - lat1);
1058 }
else if (lon == lon6) {
1059 return r16 + (lat - lat1) * (r36 - r16) / (lat3 - lat1);
1061 const Numeric fdlat = (lat - lat1) / (lat3 - lat1);
1062 const Numeric fdlon = (lon - lon5) / (lon6 - lon5);
1063 return (1 - fdlat) * (1 - fdlon) * r15 + fdlat * (1 - fdlon) * r35 +
1064 (1 - fdlat) * fdlon * r16 + fdlat * fdlon * r36;
1082 if (r15 == r35 && r15 == r36 && r15 == r16 && r35 == r36 && r35 == r16 &&
1091 rsurf_at_latlon(lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat, lon);
1104 lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat2, lon2) -
1111 lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat2, lon2) -
1115 c1 = 0.5 * (4 * dr1 - dr2);
1116 c2 = (dr1 - c1) / (dang * dang);
1162 if (lat_grid[llat] >
POLELAT) {
1166 "The upper latitude end of the atmosphere "
1167 "reached, that is not allowed.");
1171 if (ilon >= lon_grid.
nelem() - 1) {
1176 "The upper longitude end of the atmosphere "
1177 "reached, that is not allowed.");
1185 lat =
interp(itw, lat_grid, gp_lat);
1187 lon =
interp(itw, lon_grid, gp_lon);
1190 const Numeric lat1 = lat_grid[ilat];
1191 const Numeric lat3 = lat_grid[ilat + 1];
1192 const Numeric lon5 = lon_grid[ilon];
1193 const Numeric lon6 = lon_grid[ilon + 1];
1196 const Numeric r15 = re1 + z_surf(ilat, ilon);
1197 const Numeric r35 = re3 + z_surf(ilat + 1, ilon);
1198 const Numeric r36 = re3 + z_surf(ilat + 1, ilon + 1);
1199 const Numeric r16 = re1 + z_surf(ilat, ilon + 1);
1202 c1, c2, lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat, lon, aa);
1250 p0[0] = r0s - rp * sv;
1252 p0[2] = -r0s / 2 + c1c + c2s;
1253 p0[3] = -r0c / 6 - c1s / 2 + c2c;
1254 p0[4] = r0s / 24 - c1c / 6 - c2s / 2;
1255 p0[5] = r0c / 120 + c1s / 24 - c2c / 6;
1256 p0[6] = -r0s / 720 + c1c / 120 + c2s / 24;
1264 if (
abs(90 - za) > 89.9) {
1266 }
else if (
abs(90 - za) > 75) {
1272 int solutionfailure = 1;
1274 while (solutionfailure) {
1277 p = p0[
Range(0, n + 1)];
1279 if (solutionfailure) {
1296 for (
Index i = 0; i < n; i++) {
1297 if (roots(i, 1) == 0 && roots(i, 0) > dmin && roots(i, 0) < dlat) {
1364 if ((r_start >= r_hit && za_start <= 90) || ppc > r_hit) {
1372 if (za_start < ANGTOL || za_start > 180 -
ANGTOL) {
1373 l =
abs(r_hit - r_start);
1379 const Numeric p = x * dx + y * dy + z * dz;
1381 const Numeric q = x * x + y * y + z * z - r_hit * r_hit;
1400 lat =
RAD2DEG * asin((z + dz * l) / r_hit);
1401 lon =
RAD2DEG * atan2(y + dy * l, x + dx * l);
1411 const Index& atmosphere_dim,
1417 ppath.
dim = atmosphere_dim;
1438 ppath.
gp_p.resize(np);
1439 if (atmosphere_dim >= 2) {
1441 if (atmosphere_dim == 3) {
1473 "Case number ", case_nr,
" is not defined.")
1484 }
else if (ppath.
background ==
"cloud box level") {
1486 }
else if (ppath.
background ==
"cloud box interior") {
1488 }
else if (ppath.
background ==
"transmitter") {
1493 " is not a valid background case.")
1519 if (n == ppath1.
np) {
1534 for (
Index i = 0; i < n; i++) {
1537 if (ppath1.
dim >= 2) {
1541 if (ppath1.
dim == 3) {
1576 for (
Index i = 1; i < n2; i++) {
1579 ppath1.
pos(i1, 0) = ppath2.
pos(i, 0);
1580 ppath1.
pos(i1, 1) = ppath2.
pos(i, 1);
1581 ppath1.
los(i1, 0) = ppath2.
los(i, 0);
1582 ppath1.
r[i1] = ppath2.
r[i];
1587 if (ppath1.
dim >= 2) {
1591 if (ppath1.
dim == 3) {
1592 ppath1.
pos(i1, 2) = ppath2.
pos(i, 2);
1593 ppath1.
los(i1, 1) = ppath2.
los(i, 1);
1627 const Ppath& ppath) {
1629 const Index imax = ppath.
np - 1;
1632 r_start = ppath.
r[imax];
1633 lat_start = ppath.
pos(imax, 1);
1634 za_start = ppath.
los(imax, 0);
1662 const Index& endface,
1673 const Numeric r1 = refellipsoid[0] + z_field[ip];
1674 const Numeric dr = z_field[ip + 1] - z_field[ip];
1676 for (
Index i = 0; i < np; i++) {
1677 ppath.
r[i] = r_v[i];
1678 ppath.
pos(i, 0) = r_v[i] - refellipsoid[0];
1679 ppath.
pos(i, 1) = lat_v[i];
1680 ppath.
los(i, 0) = za_v[i];
1681 ppath.
nreal[i] = n_v[i];
1682 ppath.
ngroup[i] = ng_v[i];
1684 ppath.
gp_p[i].idx = ip;
1685 ppath.
gp_p[i].fd[0] = (r_v[i] - r1) / dr;
1686 ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
1690 ppath.
lstep[i - 1] = lstep[i - 1];
1701 else if (endface <= 4) {
1735 const Index imax = ppath.
np - 1;
1738 r_start = ppath.
r[imax];
1739 lat_start = ppath.
pos(imax, 1);
1740 za_start = ppath.
los(imax, 0);
1747 lat1 = lat_grid[ilat];
1748 lat3 = lat_grid[ilat + 1];
1761 r1a = re1 + z_field(ip, ilat);
1762 r3a = re3 + z_field(ip, ilat + 1);
1763 r3b = re3 + z_field(ip + 1, ilat + 1);
1764 r1b = re1 + z_field(ip + 1, ilat);
1794 r1a = re1 + z_field(ip, ilat);
1795 r3a = re3 + z_field(ip, ilat + 1);
1805 r3b = re3 + z_field(ip + 1, ilat + 1);
1806 r1b = re1 + z_field(ip + 1, ilat);
1812 rsurface1 = re1 + z_surface[ilat];
1813 rsurface3 = re3 + z_surface[ilat + 1];
1838 const Index& endface,
1842 const Index imax = np - 1;
1851 const Numeric dlat = lat_grid[ilat + 1] - lat_grid[ilat];
1852 const Numeric z1low = z_field(ip, ilat);
1853 const Numeric z1upp = z_field(ip + 1, ilat);
1854 const Numeric dzlow = z_field(ip, ilat + 1) - z1low;
1855 const Numeric dzupp = z_field(ip + 1, ilat + 1) - z1upp;
1857 const Numeric r1low = re + z1low;
1858 const Numeric r1upp = re + z1upp;
1859 re =
refell2r(refellipsoid, lat_grid[ilat + 1]);
1860 const Numeric drlow = re + z_field(ip, ilat + 1) - r1low;
1861 const Numeric drupp = re + z_field(ip + 1, ilat + 1) - r1upp;
1863 for (
Index i = 0; i < np; i++) {
1864 ppath.
r[i] = r_v[i];
1865 ppath.
pos(i, 1) = lat_v[i];
1866 ppath.
los(i, 0) = za_v[i];
1867 ppath.
nreal[i] = n_v[i];
1868 ppath.
ngroup[i] = ng_v[i];
1871 Numeric w = (lat_v[i] - lat_grid[ilat]) / dlat;
1874 const Numeric rlow = r1low +
w * drlow;
1875 const Numeric rupp = r1upp +
w * drupp;
1878 const Numeric zlow = z1low +
w * dzlow;
1879 const Numeric zupp = z1upp +
w * dzupp;
1881 ppath.
gp_p[i].idx = ip;
1882 ppath.
gp_p[i].fd[0] = (r_v[i] - rlow) / (rupp - rlow);
1883 ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
1886 ppath.
pos(i, 0) = zlow + ppath.
gp_p[i].fd[0] * (zupp - zlow);
1888 ppath.
gp_lat[i].idx = ilat;
1889 ppath.
gp_lat[i].fd[0] = (lat_v[i] - lat_grid[ilat]) / dlat;
1894 ppath.
lstep[i - 1] = lstep[i - 1];
1907 if (endface == 1 || endface == 3) {
1909 }
else if (endface == 2 || endface == 4) {
1915 if (ppath.
gp_p[imax].fd[0] < 0 || ppath.
gp_p[imax].fd[1] < 0) {
1918 if (ppath.
gp_lat[imax].fd[0] < 0 || ppath.
gp_lat[imax].fd[1] < 0) {
1964 const Index imax = ppath.
np - 1;
1967 r_start = ppath.
r[imax];
1968 lat_start = ppath.
pos(imax, 1);
1969 lon_start = ppath.
pos(imax, 2);
1970 za_start = ppath.
los(imax, 0);
1971 aa_start = ppath.
los(imax, 1);
1982 if (lat_start == 90) {
1985 gridpos(gp_tmp, lon_grid, aa_start);
1986 if (aa_start < 180) {
1991 }
else if (lat_start == -90) {
1994 gridpos(gp_tmp, lon_grid, aa_start);
1995 if (aa_start < 180) {
2001 if (lat_start > 0) {
2006 if (lon_start < lon_grid[nlon - 1]) {
2013 lat1 = lat_grid[ilat];
2014 lat3 = lat_grid[ilat + 1];
2015 lon5 = lon_grid[ilon];
2016 lon6 = lon_grid[ilon + 1];
2029 r15a = re1 + z_field(ip, ilat, ilon);
2030 r35a = re3 + z_field(ip, ilat + 1, ilon);
2031 r36a = re3 + z_field(ip, ilat + 1, ilon + 1);
2032 r16a = re1 + z_field(ip, ilat, ilon + 1);
2033 r15b = re1 + z_field(ip + 1, ilat, ilon);
2034 r35b = re3 + z_field(ip + 1, ilat + 1, ilon);
2035 r36b = re3 + z_field(ip + 1, ilat + 1, ilon + 1);
2036 r16b = re1 + z_field(ip + 1, ilat, ilon + 1);
2043 if (fabs(za_start - 90) <= 10)
2069 r15a = re1 + z_field(ip, ilat, ilon);
2070 r35a = re3 + z_field(ip, ilat + 1, ilon);
2071 r36a = re3 + z_field(ip, ilat + 1, ilon + 1);
2072 r16a = re1 + z_field(ip, ilat, ilon + 1);
2098 r15b = re1 + z_field(ip + 1, ilat, ilon);
2099 r35b = re3 + z_field(ip + 1, ilat + 1, ilon);
2100 r36b = re3 + z_field(ip + 1, ilat + 1, ilon + 1);
2101 r16b = re1 + z_field(ip + 1, ilat, ilon + 1);
2107 rsurface15 = re1 + z_surface(ilat, ilon);
2108 rsurface35 = re3 + z_surface(ilat + 1, ilon);
2109 rsurface36 = re3 + z_surface(ilat + 1, ilon + 1);
2110 rsurface16 = re1 + z_surface(ilat, ilon + 1);
2139 const Index& endface,
2143 const Index imax = np - 1;
2152 const Numeric lat1 = lat_grid[ilat];
2153 const Numeric lat3 = lat_grid[ilat + 1];
2154 const Numeric lon5 = lon_grid[ilon];
2155 const Numeric lon6 = lon_grid[ilon + 1];
2158 const Numeric r15a = re1 + z_field(ip, ilat, ilon);
2159 const Numeric r35a = re3 + z_field(ip, ilat + 1, ilon);
2160 const Numeric r36a = re3 + z_field(ip, ilat + 1, ilon + 1);
2161 const Numeric r16a = re1 + z_field(ip, ilat, ilon + 1);
2162 const Numeric r15b = re1 + z_field(ip + 1, ilat, ilon);
2163 const Numeric r35b = re3 + z_field(ip + 1, ilat + 1, ilon);
2164 const Numeric r36b = re3 + z_field(ip + 1, ilat + 1, ilon + 1);
2165 const Numeric r16b = re1 + z_field(ip + 1, ilat, ilon + 1);
2166 const Numeric dlat = lat3 - lat1;
2167 const Numeric dlon = lon6 - lon5;
2169 for (
Index i = 0; i < np; i++) {
2172 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_v[i], lon_v[i]);
2174 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_v[i], lon_v[i]);
2177 ppath.
r[i] = r_v[i];
2178 ppath.
pos(i, 1) = lat_v[i];
2179 ppath.
pos(i, 2) = lon_v[i];
2180 ppath.
los(i, 0) = za_v[i];
2181 ppath.
los(i, 1) = aa_v[i];
2182 ppath.
nreal[i] = n_v[i];
2183 ppath.
ngroup[i] = ng_v[i];
2186 ppath.
gp_p[i].idx = ip;
2187 ppath.
gp_p[i].fd[0] = (r_v[i] - rlow) / (rupp - rlow);
2188 ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
2193 lat1, lat3, lon5, lon6, re1, re3, re3, re1, lat_v[i], lon_v[i]);
2194 const Numeric zlow = rlow - re;
2195 const Numeric zupp = rupp - re;
2197 ppath.
pos(i, 0) = zlow + ppath.
gp_p[i].fd[0] * (zupp - zlow);
2200 ppath.
gp_lat[i].idx = ilat;
2201 ppath.
gp_lat[i].fd[0] = (lat_v[i] - lat1) / dlat;
2211 ppath.
gp_lon[i].idx = ilon;
2212 ppath.
gp_lon[i].fd[0] = (lon_v[i] - lon5) / dlon;
2217 ppath.
gp_lon[i].fd[0] = 0;
2218 ppath.
gp_lon[i].fd[1] = 1;
2222 ppath.
lstep[i - 1] = lstep[i - 1];
2233 if (endface == 1 || endface == 3) {
2235 }
else if (endface == 2 || endface == 4) {
2237 }
else if (endface == 5 || endface == 6) {
2243 if (ppath.
gp_p[imax].fd[0] < 0 || ppath.
gp_p[imax].fd[1] < 0) {
2246 if (ppath.
gp_lat[imax].fd[0] < 0 || ppath.
gp_lat[imax].fd[1] < 0) {
2249 if (ppath.
gp_lon[imax].fd[0] < 0 || ppath.
gp_lon[imax].fd[1] < 0) {
2304 }
else if (r_start > rb) {
2309 bool tanpoint =
false;
2313 if (za_start <= 90) {
2320 if (ra > rsurface && ra > ppc) {
2326 else if (rsurface > ppc) {
2360 Numeric r_start, lat_start, za_start;
2396 refellipsoid[0] + z_field[ip],
2397 refellipsoid[0] + z_field[ip + 1],
2398 refellipsoid[0] + z_surface);
2442 Numeric lat_start = lat_start0;
2451 if (lat_start < lat1) {
2453 }
else if (lat_start > lat3) {
2466 if (r_start < rlow) {
2468 }
else if (r_start > rupp) {
2474 poslos2cart(x, z, dx, dz, r_start, lat_start, za_start);
2477 bool unsafe =
false;
2478 bool do_surface =
false;
2484 Numeric r_end, lat_end, l_end;
2491 l_end = rupp - r_start;
2496 else if (absza > 180 -
ANGTOL) {
2498 rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_start);
2500 if (rlow > rsurface) {
2501 l_end = r_start - rlow;
2504 l_end = r_start - rsurface;
2517 cart2pol(r_corr, lat_corr, x, z, lat_start, za_start);
2520 lat_corr -= lat_start;
2535 l_end = 2 * (rupp - rlow);
2538 Numeric l_in = 0, l_out = l_end;
2539 bool ready =
false, startup =
true;
2541 if (rsurface1 +
RTOL >= r1a || rsurface3 +
RTOL >= r3a) {
2547 r_end, lat_end, x + dx * l_end, z + dz * l_end, lat_start, za_start);
2549 lat_end -= lat_corr;
2557 rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_end);
2558 if (r_surface >= rlow && r_end <= r_surface) {
2565 if (lat_end < lat1) {
2568 }
else if (lat_end > lat3) {
2571 }
else if (r_end < rlow) {
2589 l_end = (l_out + l_in) / 2;
2599 if ((l_out - l_in) <
LACC) {
2602 l_end = (l_out + l_in) / 2;
2613 n =
Index(ceil(
abs(l_end / lmax)));
2624 lat_v[0] = lat_start;
2631 for (
Index j = 1; j <= n; j++) {
2657 rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_v[j]);
2659 if (r_v[j] < r_test) {
2663 }
else if (r_v[j] < rlow) {
2669 if (r_v[j] > rupp) {
2681 }
else if (endface == 2) {
2683 }
else if (endface == 3) {
2685 }
else if (endface == 4) {
2687 }
else if (endface == 7) {
2688 r_v[n] =
rsurf_at_lat(lat1, lat3, rsurface1, rsurface3, lat_v[n]);
2725 Numeric r_start, lat_start, za_start;
2731 Numeric lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
2843 Numeric lat_start = lat_start0;
2844 Numeric lon_start = lon_start0;
2858 if (lat_start < lat1) {
2860 }
else if (lat_start > lat3) {
2863 if (lon_start < lon5) {
2865 }
else if (lon_start > lon6) {
2871 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_start, lon_start);
2873 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_start, lon_start);
2880 if (r_start < rlow) {
2882 }
else if (r_start > rupp) {
2889 x, y, z, dx, dy, dz, r_start, lat_start, lon_start, za_start, aa_start);
2892 bool unsafe =
false;
2893 bool do_surface =
false;
2899 Numeric r_end, lat_end, lon_end, l_end;
2905 l_end = rupp - r_start;
2910 else if (za_start > 180 -
ANGTOL) {
2922 if (rlow > rsurface) {
2923 l_end = r_start - rlow;
2926 l_end = r_start - rsurface;
2937 Numeric r_corr, lat_corr, lon_corr;
2951 lat_corr -= lat_start;
2952 lon_corr -= lon_start;
2967 l_end = 2 * (rupp - rlow);
2970 Numeric l_in = 0, l_out = l_end;
2971 bool ready =
false, startup =
true;
2973 if (rsurface15 +
RTOL >= r15a || rsurface35 +
RTOL >= r35a ||
2974 rsurface36 +
RTOL >= r36a || rsurface16 +
RTOL >= r16a) {
2990 lat_end -= lat_corr;
2991 lon_end -= lon_corr;
2997 lon_end = lon_start;
3003 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_end, lon_end);
3016 if (r_surface >= rlow && r_end <= r_surface) {
3023 if (lat_end < lat1) {
3026 }
else if (lat_end > lat3) {
3029 }
else if (lon_end < lon5) {
3032 }
else if (lon_end > lon6) {
3035 }
else if (r_end < rlow) {
3040 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_end, lon_end);
3054 l_end = (l_out + l_in) / 2;
3064 if ((l_out - l_in) <
LACC) {
3067 l_end = (l_out + l_in) / 2;
3078 n =
Index(ceil(
abs(l_end / lmax)));
3091 lat_v[0] = lat_start;
3092 lon_v[0] = lon_start;
3100 for (
Index j = 1; j <= n; j++) {
3136 lat1, lat3, lon5, lon6, r15a, r35a, r36a, r16a, lat_v[j], lon_v[j]);
3149 if (r_v[j] < r_test) {
3153 }
else if (r_v[j] < rlow) {
3159 lat1, lat3, lon5, lon6, r15b, r35b, r36b, r16b, lat_v[j], lon_v[j]);
3160 if (r_v[j] > rupp) {
3172 }
else if (endface == 2) {
3183 }
else if (endface == 3) {
3185 }
else if (endface == 4) {
3196 }
else if (endface == 5) {
3198 }
else if (endface == 6) {
3200 }
else if (endface == 7) {
3260 Numeric r_start, lat_start, lon_start, za_start, aa_start;
3263 Index ip, ilat, ilon;
3267 Numeric lat1, lat3, lon5, lon6;
3268 Numeric r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
3269 Numeric rsurface15, rsurface35, rsurface36, rsurface16;
3313 Vector r_v, lat_v, lon_v, za_v, aa_v;
3429 const Agenda& refr_index_air_agenda,
3441 Numeric refr_index_air, refr_index_air_group;
3444 refr_index_air_group,
3445 refr_index_air_agenda,
3453 r_array.push_back(r);
3454 lat_array.push_back(lat);
3455 za_array.push_back(za);
3456 n_array.push_back(refr_index_air);
3457 ng_array.push_back(refr_index_air_group);
3461 Numeric lstep, lcum = 0, dlat;
3489 if (lstep <= lraytrace) {
3491 dlat = lat_v[1] - lat;
3502 za_flagside = 180 - za_flagside;
3510 dlat = lat_new - lat;
3520 refr_index_air_group,
3522 refr_index_air_agenda,
3536 za += (
RAD2DEG * lstep / refr_index_air) * (-sin(za_rad) * dndr);
3541 }
else if (za > 180) {
3546 if (ready || (lmax > 0 && lcum + lraytrace > lmax)) {
3547 r_array.push_back(r);
3548 lat_array.push_back(lat);
3549 za_array.push_back(za);
3550 n_array.push_back(refr_index_air);
3551 ng_array.push_back(refr_index_air_group);
3552 l_array.push_back(lcum);
3568 const Agenda& refr_index_air_agenda,
3569 const String& rtrace_method,
3572 Numeric r_start, lat_start, za_start;
3587 Numeric refr_index_air, refr_index_air_group;
3590 refr_index_air_group,
3591 refr_index_air_agenda,
3608 Array<Numeric> r_array, lat_array, za_array, l_array, n_array, ng_array;
3611 if (rtrace_method ==
"linear_basic") {
3635 refr_index_air_agenda,
3637 refellipsoid[0] + z_surface,
3638 refellipsoid[0] + z_field(ip, 0, 0),
3639 refellipsoid[0] + z_field(ip + 1, 0, 0),
3651 Vector r_v(np), lat_v(np), za_v(np), l_v(np - 1), n_v(np), ng_v(np);
3652 for (
Index i = 0; i < np; i++) {
3653 r_v[i] = r_array[i];
3654 lat_v[i] = lat_array[i];
3655 za_v[i] = za_array[i];
3656 n_v[i] = n_array[i];
3657 ng_v[i] = ng_array[i];
3659 l_v[i] = l_array[i];
3670 z_field(
joker, 0, 0),
3736 const Agenda& refr_index_air_agenda,
3753 Numeric refr_index_air, refr_index_air_group;
3756 refr_index_air_group,
3757 refr_index_air_agenda,
3767 r_array.push_back(r);
3768 lat_array.push_back(lat);
3769 za_array.push_back(za);
3770 n_array.push_back(refr_index_air);
3771 ng_array.push_back(refr_index_air_group);
3775 Numeric lstep, lcum = 0, dlat;
3810 if (lstep <= lraytrace) {
3812 dlat = lat_v[1] - lat;
3818 if (
abs(za) <= 90) {
3824 za_flagside =
sign(za) * 180 - za_flagside;
3832 dlat = lat_new - lat;
3841 }
else if (lat > lat3) {
3850 refr_index_air_group,
3853 refr_index_air_agenda,
3869 za += (
RAD2DEG * lstep / refr_index_air) *
3870 (-sin(za_rad) * dndr + cos(za_rad) * dndlat);
3875 }
else if (za > 180) {
3881 if (lat == lat1 && za < 0) {
3884 }
else if (lat == lat3 && za > 0) {
3890 if (ready || (lmax > 0 && lcum + lraytrace > lmax)) {
3891 r_array.push_back(r);
3892 lat_array.push_back(lat);
3893 za_array.push_back(za);
3894 n_array.push_back(refr_index_air);
3895 ng_array.push_back(refr_index_air_group);
3896 l_array.push_back(lcum);
3913 const Agenda& refr_index_air_agenda,
3914 const String& rtrace_method,
3917 Numeric r_start, lat_start, za_start;
3923 Numeric lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
3951 Array<Numeric> r_array, lat_array, za_array, l_array, n_array, ng_array;
3954 if (rtrace_method ==
"linear_basic") {
3971 refr_index_air_agenda,
3992 Vector r_v(np), lat_v(np), za_v(np), l_v(np - 1), n_v(np), ng_v(np);
3993 for (
Index i = 0; i < np; i++) {
3994 r_v[i] = r_array[i];
3995 lat_v[i] = lat_array[i];
3996 za_v[i] = za_array[i];
3997 n_v[i] = n_array[i];
3998 ng_v[i] = ng_array[i];
4000 l_v[i] = l_array[i];
4096 const Agenda& refr_index_air_agenda,
4123 Numeric refr_index_air, refr_index_air_group;
4126 refr_index_air_group,
4127 refr_index_air_agenda,
4139 r_array.push_back(r);
4140 lat_array.push_back(lat);
4141 lon_array.push_back(lon);
4142 za_array.push_back(za);
4143 aa_array.push_back(aa);
4144 n_array.push_back(refr_index_air);
4145 ng_array.push_back(refr_index_air_group);
4148 Vector r_v, lat_v, lon_v, za_v, aa_v;
4194 if (lstep <= lraytrace) {
4204 Numeric x, y, z, dx, dy, dz, lat_new, lon_new;
4206 poslos2cart(x, y, z, dx, dy, dz, r, lat, lon, za, aa);
4240 refr_index_air_group,
4244 refr_index_air_agenda,
4261 const Numeric sinza = sin(za_rad);
4262 const Numeric sinaa = sin(aa_rad);
4263 const Numeric cosaa = cos(aa_rad);
4269 if (za < ANGTOL || za > 180 -
ANGTOL) {
4270 los[0] += aterm * (cos(za_rad) * (cosaa * dndlat + sinaa * dndlon));
4271 los[1] =
RAD2DEG * atan2(dndlon, dndlat);
4273 los[0] += aterm * (-sinza * dndr +
4274 cos(za_rad) * (cosaa * dndlat + sinaa * dndlon));
4275 los[1] += aterm * sinza * (cosaa * dndlon - sinaa * dndlat);
4286 if (za > 0 && za < 180) {
4287 if (lon == lon5 && aa < 0) {
4290 }
else if (lon == lon6 && aa > 0) {
4293 }
else if (lat == lat1 && lat != -90 &&
abs(aa) > 90) {
4296 }
else if (lat == lat3 && lat != 90 &&
abs(aa) < 90) {
4303 if (ready || (lmax > 0 && lcum + lraytrace > lmax)) {
4304 r_array.push_back(r);
4305 lat_array.push_back(lat);
4306 lon_array.push_back(lon);
4307 za_array.push_back(za);
4308 aa_array.push_back(aa);
4309 n_array.push_back(refr_index_air);
4310 ng_array.push_back(refr_index_air_group);
4311 l_array.push_back(lcum);
4329 const Agenda& refr_index_air_agenda,
4330 const String& rtrace_method,
4333 Numeric r_start, lat_start, lon_start, za_start, aa_start;
4336 Index ip, ilat, ilon;
4340 Numeric lat1, lat3, lon5, lon6;
4341 Numeric r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
4342 Numeric rsurface15, rsurface35, rsurface36, rsurface16;
4382 Array<Numeric> r_array, lat_array, lon_array, za_array, aa_array;
4386 if (rtrace_method ==
"linear_basic") {
4406 refr_index_air_agenda,
4437 Vector r_v(np), lat_v(np), lon_v(np), za_v(np), aa_v(np), l_v(np - 1);
4438 Vector n_v(np), ng_v(np);
4439 for (
Index i = 0; i < np; i++) {
4440 r_v[i] = r_array[i];
4441 lat_v[i] = lat_array[i];
4442 lon_v[i] = lon_array[i];
4443 za_v[i] = za_array[i];
4444 aa_v[i] = aa_array[i];
4445 n_v[i] = n_array[i];
4446 ng_v[i] = ng_array[i];
4448 l_v[i] = l_array[i];
4478 const Index& atmosphere_dim,
4485 const Index& cloudbox_on,
4487 const bool& ppath_inside_cloudbox_do,
4504 if (atmosphere_dim == 1) {
4506 ppath.
end_pos[0] = rte_pos[0];
4508 ppath.
end_los[0] = rte_los[0];
4511 if (rte_pos[0] < z_field(lp, 0, 0)) {
4514 "The ppath starting point is placed ",
4515 (z_surface(0, 0) - rte_pos[0]) / 1e3,
" km below the surface.")
4519 ppath.
r[0] = refellipsoid[0] + rte_pos[0];
4528 if (ppath.
pos(0, 0) <= z_surface(0, 0) && ppath.
los(0, 0) > 90) {
4534 if (cloudbox_on && !ppath_inside_cloudbox_do) {
4536 if (fgp >= (
Numeric)cloudbox_limits[0] &&
4537 fgp <= (
Numeric)cloudbox_limits[1]) {
4546 fgp <= (
Numeric)cloudbox_limits[1]);
4559 if (rte_los[0] <= 90 ||
4560 ppath.
constant >= refellipsoid[0] + z_field(lp, 0, 0)) {
4561 ppath.
pos(0, 0) = rte_pos[0];
4562 ppath.
pos(0, 1) = 0;
4563 ppath.
r[0] = refellipsoid[0] + rte_pos[0];
4564 ppath.
los(0, 0) = rte_los[0];
4567 out1 <<
" --- WARNING ---, path is totally outside of the "
4568 <<
"model atmosphere\n";
4573 ppath.
r[0] = refellipsoid[0] + z_field(lp, 0, 0);
4574 ppath.
pos(0, 0) = z_field(lp, 0, 0);
4583 ppath.
gp_p[0].idx = lp - 1;
4584 ppath.
gp_p[0].fd[0] = 1;
4585 ppath.
gp_p[0].fd[1] = 0;
4588 if (cloudbox_on && cloudbox_limits[1] == lp) {
4596 else if (atmosphere_dim == 2) {
4598 ppath.
end_pos[0] = rte_pos[0];
4599 ppath.
end_pos[1] = rte_pos[1];
4600 ppath.
end_los[0] = rte_los[0];
4609 bool islatin =
false;
4612 if (rte_pos[1] > lat_grid[0] && rte_pos[1] < lat_grid[llat]) {
4614 gridpos(gp_lat, lat_grid, rte_pos[1]);
4616 z_toa =
interp(itw, z_field(lp,
joker, 0), gp_lat);
4617 r_e =
refell2d(refellipsoid, lat_grid, gp_lat);
4619 r_e =
refell2r(refellipsoid, rte_pos[1]);
4623 if (islatin && rte_pos[0] < z_toa) {
4628 "The ppath starting point is placed ", (z_s - rte_pos[0]) / 1e3,
4629 " km below the surface.")
4633 ppath.
r[0] = r_e + rte_pos[0];
4653 if (ppath.
pos(0, 0) <= z_s) {
4659 z_surface(
joker, 0),
4676 if (cloudbox_on && !ppath_inside_cloudbox_do) {
4679 if (fgp >= (
Numeric)cloudbox_limits[0] &&
4680 fgp <= (
Numeric)cloudbox_limits[1] &&
4681 fgl >= (
Numeric)cloudbox_limits[2] &&
4682 fgl <= (
Numeric)cloudbox_limits[3]) {
4692 fgp <= (
Numeric)cloudbox_limits[1] &&
4693 fgl >= (
Numeric)cloudbox_limits[2] &&
4694 fgl <= (
Numeric)cloudbox_limits[3]);
4702 (rte_pos[1] >= lat_grid[llat] && rte_los[0] >= 0),
4703 "The sensor is outside (or at the limit) of the model "
4704 "atmosphere but\nlooks in the wrong direction (wrong sign "
4705 "for the zenith angle?).\nThis case includes nadir "
4706 "looking exactly at the latitude end points.")
4711 const Numeric r_p = r_e + rte_pos[0];
4716 Numeric r_toa_min = 99e99, r_toa_max = -1;
4717 for (
Index ilat = 0; ilat <= llat; ilat++) {
4719 refell2r(refellipsoid, lat_grid[ilat]) + z_field(lp, ilat, 0);
4720 if (r_toa[ilat] < r_toa_min) {
4721 r_toa_min = r_toa[ilat];
4723 if (r_toa[ilat] > r_toa_max) {
4724 r_toa_max = r_toa[ilat];
4728 "The sensor is horizontally outside (or at the limit) of "
4729 "the model\natmosphere, but is at a radius smaller than "
4730 "the maximum value of\nthe top-of-the-atmosphere radii. "
4731 "This is not allowed. Make the\nmodel atmosphere larger "
4732 "to also cover the sensor position?")
4735 if (
abs(rte_los[0]) <= 90) {
4736 ppath.
pos(0, 0) = rte_pos[0];
4737 ppath.
pos(0, 1) = rte_pos[1];
4738 ppath.
r[0] = r_e + rte_pos[0];
4739 ppath.
los(0, 0) = rte_los[0];
4742 out1 <<
" ------- WARNING -------: path is totally outside of "
4743 <<
"the model atmosphere\n";
4748 bool above =
false, ready =
false, failed =
false;
4758 if (islatin || ppath.
constant > r_toa_min) {
4769 while (!ready && !failed) {
4779 latt, lt, rt, r_p, rte_pos[1], rte_los[0], ppath.
constant);
4783 if (latt < lat_grid[0] || latt > lat_grid[llat]) {
4790 if (
abs(lt - lt_old) <
LACC || ntries == 10000) {
4796 gridpos(gp_latt, lat_grid, latt);
4798 rt =
interp(itwt, r_toa, gp_latt);
4805 if (ntries == 10000) {
4811 "The path does not enter the model atmosphere. It "
4812 "reaches the\ntop of the atmosphere "
4813 "altitude around latitude ", latt,
" deg.")
4815 ppath.
pos(0, 0) = rte_pos[0];
4816 ppath.
pos(0, 1) = rte_pos[1];
4817 ppath.
r[0] = r_e + rte_pos[0];
4818 ppath.
los(0, 0) = rte_los[0];
4821 out1 <<
" ------- WARNING -------: path is totally outside "
4822 <<
"of the model atmosphere\n";
4828 ppath.
pos(0, 1) =
interp(itwt, lat_grid, gp_latt);
4834 ppath.
gp_p[0].idx = lp - 1;
4835 ppath.
gp_p[0].fd[0] = 1;
4836 ppath.
gp_p[0].fd[1] = 0;
4842 if (cloudbox_on && cloudbox_limits[1] == lp) {
4844 if (fgp >= (
Numeric)cloudbox_limits[2] &&
4845 fgp <= (
Numeric)cloudbox_limits[3]) {
4862 resolve_lon(lon2use, lon_grid[0], lon_grid[llon]);
4865 ppath.
end_pos[0] = rte_pos[0];
4866 ppath.
end_pos[1] = rte_pos[1];
4868 ppath.
end_los[0] = rte_los[0];
4869 ppath.
end_los[1] = rte_los[1];
4875 bool islatlonin =
false;
4879 if (rte_pos[1] >= lat_grid[0] && rte_pos[1] <= lat_grid[llat] &&
4880 lon2use >= lon_grid[0] && lon2use <= lon_grid[llon]) {
4882 gridpos(gp_lat, lat_grid, rte_pos[1]);
4883 gridpos(gp_lon, lon_grid, lon2use);
4886 r_e =
refell2d(refellipsoid, lat_grid, gp_lat);
4888 r_e =
refell2r(refellipsoid, rte_pos[1]);
4892 if (islatlonin && rte_pos[0] < z_toa) {
4897 "The ppath starting point is placed ", (z_s - rte_pos[0]) / 1e3,
4898 " km below the surface.")
4902 ppath.
r[0] = r_e + rte_pos[0];
4922 if (ppath.
pos(0, 0) <= z_s) {
4948 if (cloudbox_on && !ppath_inside_cloudbox_do) {
4952 if (fgp >= (
Numeric)cloudbox_limits[0] &&
4953 fgp <= (
Numeric)cloudbox_limits[1] &&
4954 fgl >= (
Numeric)cloudbox_limits[2] &&
4955 fgl <= (
Numeric)cloudbox_limits[3] &&
4956 fgo >= (
Numeric)cloudbox_limits[4] &&
4957 fgo <= (
Numeric)cloudbox_limits[5]) {
4968 fgp <= (
Numeric)cloudbox_limits[1] &&
4969 fgl >= (
Numeric)cloudbox_limits[2] &&
4970 fgl <= (
Numeric)cloudbox_limits[3] &&
4971 fgo >= (
Numeric)cloudbox_limits[4] &&
4972 fgo <= (
Numeric)cloudbox_limits[5]);
4981 const Numeric r_p = r_e + rte_pos[0];
4985 Matrix r_toa(llat + 1, llon + 1);
4986 Numeric r_toa_min = 99e99, r_toa_max = -1;
4987 for (
Index ilat = 0; ilat <= llat; ilat++) {
4989 for (
Index ilon = 0; ilon <= llon; ilon++) {
4990 r_toa(ilat, ilon) = r_lat + z_field(lp, ilat, ilon);
4991 if (r_toa(ilat, ilon) < r_toa_min) {
4992 r_toa_min = r_toa(ilat, ilon);
4994 if (r_toa(ilat, ilon) > r_toa_max) {
4995 r_toa_max = r_toa(ilat, ilon);
5001 "r_p=",setprecision(18),r_p,
"\n"
5002 "r_toa_max=",r_toa_max,
"\n"
5003 "The sensor is horizontally outside of "
5004 "the model\natmosphere, but is at a radius smaller than "
5005 "the maximum value of\nthe top-of-the-atmosphere radii. "
5006 "This is not allowed. Make the\nmodel atmosphere larger "
5007 "to also cover the sensor position?")
5010 if (rte_los[0] <= 90) {
5011 ppath.
pos(0, 0) = rte_pos[0];
5012 ppath.
pos(0, 1) = rte_pos[1];
5013 ppath.
pos(0, 2) = rte_pos[2];
5014 ppath.
r[0] = r_e + rte_pos[0];
5015 ppath.
los(0, 0) = rte_los[0];
5016 ppath.
los(0, 1) = rte_los[1];
5019 out1 <<
" ------- WARNING -------: path is totally outside of "
5020 <<
"the model atmosphere\n";
5025 bool above =
false, ready =
false, failed =
false;
5035 if (islatlonin || ppath.
constant > r_toa_min) {
5058 while (!ready && !failed) {
5085 if (latt < lat_grid[0] || latt > lat_grid[llat] ||
5086 lont < lon_grid[0] || lont > lon_grid[llon]) {
5093 if (
abs(lt - lt_old) <
LACC) {
5099 gridpos(gp_latt, lat_grid, latt);
5100 gridpos(gp_lont, lon_grid, lont);
5102 rt =
interp(itwt, r_toa, gp_latt, gp_lont);
5108 "The path does not enter the model atmosphere. It\n"
5109 "reaches the top of the atmosphere altitude around:\n"
5110 " lat: ", latt,
" deg.\n lon: ", lont,
" deg.")
5112 ppath.
pos(0, 0) = rte_pos[0];
5113 ppath.
pos(0, 1) = rte_pos[1];
5114 ppath.
pos(0, 2) = rte_pos[2];
5116 ppath.
r[0] = r_e + rte_pos[0];
5117 ppath.
los(0, 0) = rte_los[0];
5118 ppath.
los(0, 1) = rte_los[1];
5121 out1 <<
" ------- WARNING -------: path is totally outside "
5122 <<
"of the model atmosphere\n";
5154 ppath.
gp_p[0].idx = lp - 1;
5155 ppath.
gp_p[0].fd[0] = 1;
5156 ppath.
gp_p[0].fd[1] = 0;
5163 if (cloudbox_on && cloudbox_limits[1] == lp) {
5166 if (fgp1 >= (
Numeric)cloudbox_limits[2] &&
5167 fgp1 <= (
Numeric)cloudbox_limits[3] &&
5168 fgp2 >= (
Numeric)cloudbox_limits[4] &&
5169 fgp2 <= (
Numeric)cloudbox_limits[5]) {
5181 const Agenda& ppath_step_agenda,
5182 const Index& atmosphere_dim,
5188 const Vector& refellipsoid,
5190 const Index& cloudbox_on,
5195 const Numeric& ppath_lraytrace,
5196 const bool& ppath_inside_cloudbox_do,
5207 "The WSV *ppath_inside_cloudbox_do* can only be set "
5208 "to 1 if also *cloudbox_on* is 1.");
5232 ppath_inside_cloudbox_do,
5277 const Index n = ppath_step.
np;
5283 "10 000 path points have been reached. Is this an infinite loop?");
5290 if (!ppath_inside_cloudbox_do) {
5295 (
abs(ppath_step.
los(n - 1, 0)) < 90 &&
5301 if (atmosphere_dim == 2) {
5304 "The path exits the atmosphere through the lower "
5305 "latitude end face.\nThe exit point is at an altitude"
5306 " of ", ppath_step.
pos(n - 1, 0) / 1e3,
" km.")
5308 "The path exits the atmosphere through the upper "
5309 "latitude end face.\nThe exit point is at an altitude"
5310 " of ", ppath_step.
pos(n - 1, 0) / 1e3,
" km.")
5312 if (atmosphere_dim == 3) {
5316 "The path exits the atmosphere through the lower "
5317 "latitude end face.\nThe exit point is at an altitude"
5318 " of ", ppath_step.
pos(n - 1, 0) / 1e3,
" km.")
5321 "The path exits the atmosphere through the upper "
5322 "latitude end face.\nThe exit point is at an altitude"
5323 " of ", ppath_step.
pos(n - 1, 0) / 1e3,
" km.")
5329 ppath_step.
los(n - 1, 1) < 0 &&
5330 abs(ppath_step.
pos(n - 1, 1)) < 90) {
5332 if (lon_grid[imax_lon] - lon_grid[0] >= 360) {
5333 ppath_step.
pos(n - 1, 2) = ppath_step.
pos(n - 1, 2) + 360;
5335 ppath_step.
gp_lon[n - 1], lon_grid, ppath_step.
pos(n - 1, 2));
5338 "The path exits the atmosphere through the lower "
5339 "longitude end face.\nThe exit point is at an "
5340 "altitude of ", ppath_step.
pos(n - 1, 0) / 1e3,
" km.")
5343 ppath_step.
los(n - 1, 1) > 0 &&
5344 abs(ppath_step.
pos(n - 1, 1)) < 90) {
5346 if (lon_grid[imax_lon] - lon_grid[0] >= 360) {
5347 ppath_step.
pos(n - 1, 2) = ppath_step.
pos(n - 1, 2) - 360;
5349 ppath_step.
gp_lon[n - 1], lon_grid, ppath_step.
pos(n - 1, 2));
5352 "The path exits the atmosphere through the upper "
5353 "longitude end face.\nThe exit point is at an "
5354 "altitude of ", ppath_step.
pos(n - 1, 0) / 1e3,
" km.")
5363 if (ipos >=
Numeric(cloudbox_limits[0]) &&
5364 ipos <=
Numeric(cloudbox_limits[1])) {
5365 if (atmosphere_dim == 1) {
5370 if (ipos >=
Numeric(cloudbox_limits[2]) &&
5371 ipos <=
Numeric(cloudbox_limits[3])) {
5372 if (atmosphere_dim == 2) {
5377 if (ipos >=
Numeric(cloudbox_limits[4]) &&
5378 ipos <=
Numeric(cloudbox_limits[5])) {
5400 if (ipos1 <= (
Numeric)cloudbox_limits[0] && ipos1 < ipos2) {
5404 else if (ipos1 >=
Numeric(cloudbox_limits[1]) && ipos1 > ipos2) {
5408 else if (atmosphere_dim > 1) {
5414 if (ipos1 <=
Numeric(cloudbox_limits[2]) && ipos1 < ipos2) {
5418 else if (ipos1 >=
Numeric(cloudbox_limits[3]) && ipos1 > ipos2) {
5422 else if (atmosphere_dim > 2) {
5428 if (ipos1 <=
Numeric(cloudbox_limits[4]) && ipos1 < ipos2) {
5432 else if (ipos1 >=
Numeric(cloudbox_limits[5]) && ipos1 > ipos2) {
5450 ppath_array.push_back(ppath_step);
5483 for (
Index i = 0; i < na; i++) {
5488 Index n = ppath_array[i].np;
5497 ppath.
r[
Range(np, n - i1)] = ppath_array[i].r[
Range(i1, n - i1)];
5499 ppath_array[i].pos(
Range(i1, n - i1),
joker);
5501 ppath_array[i].los(
Range(i1, n - i1),
joker);
5502 ppath.
nreal[
Range(np, n - i1)] = ppath_array[i].nreal[
Range(i1, n - i1)];
5504 ppath_array[i].ngroup[
Range(i1, n - i1)];
5505 ppath.
lstep[
Range(np - i1, n - 1)] = ppath_array[i].lstep;
5508 for (
Index j = i1; j < n; j++) {
5509 ppath.
gp_p[np + j - i1] = ppath_array[i].gp_p[j];
5511 if (atmosphere_dim >= 2) {
5512 for (
Index j = i1; j < n; j++) {
5513 ppath.
gp_lat[np + j - i1] = ppath_array[i].gp_lat[j];
5516 if (atmosphere_dim == 3) {
5517 for (
Index j = i1; j < n; j++) {
5518 ppath.
gp_lon[np + j - i1] = ppath_array[i].gp_lon[j];
Declarations for agendas.
This file contains the definition of Array.
base max(const Array< base > &x)
Max function.
base min(const Array< base > &x)
Min function.
Header file for helper functions for OpenMP.
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)
This can be used to make arrays out of anything.
Index nelem() const ARTS_NOEXCEPT
A constant view of a Matrix.
Index nrows() const noexcept
A constant view of a Tensor3.
Index npages() const
Returns the number of pages.
A constant view of a Tensor4.
A constant view of a Vector.
Index nelem() const noexcept
Returns the number of elements.
void resize(Index r, Index c)
Resize function.
void resize(Index n)
Resize function.
void mult(MatrixView C, ConstMatrixView A, const Block &B)
#define ARTS_ASSERT(condition,...)
#define ARTS_USER_ERROR(...)
#define ARTS_USER_ERROR_IF(condition,...)
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 refell2r(ConstVectorView refellipsoid, const Numeric &lat)
refell2r
void latlon_at_aa(Numeric &lat2, Numeric &lon2, const Numeric &lat1, const Numeric &lon1, const Numeric &aa, const Numeric &ddeg)
latlon_at_aa
void poslos2cart(Numeric &x, Numeric &z, Numeric &dx, Numeric &dz, const Numeric &r, const Numeric &lat, const Numeric &za)
poslos2cart
Numeric refell2d(ConstVectorView refellipsoid, ConstVectorView lat_grid, const GridPos gp)
refell2d
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
void cart2pol(Numeric &r, Numeric &lat, const Numeric &x, const Numeric &z, const Numeric &lat0, const Numeric &za0)
cart2pol
Index gridpos2gridrange(const GridPos &gp, const bool &upwards)
gridpos2gridrange
void gridpos_force_end_fd(GridPos &gp, const Index &n)
gridpos_force_end_fd
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
void gridpos_check_fd(GridPos &gp)
gridpos_check_fd
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
bool is_gridpos_at_index_i(const GridPos &gp, const Index &i, const bool &strict)
is_gridpos_at_index_i
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
void gridpos_copy(GridPos &gp_new, const GridPos &gp_old)
gridpos_copy
Numeric fractional_gp(const GridPos &gp)
fractional_gp
bool is_lon_cyclic(ConstVectorView grid, const Numeric &epsilon)
Check if the given longitude grid is cyclic.
Header file for logic.cc.
Numeric sign(const Numeric &x)
sign
void abs(Sparse &A, const Sparse &B)
Absolute value of sparse matrix elements.
NUMERIC Numeric
The type to use for all floating point numbers.
INDEX Index
The type to use for all integer numbers and indices.
Declarations having to do with the four output streams.
This file contains the definition of String, the ARTS string class.
constexpr auto deg2rad(auto x) noexcept
Converts degrees to radians.
constexpr auto rad2deg(auto x) noexcept
Converts radians to degrees.
int poly_root_solve(Matrix &roots, Vector &coeffs)
Contains the code to determine roots of polynomials.
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_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.
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.
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...
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 ...
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 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.
const Numeric LON_NOT_FOUND
void zaaa2cart(Numeric &dx, Numeric &dy, Numeric &dz, const Numeric &za, const Numeric &aa)
Converts zenith and azimuth angles to a cartesian unit vector.
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.
Numeric geompath_r_at_l(const Numeric &ppc, const Numeric &l)
Calculates the radius for a distance from the tangent point.
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.
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.
void error_if_limb_ppath(const Ppath &ppath)
Throws an error if ppath altitudes not are strictly increasing or decreasing.
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.
const Numeric LAT_NOT_FOUND
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.
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.
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.
constexpr Numeric DEG2RAD
Index ppath_what_background(const Ppath &ppath)
Returns the case number for the radiative background.
Index first_pos_before_altitude(const Ppath &p, const Numeric &alt)
Determines ppath position just below an altitude.
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.
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_append(Ppath &ppath1, const Ppath &ppath2)
Combines two Ppath structures.
void rotationmat3D(Matrix &R, ConstVectorView vrot, const Numeric &a)
Creates a 3D rotation matrix.
Numeric geometrical_ppc(const Numeric &r, const Numeric &za)
Calculates the propagation path constant for pure geometrical calculations.
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 zaaa2enu(Numeric &de, Numeric &dn, Numeric &du, const Numeric &za, const Numeric &aa)
Converts zenith and azimuth angles to ENU unit vector.
void ppath_copy(Ppath &ppath1, const Ppath &ppath2, const Index &ncopy)
Copy the content in ppath2 to ppath1.
void enu2zaaa(Numeric &za, Numeric &aa, const Numeric &de, const Numeric &dn, const Numeric &du)
Converts ENU unit vector vector to zenith and azimuth.
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 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.
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.
void cart2zaaa(Numeric &za, Numeric &aa, const Numeric &dx, const Numeric &dy, const Numeric &dz)
Converts a cartesian directional vector to zenith and azimuth.
constexpr Numeric RAD2DEG
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.
Numeric rslope_crossing3d(const Numeric &rp, const Numeric &za, const Numeric &r0, Numeric c1, Numeric c2)
3D version of rslope_crossing2d.
void find_tanpoint(Index &it, const Ppath &ppath)
Identifies the tangent point of a propagation path.
void ppath_set_background(Ppath &ppath, const Index &case_nr)
Sets the background field of a Ppath structure.
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)
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.
void resolve_lon(Numeric &lon, const Numeric &lon5, const Numeric &lon6)
Resolves which longitude angle that shall be used.
Numeric refraction_ppc(const Numeric &r, const Numeric &za, const Numeric &refr_index_air)
Calculates the propagation path constant for cases with refraction.
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.
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 geompath_r_at_za(const Numeric &ppc, const Numeric &za)
Calculates the zenith angle for a given radius along a geometrical propagation path.
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.
const Numeric R_NOT_FOUND
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.
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...
void ppath_init_structure(Ppath &ppath, const Index &atmosphere_dim, const Index &np)
Initiates a Ppath structure to hold the given number of points.
Numeric plevel_angletilt(const Numeric &r, const Numeric &c1)
Calculates the angular tilt of the surface or a pressure level.
const Numeric L_NOT_FOUND
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 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 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.
Numeric geompath_l_at_r(const Numeric &ppc, const Numeric &r)
Calculates the length from the tangent point for the given radius.
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.
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.
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.
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.
Propagation path structure and functions.
constexpr Numeric POLELAT
Size of north and south poles.
constexpr Numeric ANGTOL
Width of zenith and nadir directions.
Numeric sqrt(const Rational r)
Square root.
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
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)
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
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
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
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
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.
Declaration of functions in rte.cc.
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.
Header file for special_interp.cc.
Structure to store a grid position.
The structure to describe a propagation path and releated quantities.
Matrix los
Line-of-sight at each ppath point.
ArrayOfGridPos gp_lon
Index position with respect to the longitude grid.
String background
Radiative background.
Index np
Number of points describing the ppath.
Matrix pos
The distance between start pos and the last position in pos.
ArrayOfGridPos gp_lat
Index position with respect to the latitude grid.
Numeric end_lstep
The distance between end pos and the first position in pos.
Vector start_pos
Start position.
Vector lstep
The length between ppath points.
Numeric start_lstep
Length between sensor and atmospheric boundary.
Numeric constant
The propagation path constant (only used for 1D)
Vector r
Radius of each ppath point.
ArrayOfGridPos gp_p
Index position with respect to the pressure grid.
Vector ngroup
The group index of refraction.
Index dim
Atmospheric dimensionality.
Vector end_pos
End position.
Vector start_los
Start line-of-sight.
Vector nreal
The real part of the refractive index at each path position.
Vector end_los
End line-of-sight.