Go to the documentation of this file.
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));
245 const bool& tanpoint,
272 lstep = (l2 - l1) / (
Numeric)n;
283 for (
Index i = 1; i < n; i++) {
300 for (
Index i = 1; i <= n; i++) {
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]);
510 assert(
abs(za) <= 180);
516 assert(lon6 >= lon5);
518 if (
lon < lon5 &&
lon + 180 <= lon6) {
520 }
else if (
lon > lon6 &&
lon - 180 >= lon5) {
532 if (it == 0 || it ==
ppath.np - 1) {
539 bool below =
false, above =
false;
542 for (
Index i = 0; i < p.
np; i++) {
543 if (p.
pos(i, 0) < alt) {
544 if (above)
return i - 1;
547 if (below)
return i - 1;
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);
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)
819 for (
Index i = 0; i < n; i++) {
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) {
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 &&
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);
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.");
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) {
1312 for (
Index i = 0; i < n; i++) {
1313 if (roots(i, 1) == 0 && roots(i, 0) >
dmin && roots(i, 0) < 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);
1397 const Numeric q =
x *
x +
y *
y + z * z - r_hit * r_hit;
1435 ppath.constant = -1;
1440 ppath.start_pos.resize(npos);
1441 ppath.start_pos = -999;
1442 ppath.start_los.resize(nlos);
1443 ppath.start_los = -999;
1444 ppath.start_lstep = 0;
1445 ppath.end_pos.resize(npos);
1446 ppath.end_los.resize(nlos);
1447 ppath.end_lstep = 0;
1450 ppath.los.resize(np, nlos);
1452 ppath.lstep.resize(np - 1);
1454 ppath.gp_p.resize(np);
1456 ppath.gp_lat.resize(np);
1458 ppath.gp_lon.resize(np);
1463 ppath.nreal.resize(np);
1464 ppath.ngroup.resize(np);
1470 ppath.background =
"unvalid";
1473 ppath.background =
"space";
1476 ppath.background =
"surface";
1479 ppath.background =
"cloud box level";
1482 ppath.background =
"cloud box interior";
1485 ppath.background =
"transmitter";
1489 os <<
"Case number " << case_nr <<
" is not defined.";
1490 throw runtime_error(os.str());
1495 if (
ppath.background ==
"unvalid") {
1497 }
else if (
ppath.background ==
"space") {
1499 }
else if (
ppath.background ==
"surface") {
1501 }
else if (
ppath.background ==
"cloud box level") {
1503 }
else if (
ppath.background ==
"cloud box interior") {
1505 }
else if (
ppath.background ==
"transmitter") {
1509 os <<
"The string " <<
ppath.background
1510 <<
" is not a valid background case.";
1511 throw runtime_error(os.str());
1523 assert(ppath1.
np >= n);
1537 if (n == ppath1.
np) {
1552 for (
Index i = 0; i < n; i++) {
1555 if (ppath1.
dim >= 2) {
1559 if (ppath1.
dim == 3) {
1594 for (
Index i = 1; i < n2; i++) {
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);
1650 r_start =
ppath.r[imax];
1652 za_start =
ppath.los(imax, 0);
1680 const Index& endface,
1688 ppath.constant = ppc;
1694 for (
Index i = 0; i < np; i++) {
1695 ppath.r[i] = r_v[i];
1698 ppath.los(i, 0) = za_v[i];
1699 ppath.nreal[i] = n_v[i];
1700 ppath.ngroup[i] = ng_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) {
1756 r_start =
ppath.r[imax];
1758 za_start =
ppath.los(imax, 0);
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);
1856 const Index& endface,
1860 const Index imax = np - 1;
1866 ppath.constant = ppc;
1875 const Numeric r1low = re + z1low;
1876 const Numeric r1upp = re + z1upp;
1881 for (
Index i = 0; i < np; i++) {
1882 ppath.r[i] = r_v[i];
1884 ppath.los(i, 0) = za_v[i];
1885 ppath.nreal[i] = n_v[i];
1886 ppath.ngroup[i] = ng_v[i];
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);
1906 ppath.gp_lat[i].idx = ilat;
1908 ppath.gp_lat[i].fd[1] = 1 -
ppath.gp_lat[i].fd[0];
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) {
1985 r_start =
ppath.r[imax];
1988 za_start =
ppath.los(imax, 0);
1989 aa_start =
ppath.los(imax, 1);
2000 if (lat_start == 90) {
2004 if (aa_start < 180) {
2009 }
else if (lat_start == -90) {
2013 if (aa_start < 180) {
2019 if (lat_start > 0) {
2024 if (lon_start <
lon_grid[nlon - 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;
2167 ppath.constant = ppc;
2184 const Numeric dlat = lat3 - lat1;
2185 const Numeric dlon = lon6 - lon5;
2187 for (
Index i = 0; i < np; i++) {
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];
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;
2220 ppath.gp_lat[i].fd[1] = 1 -
ppath.gp_lat[i].fd[0];
2229 ppath.gp_lon[i].idx = ilon;
2230 ppath.gp_lon[i].fd[0] = (lon_v[i] - lon5) / dlon;
2231 ppath.gp_lon[i].fd[1] = 1 -
ppath.gp_lon[i].fd[0];
2234 ppath.gp_lon[i].idx = 0;
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;
2390 if (
ppath.constant < 0) {
2393 ppc =
ppath.constant;
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) {
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;
2774 if (
ppath.constant < 0) {
2777 ppc =
ppath.constant;
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;
3324 if (
ppath.constant < 0) {
3327 ppc =
ppath.constant;
3331 Vector r_v, lat_v, lon_v, za_v, aa_v;
3471 r_array.push_back(r);
3472 lat_array.push_back(
lat);
3473 za_array.push_back(za);
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;
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);
3570 l_array.push_back(lcum);
3587 const String& rtrace_method,
3590 Numeric r_start, lat_start, za_start;
3604 if (
ppath.constant < 0) {
3619 ppc =
ppath.constant;
3626 Array<Numeric> r_array, lat_array, za_array, l_array, n_array, ng_array;
3629 if (rtrace_method ==
"linear_basic") {
3669 Vector r_v(np), lat_v(np), za_v(np), l_v(np - 1), n_v(np), ng_v(np);
3670 for (
Index i = 0; i < np; i++) {
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];
3785 r_array.push_back(r);
3786 lat_array.push_back(
lat);
3787 za_array.push_back(za);
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) {
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);
3914 l_array.push_back(lcum);
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") {
4010 Vector r_v(np), lat_v(np), za_v(np), l_v(np - 1), n_v(np), ng_v(np);
4011 for (
Index i = 0; i < np; i++) {
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];
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);
4166 Vector r_v, lat_v, lon_v, za_v, aa_v;
4207 assert(r_v.
nelem() == 2);
4212 if (lstep <= lraytrace) {
4224 poslos2cart(
x,
y, z,
dx, dy, dz, r,
lat,
lon, za, aa);
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);
4329 l_array.push_back(lcum);
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") {
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);
4457 for (
Index i = 0; i < np; i++) {
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];
4525 ppath.end_pos[1] = 0;
4533 os <<
"The ppath starting point is placed "
4535 throw runtime_error(os.str());
4588 out1 <<
" --- WARNING ---, path is totally outside of the "
4589 <<
"model atmosphere\n";
4604 ppath.gp_p[0].idx = lp - 1;
4605 ppath.gp_p[0].fd[0] = 1;
4606 ppath.gp_p[0].fd[1] = 0;
4630 bool islatin =
false;
4644 if (islatin &&
rte_pos[0] < z_toa) {
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());
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());
4743 Numeric r_toa_min = 99e99, r_toa_max = -1;
4744 for (
Index ilat = 0; ilat <= llat; ilat++) {
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());
4772 out1 <<
" ------- WARNING -------: path is totally outside of "
4773 <<
"the model atmosphere\n";
4778 bool above =
false, ready =
false, failed =
false;
4784 if (
ppath.constant >= r_toa_max) {
4788 if (islatin ||
ppath.constant > r_toa_min) {
4797 while (!ready && !failed) {
4799 if (rt <
ppath.constant) {
4818 if (
abs(lt - lt_old) <
LACC) {
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());
4844 out1 <<
" ------- WARNING -------: path is totally outside "
4845 <<
"of the model atmosphere\n";
4853 ppath.end_lstep = lt;
4856 ppath.gp_p[0].idx = lp - 1;
4857 ppath.gp_p[0].fd[0] = 1;
4858 ppath.gp_p[0].fd[1] = 0;
4889 ppath.end_pos[2] = lon2use;
4897 bool islatlonin =
false;
4914 if (islatlonin &&
rte_pos[0] < z_toa) {
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());
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());
5045 out1 <<
" ------- WARNING -------: path is totally outside of "
5046 <<
"the model atmosphere\n";
5051 bool above =
false, ready =
false, failed =
false;
5057 if (
ppath.constant >= r_toa_max) {
5061 if (islatlonin ||
ppath.constant > r_toa_min) {
5084 while (!ready && !failed) {
5086 if (rt <
ppath.constant) {
5119 if (
abs(lt - lt_old) <
LACC) {
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());
5148 out1 <<
" ------- WARNING -------: path is totally outside "
5149 <<
"of the model atmosphere\n";
5178 ppath.end_lstep = lt;
5181 ppath.gp_p[0].idx = lp - 1;
5182 ppath.gp_p[0].fd[0] = 1;
5183 ppath.gp_p[0].fd[1] = 0;
5234 throw runtime_error(
5235 "The WSV *ppath_inside_cloudbox_do* can only be set "
5236 "to 1 if also *cloudbox_on* is 1.");
5310 if (istep > (
Index)1e4)
5311 throw runtime_error(
5312 "10 000 path points have been reached. Is this an infinite loop?");
5334 os <<
"The path exits the atmosphere through the lower "
5335 <<
"latitude end face.\nThe exit point is at an altitude"
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"
5344 throw runtime_error(os.str());
5352 os <<
"The path exits the atmosphere through the lower "
5353 <<
"latitude end face.\nThe exit point is at an altitude"
5355 throw runtime_error(os.str());
5360 os <<
"The path exits the atmosphere through the upper "
5361 <<
"latitude end face.\nThe exit point is at an altitude"
5363 throw runtime_error(os.str());
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());
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());
5526 for (
Index i = 0; i < na; i++) {
5531 Index n = ppath_array[i].np;
5542 ppath_array[i].pos(
Range(i1, n - i1),
joker);
5544 ppath_array[i].los(
Range(i1, n - i1),
joker);
5545 ppath.nreal[
Range(np, n - i1)] = ppath_array[i].nreal[
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];
5555 for (
Index j = i1; j < n; j++) {
5556 ppath.gp_lat[np + j - i1] = ppath_array[i].gp_lat[j];
5560 for (
Index j = i1; j < n; j++) {
5561 ppath.gp_lon[np + j - i1] = ppath_array[i].gp_lon[j];
5571 ppath.end_lstep = end_lstep;
5572 ppath.end_pos = end_pos;
5573 ppath.end_los = end_los;
Index atmosphere_dim(Workspace &ws) noexcept
std::size_t pos() const noexcept
Ppath ppath_step(Workspace &ws) noexcept
Index first_pos_before_altitude(const Ppath &p, const Numeric &alt)
Determines ppath position just below an altitude.
const Numeric ANGTOL
Width of zenith and nadir directions.
Tensor3 z_field(Workspace &ws) noexcept
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 ppath_init_structure(Ppath &ppath, const Index &atmosphere_dim, const Index &np)
Initiates a Ppath structure to hold the given number of points.
const Numeric R_NOT_FOUND
Agenda ppath_step_agenda(Workspace &ws) noexcept
Numeric lat(Workspace &ws) noexcept
Numeric plevel_angletilt(const Numeric &r, const Numeric &c1)
Calculates the angular tilt of the surface or a pressure level.
void gridpos_copy(GridPos &gp_new, const GridPos &gp_old)
gridpos_copy
Complex w(Complex z) noexcept
The Faddeeva function.
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
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 gridpos_check_fd(GridPos &gp)
gridpos_check_fd
Numeric sign(const Numeric &x)
sign
void ppath_append(Ppath &ppath1, const Ppath &ppath2)
Combines two Ppath structures.
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.
Vector lat_grid(Workspace &ws) noexcept
Numeric refell2d(ConstVectorView refellipsoid, ConstVectorView lat_grid, const GridPos gp)
refell2d
Numeric geompath_r_at_lat(const Numeric &ppc, const Numeric &lat0, const Numeric &za0, const Numeric &lat)
Calculates the radius for a given latitude.
Index ppath_inside_cloudbox_do(Workspace &ws) noexcept
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
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.
Verbosity verbosity(Workspace &ws) noexcept
Agenda refr_index_air_agenda(Workspace &ws) noexcept
void error_if_limb_ppath(const Ppath &ppath)
Throws an error if ppath altitudes not are strictly increasing or decreasing.
void mult(ComplexVectorView y, const ConstComplexMatrixView &M, const ConstComplexVectorView &x)
Matrix-Vector Multiplication.
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 ...
String background
Radiative background.
const Numeric POLELAT
Size of north and south poles.
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.
Contains the code to determine roots of polynomials.
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.
ArrayOfIndex cloudbox_limits(Workspace &ws) noexcept
Numeric end_lstep
The distance between end pos and the first position in pos.
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.
Vector y(Workspace &ws) noexcept
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 resize(Index n)
Resize function.
Numeric refr_index_air(Workspace &ws) noexcept
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...
Numeric start_lstep
Length between sensor and atmospheric boundary.
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 fractional_gp(const GridPos &gp)
fractional_gp
Index nrows() const
Returns the number of rows.
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
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
This file contains the definition of Array.
bool is_gridpos_at_index_i(const GridPos &gp, const Index &i, const bool &strict)
is_gridpos_at_index_i
The structure to describe a propagation path and releated quantities.
ArrayOfGridPos gp_p
Index position with respect to the pressure grid.
Numeric lon(Workspace &ws) noexcept
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.
Vector end_pos
End position.
Numeric sqrt(const Rational r)
Square root.
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.
A constant view of a Tensor4.
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
This can be used to make arrays out of anything.
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 cart2pol(Numeric &r, Numeric &lat, const Numeric &x, const Numeric &z, const Numeric &lat0, const Numeric &za0)
cart2pol
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...
Declarations for agendas.
ArrayOfGridPos gp_lat
Index position with respect to the latitude grid.
Declarations having to do with the four output streams.
Vector rte_pos(Workspace &ws) noexcept
Vector ngroup
The group index of refraction.
Index ncols() const
Returns the number of columns.
Matrix los
Line-of-sight at each ppath point.
Vector start_pos
Start position.
ArrayOfGridPos gp_lon
Index position with respect to the longitude grid.
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.
Index np
Number of points describing the ppath.
Index nelem() const
Returns the number of elements.
Numeric geompath_l_at_r(const Numeric &ppc, const Numeric &r)
Calculates the length from the tangent point for the given radius.
Tensor4 vmr_field(Workspace &ws) noexcept
Vector rte_los(Workspace &ws) noexcept
Vector p_grid(Workspace &ws) noexcept
Ppath ppath(Workspace &ws) noexcept
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
NUMERIC Numeric
The type to use for all floating point numbers.
int poly_root_solve(Matrix &roots, Vector &coeffs)
Numeric refr_index_air_group(Workspace &ws) noexcept
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 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.
Vector lstep
The length between ppath points.
Vector refellipsoid(Workspace &ws) noexcept
void zaaa2cart(Numeric &dx, Numeric &dy, Numeric &dz, const Numeric &za, const Numeric &aa)
Converts zenith and azimuth angles to a cartesian unit vector.
Vector start_los
Start line-of-sight.
Vector f_grid(Workspace &ws) noexcept
bool is_lon_cyclic(ConstVectorView grid, const Numeric &epsilon)
Check if the given longitude grid is cyclic.
const Numeric LON_NOT_FOUND
Numeric refraction_ppc(const Numeric &r, const Numeric &za, const Numeric &refr_index_air)
Calculates the propagation path constant for cases with refraction.
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 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.
void resize(Index r, Index c)
Resize function.
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.
Vector nreal
The real part of the refractive index at each path position.
Vector lon_grid(Workspace &ws) noexcept
void gridpos_force_end_fd(GridPos &gp, const Index &n)
gridpos_force_end_fd
Numeric ppath_lmax(Workspace &ws) noexcept
A constant view of a Matrix.
Vector end_los
End line-of-sight.
Numeric ppath_lraytrace(Workspace &ws) noexcept
void rotationmat3D(Matrix &R, ConstVectorView vrot, const Numeric &a)
Creates a 3D rotation matrix.
invlib::Vector< ArtsVector > Vector
invlib wrapper type for ARTS vectors.
void ppath_copy(Ppath &ppath1, const Ppath &ppath2, const Index &ncopy)
Copy the content in ppath2 to ppath1.
Structure to store a grid position.
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_step_agendaExecute(Workspace &ws, Ppath &ppath_step, const Numeric ppath_lmax, const Numeric ppath_lraytrace, const Vector &f_grid, const Agenda &input_agenda)
Propagation path structure and functions.
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 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.
void find_tanpoint(Index &it, const Ppath &ppath)
Identifies the tangent point of a propagation path.
Numeric constant
The propagation path constant (only used for 1D)
Index gridpos2gridrange(const GridPos &gp, const bool &upwards)
gridpos2gridrange
Header file for logic.cc.
const Numeric LAT_NOT_FOUND
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.
Declaration of functions in rte.cc.
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.
Tensor3 t_field(Workspace &ws) noexcept
void cart2zaaa(Numeric &za, Numeric &aa, const Numeric &dx, const Numeric &dy, const Numeric &dz)
Converts a cartesian directional vector to zenith and azimuth.
A constant view of a Tensor3.
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.
Vector r
Radius of each ppath point.
void resolve_lon(Numeric &lon, const Numeric &lon5, const Numeric &lon6)
Resolves which longitude angle that shall be used.
Header file for special_interp.cc.
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 geometrical_ppc(const Numeric &r, const Numeric &za)
Calculates the propagation path constant for pure geometrical calculations.
void poslos2cart(Numeric &x, Numeric &z, Numeric &dx, Numeric &dz, const Numeric &r, const Numeric &lat, const Numeric &za)
poslos2cart
const Numeric L_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 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 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.
Numeric rslope_crossing3d(const Numeric &rp, const Numeric &za, const Numeric &r0, Numeric c1, Numeric c2)
3D version of rslope_crossing2d.
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 ppath_set_background(Ppath &ppath, const Index &case_nr)
Sets the background field of a Ppath structure.
Vector x(Workspace &ws) noexcept
INDEX Index
The type to use for all integer numbers and indices.
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 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 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 latlon_at_aa(Numeric &lat2, Numeric &lon2, const Numeric &lat1, const Numeric &lon1, const Numeric &aa, const Numeric &ddeg)
latlon_at_aa
Index dim
Atmospheric dimensionality.
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.
Index ppath_what_background(const Ppath &ppath)
Returns the case number for the radiative background.
Header file for helper functions for OpenMP.
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.
A constant view of a Vector.
Matrix pos
The distance between start pos and the last position in pos.
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 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.
Index nelem() const
Number of elements.
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
Matrix z_surface(Workspace &ws) noexcept
This file contains the definition of String, the ARTS string class.
Numeric refell2r(ConstVectorView refellipsoid, const Numeric &lat)
refell2r
Index cloudbox_on(Workspace &ws) noexcept