26#include "matpack_complex.h"
31#include "matpack_math.h"
56 const Numeric& surface_skin_t,
58 const Numeric& salinity,
59 const Numeric& wind_speed,
60 const Numeric& rel_aa,
61 const Vector& transmittance,
62 const Index& fastem_version,
64 const Index nf = f_grid.nelem();
72 if (fastem_version < 3 || fastem_version > 6)
73 throw std::runtime_error(
74 "Invalid fastem version: 3 <= fastem_version <= 6");
76 emissivity.resize(nf, 4);
77 reflectivity.resize(nf, 4);
79 const Numeric t =
max(surface_skin_t, Numeric(270));
81 for (Index i = 0; i < nf; i++) {
82 if (f_grid[i] > 250e9)
83 throw std::runtime_error(
"Only frequency <= 250 GHz are allowed");
99 emissivity(i, joker) = e;
100 reflectivity(i, joker) = r;
105 for (Index i = 0; i < nf; i++) {
106 for (Index s = 0; s < 2; s++) {
107 if (emissivity(i, s) > 1) {
108 emissivity(i, s) = 1;
109 reflectivity(i, s) = 0;
111 if (emissivity(i, s) < 0) {
112 emissivity(i, s) = 0;
113 reflectivity(i, s) = 1;
115 if (reflectivity(i, s) > 1) {
116 emissivity(i, s) = 0;
117 reflectivity(i, s) = 1;
119 if (reflectivity(i, s) < 0) {
120 emissivity(i, s) = 1;
121 reflectivity(i, s) = 0;
129 const Index& atmosphere_dim,
130 const Vector& lat_grid,
131 const Vector& lat_true,
132 const Vector& lon_true,
133 const Vector& rtp_pos,
137 Index gfield_latID = 0;
138 Index gfield_lonID = 1;
149 const Index nlat = gfield2.
data.nrows();
150 const Index nlon = gfield2.
data.ncols();
152 if (nlat < 2 || nlon < 2) {
154 os <<
"The data in *gfield2* must span a geographical region. That is,\n"
155 <<
"the latitude and longitude grids must have a length >= 2.";
156 throw runtime_error(os.str());
163 Vector lat(1), lon(1);
165 lat[0], lon[0], atmosphere_dim, lat_grid, lat_true, lon_true, rtp_pos);
173 chk_if_in_range(
"rtp_pos.lon", lon[0], lon_shifted[0], lon_shifted[nlon - 1]);
178 gridpos(gp_lat, GFlat, lat[0]);
179 gridpos(gp_lon, lon_shifted, lon[0]);
182 outvalue =
interp(itw, gfield2.
data, gp_lat, gp_lon);
188 const Index& atmosphere_dim,
189 const Vector& lat_grid,
190 const Vector& lon_grid,
191 const Vector& rtp_pos,
192 const Matrix& z_surface,
196 chk_atm_grids(atmosphere_dim, uniform_grid(2, 2, -1), lat_grid, lon_grid);
198 "input argument *field*", field, atmosphere_dim, lat_grid, lon_grid);
201 const Numeric zmax =
max(z_surface);
202 const Numeric zmin =
min(z_surface);
203 const Numeric dzok = 1;
204 if (rtp_pos[0] < zmin - dzok || rtp_pos[0] > zmax + dzok) {
206 os <<
"The given position does not match *z_surface*.\nThe altitude in "
207 <<
"*rtp_pos* is " << rtp_pos[0] / 1e3 <<
" km.\n"
208 <<
"The altitude range covered by *z_surface* is [" << zmin / 1e3 <<
","
209 << zmax / 1e3 <<
"] km.\n"
210 <<
"One possible mistake is to mix up *rtp_pos* and *rte_los*.";
211 throw runtime_error(os.str());
214 if (atmosphere_dim == 1) {
215 outvalue = field(0, 0);
219 gridpos(gp_lat, lat_grid, rtp_pos[1]);
220 if (atmosphere_dim == 3) {
222 gridpos(gp_lon, lon_grid, rtp_pos[2]);
230 out3 <<
" Result = " << outvalue <<
"\n";
236 ArrayOfTensor3& diy_dx,
237 const Tensor3& iy_transmittance,
239 const Index& jacobian_do,
240 const Index& atmosphere_dim,
242 const Index& cloudbox_on,
243 const Index& stokes_dim,
244 const Vector& f_grid,
245 const Vector& rtp_pos,
246 const Vector& rtp_los,
247 const Vector& rte_pos2,
249 const Agenda& iy_main_agenda,
250 const Numeric& surface_skin_t,
251 const Numeric& salinity,
252 const Numeric& wind_speed,
253 const Numeric& wind_direction,
254 const Index& fastem_version,
261 Vector specular_los, surface_normal;
271 iy_aux_vars[0] =
"Optical depth";
276 const Index nf = f_grid.
nelem();
277 Vector transmittance(nf);
279 ArrayOfMatrix iy_aux;
303 for (Index i = 0; i < nf; i++) {
304 transmittance[i] = exp(-iy_aux[0](i, 0));
310 Tensor4 surface_rmatrix;
311 Matrix surface_emission;
331 Tensor3 I(1, nf, stokes_dim);
332 I(0, joker, joker) = iy;
333 Matrix sensor_los_dummy(1, 1, 0);
335 surface_calc(iy, I, sensor_los_dummy, surface_rmatrix, surface_emission);
340 if (iy_transmittance.npages()) {
341 for (Index q = 0; q < diy_dx.nelem(); q++) {
342 for (Index p = 0; p < diy_dx[q].npages(); p++) {
343 for (Index i = 0; i < nf; i++) {
344 Vector x{diy_dx[q](p, i, joker)};
345 mult(diy_dx[q](p, i, joker), surface_rmatrix(0, i, joker, joker), x);
355 ArrayOfTensor3& diy_dx,
356 ArrayOfTensor4& dsurface_rmatrix_dx,
357 ArrayOfMatrix& dsurface_emission_dx,
358 const Tensor3& iy_transmittance,
360 const Index& jacobian_do,
361 const Index& suns_do,
362 const Index& atmosphere_dim,
364 const Index& cloudbox_on,
365 const Index& stokes_dim,
366 const Vector& f_grid,
367 const Vector& lat_grid,
368 const Vector& lon_grid,
369 const Matrix& z_surface,
370 const Vector& refellipsoid,
371 const Vector& rtp_pos,
372 const Vector& rtp_los,
373 const Vector& rte_pos2,
375 const Tensor3& surface_reflectivity,
376 const Tensor3& surface_props_data,
380 const Agenda& iy_main_agenda,
384 ARTS_USER_ERROR_IF(atmosphere_dim==2,
"This method does not work for 2d atmospheres.")
388 chk_size(
"iy",iy,f_grid.nelem(),stokes_dim);
395 surface_props_names);
401 gp_lat[0], gp_lon[0], atmosphere_dim, lat_grid, lon_grid, rtp_pos);
405 Vector surface_skin_t(1);
413 surface_props_names);
420 Tensor3 iy_trans_new;
422 Vector specular_los, surface_normal;
423 ArrayOfMatrix iy_aux;
425 ArrayOfTensor3 diy_dx_dumb;
427 Tensor4 surface_rmatrix;
428 Matrix surface_emission;
429 Tensor3 I(1,f_grid.nelem(),stokes_dim);
430 if (iy_transmittance.npages()) {
431 iy_trans_new=iy_transmittance;
459 surface_reflectivity,
469 dsurface_emission_dx);
476 const Numeric dd = 0.1;
479 dsurface_rmatrix_dx[irq],
480 dsurface_emission_dx[irq],
487 surface_skin_t[0]+dd,
488 surface_reflectivity,
490 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
491 dsurface_rmatrix_dx[irq] /= dd;
492 dsurface_emission_dx[irq] -= surface_emission;
493 dsurface_emission_dx[irq] /= dd;
505 dsurface_emission_dx,
530 const Vector& rtp_pos,
531 const Vector& rtp_los,
532 const Index& stokes_dim,
533 const Vector& f_grid,
534 const Index& atmosphere_dim,
535 const Vector& p_grid,
536 const Vector& lat_grid,
537 const Vector& lon_grid,
538 const Tensor3& z_field,
539 const Tensor3& t_field,
541 const Tensor4& vmr_field,
543 const Tensor3& wind_u_field,
544 const Tensor3& wind_v_field,
545 const Tensor3& wind_w_field,
546 const Tensor3& mag_u_field,
547 const Tensor3& mag_v_field,
548 const Tensor3& mag_w_field,
549 const Matrix& z_surface,
550 const Tensor3& surface_reflectivity,
551 const Vector& refellipsoid,
552 const Tensor4& pnd_field,
553 const ArrayOfTensor4& dpnd_field_dx,
556 const Numeric& ppath_lmax,
557 const Numeric& ppath_lraytrace,
558 const Index& ppath_inside_cloudbox_do,
559 const Index& cloudbox_on,
561 const Index& suns_do,
562 const Index& gas_scattering_do,
563 const Index& jacobian_do,
566 const Numeric& rte_alonglos_v,
568 const Agenda& propmat_clearsky_agenda,
569 const Agenda& water_p_eq_agenda,
570 const Agenda& gas_scattering_agenda,
571 const Agenda& ppath_step_agenda,
575 "If suns are present only iy_unit=\"1\" can be used.");
577 chk_size(
"iy", iy, f_grid.nelem(), stokes_dim);
617 ppath_inside_cloudbox_do,
625 propmat_clearsky_agenda,
627 gas_scattering_agenda,
633 Tensor4 surface_rmatrix;
634 Matrix surface_emission;
635 Numeric surface_skin_t_dummy = 1.;
649 surface_skin_t_dummy,
650 surface_reflectivity,
653 surface_emission *= 0.;
655 Tensor3 I(1, f_grid.nelem(), stokes_dim);
656 I(0, joker, joker) = iy_incoming;
658 surface_calc(iy, I, surface_los, surface_rmatrix, surface_emission);
668 ArrayOfTensor3& diy_dx,
669 ArrayOfTensor4& dsurface_rmatrix_dx,
670 ArrayOfMatrix& dsurface_emission_dx,
671 const Tensor3& iy_transmittance,
673 const Index& jacobian_do,
674 const Index& suns_do,
675 const Index& atmosphere_dim,
677 const Index& cloudbox_on,
678 const Index& stokes_dim,
679 const Vector& f_grid,
680 const Vector& lat_grid,
681 const Vector& lon_grid,
682 const Matrix& z_surface,
683 const Vector& refellipsoid,
684 const Vector& rtp_pos,
685 const Vector& rtp_los,
686 const Vector& rte_pos2,
689 const Tensor3& surface_props_data,
693 const Agenda& iy_main_agenda,
697 ARTS_USER_ERROR_IF(atmosphere_dim==2,
"This method does not work for 2d atmospheres.")
701 chk_size(
"iy",iy,f_grid.nelem(),stokes_dim);
708 surface_props_names);
714 gp_lat[0], gp_lon[0], atmosphere_dim, lat_grid, lon_grid, rtp_pos);
718 Vector surface_skin_t(1);
726 surface_props_names);
732 Tensor3 iy_trans_new;
734 Vector specular_los, surface_normal;
735 ArrayOfMatrix iy_aux;
737 ArrayOfTensor3 diy_dx_dumb;
739 Tensor4 surface_rmatrix;
740 Matrix surface_emission;
741 Tensor3 I(1,f_grid.nelem(),stokes_dim);
742 if (iy_transmittance.npages()) {
743 iy_trans_new=iy_transmittance;
771 surface_complex_refr_index,
781 dsurface_emission_dx);
788 const Numeric dd = 0.1;
791 dsurface_rmatrix_dx[irq],
792 dsurface_emission_dx[irq],
799 surface_skin_t[0]+dd,
800 surface_complex_refr_index,
802 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
803 dsurface_rmatrix_dx[irq] /= dd;
804 dsurface_emission_dx[irq] -= surface_emission;
805 dsurface_emission_dx[irq] /= dd;
817 dsurface_emission_dx,
842 const Vector& rtp_pos,
843 const Vector& rtp_los,
844 const Index& stokes_dim,
845 const Vector& f_grid,
846 const Index& atmosphere_dim,
847 const Vector& p_grid,
848 const Vector& lat_grid,
849 const Vector& lon_grid,
850 const Tensor3& z_field,
851 const Tensor3& t_field,
853 const Tensor4& vmr_field,
855 const Tensor3& wind_u_field,
856 const Tensor3& wind_v_field,
857 const Tensor3& wind_w_field,
858 const Tensor3& mag_u_field,
859 const Tensor3& mag_v_field,
860 const Tensor3& mag_w_field,
861 const Matrix& z_surface,
863 const Vector& refellipsoid,
864 const Tensor4& pnd_field,
865 const ArrayOfTensor4& dpnd_field_dx,
868 const Numeric& ppath_lmax,
869 const Numeric& ppath_lraytrace,
870 const Index& ppath_inside_cloudbox_do,
871 const Index& cloudbox_on,
873 const Index& suns_do,
874 const Index& gas_scattering_do,
875 const Index& jacobian_do,
878 const Numeric& rte_alonglos_v,
880 const Agenda& propmat_clearsky_agenda,
881 const Agenda& water_p_eq_agenda,
882 const Agenda& gas_scattering_agenda,
883 const Agenda& ppath_step_agenda,
887 "If suns are present only iy_unit=\"1\" can be used.");
889 chk_size(
"iy", iy, f_grid.nelem(), stokes_dim);
929 ppath_inside_cloudbox_do,
937 propmat_clearsky_agenda,
939 gas_scattering_agenda,
945 Tensor4 surface_rmatrix;
946 Matrix surface_emission;
947 Numeric surface_skin_t_dummy = 1.;
961 surface_skin_t_dummy,
962 surface_complex_refr_index,
965 surface_emission *= 0.;
967 Tensor3 I(1, f_grid.nelem(), stokes_dim);
968 I(0, joker, joker) = iy_incoming;
970 surface_calc(iy, I, surface_los, surface_rmatrix, surface_emission);
979 const Vector& f_grid,
980 const Index& stokes_dim,
982 iy.resize(f_grid.nelem(), stokes_dim);
989 ArrayOfTensor3& diy_dx,
990 const Tensor3& iy_transmittance,
992 const Index& jacobian_do,
993 const Index& suns_do,
994 const Index& atmosphere_dim,
996 const Index& cloudbox_on,
997 const Index& stokes_dim,
998 const Vector& f_grid,
999 const Vector& lat_grid,
1000 const Vector& lon_grid,
1001 const Matrix& z_surface,
1002 const Vector& refellipsoid,
1003 const Vector& rtp_pos,
1004 const Vector& rtp_los,
1005 const Vector& rte_pos2,
1007 const Vector& surface_scalar_reflectivity,
1008 const Tensor3& surface_props_data,
1012 const Agenda& iy_main_agenda,
1018 surface_scalar_reflectivity.nelem() != 1,
1019 "The number of elements in *surface_scalar_reflectivity* should\n",
1020 "match length of *f_grid* or be 1.",
1021 "\n length of *f_grid* : ", f_grid.nelem(),
1022 "\n length of *surface_scalar_reflectivity* : ",
1023 surface_scalar_reflectivity.nelem());
1025 max(surface_scalar_reflectivity) > 1,
1026 "All values in *surface_scalar_reflectivity* must be inside [0,1].");
1027 ARTS_USER_ERROR_IF(atmosphere_dim==2,
"This method does not work for 2d atmospheres.");
1031 chk_size(
"iy",iy,f_grid.nelem(),stokes_dim);
1038 surface_props_names);
1044 gp_lat[0], gp_lon[0], atmosphere_dim, lat_grid, lon_grid, rtp_pos);
1048 Vector surface_skin_t(1);
1056 surface_props_names);
1063 const Index nf = f_grid.nelem();
1065 Vector za_grid, aa_grid, za_grid_weights;
1078 Tensor3 iy_trans_new;
1083 iy_aux_var.resize(1);
1084 iy_aux_var[0] =
"Direct radiation";
1088 Matrix Flx(nf, 1, 0.);
1090 if (iy_transmittance.npages()) {
1091 iy_trans_new=iy_transmittance;
1095 ArrayOfTensor3 diy_dx_dumb;
1096 iy.resize(nf, stokes_dim);
1106 for (Index i_za = 0; i_za < N_za; i_za++) {
1108 if (atmosphere_dim==1){
1117 los[0] = za_grid[i_za];
1121 ArrayOfMatrix iy_aux;
1123 Vector geo_pos_dumb;
1124 Index iy_id_new = iy_id + i_za + i_aa * N_za + 1;
1150 iy_temp -= iy_aux[0];
1152 iy_temp *= abs(cos(deg2rad(los[0])) * sin(deg2rad(los[0]))) *
1153 za_grid_weights[i_za];
1154 Flx(joker, 0) += iy_temp(joker, 0);
1163 Vector aa_grid_weights;
1164 Vector aa_grid_rad = aa_grid;
1167 for (Index i = 0; i < aa_grid_rad.nelem(); i++) {
1168 aa_grid_rad[i] = deg2rad(aa_grid_rad[i]);
1176 for (Index i_aa = 0; i_aa < N_aa; i_aa++) {
1177 for (Index i_za = 0; i_za < N_za; i_za++) {
1180 los[0] = za_grid[i_za];
1181 los[1] = aa_grid[i_aa];
1184 ArrayOfMatrix iy_aux;
1186 Vector geo_pos_dumb;
1187 Index iy_id_new = iy_id + i_za + i_aa * N_za + 1;
1213 iy_temp -= iy_aux[0];
1215 iy_temp *= abs(cos(deg2rad(los[0])) * sin(deg2rad(los[0]))) *
1216 za_grid_weights[i_za] * aa_grid_weights[i_aa];
1217 Flx(joker, 0) += iy_temp(joker, 0);
1222 Vector specular_los, surface_normal;
1237 planck(
b, f_grid, surface_skin_t[0]);
1241 for (Index i_freq = 0; i_freq < f_grid.nelem(); i_freq++) {
1242 if (i_freq == 0 || surface_scalar_reflectivity.nelem() > 1) {
1243 r = surface_scalar_reflectivity[i_freq];
1246 cos(deg2rad(specular_los[0])) / pi * Flx(i_freq, 0) +
1247 (1 - r) *
b[i_freq];
1251 if (jacobian_do && dsurface_names.
nelem()) {
1259 for (Index j = 0; j < jacobian_quantities.
nelem() && ihit < 0; j++) {
1260 if (dsurface_names[irq] == jacobian_quantities[j].Subtag()) {
1266 Matrix diy_dpos0(f_grid.nelem(), stokes_dim, 0.), diy_dpos;
1267 dplanck_dt(diy_dpos0(joker, 0), f_grid, surface_skin_t[0]);
1269 Vector emissivity=surface_scalar_reflectivity;
1272 diy_dpos0*=ExhaustiveMatrixView{emissivity};
1279 jacobian_quantities[ihit],
1292 const Vector& rtp_pos,
1293 const Index& stokes_dim,
1294 const Vector& f_grid,
1295 const Index& atmosphere_dim,
1296 const Vector& p_grid,
1297 const Vector& lat_grid,
1298 const Vector& lon_grid,
1299 const Tensor3& z_field,
1300 const Tensor3& t_field,
1302 const Tensor4& vmr_field,
1304 const Tensor3& wind_u_field,
1305 const Tensor3& wind_v_field,
1306 const Tensor3& wind_w_field,
1307 const Tensor3& mag_u_field,
1308 const Tensor3& mag_v_field,
1309 const Tensor3& mag_w_field,
1310 const Matrix& z_surface,
1311 const Vector& surface_scalar_reflectivity,
1312 const Vector& refellipsoid,
1313 const Tensor4& pnd_field,
1314 const ArrayOfTensor4& dpnd_field_dx,
1317 const Numeric& ppath_lmax,
1318 const Numeric& ppath_lraytrace,
1319 const Index& cloudbox_on,
1321 const Index& suns_do,
1322 const Index& gas_scattering_do,
1323 const Index& jacobian_do,
1326 const Numeric& rte_alonglos_v,
1328 const Agenda& propmat_clearsky_agenda,
1329 const Agenda& water_p_eq_agenda,
1330 const Agenda& gas_scattering_agenda,
1331 const Agenda& ppath_step_agenda,
1334 ArrayOfVector sun_rte_los(suns.
nelem());
1335 ArrayOfMatrix transmitted_sunlight;
1336 ArrayOfArrayOfTensor3 dtransmitted_sunlight;
1342 "If suns are present only iy_unit=\"1\" can be used.");
1344 chk_size(
"iy",iy,f_grid.nelem(),stokes_dim);
1347 surface_scalar_reflectivity.nelem() != 1,
1348 "The number of elements in *surface_scalar_reflectivity* should\n",
1349 "match length of *f_grid* or be 1.",
1350 "\n length of *f_grid* : ", f_grid.nelem(),
1351 "\n length of *surface_scalar_reflectivity* : ",
1352 surface_scalar_reflectivity.nelem());
1354 max(surface_scalar_reflectivity) > 1,
1355 "All values in *surface_scalar_reflectivity* must be inside [0,1].");
1384 transmitted_sunlight,
1385 dtransmitted_sunlight,
1415 jacobian_quantities,
1416 propmat_clearsky_agenda,
1418 gas_scattering_agenda,
1423 Vector specular_los, surface_normal;
1425 for (Index i_sun = 0; i_sun < suns.
nelem(); i_sun++) {
1426 if (suns_visible[i_sun]) {
1429 Vector incoming_los;
1430 mirror_los(incoming_los,sun_rte_los[i_sun], atmosphere_dim);
1453 Vector iy_surface_direct(f_grid.nelem());
1455 for (Index i_freq = 0; i_freq < f_grid.nelem(); i_freq++) {
1456 if (i_freq == 0 || surface_scalar_reflectivity.nelem() > 1) {
1457 r = surface_scalar_reflectivity[i_freq];
1459 iy_surface_direct[i_freq] = r / pi *
1460 transmitted_sunlight[i_sun](i_freq, 0) *
1461 cos(deg2rad(specular_los[0]));
1465 iy(joker, 0) += iy_surface_direct;
1476 ArrayOfTensor3& diy_dx,
1477 Numeric& surface_skin_t,
1478 Matrix& surface_los,
1479 Tensor4& surface_rmatrix,
1480 Matrix& surface_emission,
1481 const Tensor3& iy_transmittance,
1483 const Index& jacobian_do,
1484 const Index& suns_do,
1485 const Index& atmosphere_dim,
1487 const Index& cloudbox_on,
1488 const Index& stokes_dim,
1489 const Vector& f_grid,
1490 const Vector& rtp_pos,
1491 const Vector& rtp_los,
1492 const Vector& rte_pos2,
1494 const Agenda& iy_main_agenda,
1495 const Agenda& surface_rtprop_agenda,
1511 surface_rtprop_agenda);
1514 const Index nlos = surface_los.nrows();
1515 const Index nf = f_grid.nelem();
1519 if (surface_los.ncols() != rtp_los.nelem())
1520 throw runtime_error(
"Number of columns in *surface_los* is not correct.");
1521 if (nlos != surface_rmatrix.nbooks())
1522 throw runtime_error(
1523 "Mismatch in size of *surface_los* and *surface_rmatrix*.");
1524 if (surface_rmatrix.npages() != nf)
1525 throw runtime_error(
1526 "Mismatch in size of *surface_rmatrix* and *f_grid*.");
1527 if (surface_rmatrix.nrows() != stokes_dim ||
1528 surface_rmatrix.ncols() != stokes_dim)
1529 throw runtime_error(
1530 "Mismatch between size of *surface_rmatrix* and *stokes_dim*.");
1532 if (surface_emission.ncols() != stokes_dim)
1533 throw runtime_error(
1534 "Mismatch between size of *surface_emission* and *stokes_dim*.");
1535 if (surface_emission.nrows() != nf)
1536 throw runtime_error(
"Mismatch in size of *surface_emission* and f_grid*.");
1539 Tensor3 I(nlos, nf, stokes_dim);
1542 if (suns_do) iy_aux_var.emplace_back(
"Direct radiation");
1546 for (Index ilos = 0; ilos < nlos; ilos++) {
1547 Vector los{surface_los(ilos, joker)};
1553 Tensor3 iy_trans_new;
1555 if (iy_transmittance.npages()) {
1558 surface_rmatrix(ilos, joker, joker, joker));
1564 ArrayOfMatrix iy_aux;
1567 Index iy_id_new = iy_id + ilos + 1;
1598 if (iy.ncols() != stokes_dim || iy.nrows() != nf) {
1600 os <<
"The size of *iy* returned from *" << iy_main_agenda.
name()
1603 <<
" expected size = [" << nf <<
"," << stokes_dim <<
"]\n"
1604 <<
" size of iy = [" << iy.nrows() <<
"," << iy.ncols() <<
"]\n";
1605 throw runtime_error(os.str());
1608 I(ilos, joker, joker) = iy;
1613 surface_calc(iy, I, surface_los, surface_rmatrix, surface_emission);
1619 ArrayOfTensor3& diy_dx,
1620 const Matrix& surface_los,
1621 const Tensor4& surface_rmatrix,
1622 const Matrix& surface_emission,
1624 const ArrayOfTensor4& dsurface_rmatrix_dx,
1625 const ArrayOfMatrix& dsurface_emission_dx,
1626 const Tensor3& iy_transmittance,
1628 const Index& jacobian_do,
1629 const Index& suns_do,
1631 const Index& atmosphere_dim,
1633 const Index& cloudbox_on,
1634 const Index& stokes_dim,
1635 const Vector& f_grid,
1636 const Vector& rtp_pos,
1637 const Vector& rtp_los,
1638 const Vector& rte_pos2,
1640 const Agenda& iy_main_agenda,
1648 const Index nlos = surface_los.nrows();
1649 const Index nf = f_grid.nelem();
1653 if (surface_los.ncols() != rtp_los.nelem())
1654 throw runtime_error(
"Number of columns in *surface_los* is not correct.");
1655 if (nlos != surface_rmatrix.nbooks())
1656 throw runtime_error(
1657 "Mismatch in size of *surface_los* and *surface_rmatrix*.");
1658 if (surface_rmatrix.npages() != nf)
1659 throw runtime_error(
1660 "Mismatch in size of *surface_rmatrix* and *f_grid*.");
1661 if (surface_rmatrix.nrows() != stokes_dim ||
1662 surface_rmatrix.ncols() != stokes_dim)
1663 throw runtime_error(
1664 "Mismatch between size of *surface_rmatrix* and *stokes_dim*.");
1666 if (surface_emission.ncols() != stokes_dim)
1667 throw runtime_error(
1668 "Mismatch between size of *surface_emission* and *stokes_dim*.");
1669 if (surface_emission.nrows() != nf)
1670 throw runtime_error(
"Mismatch in size of *surface_emission* and f_grid*.");
1673 Tensor3 I(nlos, nf, stokes_dim);
1676 if (suns_do) iy_aux_var.emplace_back(
"Direct radiation");
1680 for (Index ilos = 0; ilos < nlos; ilos++) {
1681 Vector los{surface_los(ilos, joker)};
1687 Tensor3 iy_trans_new;
1689 if (iy_transmittance.npages()) {
1692 surface_rmatrix(ilos, joker, joker, joker));
1698 ArrayOfMatrix iy_aux;
1731 if (iy.ncols() != stokes_dim || iy.nrows() != nf) {
1733 os <<
"The size of *iy* returned from *" << iy_main_agenda.
name()
1736 <<
" expected size = [" << nf <<
"," << stokes_dim <<
"]\n"
1737 <<
" size of iy = [" << iy.nrows() <<
"," << iy.ncols() <<
"]\n";
1738 throw runtime_error(os.str());
1741 I(ilos, joker, joker) = iy;
1746 surface_calc(iy, I, surface_los, surface_rmatrix, surface_emission);
1749 if (jacobian_do && dsurface_names.
nelem()) {
1751 for (Index i = 0; i < dsurface_names.
nelem(); i++) {
1754 if (dsurface_emission_dx[i].empty() || dsurface_rmatrix_dx[i].empty()) {
1756 os <<
"The derivatives for surface quantity: " << dsurface_names[i]
1757 <<
"\nwere not calculated by *iy_surface_agenda*.\n"
1758 <<
"That is, *dsurface_emission_dx* and/or *dsurface_rmatrix_dx*\n"
1760 throw runtime_error(os.str());
1764 for (Index j = 0; j < jacobian_quantities.
nelem() && ihit < 0; j++) {
1765 if (dsurface_names[i] == jacobian_quantities[j].Subtag()) {
1771 Matrix diy_dpos0, diy_dpos;
1775 dsurface_rmatrix_dx[i],
1776 dsurface_emission_dx[i]);
1781 jacobian_quantities[ihit],
1792 Vector& surface_normal,
1793 const Vector& rtp_pos,
1794 const Vector& rtp_los,
1795 const Index& atmosphere_dim,
1801 surface_normal.resize(
max(Index(1), atmosphere_dim - 1));
1802 specular_los.resize(
max(Index(1), atmosphere_dim - 1));
1804 if (atmosphere_dim == 1) {
1805 surface_normal[0] = 0;
1806 if (rtp_los[0] < 90) {
1807 throw runtime_error(
1808 "Invalid zenith angle. The zenith angle corresponds "
1809 "to observe the surface from below.");
1811 specular_los[0] = 180 - rtp_los[0];
1814 else if (atmosphere_dim == 2) {
1815 specular_los[0] =
sign(rtp_los[0]) * 180 - rtp_los[0];
1816 surface_normal[0] = 0;
1819 else if (atmosphere_dim == 3) {
1820 specular_los[0] = 180 - rtp_los[0];
1821 specular_los[1] = rtp_los[1];
1822 surface_normal[0] = 0;
1823 surface_normal[1] = 0;
1829 Vector& surface_normal,
1830 const Vector& rtp_pos,
1831 const Vector& rtp_los,
1832 const Index& atmosphere_dim,
1833 const Vector& lat_grid,
1834 const Vector& lon_grid,
1835 const Vector& refellipsoid,
1836 const Matrix& z_surface,
1837 const Index& ignore_surface_slope,
1845 if (atmosphere_dim == 1 || ignore_surface_slope) {
1855 surface_normal.resize(
max(Index(1), atmosphere_dim - 1));
1856 specular_los.resize(
max(Index(1), atmosphere_dim - 1));
1858 if (atmosphere_dim == 2) {
1861 gridpos(gp_lat, lat_grid, rtp_pos[1]);
1864 c1, lat_grid, refellipsoid, z_surface(joker, 0), gp_lat, rtp_los[0]);
1867 const Numeric rv_surface =
refell2d(refellipsoid, lat_grid, gp_lat) +
1868 interp(itw, z_surface(joker, 0), gp_lat);
1870 if (abs(rtp_los[0] - surface_normal[0]) < 90) {
1871 throw runtime_error(
1872 "Invalid zenith angle. The zenith angle corresponds "
1873 "to observe the surface from below.");
1876 sign(rtp_los[0]) * 180 - rtp_los[0] + 2 * surface_normal[0];
1884 gridpos(gp_lat, lat_grid, rtp_pos[1]);
1885 gridpos(gp_lon, lon_grid, rtp_pos[2]);
1888 c1, c2, lat_grid, lon_grid, refellipsoid, z_surface, gp_lat, gp_lon, 0);
1891 const Numeric rv_surface =
refell2d(refellipsoid, lat_grid, gp_lat) +
1892 interp(itw, z_surface, gp_lat, gp_lon);
1906 Vector tangentSN(3), tangentEW(3), normal(3);
1907 zaaa2cart(tangentSN[0], tangentSN[1], tangentSN[2], zaSN, 0);
1908 zaaa2cart(tangentEW[0], tangentEW[1], tangentEW[2], zaEW, 90);
1909 cross3(normal, tangentSN, tangentEW);
1912 zaaa2cart(di[0], di[1], di[2], rtp_los[0], rtp_los[1]);
1916 surface_normal[0], surface_normal[1], normal[0], normal[1], normal[2]);
1917 if (abs(rtp_los[0] - surface_normal[0]) < 90) {
1918 throw runtime_error(
1919 "Invalid zenith angle. The zenith angle corresponds "
1920 "to observe the surface from below.");
1924 const Numeric
fac = 2 * (normal * di);
1925 for (Index i = 0; i < 3; i++) {
1926 speccart[i] =
fac * normal[i] - di[i];
1938 Tensor4& surface_rmatrix,
1939 Matrix& surface_emission,
1940 const Index& atmosphere_dim,
1941 const Vector& f_grid,
1942 const Index& stokes_dim,
1943 const Vector& rtp_pos,
1944 const Vector& rtp_los,
1945 const Numeric& surface_skin_t,
1953 out2 <<
" Sets variables to model a blackbody surface with a temperature "
1954 <<
" of " << surface_skin_t <<
" K.\n";
1956 surface_los.resize(0, 0);
1957 surface_rmatrix.resize(0, 0, 0, 0);
1959 const Index nf = f_grid.nelem();
1962 planck(
b, f_grid, surface_skin_t);
1964 surface_emission.resize(nf, stokes_dim);
1965 surface_emission = 0.0;
1967 for (Index iv = 0; iv < nf; iv++) {
1968 surface_emission(iv, 0) =
b[iv];
1969 for (Index is = 1; is < stokes_dim; is++) {
1970 surface_emission(iv, is) = 0;
1977 Tensor4& surface_rmatrix,
1978 Matrix& surface_emission,
1979 const Index& atmosphere_dim,
1980 const Index& stokes_dim,
1981 const Vector& f_grid,
1982 const Vector& rtp_pos,
1983 const Vector& rtp_los,
1984 const Numeric& surface_skin_t,
1985 const Numeric& salinity,
1986 const Numeric& wind_speed,
1987 const Numeric& wind_direction,
1988 const Vector& transmittance,
1989 const Index& fastem_version,
1997 const Index nf = f_grid.nelem();
2000 Vector specular_los, surface_normal;
2016 Numeric rel_azimuth = wind_direction;
2017 if (atmosphere_dim == 2 && rtp_los[0] < 0) {
2020 }
else if (atmosphere_dim == 3) {
2021 rel_azimuth -= rtp_los[1];
2026 Matrix emissivity, reflectivity;
2040 surface_los.resize(1, specular_los.nelem());
2041 surface_los(0, joker) = specular_los;
2046 planck(
b, f_grid, surface_skin_t);
2048 surface_emission.resize(nf, stokes_dim);
2049 for (Index i = 0; i < nf; i++) {
2051 surface_emission(i, 0) =
b[i] * 0.5 * (emissivity(i, 0) + emissivity(i, 1));
2053 if (stokes_dim >= 2) {
2054 surface_emission(i, 1) =
2055 b[i] * 0.5 * (emissivity(i, 0) - emissivity(i, 1));
2058 for (Index j = 2; j < stokes_dim; j++) {
2059 surface_emission(i, j) =
b[i] * emissivity(i, j);
2065 surface_rmatrix.resize(1, nf, stokes_dim, stokes_dim);
2066 surface_rmatrix = 0.0;
2067 for (Index iv = 0; iv < nf; iv++) {
2068 surface_rmatrix(0, iv, 0, 0) =
2069 0.5 * (reflectivity(iv, 0) + reflectivity(iv, 1));
2070 if (stokes_dim >= 2) {
2071 surface_rmatrix(0, iv, 0, 1) =
2072 0.5 * (reflectivity(iv, 0) - reflectivity(iv, 1));
2074 surface_rmatrix(0, iv, 1, 0) = surface_rmatrix(0, iv, 0, 1);
2075 surface_rmatrix(0, iv, 1, 1) = surface_rmatrix(0, iv, 0, 0);
2077 for (Index i = 2; i < stokes_dim; i++) {
2078 surface_rmatrix(0, iv, i, i) = surface_rmatrix(0, iv, 0, 0);
2086 Tensor4& surface_rmatrix,
2087 const Index& stokes_dim,
2088 const Numeric& pol_angle,
2091 "You should only use this method where the main calculations are "
2092 "done with *stokes_dim* set to 1.");
2094 Index local_stokes = surface_emission.ncols();
2096 "This method requires that the input surface proporties match a Stokes "
2097 "dimension of 2-4. Incoming *surface_emission* matches stokes_dim=1.");
2099 const Index nf = surface_emission.nrows();
2100 const Index nlos = surface_rmatrix.nbooks();
2101 Matrix se = surface_emission;
2102 Tensor4 sr = surface_rmatrix;
2103 surface_emission.resize(nf, 1);
2104 surface_rmatrix.resize(nlos, nf, 1, 1);
2106 if (local_stokes == 2) {
2107 const Numeric alpha =
DEG2RAD * pol_angle;
2108 const Numeric c2 = pow( cos(alpha), 2 );
2109 const Numeric s2 = pow( sin(alpha), 2 );
2110 for (Index f=0; f<nf; ++f) {
2111 const Numeric bv = se(f,0) + se(f,1);
2112 const Numeric bh = se(f,0) - se(f,1);
2113 surface_emission(f,0) = c2*bv + s2*bh;
2114 for (Index l=0; l<nlos; ++l) {
2115 const Numeric rv = sr(l,f,0,0) + sr(l,f,1,0);
2116 const Numeric rh = sr(l,f,0,0) - sr(l,f,1,0);
2117 surface_rmatrix(l,f,0,0) = c2*rv + s2*rh;
2121 Matrix Cm, Cs, Lp, Lm;
2126 Matrix Mleft(local_stokes,local_stokes), Mright(local_stokes,local_stokes);
2127 mult(Mleft, Cm, Lp);
2128 mult(Mright, Lm, Cs);
2130 Vector Vr(local_stokes);
2131 Matrix Tmp(local_stokes,local_stokes), Mr(local_stokes,local_stokes);
2133 for (Index f=0; f<nf; ++f) {
2134 mult(Vr, Mleft, se(f,joker) );
2135 surface_emission(f,0) = 2.0 * Vr[0];
2136 for (Index l=0; l<nlos; ++l) {
2137 mult(Tmp, sr(l,f,joker,joker), Mright);
2138 mult(Mr, Mleft, Tmp);
2139 surface_rmatrix(l,f,0,0) = Tmp(0,0);
2147 Tensor4& surface_rmatrix,
2148 Matrix& surface_emission,
2149 const Index& atmosphere_dim,
2150 const Index& stokes_dim,
2151 const Vector& f_grid,
2152 const Vector& lat_grid,
2153 const Vector& lat_true,
2154 const Vector& lon_true,
2155 const Vector& rtp_pos,
2156 const Vector& rtp_los,
2157 const Vector& specular_los,
2158 const Numeric& surface_skin_t,
2160 const Numeric& r_min,
2161 const Numeric& r_max,
2162 const Numeric& d_max,
2170 "surface skin temperature", surface_skin_t, 190.0, 373.0);
2172 const Index nf = f_grid.nelem();
2173 Matrix surface_rv_rh(nf, 2);
2179 lat, lon, atmosphere_dim, lat_grid, lat_true, lon_true, rtp_pos);
2182 lon = fmod(lon, 360.0);
2192 throw std::runtime_error(
2193 "Given coordinates are not contained in "
2194 " TELSEM atlas. To enable nearest neighbour"
2195 "interpolation set *d_max* to a positive "
2199 Numeric lat_nn, lon_nn;
2201 Numeric
d =
sphdist(lat, lon, lat_nn, lon_nn);
2203 std::ostringstream out{};
2204 out <<
"Distance of nearest neighbour exceeds provided limit (";
2205 out <<
d <<
" > " << d_max <<
").";
2206 throw std::runtime_error(out.str());
2214 Vector emis_h = atlas.
get_emis_h(cellnumber);
2215 Vector emis_v = atlas.
get_emis_v(cellnumber);
2219 const Numeric theta =
calc_incang(rtp_los, specular_los);
2222 for (Index i = 0; i < nf; ++i) {
2223 if (f_grid[i] < 5e9)
2224 throw std::runtime_error(
"Only frequency >= 5 GHz are allowed");
2225 if (f_grid[i] > 900e9)
2226 throw std::runtime_error(
"Only frequency <= 900 GHz are allowed");
2230 Numeric f = std::min(f_grid[i], 700e9) * 1e-9;
2231 std::tie(e_v, e_h) =
2232 atlas.
emis_interp(theta, f, class1, class2, emis_v, emis_h);
2234 surface_rv_rh(i, 0) =
min(
max(1.0 - e_v, r_min), r_max);
2235 surface_rv_rh(i, 1) =
min(
max(1.0 - e_h, r_min), r_max);
2254 Tensor4& surface_rmatrix,
2255 Matrix& surface_emission,
2256 const Index& atmosphere_dim,
2257 const Index& stokes_dim,
2258 const Vector& f_grid,
2259 const Vector& rtp_pos,
2260 const Vector& rtp_los,
2261 const Numeric& surface_skin_t,
2264 const Numeric& salinity,
2265 const Numeric& wind_speed,
2272 "surface skin temperature", surface_skin_t, 260.0, 373.0);
2277 Vector specular_los, surface_normal;
2288 VectorView e_h = out[Range(0, 1)];
2289 VectorView e_v = out[Range(1, 1)];
2292 in[1] = 180.0 - abs(rtp_los[0]);
2294 in[3] = surface_skin_t;
2299 const Index nf = f_grid.nelem();
2300 Matrix surface_rv_rh(nf, 2);
2302 for (Index i = 0; i < nf; ++i) {
2303 if (f_grid[i] < 5e9)
2304 throw std::runtime_error(
"Only frequency >= 5 GHz are allowed");
2305 if (f_grid[i] > 900e9)
2306 throw std::runtime_error(
"Only frequency <= 900 GHz are allowed");
2313 surface_rv_rh(i, 0) =
min(
max(1 - e_v[0], (Numeric)0), (Numeric)1);
2314 surface_rv_rh(i, 1) =
min(
max(1 - e_h[0], (Numeric)0), (Numeric)1);
2333 Tensor4& surface_rmatrix,
2334 Matrix& surface_emission,
2335 const Vector& f_grid,
2336 const Index& stokes_dim,
2337 const Index& atmosphere_dim,
2338 const Vector& rtp_pos,
2339 const Vector& rtp_los,
2340 const Vector& specular_los,
2341 const Numeric& surface_skin_t,
2356 const Index nf = f_grid.nelem();
2358 Matrix n_real(nf, 1), n_imag(nf, 1);
2362 surface_complex_refr_index,
2363 "surface_complex_refr_index",
2365 Vector(1, surface_skin_t));
2367 out2 <<
" Sets variables to model a flat surface\n";
2368 out3 <<
" surface temperature: " << surface_skin_t <<
" K.\n";
2370 surface_los.resize(1, specular_los.nelem());
2371 surface_los(0, joker) = specular_los;
2373 surface_emission.resize(nf, stokes_dim);
2374 surface_rmatrix.resize(1, nf, stokes_dim, stokes_dim);
2377 const Numeric incang =
calc_incang(rtp_los, specular_los);
2383 for (Index iv = 0; iv < nf; iv++) {
2385 Complex n2(n_real(iv, 0), n_imag(iv, 0));
2388 fresnel(Rv, Rh, Numeric(1.0), n2, incang);
2392 surface_emission(iv, joker),
2403 Tensor4& surface_rmatrix,
2404 Matrix& surface_emission,
2405 const Vector& f_grid,
2406 const Index& stokes_dim,
2407 const Index& atmosphere_dim,
2408 const Vector& rtp_pos,
2409 const Vector& rtp_los,
2410 const Vector& specular_los,
2411 const Numeric& surface_skin_t,
2412 const Tensor3& surface_reflectivity,
2423 const Index nf = f_grid.nelem();
2425 if (surface_reflectivity.nrows() != stokes_dim &&
2426 surface_reflectivity.ncols() != stokes_dim) {
2428 os <<
"The number of rows and columnss in *surface_reflectivity* must\n"
2429 <<
"match *stokes_dim*."
2430 <<
"\n stokes_dim : " << stokes_dim
2431 <<
"\n number of rows in *surface_reflectivity* : "
2432 << surface_reflectivity.nrows()
2433 <<
"\n number of columns in *surface_reflectivity* : "
2434 << surface_reflectivity.ncols() <<
"\n";
2435 throw runtime_error(os.str());
2438 if (surface_reflectivity.npages() != nf &&
2439 surface_reflectivity.npages() != 1) {
2441 os <<
"The number of pages in *surface_reflectivity* should\n"
2442 <<
"match length of *f_grid* or be 1."
2443 <<
"\n length of *f_grid* : " << nf
2444 <<
"\n dimension of *surface_reflectivity* : "
2445 << surface_reflectivity.npages() <<
"\n";
2446 throw runtime_error(os.str());
2449 out2 <<
" Sets variables to model a flat surface\n";
2451 surface_los.resize(1, specular_los.nelem());
2452 surface_los(0, joker) = specular_los;
2454 surface_emission.resize(nf, stokes_dim);
2455 surface_rmatrix.resize(1, nf, stokes_dim, stokes_dim);
2457 Matrix R, IR(stokes_dim, stokes_dim);
2460 planck(
b, f_grid, surface_skin_t);
2462 Vector B(stokes_dim, 0);
2464 for (Index iv = 0; iv < nf; iv++) {
2465 if (iv == 0 || surface_reflectivity.npages() > 1) {
2466 R = surface_reflectivity(iv, joker, joker);
2467 for (Index i = 0; i < stokes_dim; i++) {
2468 for (Index j = 0; j < stokes_dim; j++) {
2470 IR(i, j) = 1 - R(i, j);
2472 IR(i, j) = -R(i, j);
2478 surface_rmatrix(0, iv, joker, joker) = R;
2481 mult(surface_emission(iv, joker), IR, B);
2487 Tensor4& surface_rmatrix,
2488 Matrix& surface_emission,
2489 const Vector& f_grid,
2490 const Index& stokes_dim,
2491 const Index& atmosphere_dim,
2492 const Vector& rtp_pos,
2493 const Vector& rtp_los,
2494 const Vector& specular_los,
2495 const Numeric& surface_skin_t,
2496 const Matrix& surface_rv_rh,
2505 const Index nf = f_grid.nelem();
2507 if (surface_rv_rh.ncols() != 2) {
2509 os <<
"The number of columns in *surface_rv_rh* must be two,\n"
2510 <<
"but the actual number of columns is " << surface_rv_rh.ncols()
2512 throw runtime_error(os.str());
2515 if (surface_rv_rh.nrows() != nf && surface_rv_rh.nrows() != 1) {
2517 os <<
"The number of rows in *surface_rv_rh* should\n"
2518 <<
"match length of *f_grid* or be 1."
2519 <<
"\n length of *f_grid* : " << nf
2520 <<
"\n rows in *surface_rv_rh* : " << surface_rv_rh.nrows() <<
"\n";
2521 throw runtime_error(os.str());
2524 if (
min(surface_rv_rh) < 0 ||
max(surface_rv_rh) > 1) {
2525 throw runtime_error(
"All values in *surface_rv_rh* must be inside [0,1].");
2528 surface_los.resize(1, specular_los.nelem());
2529 surface_los(0, joker) = specular_los;
2531 surface_emission.resize(nf, stokes_dim);
2532 surface_rmatrix.resize(1, nf, stokes_dim, stokes_dim);
2534 surface_emission = 0;
2535 surface_rmatrix = 0;
2538 planck(
b, f_grid, surface_skin_t);
2540 Numeric rmean = 0.0, rdiff = 0.0;
2542 for (Index iv = 0; iv < nf; iv++) {
2543 if (iv == 0 || surface_rv_rh.nrows() > 1) {
2544 rmean = 0.5 * (surface_rv_rh(iv, 0) + surface_rv_rh(iv, 1));
2545 rdiff = 0.5 * (surface_rv_rh(iv, 0) - surface_rv_rh(iv, 1));
2548 surface_emission(iv, 0) = (1.0 - rmean) *
b[iv];
2549 surface_rmatrix(0, iv, 0, 0) = rmean;
2551 if (stokes_dim > 1) {
2552 surface_emission(iv, 1) = -rdiff *
b[iv];
2554 surface_rmatrix(0, iv, 0, 1) = rdiff;
2555 surface_rmatrix(0, iv, 1, 0) = rdiff;
2556 surface_rmatrix(0, iv, 1, 1) = rmean;
2558 for (Index i = 2; i < stokes_dim; i++) {
2559 surface_rmatrix(0, iv, i, i) = rmean;
2567 Tensor4& surface_rmatrix,
2568 Matrix& surface_emission,
2569 const Vector& f_grid,
2570 const Index& stokes_dim,
2571 const Index& atmosphere_dim,
2572 const Vector& rtp_pos,
2573 const Vector& rtp_los,
2574 const Vector& specular_los,
2575 const Numeric& surface_skin_t,
2576 const Vector& surface_scalar_reflectivity,
2585 const Index nf = f_grid.nelem();
2587 if (surface_scalar_reflectivity.nelem() != nf &&
2588 surface_scalar_reflectivity.nelem() != 1) {
2590 os <<
"The number of elements in *surface_scalar_reflectivity* should\n"
2591 <<
"match length of *f_grid* or be 1."
2592 <<
"\n length of *f_grid* : " << nf
2593 <<
"\n length of *surface_scalar_reflectivity* : "
2594 << surface_scalar_reflectivity.nelem() <<
"\n";
2595 throw runtime_error(os.str());
2598 if (
min(surface_scalar_reflectivity) < 0 ||
2599 max(surface_scalar_reflectivity) > 1) {
2600 throw runtime_error(
2601 "All values in *surface_scalar_reflectivity* must be inside [0,1].");
2604 surface_los.resize(1, specular_los.nelem());
2605 surface_los(0, joker) = specular_los;
2607 surface_emission.resize(nf, stokes_dim);
2608 surface_rmatrix.resize(1, nf, stokes_dim, stokes_dim);
2610 surface_emission = 0;
2611 surface_rmatrix = 0;
2614 planck(
b, f_grid, surface_skin_t);
2618 for (Index iv = 0; iv < nf; iv++) {
2619 if (iv == 0 || surface_scalar_reflectivity.nelem() > 1) {
2620 r = surface_scalar_reflectivity[iv];
2623 surface_emission(iv, 0) = (1.0 - r) *
b[iv];
2624 surface_rmatrix(0, iv, 0, 0) = r;
2625 for (Index i = 1; i < stokes_dim; i++) {
2626 surface_rmatrix(0, iv, i, i) = r;
2633 Tensor4& surface_rmatrix,
2634 Matrix& surface_emission,
2635 const Vector& f_grid,
2636 const Index& stokes_dim,
2637 const Index& atmosphere_dim,
2638 const Vector& rtp_pos,
2639 const Vector& rtp_los,
2640 const Vector& surface_normal,
2641 const Numeric& surface_skin_t,
2642 const Vector& surface_scalar_reflectivity,
2643 const Index& lambertian_nza,
2644 const Numeric& za_pos,
2646 const Index nf = f_grid.nelem();
2655 if (surface_scalar_reflectivity.nelem() != nf &&
2656 surface_scalar_reflectivity.nelem() != 1) {
2658 os <<
"The number of elements in *surface_scalar_reflectivity* should\n"
2659 <<
"match length of *f_grid* or be 1."
2660 <<
"\n length of *f_grid* : " << nf
2661 <<
"\n length of *surface_scalar_reflectivity* : "
2662 << surface_scalar_reflectivity.nelem() <<
"\n";
2663 throw runtime_error(os.str());
2666 if (
min(surface_scalar_reflectivity) < 0 ||
2667 max(surface_scalar_reflectivity) > 1) {
2668 throw runtime_error(
2669 "All values in *surface_scalar_reflectivity* must be inside [0,1].");
2674 surface_los.resize(lambertian_nza, rtp_los.nelem());
2675 surface_rmatrix.resize(lambertian_nza, nf, stokes_dim, stokes_dim);
2676 surface_emission.resize(nf, stokes_dim);
2679 surface_rmatrix = 0.0;
2680 surface_emission = 0.0;
2684 const Numeric dza = (90.0 - abs(surface_normal[0])) / (Numeric)lambertian_nza;
2685 const Vector za_lims=uniform_grid(0.0, lambertian_nza + 1, dza);
2688 for (Index ip = 0; ip < lambertian_nza; ip++) {
2689 surface_los(ip, 0) = za_lims[ip] + za_pos * dza;
2690 if (atmosphere_dim == 2) {
2691 if (rtp_los[0] < 0) {
2692 surface_los(ip, 0) *= -1.0;
2695 }
else if (atmosphere_dim == 3) {
2696 surface_los(ip, 1) = rtp_los[1];
2701 planck(
b, f_grid, surface_skin_t);
2707 for (Index iv = 0; iv < nf; iv++) {
2709 if (iv == 0 || surface_scalar_reflectivity.nelem() > 1) {
2710 r = surface_scalar_reflectivity[iv];
2721 for (Index ip = 0; ip < lambertian_nza; ip++) {
2724 (cos(2 *
DEG2RAD * za_lims[ip]) - cos(2 *
DEG2RAD * za_lims[ip + 1]));
2725 surface_rmatrix(ip, iv, 0, 0) =
w;
2729 surface_emission(iv, 0) = (1 - r) *
b[iv];
2736 const Index& atmosphere_dim,
2737 const Vector& lat_grid,
2738 const Vector& lat_true,
2739 const Vector& lon_true,
2740 const Vector& rtp_pos,
2744 Index gfield_fID = 0;
2745 Index gfield_tID = 1;
2746 Index gfield_compID = 2;
2747 Index gfield_latID = 3;
2748 Index gfield_lonID = 4;
2762 const Index nf = complex_n_field.
data.nshelves();
2763 const Index nt = complex_n_field.
data.nbooks();
2764 const Index nn = complex_n_field.
data.npages();
2765 const Index nlat = complex_n_field.
data.nrows();
2766 const Index nlon = complex_n_field.
data.ncols();
2768 if (nlat < 2 || nlon < 2) {
2770 os <<
"The data in *complex_refr_index_field* must span a geographical "
2771 <<
"region. That is,\nthe latitude and longitude grids must have a "
2773 throw runtime_error(os.str());
2778 os <<
"The data in *complex_refr_index_field* must have exactly two "
2779 <<
"pages. One page each\nfor the real and imaginary part of the "
2780 <<
"complex refractive index.";
2781 throw runtime_error(os.str());
2788 Vector lat(1), lon(1);
2790 lat[0], lon[0], atmosphere_dim, lat_grid, lat_true, lon_true, rtp_pos);
2798 chk_if_in_range(
"rtp_pos.lon", lon[0], lon_shifted[0], lon_shifted[nlon - 1]);
2801 surface_complex_refr_index.
resize(nf, nt, 2);
2803 surface_complex_refr_index.
set_grid(
2806 surface_complex_refr_index.
set_grid(
2809 surface_complex_refr_index.
set_grid(2, {
"real",
"imaginary"});
2814 gridpos(gp_lat, GFlat, lat[0]);
2815 gridpos(gp_lon, lon_shifted, lon[0]);
2819 for (Index iv = 0; iv < nf; iv++) {
2820 for (Index it = 0; it < nt; it++) {
2821 surface_complex_refr_index.
data(iv, it, 0) =
interp(
2822 itw, complex_n_field.
data(iv, it, 0, joker, joker), gp_lat, gp_lon);
2823 surface_complex_refr_index.
data(iv, it, 1) =
interp(
2824 itw, complex_n_field.
data(iv, it, 1, joker, joker), gp_lat, gp_lon);
2831 const Index& stokes_dim,
2832 const Vector& f_grid,
2833 const Index& atmosphere_dim,
2834 const Vector& lat_grid,
2835 const Vector& lat_true,
2836 const Vector& lon_true,
2837 const Vector& rtp_pos,
2838 const Vector& rtp_los,
2855 const Index nf_in = r_field.
data.nvitrines();
2856 const Index ns2 = r_field.
data.nshelves();
2857 const Index ns1 = r_field.
data.nbooks();
2858 const Index nza = r_field.
data.npages();
2859 const Index nlat = r_field.
data.nrows();
2860 const Index nlon = r_field.
data.ncols();
2862 if (nlat < 2 || nlon < 2) {
2864 os <<
"The data in *r_field* must span a geographical region. That is,\n"
2865 <<
"the latitude and longitude grids must have a length >= 2.";
2866 throw runtime_error(os.str());
2871 os <<
"The data in *r_field* must span a range of zenith angles. That\n"
2872 <<
"is the zenith angle grid must have a length >= 2.";
2873 throw runtime_error(os.str());
2875 if (ns1 < stokes_dim || ns2 < stokes_dim || ns1 > 4 || ns2 > 4) {
2877 os <<
"The \"Stokes dimensions\" must have a size that is >= "
2878 <<
"*stokes_dim* (but not exceeding 4).";
2879 throw runtime_error(os.str());
2883 Vector lat(1), lon(1);
2885 lat[0], lon[0], atmosphere_dim, lat_grid, lat_true, lon_true, rtp_pos);
2892 Tensor4 r_f_za(nf_in, stokes_dim, stokes_dim, nza);
2899 gridpos(gp_lon, lon_shifted, lon[0]);
2902 for (Index iv = 0; iv < nf_in; iv++) {
2903 for (Index iz = 0; iz < nza; iz++) {
2904 for (Index is1 = 0; is1 < stokes_dim; is1++) {
2905 for (Index is2 = 0; is2 < stokes_dim; is2++) {
2906 r_f_za(iv, is1, is2, iz) =
2908 r_field.
data(iv, is1, is2, iz, joker, joker),
2918 Tensor3 r_f(nf_in, stokes_dim, stokes_dim);
2925 "Incidence angle interpolation", r_field.
get_numeric_grid(3), 180 - rtp_los[0]);
2926 const LagrangeInterpolation lag(0, 180 - rtp_los[0], r_field.
get_numeric_grid(3), order);
2929 for (Index i = 0; i < nf_in; i++) {
2930 for (Index is1 = 0; is1 < stokes_dim; is1++) {
2931 for (Index is2 = 0; is2 < stokes_dim; is2++) {
2932 r_f(i, is1, is2) =
interp(r_f_za(i, is1, is2, joker), itw, lag);
2941 surface_reflectivity = r_f;
2945 const Index nf_out = f_grid.nelem();
2946 surface_reflectivity.resize(nf_out, stokes_dim, stokes_dim);
2949 Matrix itw(nf_out, 2);
2952 for (Index is1 = 0; is1 < stokes_dim; is1++) {
2953 for (Index is2 = 0; is2 < stokes_dim; is2++) {
2954 interp(surface_reflectivity(joker, is1, is2),
2956 r_f(joker, is1, is2),
2965 Vector& surface_scalar_reflectivity,
2966 const Index& stokes_dim,
2967 const Vector& f_grid,
2968 const Index& atmosphere_dim,
2969 const Vector& lat_grid,
2970 const Vector& lat_true,
2971 const Vector& lon_true,
2972 const Vector& rtp_pos,
2973 const Vector& rtp_los,
2988 const Index nf_in = r_field.
data.nbooks();
2989 const Index nza = r_field.
data.npages();
2990 const Index nlat = r_field.
data.nrows();
2991 const Index nlon = r_field.
data.ncols();
2993 if (nlat < 2 || nlon < 2) {
2995 os <<
"The data in *r_field* must span a geographical region. That is,\n"
2996 <<
"the latitude and longitude grids must have a length >= 2.";
2997 throw runtime_error(os.str());
3002 os <<
"The data in *r_field* must span a range of zenith angles. That\n"
3003 <<
"is the zenith angle grid must have a length >= 2.";
3004 throw runtime_error(os.str());
3008 Vector lat(1), lon(1);
3010 lat[0], lon[0], atmosphere_dim, lat_grid, lat_true, lon_true, rtp_pos);
3017 Matrix r_f_za(nf_in, nza);
3024 gridpos(gp_lon, lon_shifted, lon[0]);
3027 for (Index iv = 0; iv < nf_in; iv++) {
3028 for (Index iz = 0; iz < nza; iz++) {
3030 interp(itw, r_field.
data(iv, iz, joker, joker), gp_lat, gp_lon);
3043 "Incidence angle interpolation", r_field.
get_numeric_grid(1), 180 - rtp_los[0]);
3044 const LagrangeInterpolation lag(0, 180 - rtp_los[0], r_field.
get_numeric_grid(1), order);
3046 for (Index i = 0; i < nf_in; i++) {
3047 r_f[i] =
interp(r_f_za(i, joker), itw, lag);
3054 surface_scalar_reflectivity.resize(1);
3055 surface_scalar_reflectivity[0] = r_f[0];
3059 const Index nf_out = f_grid.nelem();
3060 surface_scalar_reflectivity.resize(nf_out);
3063 Matrix itw(nf_out, 2);
3066 interp(surface_scalar_reflectivity, itw, r_f, gp);
3072 Vector& surface_scalar_reflectivity,
3073 const Tensor4& surface_rmatrix,
3075 const Index nf = surface_rmatrix.npages();
3076 const Index nlos = surface_rmatrix.nbooks();
3078 surface_scalar_reflectivity.resize(nf);
3079 surface_scalar_reflectivity = 0;
3081 for (Index i = 0; i < nf; i++) {
3082 for (Index l = 0; l < nlos; l++) {
3083 surface_scalar_reflectivity[i] += surface_rmatrix(l, i, 0, 0);
3090 const Index& atmosphere_dim,
3091 const Vector& lat_grid,
3092 const Vector& lat_true,
3093 const Vector& lon_true,
3094 const Vector& rtp_pos,
3098 Index gfield_latID = 0;
3099 Index gfield_lonID = 1;
3110 const Index nlat = surface_type_mask.
data.nrows();
3111 const Index nlon = surface_type_mask.
data.ncols();
3113 if (nlat < 2 || nlon < 2) {
3115 os <<
"The data in *surface_type_mask* must span a geographical "
3116 <<
"region. Accordingly,\nthe latitude and longitude grids must "
3117 <<
"both have a length >= 2.";
3118 throw runtime_error(os.str());
3125 Vector lat(1), lon(1);
3127 lat[0], lon[0], atmosphere_dim, lat_grid, lat_true, lon_true, rtp_pos);
3135 chk_if_in_range(
"rtp_pos.lon", lon[0], lon_shifted[0], lon_shifted[nlon - 1]);
3139 gridpos(gp_lat, GFlat, lat[0]);
3140 gridpos(gp_lon, lon_shifted, lon[0]);
3144 if (gp_lat.
fd[0] < 0.5) {
3147 ilat = gp_lat.
idx + 1;
3149 if (gp_lon.
fd[0] < 0.5) {
3152 ilon = gp_lon.
idx + 1;
3154 surface_type = (Index)round(surface_type_mask.
data(ilat, ilon));
3160 Vector& surface_type_mix,
3161 Numeric& surface_skin_t,
3162 Matrix& surface_los,
3163 Tensor4& surface_rmatrix,
3164 Matrix& surface_emission,
3165 const Vector& f_grid,
3166 const Index& stokes_dim,
3167 const Index& atmosphere_dim,
3168 const Vector& lat_grid,
3169 const Vector& lon_grid,
3170 const Vector& lat_true,
3171 const Vector& lon_true,
3172 const Vector& rtp_pos,
3173 const Vector& rtp_los,
3174 const Vector& refellipsoid,
3177 const Numeric& z_sensor,
3179 const Vector& dlos_weight_vector,
3185 Vector sat_pos = rtp_pos;
3186 Vector sat_los = rtp_los;
3198 const Index nf = f_grid.nelem();
3199 const Index ntypes = surface_rtprop_agenda_array.
nelem();
3200 const Index nlos = dlos.nrows();
3203 Matrix ground_pos, ground_los, sensor_pos(nlos, 3), sensor_los;
3205 sensor_pos(joker, 0) = sat_pos[0];
3206 sensor_pos(joker, 1) = sat_pos[1];
3207 sensor_pos(joker, 2) = sat_pos[2];
3221 surface_type_mix.resize(ntypes);
3222 surface_type_mix = 0.;
3223 surface_skin_t = 0.;
3224 surface_los.resize(1,2);
3226 surface_rmatrix.resize(1, nf, stokes_dim, stokes_dim);
3227 surface_rmatrix = 0.;
3228 surface_emission.resize(nf, stokes_dim);
3229 surface_emission = 0.;
3232 const Numeric weight_sum = sum(dlos_weight_vector);
3234 Vector tmp_type_mix;
3235 Matrix tmp_emission, tmp_los;
3236 Tensor4 tmp_rmatrix;
3239 for (Index i=0; i<nlos; ++i) {
3251 Vector{ground_pos(i, joker)},
3252 Vector{ground_los(i, joker)},
3254 surface_rtprop_agenda_array,
3257 "This method requires that all surface types "
3258 "returns a *surface_los* with one row.");
3261 const Numeric weight = dlos_weight_vector[i] / weight_sum;
3262 tmp_type_mix *= weight;
3263 surface_type_mix += tmp_type_mix;
3264 surface_skin_t += weight * tmp_skin_t;
3266 surface_los += tmp_los;
3267 tmp_rmatrix *= weight;
3268 surface_rmatrix += tmp_rmatrix;
3269 tmp_emission *= weight;
3270 surface_emission += tmp_emission;
3276 Vector& surface_type_mix,
3277 Numeric& surface_skin_t,
3278 Matrix& surface_los,
3279 Tensor4& surface_rmatrix,
3280 Matrix& surface_emission,
3281 const Vector& f_grid,
3282 const Vector& rtp_pos,
3283 const Vector& rtp_los,
3285 const Index& surface_type,
3289 surface_type >= surface_rtprop_agenda_array.
nelem(),
3290 "Provided surface type index invalid (<0 or too high w.r.t. "
3291 "length of *surface_rtprop_agenda_array*).");
3293 surface_type_mix.resize(surface_rtprop_agenda_array.
nelem());
3294 surface_type_mix = 0.0;
3295 surface_type_mix[surface_type] = 1.0;
3306 surface_rtprop_agenda_array);
3311 Vector& surface_type_mix,
3312 Numeric& surface_skin_t,
3313 Matrix& surface_los,
3314 Tensor4& surface_rmatrix,
3315 Matrix& surface_emission,
3316 const Vector& f_grid,
3317 const Index& atmosphere_dim,
3318 const Vector& lat_grid,
3319 const Vector& lat_true,
3320 const Vector& lon_true,
3321 const Vector& rtp_pos,
3322 const Vector& rtp_los,
3337 surface_type >= surface_rtprop_agenda_array.
nelem(),
3338 "Interpolation gave invalid surface type index (<0 or too "
3339 "high w.f.t. length of *surface_rtprop_agenda_array*).");
3341 surface_type_mix.resize(surface_rtprop_agenda_array.
nelem());
3342 surface_type_mix = 0.0;
3343 surface_type_mix[surface_type] = 1.0;
3354 surface_rtprop_agenda_array);
3359 Tensor4& surface_rmatrix,
3360 Matrix& surface_emission,
3361 const Vector& f_new,
3363 const Index nf = f_grid.nelem();
3364 const Index ns = surface_emission.ncols();
3365 const Index nlos = surface_rmatrix.nbooks();
3366 const Index nnew = f_new.nelem();
3370 "Different number of frequencies in *f_grid* and *surface_emission*.");
3372 "Different number of frequencies in *f_grid* and *surface_rmatrix*.");
3374 "Different number of Stokes elements in *surface_emission* and *surface_rmatrix*.");
3379 Matrix itw(nnew, 2);
3384 Tensor4 rmatrix = surface_rmatrix;
3385 Matrix emission = surface_emission;
3386 surface_rmatrix.resize(nlos, nnew, ns, ns);
3387 surface_emission.resize(nnew, ns);
3389 for (Index is = 0; is < ns; ++is) {
3390 interp(surface_emission(joker, is), itw, emission(joker, is), gp);
3391 for (Index il = 0; il < nlos; ++il) {
3392 for (Index is2 = 0; is2 < ns; ++is2) {
3393 interp(surface_rmatrix(il, joker, is, is2),
3395 rmatrix(il, joker, is, is2),
3405 Tensor4& surface_rmatrix,
3406 ArrayOfTensor4& dsurface_rmatrix_dx,
3407 Matrix& surface_emission,
3408 ArrayOfMatrix& dsurface_emission_dx,
3409 const Index& stokes_dim,
3410 const Index& atmosphere_dim,
3411 const Vector& lat_grid,
3412 const Vector& lon_grid,
3413 const Vector& f_grid,
3414 const Vector& rtp_pos,
3415 const Vector& rtp_los,
3416 const Tensor3& surface_props_data,
3419 const Index& jacobian_do,
3426 surface_props_names);
3432 gp_lat[0], gp_lon[0], atmosphere_dim, lat_grid, lon_grid, rtp_pos);
3444 surface_props_names);
3457 surface_rmatrix.resize(1, f_grid.nelem(), stokes_dim, stokes_dim);
3458 surface_rmatrix = 0.0;
3464 dsurface_rmatrix_dx,
3465 dsurface_emission_dx);
3472 Matrix dbdt(f_grid.nelem(), 1);
3473 dplanck_dt(dbdt(joker, 0), f_grid, skin_t[0]);
3474 dsurface_emission_dx[irq] = dbdt;
3475 dsurface_rmatrix_dx[irq].resize(surface_rmatrix.nbooks(),
3476 surface_rmatrix.npages(),
3477 surface_rmatrix.nrows(),
3478 surface_rmatrix.ncols());
3479 dsurface_rmatrix_dx[irq] = 0;
3486 ArrayOfMatrix& dsurface_emission_dx,
3487 const Index& atmosphere_dim,
3488 const Vector& lat_grid,
3489 const Vector& lon_grid,
3490 const Tensor3& surface_props_data,
3493 const Index& jacobian_do,
3495 if (surface_props_names.
nelem())
3496 throw runtime_error(
3497 "When calling this method, *surface_props_names* should be empty.");
3503 surface_props_names);
3508 dsurface_rmatrix_dx,
3509 dsurface_emission_dx);
3515 Tensor4& surface_rmatrix,
3516 ArrayOfTensor4& dsurface_rmatrix_dx,
3517 Matrix& surface_emission,
3518 ArrayOfMatrix& dsurface_emission_dx,
3519 const Index& stokes_dim,
3520 const Index& atmosphere_dim,
3521 const Vector& lat_grid,
3522 const Vector& lon_grid,
3523 const Vector& f_grid,
3524 const Vector& rtp_pos,
3525 const Vector& rtp_los,
3526 const Tensor3& surface_props_data,
3529 const Index& jacobian_do,
3530 const Vector& transmittance,
3531 const Index& fastem_version,
3538 surface_props_names);
3544 gp_lat[0], gp_lon[0], atmosphere_dim, lat_grid, lon_grid, rtp_pos);
3550 "Water skin temperature",
3556 surface_props_names);
3559 Vector wind_speed(1);
3567 surface_props_names);
3570 Vector wind_direction(1);
3578 surface_props_names);
3589 surface_props_names);
3612 dsurface_rmatrix_dx,
3613 dsurface_emission_dx);
3620 const Numeric dd = 0.1;
3621 Matrix surface_los2;
3623 dsurface_rmatrix_dx[irq],
3624 dsurface_emission_dx[irq],
3638 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
3639 dsurface_rmatrix_dx[irq] /= dd;
3640 dsurface_emission_dx[irq] -= surface_emission;
3641 dsurface_emission_dx[irq] /= dd;
3647 const Numeric dd = 0.1;
3648 Matrix surface_los2;
3650 dsurface_rmatrix_dx[irq],
3651 dsurface_emission_dx[irq],
3665 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
3666 dsurface_rmatrix_dx[irq] /= dd;
3667 dsurface_emission_dx[irq] -= surface_emission;
3668 dsurface_emission_dx[irq] /= dd;
3674 const Numeric dd = 1;
3675 Matrix surface_los2;
3677 dsurface_rmatrix_dx[irq],
3678 dsurface_emission_dx[irq],
3687 wind_direction[0] + dd,
3692 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
3693 dsurface_rmatrix_dx[irq] /= dd;
3694 dsurface_emission_dx[irq] -= surface_emission;
3695 dsurface_emission_dx[irq] /= dd;
3701 const Numeric dd = 0.0005;
3702 Matrix surface_los2;
3704 dsurface_rmatrix_dx[irq],
3705 dsurface_emission_dx[irq],
3719 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
3720 dsurface_rmatrix_dx[irq] /= dd;
3721 dsurface_emission_dx[irq] -= surface_emission;
3722 dsurface_emission_dx[irq] /= dd;
3730 Tensor4& surface_rmatrix,
3731 ArrayOfTensor4& dsurface_rmatrix_dx,
3732 Matrix& surface_emission,
3733 ArrayOfMatrix& dsurface_emission_dx,
3734 const Index& stokes_dim,
3735 const Index& atmosphere_dim,
3736 const Vector& lat_grid,
3737 const Vector& lon_grid,
3738 const Vector& f_grid,
3739 const Vector& rtp_pos,
3740 const Vector& rtp_los,
3741 const Vector& specular_los,
3742 const Tensor3& surface_props_data,
3745 const Index& jacobian_do,
3746 const Vector& f_reflectivities,
3753 surface_props_names);
3759 const Index nr = f_reflectivities.nelem();
3760 const Index nf = f_grid.nelem();
3766 gp_lat[0], gp_lon[0], atmosphere_dim, lat_grid, lon_grid, rtp_pos);
3770 Vector surface_skin_t(1);
3778 surface_props_names);
3781 Vector reflectivities(nr);
3783 for (Index i=0; i<nr; i++) {
3786 sstr <<
"Scalar reflectivity " << i;
3794 surface_props_names);
3795 reflectivities[i] = rv[0];
3799 Vector surface_scalar_reflectivity(nf);
3804 gridpos(gp, f_reflectivities, f_grid, 1e99);
3809 interp( surface_scalar_reflectivity, itw2, reflectivities, gp);
3822 surface_scalar_reflectivity,
3829 dsurface_rmatrix_dx,
3830 dsurface_emission_dx);
3837 const Numeric dd = 0.1;
3838 Matrix surface_los2;
3840 dsurface_rmatrix_dx[irq],
3841 dsurface_emission_dx[irq],
3848 surface_skin_t[0]+dd,
3849 surface_scalar_reflectivity,
3851 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
3852 dsurface_rmatrix_dx[irq] /= dd;
3853 dsurface_emission_dx[irq] -= surface_emission;
3854 dsurface_emission_dx[irq] /= dd;
3858 for (Index i=0; i<nr; i++) {
3860 sstr <<
"Scalar reflectivity " << i;
3863 const Numeric dd = 1e-4;
3864 Vector rpert = reflectivities;
3866 interp( surface_scalar_reflectivity, itw2, rpert, gp);
3868 Matrix surface_los2;
3870 dsurface_rmatrix_dx[irq],
3871 dsurface_emission_dx[irq],
3879 surface_scalar_reflectivity,
3881 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
3882 dsurface_rmatrix_dx[irq] /= dd;
3883 dsurface_emission_dx[irq] -= surface_emission;
3884 dsurface_emission_dx[irq] /= dd;
3892 Tensor4& surface_rmatrix,
3893 ArrayOfTensor4& dsurface_rmatrix_dx,
3894 Matrix& surface_emission,
3895 ArrayOfMatrix& dsurface_emission_dx,
3896 const Index& stokes_dim,
3897 const Index& atmosphere_dim,
3898 const Vector& lat_grid,
3899 const Vector& lon_grid,
3900 const Vector& f_grid,
3901 const Vector& rtp_pos,
3902 const Vector& rtp_los,
3905 const Tensor3& surface_props_data,
3908 const Index& jacobian_do,
3915 surface_props_names);
3921 gp_lat[0], gp_lon[0], atmosphere_dim, lat_grid, lon_grid, rtp_pos);
3927 "Water skin temperature",
3933 surface_props_names);
3936 Vector wind_speed(1);
3944 surface_props_names);
3955 surface_props_names);
3977 dsurface_rmatrix_dx,
3978 dsurface_emission_dx);
3985 const Numeric dd = 0.1;
3986 Matrix surface_los2;
3988 dsurface_rmatrix_dx[irq],
3989 dsurface_emission_dx[irq],
4002 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
4003 dsurface_rmatrix_dx[irq] /= dd;
4004 dsurface_emission_dx[irq] -= surface_emission;
4005 dsurface_emission_dx[irq] /= dd;
4011 const Numeric dd = 0.1;
4012 Matrix surface_los2;
4014 dsurface_rmatrix_dx[irq],
4015 dsurface_emission_dx[irq],
4028 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
4029 dsurface_rmatrix_dx[irq] /= dd;
4030 dsurface_emission_dx[irq] -= surface_emission;
4031 dsurface_emission_dx[irq] /= dd;
4037 const Numeric dd = 0.0005;
4038 Matrix surface_los2;
4040 dsurface_rmatrix_dx[irq],
4041 dsurface_emission_dx[irq],
4054 dsurface_rmatrix_dx[irq] -= surface_rmatrix;
4055 dsurface_rmatrix_dx[irq] /= dd;
4056 dsurface_emission_dx[irq] -= surface_emission;
4057 dsurface_emission_dx[irq] /= dd;
4065 const ArrayOfMatrix& iy_aux,
4069 for (Index i = 0; i < iy_aux_vars.
nelem(); i++) {
4070 if (iy_aux_vars[i] ==
"Optical depth") {
4077 throw runtime_error(
"No element in *iy_aux* holds optical depths.");
4079 const Index n = iy_aux[ihit].nrows();
4081 transmittance.resize(n);
4083 for (Index i = 0; i < n; i++) {
4084 transmittance[i] = exp(-iy_aux[ihit](i, 0));
This file contains the definition of Array.
Index find_first(const Array< base > &x, const base &w)
Find first occurance.
base max(const Array< base > &x)
Max function.
base min(const Array< base > &x)
Min function.
The global header file for ARTS.
Constants of physical expressions as constexpr.
void iy_main_agendaExecute(Workspace &ws, Matrix &iy, ArrayOfMatrix &iy_aux, Ppath &ppath, ArrayOfTensor3 &diy_dx, Vector &geo_pos, const Index iy_agenda_call1, const Tensor3 &iy_transmittance, const ArrayOfString &iy_aux_vars, const Index iy_id, const String &iy_unit, const Index cloudbox_on, const Index jacobian_do, const Vector &f_grid, const EnergyLevelMap &nlte_field, const Vector &rte_pos, const Vector &rte_los, const Vector &rte_pos2, const Agenda &input_agenda)
void surface_rtprop_agenda_arrayExecute(Workspace &ws, Numeric &surface_skin_t, Matrix &surface_emission, Matrix &surface_los, Tensor4 &surface_rmatrix, const Index agenda_array_index, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const ArrayOfAgenda &input_agenda_array)
void surface_rtprop_agendaExecute(Workspace &ws, Numeric &surface_skin_t, Matrix &surface_emission, Matrix &surface_los, Tensor4 &surface_rmatrix, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Agenda &input_agenda)
String name() const
Agenda name.
Index nelem() const ARTS_NOEXCEPT
void checksize_strict() const final
Strict consistency check.
void resize(const GriddedField3 &gf)
Make this GriddedField3 the same size as the given one.
void checksize_strict() const final
Strict consistency check.
void checksize_strict() const final
Strict consistency check.
void checksize_strict() const final
Strict consistency check.
void set_grid_name(Index i, const String &s)
Set grid name.
void set_grid(Index i, const Vector &g)
Set a numeric grid.
const Vector & get_numeric_grid(Index i) const
Get a numeric grid.
Index calc_cellnum(Numeric lat, Numeric lon) const
bool contains(Index cellnumber) const
Index get_class2(Index cellnumber) const
Index calc_cellnum_nearest_neighbor(Numeric lat, Numeric lon) const
Vector get_emis_h(Index cellnum) const
std::pair< Numeric, Numeric > get_coordinates(Index cellnum) const
Index get_class1(Index cellnumber) const
std::pair< Numeric, Numeric > emis_interp(Numeric theta, Numeric freq, Index class1, Index class2, const ConstVectorView &ev, const ConstVectorView &eh) const
Vector get_emis_v(Index i) const
void mult(MatrixView C, ConstMatrixView A, const Block &B)
#define ARTS_ASSERT(condition,...)
#define ARTS_USER_ERROR_IF(condition,...)
void fastem(Vector &emissivity, Vector &reflectivity, const Numeric frequency, const Numeric za, const Numeric temperature, const Numeric salinity, const Numeric wind_speed, const Numeric transmittance, const Numeric rel_azimuth, const Index fastem_version)
Calculate the surface emissivity using FASTEM.
This file contains functions that are adapted from FASTEM code which is used to calculate surface emi...
Header file for functions related to gas scattering.
Numeric sphdist(const Numeric &lat1, const Numeric &lon1, const Numeric &lat2, const Numeric &lon2)
sphdist
void lon_shiftgrid(Vector &longrid_out, ConstVectorView longrid_in, const Numeric lon)
lon_shiftgrid
Numeric refell2d(ConstVectorView refellipsoid, ConstVectorView lat_grid, const GridPos gp)
refell2d
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
void gp4length1grid(ArrayOfGridPos &gp)
Grid position matching a grid of length 1.
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
Header file for interpolation.cc.
void diy_from_pos_to_rgrids(Tensor3View diy_dx, const RetrievalQuantity &jacobian_quantity, ConstMatrixView diy_dpos, const Index &atmosphere_dim, ConstVectorView rtp_pos)
diy_from_pos_to_rgrids
void jacobian_type_extrapol(ArrayOfGridPos &gp)
Adopts grid positions to extrapolation used for jacobians.
void AngularGridsSetFluxCalc(Vector &za_grid, Vector &aa_grid, Vector &za_grid_weights, const Index &N_za_grid, const Index &N_aa_grid, const String &za_grid_type, const Verbosity &)
WORKSPACE METHOD: AngularGridsSetFluxCalc.
void IntersectionGeometricalWithAltitude(Matrix &pos, Matrix &los, const Matrix &sensor_pos, const Matrix &sensor_los, const Vector &refellipsoid, const Vector &lat_grid, const Vector &lon_grid, const Numeric &altitude, const Verbosity &)
WORKSPACE METHOD: IntersectionGeometricalWithAltitude.
void losAddLosAndDlos(Matrix &new_los, const Vector &ref_los, const Matrix &dlos, const Verbosity &)
WORKSPACE METHOD: losAddLosAndDlos.
void rte_pos_losBackwardToAltitude(Vector &rte_pos, Vector &rte_los, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &refellipsoid, const Numeric &altitude, const Index &los_is_reversed, const Verbosity &verbosity)
WORKSPACE METHOD: rte_pos_losBackwardToAltitude.
void surfaceTelsem(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &f_grid, const Vector &lat_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const Vector &rtp_los, const Vector &specular_los, const Numeric &surface_skin_t, const TelsemAtlas &atlas, const Numeric &r_min, const Numeric &r_max, const Numeric &d_max, const Verbosity &verbosity)
WORKSPACE METHOD: surfaceTelsem.
void surface_scalar_reflectivityFromGriddedField4(Vector &surface_scalar_reflectivity, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const Vector &rtp_los, const GriddedField4 &r_field, const Verbosity &)
WORKSPACE METHOD: surface_scalar_reflectivityFromGriddedField4.
void surface_complex_refr_indexFromGriddedField5(GriddedField3 &surface_complex_refr_index, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const GriddedField5 &complex_n_field, const Verbosity &)
WORKSPACE METHOD: surface_complex_refr_indexFromGriddedField5.
void InterpSurfaceFieldToPosition(Numeric &outvalue, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &rtp_pos, const Matrix &z_surface, const Matrix &field, const Verbosity &verbosity)
WORKSPACE METHOD: InterpSurfaceFieldToPosition.
void surfaceTessem(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Numeric &surface_skin_t, const TessemNN &net_h, const TessemNN &net_v, const Numeric &salinity, const Numeric &wind_speed, const Verbosity &verbosity)
WORKSPACE METHOD: surfaceTessem.
constexpr Numeric EARTH_RADIUS
void specular_losCalc(Vector &specular_los, Vector &surface_normal, const Vector &rtp_pos, const Vector &rtp_los, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &refellipsoid, const Matrix &z_surface, const Index &ignore_surface_slope, const Verbosity &verbosity)
WORKSPACE METHOD: specular_losCalc.
constexpr Numeric DEG2RAD
void surfaceFastem(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Numeric &surface_skin_t, const Numeric &salinity, const Numeric &wind_speed, const Numeric &wind_direction, const Vector &transmittance, const Index &fastem_version, const Verbosity &verbosity)
WORKSPACE METHOD: surfaceFastem.
void surfaceMapToLinearPolarisation(Matrix &surface_emission, Tensor4 &surface_rmatrix, const Index &stokes_dim, const Numeric &pol_angle, const Verbosity &)
WORKSPACE METHOD: surfaceMapToLinearPolarisation.
void surfaceFlatRefractiveIndex(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &rtp_pos, const Vector &rtp_los, const Vector &specular_los, const Numeric &surface_skin_t, const GriddedField3 &surface_complex_refr_index, const Verbosity &verbosity)
WORKSPACE METHOD: surfaceFlatRefractiveIndex.
void surface_rtpropFromTypesNearest(Workspace &ws, Vector &surface_type_mix, Numeric &surface_skin_t, Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const Vector &rtp_los, const GriddedField2 &surface_type_mask, const ArrayOfAgenda &surface_rtprop_agenda_array, const Verbosity &verbosity)
WORKSPACE METHOD: surface_rtpropFromTypesNearest.
void SurfaceBlackbody(Matrix &surface_los, Tensor4 &surface_rmatrix, ArrayOfTensor4 &dsurface_rmatrix_dx, Matrix &surface_emission, ArrayOfMatrix &dsurface_emission_dx, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const Index &jacobian_do, const Verbosity &verbosity)
WORKSPACE METHOD: SurfaceBlackbody.
void surface_rtpropInterpFreq(Vector &f_grid, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_new, const Verbosity &)
WORKSPACE METHOD: surface_rtpropInterpFreq.
void specular_losCalcNoTopography(Vector &specular_los, Vector &surface_normal, const Vector &rtp_pos, const Vector &rtp_los, const Index &atmosphere_dim, const Verbosity &)
WORKSPACE METHOD: specular_losCalcNoTopography.
void iySurfaceFlatRefractiveIndex(Workspace &ws, Matrix &iy, ArrayOfTensor3 &diy_dx, ArrayOfTensor4 &dsurface_rmatrix_dx, ArrayOfMatrix &dsurface_emission_dx, const Tensor3 &iy_transmittance, const Index &iy_id, const Index &jacobian_do, const Index &suns_do, const Index &atmosphere_dim, const EnergyLevelMap &nlte_field, const Index &cloudbox_on, const Index &stokes_dim, const Vector &f_grid, const Vector &lat_grid, const Vector &lon_grid, const Matrix &z_surface, const Vector &refellipsoid, const Vector &rtp_pos, const Vector &rtp_los, const Vector &rte_pos2, const String &iy_unit, const GriddedField3 &surface_complex_refr_index, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const ArrayOfRetrievalQuantity &jacobian_quantities, const Agenda &iy_main_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: iySurfaceFlatRefractiveIndex.
void iySurfaceLambertian(Workspace &ws, Matrix &iy, ArrayOfTensor3 &diy_dx, const Tensor3 &iy_transmittance, const Index &iy_id, const Index &jacobian_do, const Index &suns_do, const Index &atmosphere_dim, const EnergyLevelMap &nlte_field, const Index &cloudbox_on, const Index &stokes_dim, const Vector &f_grid, const Vector &lat_grid, const Vector &lon_grid, const Matrix &z_surface, const Vector &refellipsoid, const Vector &rtp_pos, const Vector &rtp_los, const Vector &rte_pos2, const String &iy_unit, const Vector &surface_scalar_reflectivity, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const ArrayOfRetrievalQuantity &jacobian_quantities, const Agenda &iy_main_agenda, const Index &N_za, const Index &N_aa, const Verbosity &verbosity)
WORKSPACE METHOD: iySurfaceLambertian.
void surfaceBlackbody(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Index &atmosphere_dim, const Vector &f_grid, const Index &stokes_dim, const Vector &rtp_pos, const Vector &rtp_los, const Numeric &surface_skin_t, const Verbosity &verbosity)
WORKSPACE METHOD: surfaceBlackbody.
void InterpSurfaceTypeMask(Index &surface_type, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const GriddedField2 &surface_type_mask, const Verbosity &)
WORKSPACE METHOD: InterpSurfaceTypeMask.
void SurfaceFastem(Matrix &surface_los, Tensor4 &surface_rmatrix, ArrayOfTensor4 &dsurface_rmatrix_dx, Matrix &surface_emission, ArrayOfMatrix &dsurface_emission_dx, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const Index &jacobian_do, const Vector &transmittance, const Index &fastem_version, const Verbosity &verbosity)
WORKSPACE METHOD: SurfaceFastem.
void iySurfaceRtpropAgenda(Workspace &ws, Matrix &iy, ArrayOfTensor3 &diy_dx, Numeric &surface_skin_t, Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Tensor3 &iy_transmittance, const Index &iy_id, const Index &jacobian_do, const Index &suns_do, const Index &atmosphere_dim, const EnergyLevelMap &nlte_field, const Index &cloudbox_on, const Index &stokes_dim, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Vector &rte_pos2, const String &iy_unit, const Agenda &iy_main_agenda, const Agenda &surface_rtprop_agenda, const Verbosity &)
WORKSPACE METHOD: iySurfaceRtpropAgenda.
void surfaceFlatScalarReflectivity(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &rtp_pos, const Vector &rtp_los, const Vector &specular_los, const Numeric &surface_skin_t, const Vector &surface_scalar_reflectivity, const Verbosity &)
WORKSPACE METHOD: surfaceFlatScalarReflectivity.
void surface_reflectivityFromGriddedField6(Tensor3 &surface_reflectivity, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const Vector &rtp_los, const GriddedField6 &r_field, const Verbosity &)
WORKSPACE METHOD: surface_reflectivityFromGriddedField6.
void surfaceFlatReflectivity(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &rtp_pos, const Vector &rtp_los, const Vector &specular_los, const Numeric &surface_skin_t, const Tensor3 &surface_reflectivity, const Verbosity &verbosity)
WORKSPACE METHOD: surfaceFlatReflectivity.
void surfaceFlatRvRh(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &rtp_pos, const Vector &rtp_los, const Vector &specular_los, const Numeric &surface_skin_t, const Matrix &surface_rv_rh, const Verbosity &)
WORKSPACE METHOD: surfaceFlatRvRh.
void surface_rtpropFromTypesAverage(Workspace &ws, Vector &surface_type_mix, Numeric &surface_skin_t, Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const Vector &rtp_los, const Vector &refellipsoid, const GriddedField2 &surface_type_mask, const ArrayOfAgenda &surface_rtprop_agenda_array, const Numeric &z_sensor, const Matrix &dlos, const Vector &dlos_weight_vector, const Verbosity &verbosity)
WORKSPACE METHOD: surface_rtpropFromTypesAverage.
void iySurfaceLambertianDirect(Workspace &ws, Matrix &iy, const Vector &rtp_pos, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Tensor3 &t_field, const EnergyLevelMap &nlte_field, const Tensor4 &vmr_field, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Matrix &z_surface, const Vector &surface_scalar_reflectivity, const Vector &refellipsoid, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfString &scat_species, const ArrayOfArrayOfSingleScatteringData &scat_data, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &suns_do, const Index &gas_scattering_do, const Index &jacobian_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfSun &suns, const Numeric &rte_alonglos_v, const String &iy_unit, const Agenda &propmat_clearsky_agenda, const Agenda &water_p_eq_agenda, const Agenda &gas_scattering_agenda, const Agenda &ppath_step_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: iySurfaceLambertianDirect.
void transmittanceFromIy_aux(Vector &transmittance, const ArrayOfString &iy_aux_vars, const ArrayOfMatrix &iy_aux, const Verbosity &)
WORKSPACE METHOD: transmittanceFromIy_aux.
void iySurfaceFlatReflectivity(Workspace &ws, Matrix &iy, ArrayOfTensor3 &diy_dx, ArrayOfTensor4 &dsurface_rmatrix_dx, ArrayOfMatrix &dsurface_emission_dx, const Tensor3 &iy_transmittance, const Index &iy_id, const Index &jacobian_do, const Index &suns_do, const Index &atmosphere_dim, const EnergyLevelMap &nlte_field, const Index &cloudbox_on, const Index &stokes_dim, const Vector &f_grid, const Vector &lat_grid, const Vector &lon_grid, const Matrix &z_surface, const Vector &refellipsoid, const Vector &rtp_pos, const Vector &rtp_los, const Vector &rte_pos2, const String &iy_unit, const Tensor3 &surface_reflectivity, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const ArrayOfRetrievalQuantity &jacobian_quantities, const Agenda &iy_main_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: iySurfaceFlatReflectivity.
void surfaceLambertianSimple(Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &rtp_pos, const Vector &rtp_los, const Vector &surface_normal, const Numeric &surface_skin_t, const Vector &surface_scalar_reflectivity, const Index &lambertian_nza, const Numeric &za_pos, const Verbosity &)
WORKSPACE METHOD: surfaceLambertianSimple.
void iySurfaceFastem(Workspace &ws, Matrix &iy, ArrayOfTensor3 &diy_dx, const Tensor3 &iy_transmittance, const Index &iy_id, const Index &jacobian_do, const Index &atmosphere_dim, const EnergyLevelMap &nlte_field, const Index &cloudbox_on, const Index &stokes_dim, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Vector &rte_pos2, const String &iy_unit, const Agenda &iy_main_agenda, const Numeric &surface_skin_t, const Numeric &salinity, const Numeric &wind_speed, const Numeric &wind_direction, const Index &fastem_version, const Verbosity &verbosity)
WORKSPACE METHOD: iySurfaceFastem.
void surface_scalar_reflectivityFromSurface_rmatrix(Vector &surface_scalar_reflectivity, const Tensor4 &surface_rmatrix, const Verbosity &)
WORKSPACE METHOD: surface_scalar_reflectivityFromSurface_rmatrix.
void iySurfaceRtpropCalc(Workspace &ws, Matrix &iy, ArrayOfTensor3 &diy_dx, const Matrix &surface_los, const Tensor4 &surface_rmatrix, const Matrix &surface_emission, const ArrayOfString &dsurface_names, const ArrayOfTensor4 &dsurface_rmatrix_dx, const ArrayOfMatrix &dsurface_emission_dx, const Tensor3 &iy_transmittance, const Index &iy_id, const Index &jacobian_do, const Index &suns_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const Index &atmosphere_dim, const EnergyLevelMap &nlte_field, const Index &cloudbox_on, const Index &stokes_dim, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Vector &rte_pos2, const String &iy_unit, const Agenda &iy_main_agenda, const Verbosity &)
WORKSPACE METHOD: iySurfaceRtpropCalc.
void SurfaceTessem(Matrix &surface_los, Tensor4 &surface_rmatrix, ArrayOfTensor4 &dsurface_rmatrix_dx, Matrix &surface_emission, ArrayOfMatrix &dsurface_emission_dx, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const TessemNN &net_h, const TessemNN &net_v, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const Index &jacobian_do, const Verbosity &verbosity)
WORKSPACE METHOD: SurfaceTessem.
void SurfaceDummy(ArrayOfTensor4 &dsurface_rmatrix_dx, ArrayOfMatrix &dsurface_emission_dx, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const Index &jacobian_do, const Verbosity &)
WORKSPACE METHOD: SurfaceDummy.
void surface_rtpropFromTypesManual(Workspace &ws, Vector &surface_type_mix, Numeric &surface_skin_t, Matrix &surface_los, Tensor4 &surface_rmatrix, Matrix &surface_emission, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const ArrayOfAgenda &surface_rtprop_agenda_array, const Index &surface_type, const Verbosity &)
WORKSPACE METHOD: surface_rtpropFromTypesManual.
void iySurfaceInit(Matrix &iy, const Vector &f_grid, const Index &stokes_dim, const Verbosity &)
WORKSPACE METHOD: iySurfaceInit.
void iySurfaceFlatReflectivityDirect(Workspace &ws, Matrix &iy, const Vector &rtp_pos, const Vector &rtp_los, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Tensor3 &t_field, const EnergyLevelMap &nlte_field, const Tensor4 &vmr_field, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Matrix &z_surface, const Tensor3 &surface_reflectivity, const Vector &refellipsoid, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfString &scat_species, const ArrayOfArrayOfSingleScatteringData &scat_data, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Index &ppath_inside_cloudbox_do, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &suns_do, const Index &gas_scattering_do, const Index &jacobian_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfSun &suns, const Numeric &rte_alonglos_v, const String &iy_unit, const Agenda &propmat_clearsky_agenda, const Agenda &water_p_eq_agenda, const Agenda &gas_scattering_agenda, const Agenda &ppath_step_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: iySurfaceFlatReflectivityDirect.
void InterpGriddedField2ToPosition(Numeric &outvalue, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lat_true, const Vector &lon_true, const Vector &rtp_pos, const GriddedField2 &gfield2, const Verbosity &)
WORKSPACE METHOD: InterpGriddedField2ToPosition.
void iySurfaceFlatRefractiveIndexDirect(Workspace &ws, Matrix &iy, const Vector &rtp_pos, const Vector &rtp_los, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Tensor3 &t_field, const EnergyLevelMap &nlte_field, const Tensor4 &vmr_field, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Matrix &z_surface, const GriddedField3 &surface_complex_refr_index, const Vector &refellipsoid, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfString &scat_species, const ArrayOfArrayOfSingleScatteringData &scat_data, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Index &ppath_inside_cloudbox_do, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &suns_do, const Index &gas_scattering_do, const Index &jacobian_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfSun &suns, const Numeric &rte_alonglos_v, const String &iy_unit, const Agenda &propmat_clearsky_agenda, const Agenda &water_p_eq_agenda, const Agenda &gas_scattering_agenda, const Agenda &ppath_step_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: iySurfaceFlatRefractiveIndexDirect.
void FastemStandAlone(Matrix &emissivity, Matrix &reflectivity, const Vector &f_grid, const Numeric &surface_skin_t, const Numeric &za, const Numeric &salinity, const Numeric &wind_speed, const Numeric &rel_aa, const Vector &transmittance, const Index &fastem_version, const Verbosity &)
WORKSPACE METHOD: FastemStandAlone.
void SurfaceFlatScalarReflectivity(Matrix &surface_los, Tensor4 &surface_rmatrix, ArrayOfTensor4 &dsurface_rmatrix_dx, Matrix &surface_emission, ArrayOfMatrix &dsurface_emission_dx, const Index &stokes_dim, const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Vector &specular_los, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const Index &jacobian_do, const Vector &f_reflectivities, const Verbosity &verbosity)
WORKSPACE METHOD: SurfaceFlatScalarReflectivity.
Numeric fac(const Index n)
fac
Numeric sign(const Numeric &x)
sign
void calculate_int_weights_arbitrary_grid(Vector &w, const Vector &x)
Calculates trapezoidal integration weights for arbitray grid.
Declarations having to do with the four output streams.
my_basic_string< char > String
The String type for ARTS.
constexpr Numeric pi
The following mathematical constants are generated in python Decimal package by the code:
constexpr Numeric earth_radius
Global constant, the radius of the Earth [m].
constexpr auto deg2rad(auto x) noexcept
Converts degrees to radians.
Numeric planck(const Numeric &f, const Numeric &t)
planck
Numeric dplanck_dt(const Numeric &f, const Numeric &t)
dplanck_dt
void fresnel(Complex &Rv, Complex &Rh, const Complex &n1, const Complex &n2, const Numeric &theta)
fresnel
This file contains declerations of functions of physical character.
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 cart2zaaa(Numeric &za, Numeric &aa, const Numeric &dx, const Numeric &dy, const Numeric &dz)
Converts a cartesian directional vector to zenith and azimuth.
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 resolve_lon(Numeric &lon, const Numeric &lon5, const Numeric &lon6)
Resolves which longitude angle that shall be used.
Numeric plevel_angletilt(const Numeric &r, const Numeric &c1)
Calculates the angular tilt of the surface or a pressure level.
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.
Propagation path structure and functions.
void mueller_stokes2modif(Matrix &Cm, const Index &stokes_dim)
mueller_stokes2modif
void pos2true_latlon(Numeric &lat, Numeric &lon, const Index &atmosphere_dim, const ConstVectorView &lat_grid, const ConstVectorView &lat_true, const ConstVectorView &lon_true, const ConstVectorView &pos)
Determines the true alt and lon for an "ARTS position".
void iy_transmittance_mult(Tensor3 &iy_trans_total, const ConstTensor3View &iy_trans_old, const ConstTensor3View &iy_trans_new)
Multiplicates iy_transmittance with transmissions.
void mueller_modif2stokes(Matrix &Cs, const Index &stokes_dim)
mueller_modif2stokes
void mueller_rotation(Matrix &L, const Index &stokes_dim, const Numeric &rotangle)
mueller_rotation
void mirror_los(Vector &los_mirrored, const ConstVectorView &los, const Index &atmosphere_dim)
Determines the backward direction for a given line-of-sight.
Declaration of functions in rte.cc.
void complex_n_interp(MatrixView n_real, MatrixView n_imag, const GriddedField3 &complex_n, const String &varname, ConstVectorView f_grid, ConstVectorView t_grid)
General function for interpolating data of complex n type.
void interp_atmsurface_gp2itw(Matrix &itw, const Index &atmosphere_dim, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon)
Converts atmospheric grid positions to weights for interpolation of a surface-type variable.
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 interp_atmsurface_by_gp(VectorView x, const Index &atmosphere_dim, ConstMatrixView x_surface, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon)
Interpolates a surface-type variable given the grid positions.
Header file for special_interp.cc.
Structure to store a grid position.
std::array< Numeric, 2 > fd
The structure to describe a propagation path and releated quantities.
void get_direct_radiation(Workspace &ws, ArrayOfMatrix &direct_radiation, ArrayOfArrayOfTensor3 &ddirect_radiation_dx, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &t_field, const EnergyLevelMap &nlte_field, const Tensor4 &vmr_field, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &gas_scattering_do, const Index &irradiance_flag, const ArrayOfPpath &sun_ppaths, const ArrayOfSun &suns, const ArrayOfIndex &suns_visible, const Vector &refellipsoid, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfString &scat_species, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &jacobian_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const Agenda &propmat_clearsky_agenda, const Agenda &water_p_eq_agenda, const Agenda &gas_scattering_agenda, const Numeric &rte_alonglos_v, const Verbosity &verbosity)
Calculates the transmitted sun radiation at the end position of the ppath.
void get_sun_ppaths(Workspace &ws, ArrayOfPpath &sun_ppaths, ArrayOfIndex &suns_visible, ArrayOfVector &sun_rte_los, const Vector &rte_pos, const ArrayOfSun &suns, const Vector &f_grid, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &z_surface, const Vector &refellipsoid, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Agenda &ppath_step_agenda, const Verbosity &verbosity)
Calculates the ppath towards the suns from a given position and indicates if sun is visible or not.
void surface_get_incoming_direct(Workspace &ws, Matrix &iy_incoming, Index &stars_visible, Vector &specular_los, const Vector &rtp_pos, const Vector &rtp_los, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Tensor3 &t_field, const EnergyLevelMap &nlte_field, const Tensor4 &vmr_field, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Matrix &z_surface, const Vector &refellipsoid, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfString &scat_species, const ArrayOfArrayOfSingleScatteringData &scat_data, const Numeric &ppath_lmax, const Numeric &ppath_lraytrace, const Index &ppath_inside_cloudbox_do, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &gas_scattering_do, const Index &jacobian_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfSun &suns, const Numeric &rte_alonglos_v, const Agenda &propmat_clearsky_agenda, const Agenda &water_p_eq_agenda, const Agenda &gas_scattering_agenda, const Agenda &ppath_step_agenda, const Verbosity &verbosity)
Calculate the incoming direct radiation at the surface for a given line of sight.
void dsurface_check(const ArrayOfString &surface_props_names, const ArrayOfString &dsurface_names, const ArrayOfTensor4 dsurface_rmatrix_dx, const ArrayOfMatrix &dsurface_emission_dx)
Peforms basic checks of the dsurface variables.
void surface_calc(Matrix &iy, ConstTensor3View I, ConstMatrixView surface_los, ConstTensor4View surface_rmatrix, ConstMatrixView surface_emission)
Weights together downwelling radiation and surface emission.
void surface_props_check(const Index &atmosphere_dim, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names)
Peforms basic checks of surface_props_data and surface_props_names
Numeric calc_incang(ConstVectorView rte_los, ConstVectorView specular_los)
Calculates the incidence angle for a flat surface, based on rte_los and specular_los.
void surface_props_interp(Vector &v, const String &vname, const Index &atmosphere_dim, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon, const Matrix &itw, const Tensor3 &surface_props_data, const ArrayOfString &surface_props_names)
Peforms an interpolation of surface_props_data
void surface_specular_R_and_b(MatrixView surface_rmatrix, VectorView surface_emission, const Complex &Rv, const Complex &Rh, const Numeric &f, const Index &stokes_dim, const Numeric &surface_skin_t)
Sets up the surface reflection matrix and emission vector for the case of specular reflection.
void tessem_prop_nn(VectorView ny, const TessemNN &net, ConstVectorView nx)
This file contains functions that are adapted from TESSEM code which is used to calculate surface emi...