61 #define PART_TYPE scat_data[i_ss][i_se].ptype 62 #define F_DATAGRID scat_data[i_ss][i_se].f_grid 63 #define T_DATAGRID scat_data[i_ss][i_se].T_grid 64 #define ZA_DATAGRID scat_data[i_ss][i_se].za_grid 65 #define AA_DATAGRID scat_data[i_ss][i_se].aa_grid 66 #define PHA_MAT_DATA scat_data[i_ss][i_se].pha_mat_data 67 #define EXT_MAT_DATA scat_data[i_ss][i_se].ext_mat_data 68 #define ABS_VEC_DATA scat_data[i_ss][i_se].abs_vec_data 72 #define PND_LIMIT 1e-12 81 const Index& za_index,
82 const Index& aa_index,
87 const Index& scat_p_index,
88 const Index& scat_lat_index,
89 const Index& scat_lon_index,
92 if (stokes_dim > 4 || stokes_dim < 1) {
94 "The dimension of the stokes vector \n" 95 "must be 1,2,3 or 4");
100 if (N_se_total != pnd_field.
nbooks()) {
102 os <<
"Total number of scattering elements in scat_data " 103 <<
"inconsistent with size of pnd_field.";
104 throw runtime_error(os.
str());
109 assert(pha_mat_spt.
nshelves() == N_se_total);
118 if (scat_data[0][0].f_grid.
nelem() < 2) {
120 os <<
"Scattering data seems to be *scat_data_mono* (1 freq point only),\n" 121 <<
"but frequency interpolable data (*scat_data* with >=2 freq points) " 122 <<
"is expected here.";
123 throw runtime_error(os.
str());
134 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
138 for (
Index i_se = 0; i_se < N_se; i_se++) {
142 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
168 }
else if (rtp_temperature < 0.)
171 if (rtp_temperature > -10.)
174 }
else if (rtp_temperature > -20.)
186 os <<
"In pha_mat_sptFromData.\n" 187 <<
"The temperature grid of the scattering data does not\n" 188 <<
"cover the atmospheric temperature at cloud location.\n" 189 <<
"The data should include the value T = " << rtp_temperature
210 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc,
i) =
236 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc,
i) =
249 for (
Index za_inc_idx = 0; za_inc_idx < za_grid.
nelem();
251 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
254 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker),
280 const Index& doit_za_grid_size,
282 const Index& za_index,
283 const Index& aa_index,
284 const Numeric& rtp_temperature,
286 const Index& scat_p_index,
287 const Index& scat_lat_index,
288 const Index& scat_lon_index,
292 if (N_se_total != pnd_field.
nbooks()) {
294 os <<
"Total number of scattering elements in scat_data_mono " 295 <<
"inconsistent with size of pnd_field.";
296 throw runtime_error(os.
str());
301 assert(pha_mat_spt.
nshelves() == N_se_total);
304 if (pnd_field.
ncols() > 1) {
305 assert(pha_mat_sptDOITOpt.
nelem() == N_se_total);
308 assert(pha_mat_sptDOITOpt[0].nlibraries() ==
309 scat_data_mono[0][0].T_grid.
nelem());
310 assert(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
311 assert(pha_mat_sptDOITOpt[0].nshelves() == aa_grid.
nelem());
312 assert(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
313 assert(pha_mat_sptDOITOpt[0].npages() == aa_grid.
nelem());
317 else if (pnd_field.
ncols() == 1) {
324 assert(pha_mat_sptDOITOpt[0].nlibraries() ==
325 scat_data_mono[0][0].T_grid.
nelem());
326 assert(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
327 assert(pha_mat_sptDOITOpt[0].nshelves() == 1);
328 assert(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
329 assert(pha_mat_sptDOITOpt[0].npages() == aa_grid.
nelem());
332 assert(doit_za_grid_size > 0);
343 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
345 os <<
"Scattering data seems to be *scat_data* (several freq points),\n" 346 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
347 throw runtime_error(os.
str());
352 nlinspace(za_grid, 0, 180, doit_za_grid_size);
357 if (stokes_dim > 4 || stokes_dim < 1) {
359 "The dimension of the stokes vector \n" 360 "must be 1,2,3 or 4");
372 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
373 const Index N_se = scat_data_mono[i_ss].
nelem();
375 for (
Index i_se = 0; i_se < N_se; i_se++) {
379 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
382 Index nT = scat_data_mono[i_ss][i_se].pha_mat_data.nvitrines();
388 }
else if (rtp_temperature < 0.)
391 if (rtp_temperature > -10.)
394 }
else if (rtp_temperature > -20.)
403 os <<
"In pha_mat_sptFromDataDOITOpt.\n" 404 <<
"The temperature grid of the scattering data does not\n" 405 <<
"cover the atmospheric temperature at cloud location.\n" 406 <<
"The data should include the value T = " << rtp_temperature
409 os.
str(), scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
412 gridpos(T_gp, scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
417 for (
Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
419 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
423 for (
Index i = 0;
i < stokes_dim;
i++) {
424 for (
Index j = 0; j < stokes_dim; j++) {
425 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
i, j) =
427 pha_mat_sptDOITOpt[i_se_flat](
joker,
438 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker) =
439 pha_mat_sptDOITOpt[i_se_flat](ti,
464 const Index& za_index,
465 const Index& aa_index,
466 const Index& f_index,
468 const Numeric& rtp_temperature,
470 const Index& scat_p_index,
471 const Index& scat_lat_index,
472 const Index& scat_lon_index,
475 const Numeric za_sca = za_grid[za_index];
476 const Numeric aa_sca = aa_grid[aa_index];
480 assert(ext_mat_spt[0].NumberOfFrequencies() == N_se_total);
481 assert(abs_vec_spt[0].NumberOfFrequencies() == N_se_total);
491 if (scat_data[0][0].f_grid.
nelem() < 2) {
493 os <<
"Scattering data seems to be *scat_data_mono* (1 freq point only),\n" 494 <<
"but frequency interpolable data (*scat_data* with >=2 freq points) " 495 <<
"is expected here.";
496 throw runtime_error(os.
str());
510 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
514 for (
Index i_se = 0; i_se < N_se; i_se++) {
519 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
531 ext_mat_data_int.resize(
545 os <<
"In opt_prop_sptFromData.\n" 546 <<
"The temperature grid of the scattering data does not\n" 547 <<
"cover the atmospheric temperature at cloud location.\n" 548 <<
"The data should include the value T = " << rtp_temperature
566 ext_mat_data_int(i_za_sca, i_aa_sca,
i) =
583 abs_vec_data_int(i_za_sca, i_aa_sca,
i) =
604 ext_mat_data_int(i_za_sca, i_aa_sca,
i) =
620 abs_vec_data_int(i_za_sca, i_aa_sca,
i) =
666 const Index& scat_data_checked,
669 const Index& za_index,
670 const Index& aa_index,
671 const Index& f_index,
672 const Numeric& rtp_temperature,
674 const Index& scat_p_index,
675 const Index& scat_lat_index,
676 const Index& scat_lon_index,
678 if (scat_data_checked != 1)
680 "The scattering data must be flagged to have " 681 "passed a consistency check (scat_data_checked=1).");
684 const Index stokes_dim = ext_mat_spt[0].StokesDimensions();
685 const Numeric za_sca = za_grid[za_index];
686 const Numeric aa_sca = aa_grid[aa_index];
688 if (stokes_dim > 4 || stokes_dim < 1) {
690 "The dimension of the stokes vector \n" 691 "must be 1,2,3 or 4");
695 assert(ext_mat_spt.
nelem() == N_se_total);
696 assert(abs_vec_spt.
nelem() == N_se_total);
704 for (
auto&
pm : ext_mat_spt)
pm.SetZero();
705 for (
auto& sv : abs_vec_spt) sv.SetZero();
711 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
715 for (
Index i_se = 0; i_se < N_se; i_se++) {
720 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
727 ext_mat_data_int.resize(
737 os <<
"In opt_prop_sptFromScat_data.\n" 738 <<
"The temperature grid of the scattering data does not\n" 739 <<
"cover the atmospheric temperature at cloud location.\n" 740 <<
"The data should include the value T = " << rtp_temperature
756 this_f_index = f_index;
765 ext_mat_data_int(i_za_sca, i_aa_sca,
i) =
interp(
794 this_f_index = f_index;
803 abs_vec_data_int(i_za_sca, i_aa_sca,
i) =
interp(
864 const Index& scat_p_index,
865 const Index& scat_lat_index,
866 const Index& scat_lon_index,
870 if (ext_mat_spt.
nelem() not_eq N_se) {
872 os <<
"Number of scattering elements in *abs_vec_spt* and *ext_mat_spt*\n" 873 <<
"does not agree.";
874 throw runtime_error(os.
str());
877 Index stokes_dim = abs_vec_spt[0].StokesDimensions();
879 if (ext_mat_spt[0].StokesDimensions() not_eq stokes_dim) {
881 os <<
"*stokes_dim* of *abs_vec_spt* and *ext_mat_spt* does not agree.";
882 throw runtime_error(os.
str());
884 if (stokes_dim > 4 || stokes_dim < 1) {
886 os <<
"The dimension of stokes vector can only be 1, 2, 3, or 4.";
887 throw runtime_error(os.
str());
901 for (
Index l = 0; l < N_se; l++) {
903 pnd_field(l, scat_p_index, scat_lat_index, scat_lon_index),
906 pnd_field(l, scat_p_index, scat_lat_index, scat_lon_index),
911 abs_vec += abs_vec_part;
913 ext_mat += ext_mat_part;
925 if (stokes_dim != propmat_clearsky[0].StokesDimensions())
927 "Col dimension of propmat_clearsky " 928 "inconsistent with col dimension in ext_mat.");
935 if (f_dim != propmat_clearsky[0].NumberOfFrequencies())
937 "Frequency dimension of ext_mat and propmat_clearsky\n" 938 "are inconsistent in ext_matAddGas.");
940 for (
auto&
pm : propmat_clearsky) ext_mat +=
pm;
953 if (f_dim != propmat_clearsky[0].NumberOfFrequencies())
955 "Frequency dimension of abs_vec and propmat_clearsky\n" 956 "are inconsistent in abs_vecAddGas.");
957 if (stokes_dim != propmat_clearsky[0].StokesDimensions())
959 "Stokes dimension of abs_vec and propmat_clearsky\n" 960 "are inconsistent in abs_vecAddGas.");
964 for (
auto&
pm : propmat_clearsky)
1018 const Index& atmosphere_dim,
1019 const Index& scat_p_index,
1020 const Index& scat_lat_index,
1021 const Index& scat_lon_index,
1028 pha_mat.
resize(Nza, Naa, stokes_dim, stokes_dim);
1035 if (atmosphere_dim > 1) ilat = scat_lat_index;
1036 if (atmosphere_dim > 2) ilon = scat_lon_index;
1038 if (atmosphere_dim == 1) {
1046 for (
Index pt_index = 0; pt_index < N_se; ++pt_index)
1048 for (
Index za_index = 0; za_index < Nza; ++za_index)
1049 for (
Index aa_index = 0; aa_index < Naa - 1; ++aa_index)
1051 for (
Index stokes_index_1 = 0; stokes_index_1 < stokes_dim;
1053 for (
Index stokes_index_2 = 0; stokes_index_2 < stokes_dim;
1057 pha_mat(za_index, 0, stokes_index_1, stokes_index_2) +=
1058 ((pha_mat_spt(pt_index,
1063 pha_mat_spt(pt_index,
1068 2 * grid_step_size_azimuth *
1069 pnd_field(pt_index, scat_p_index, ilat, ilon));
1072 for (
Index pt_index = 0; pt_index < N_se; ++pt_index)
1074 for (
Index za_index = 0; za_index < Nza; ++za_index)
1075 for (
Index aa_index = 0; aa_index < Naa; ++aa_index)
1077 for (
Index stokes_index_1 = 0; stokes_index_1 < stokes_dim;
1079 for (
Index stokes_index_2 = 0; stokes_index_2 < stokes_dim;
1083 pha_mat(za_index, aa_index, stokes_index_1, stokes_index_2) +=
1084 (pha_mat_spt(pt_index,
1089 pnd_field(pt_index, scat_p_index, ilat, ilon));
1096 const String& check_type,
1116 out2 <<
" checking for negative values in Z11, K11, and a1, and for K11<a1\n";
1117 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1121 for (
Index i_se = 0; i_se < N_se; i_se++) {
1129 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1130 <<
" contains negative K11 or a1 at f#" << f <<
", T#" << t
1131 <<
", za#" << zai <<
", aa#" << aai <<
"\n";
1132 throw runtime_error(os.
str());
1137 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1138 <<
" has K11<a1 at f#" << f <<
", T#" << t <<
", za#" << zai
1139 <<
", aa#" << aai <<
"\n";
1140 throw runtime_error(os.
str());
1147 for (
Index t = 0; t < nTpha; t++) {
1152 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1153 <<
" contains negative Z11 at f#" << f <<
", T#" << t
1154 <<
" (of " << nTpha <<
"), za_sca#" << zas <<
", aa_sca#" 1155 << aas <<
", za_inc#" << zai <<
", aa_inc#" << aai
1157 throw runtime_error(os.
str());
1166 out2 <<
" checking for NaN anywhere in Z, K, and a\n";
1167 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1171 for (
Index i_se = 0; i_se < N_se; i_se++) {
1179 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1180 <<
" contains NaN in abs_vec at f#" << f <<
", T#" << t
1181 <<
", za#" << zai <<
", aa#" << aai <<
", stokes #" << st
1183 throw runtime_error(os.
str());
1188 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1189 <<
" contains NaN in ext_mat at f#" << f <<
", T#" << t
1190 <<
", za#" << zai <<
", aa#" << aai <<
", stokes #" << st
1192 throw runtime_error(os.
str());
1196 for (
Index t = 0; t < nTpha; t++) {
1203 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1204 <<
" contains NaN in pha_mat at f#" << f <<
", T#" << t
1205 <<
" (of " << nTpha <<
"), za_sca#" << zas
1206 <<
", aa_sca#" << aas <<
", za_inc#" << zai
1207 <<
", aa_inc#" << aai <<
", stokes #" 1209 throw runtime_error(os.
str());
1217 if (check_type.
toupper() ==
"ALL") {
1219 out2 <<
" checking normalization of scattering matrix\n";
1220 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1224 for (
Index i_se = 0; i_se < N_se; i_se++)
1234 Numeric Csca_data = Cext_data - Cabs_data;
1252 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
1254 os <<
" Deviations in scat_data too large:\n" 1255 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1256 <<
" at nominal (actual) albedo of " 1257 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
1259 <<
" Check entry for scattering element " << i_se
1260 <<
" of scattering species " << i_ss <<
" at " << f
1261 <<
".frequency and " << t <<
".temperature!\n";
1262 throw runtime_error(os.
str());
1281 Numeric Csca_data = Cext_data - Cabs_data;
1299 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
1301 os <<
" Deviations in scat_data too large:\n" 1302 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1303 <<
" at nominal (actual) albedo of " 1304 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
1306 <<
" Check entry for scattering element " << i_se
1307 <<
" of scattering species " << i_ss <<
" at " << f
1308 <<
". frequency, " << t <<
". temperature, and " << iza
1309 <<
". incident polar angle!\n";
1310 throw runtime_error(os.
str());
1321 <<
" scat_data consistency check not implemented (yet?!) for\n" 1326 out2 <<
" WARNING:\n" 1327 <<
" scat_data norm check can not be performed for pha_mat-only" 1328 <<
" T-reduced scattering elements\n" 1329 <<
" as found in scatt element #" << i_se
1330 <<
" of scatt species #" << i_ss <<
"!\n";
1332 }
else if (check_type.
toupper() ==
"SANE") {
1333 out1 <<
" WARNING:\n" 1334 <<
" Normalization check on pha_mat switched off.\n" 1335 <<
" Scattering solution might be wrong.\n";
1338 os <<
"Invalid value for argument *check_type*: '" << check_type <<
"'.\n";
1339 os <<
"Valid values are 'all' or 'none'.";
1340 throw runtime_error(os.
str());
1353 const Index& doit_za_grid_size,
1355 const Index& scat_data_checked,
1356 const Index& f_index,
1357 const Index& atmosphere_dim,
1358 const Index& stokes_dim,
1362 const Agenda& pha_mat_spt_agenda,
1364 if (scat_data_checked != 1)
1365 throw runtime_error(
1366 "The scattering data must be flagged to have " 1367 "passed a consistency check (scat_data_checked=1).");
1372 grid_stepsize[0] = 180. / (
Numeric)(doit_za_grid_size - 1);
1382 Tensor4 pha_mat_local(doit_za_grid_size, Naa, stokes_dim, stokes_dim, 0.);
1383 Tensor6 pha_mat_local_out(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1396 if (atmosphere_dim == 1)
1399 N_aa_sca = aa_grid.
nelem();
1402 nlinspace(za_grid, 0, 180, doit_za_grid_size);
1404 assert(scat_data.
nelem() == scat_data_mono.
nelem());
1411 Index i_se_flat = 0;
1412 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1415 for (
Index i_se = 0; i_se < N_se; i_se++) {
1416 Index N_T = scat_data_mono[i_ss][i_se].T_grid.
nelem();
1417 pha_mat_sptDOITOpt[i_se_flat].resize(N_T,
1426 pha_mat_sptDOITOpt[i_se_flat] = 0.;
1430 for (
Index t_idx = 0; t_idx < N_T; t_idx++) {
1432 for (
Index za_sca_idx = 0; za_sca_idx < doit_za_grid_size;
1434 for (
Index aa_sca_idx = 0; aa_sca_idx < N_aa_sca; aa_sca_idx++) {
1436 for (
Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
1438 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
1441 pha_mat_sptDOITOpt[i_se_flat](t_idx,
1448 scat_data_mono[i_ss][i_se].pha_mat_data(
1450 scat_data_mono[i_ss][i_se].za_grid,
1451 scat_data_mono[i_ss][i_se].aa_grid,
1452 scat_data_mono[i_ss][i_se].ptype,
1470 pha_mat_doit.
resize(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1479 if (atmosphere_dim == 1) {
1480 Index aa_index_local = 0;
1484 for (
Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
1486 Numeric rtp_temperature_local =
1487 t_field(p_index + cloudbox_limits[0], 0, 0);
1489 for (
Index za_index_local = 0;
1490 za_index_local < doit_za_grid_size;
1493 Index index_zero = 0;
1503 rtp_temperature_local,
1504 pha_mat_spt_agenda);
1532 const Index& interp_order,
1545 const String which_interpolation =
"scat_data_raw.f_grid to f_grid";
1546 for (
Index i_ss = 0; i_ss < scat_data_raw.
nelem(); i_ss++) {
1547 for (
Index i_se = 0; i_se < scat_data_raw[i_ss].
nelem(); i_se++) {
1550 if (scat_data_raw[i_ss][i_se].f_grid.
nelem() == 1 && nf == 1)
1555 os <<
"There is a problem with the grids for the following " 1556 <<
"interpolation:\n" 1557 << which_interpolation <<
"\n" 1558 <<
"If original grid has only 1 element, the new grid must also have\n" 1559 <<
"only a single element and hold the same value as the original grid.";
1560 throw runtime_error(os.
str());
1565 scat_data_raw[i_ss][i_se].f_grid,
1572 scat_data.resize(scat_data_raw.
nelem());
1575 for (
Index i_ss = 0; i_ss < scat_data_raw.
nelem(); i_ss++) {
1576 const Index N_se = scat_data_raw[i_ss].
nelem();
1579 scat_data[i_ss].resize(N_se);
1582 for (
Index i_se = 0; i_se < N_se; i_se++) {
1584 PART_TYPE = scat_data_raw[i_ss][i_se].ptype;
1586 T_DATAGRID = scat_data_raw[i_ss][i_se].T_grid;
1592 scat_data_raw[i_ss][i_se].pha_mat_data.nvitrines(),
1593 scat_data_raw[i_ss][i_se].pha_mat_data.nshelves(),
1594 scat_data_raw[i_ss][i_se].pha_mat_data.nbooks(),
1595 scat_data_raw[i_ss][i_se].pha_mat_data.npages(),
1596 scat_data_raw[i_ss][i_se].pha_mat_data.nrows(),
1597 scat_data_raw[i_ss][i_se].pha_mat_data.ncols());
1599 scat_data_raw[i_ss][i_se].ext_mat_data.nbooks(),
1600 scat_data_raw[i_ss][i_se].ext_mat_data.npages(),
1601 scat_data_raw[i_ss][i_se].ext_mat_data.nrows(),
1602 scat_data_raw[i_ss][i_se].ext_mat_data.ncols());
1604 scat_data_raw[i_ss][i_se].abs_vec_data.nbooks(),
1605 scat_data_raw[i_ss][i_se].abs_vec_data.npages(),
1606 scat_data_raw[i_ss][i_se].abs_vec_data.nrows(),
1607 scat_data_raw[i_ss][i_se].abs_vec_data.ncols());
1609 const bool single_se_fgrid =
1610 (scat_data_raw[i_ss][i_se].f_grid.
nelem() == 1);
1611 if (!single_se_fgrid) {
1616 freq_gp, scat_data_raw[i_ss][i_se].f_grid, f_grid, interp_order);
1619 Matrix itw(nf, interp_order + 1);
1623 for (
Index t_index = 0;
1624 t_index < scat_data_raw[i_ss][i_se].pha_mat_data.nvitrines();
1626 for (
Index i_za_sca = 0;
1627 i_za_sca < scat_data_raw[i_ss][i_se].pha_mat_data.nshelves();
1629 for (
Index i_aa_sca = 0;
1630 i_aa_sca < scat_data_raw[i_ss][i_se].pha_mat_data.nbooks();
1632 for (
Index i_za_inc = 0;
1633 i_za_inc < scat_data_raw[i_ss][i_se].pha_mat_data.npages();
1635 for (
Index i_aa_inc = 0;
1636 i_aa_inc < scat_data_raw[i_ss][i_se].pha_mat_data.nrows();
1639 i < scat_data_raw[i_ss][i_se].pha_mat_data.ncols();
1649 scat_data_raw[i_ss][i_se].pha_mat_data(
joker,
1665 for (
Index t_index = 0;
1666 t_index < scat_data_raw[i_ss][i_se].ext_mat_data.nbooks();
1668 for (
Index i_za_sca = 0;
1669 i_za_sca < scat_data_raw[i_ss][i_se].ext_mat_data.npages();
1671 for (
Index i_aa_sca = 0;
1672 i_aa_sca < scat_data_raw[i_ss][i_se].ext_mat_data.nrows();
1675 i < scat_data_raw[i_ss][i_se].ext_mat_data.ncols();
1677 interp(scat_data[i_ss][i_se].ext_mat_data(
1678 joker, t_index, i_za_sca, i_aa_sca,
i),
1680 scat_data_raw[i_ss][i_se].ext_mat_data(
1681 joker, t_index, i_za_sca, i_aa_sca,
i),
1689 for (
Index t_index = 0;
1690 t_index < scat_data_raw[i_ss][i_se].abs_vec_data.nbooks();
1692 for (
Index i_za_sca = 0;
1693 i_za_sca < scat_data_raw[i_ss][i_se].abs_vec_data.npages();
1695 for (
Index i_aa_sca = 0;
1696 i_aa_sca < scat_data_raw[i_ss][i_se].abs_vec_data.nrows();
1699 i < scat_data_raw[i_ss][i_se].abs_vec_data.ncols();
1701 interp(scat_data[i_ss][i_se].abs_vec_data(
1702 joker, t_index, i_za_sca, i_aa_sca,
i),
1704 scat_data_raw[i_ss][i_se].abs_vec_data(
1705 joker, t_index, i_za_sca, i_aa_sca,
i),
1716 scat_data[i_ss][i_se].pha_mat_data =
1717 scat_data_raw[i_ss][i_se].pha_mat_data;
1718 scat_data[i_ss][i_se].ext_mat_data =
1719 scat_data_raw[i_ss][i_se].ext_mat_data;
1720 scat_data[i_ss][i_se].abs_vec_data =
1721 scat_data_raw[i_ss][i_se].abs_vec_data;
1731 const Index& interp_order,
1732 const Index& phamat_only,
1744 os <<
"Can not T-reduce scattering species #" << i_ss <<
".\n" 1745 <<
"*scat_data* contains only " << nss <<
" scattering species.";
1746 throw runtime_error(os.
str());
1750 for (
Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
1756 <<
" can be handled.\n" 1757 <<
"Scattering element #" << i_se <<
" has ptype " <<
PART_TYPE <<
".";
1758 throw runtime_error(os.
str());
1771 os <<
"Single scattering data of scat element #" << i_se
1772 <<
" of scat species #" << i_ss <<
"\n" 1773 <<
"seems to have undergone some temperature grid manipulation in\n" 1774 <<
"*pha_mat_data* already. That can not be done twice!";
1775 throw runtime_error(os.
str());
1785 ost <<
"Scattering data temperature interpolation for\n" 1786 <<
"scat element #" << i_se <<
" of scat species #" << i_ss <<
".";
1792 Vector itw(interp_order + 1);
1828 phamat_tmp(i_f, 0, i_za1, i_aa1, i_za2, i_aa2, i_st) =
1831 i_f,
joker, i_za1, i_aa1, i_za2, i_aa2, i_st),
1841 extmat_tmp(i_f, 0, i_za, i_aa, i_st) =
1844 absvec_tmp(i_f, 0, i_za, i_aa, i_st) =
1896 this_threshold = threshold;
1898 "T-reduced *pha_mat_data* norm (=sca xs) deviates too " 1899 "much from non-reduced *ext_mat_data* and *abs_vec_data*:";
1901 this_threshold = 2 * threshold;
1903 "T-reduced *scat_data* deviates too much from original " 1919 Numeric Cext_data = extmat_tmp(f, 0, 0, 0, 0);
1921 Numeric Cabs_data = absvec_tmp(f, 0, 0, 0, 0);
1922 Numeric Csca_data = Cext_data - Cabs_data;
1939 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
1941 os <<
" Deviations in T-reduced scat_data too large:\n" 1942 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1943 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
1944 <<
" (" << Csca / Cext_data <<
").\n" 1945 <<
" Problem occurs for scattering element #" << i_se
1946 <<
" at " << f <<
".frequency!\n";
1947 throw runtime_error(os.
str());
1949 Numeric norm_dev = (Csca - Csca) / Cext_data;
1957 Numeric xs_dev = (Csca - Csca_data) / Cext_data;
1958 if (
abs(norm_dev + (Csca - Csca_data) / Cext_data) >
1960 cout <<
"Accumulated deviation (abs(" << norm_dev <<
"+" 1961 << xs_dev <<
")=" <<
abs(norm_dev + xs_dev)
1962 <<
" exceeding threshold (" << this_threshold <<
").\n";
1963 if (
abs(Csca - Csca_data) / Cext_data > this_threshold) {
1965 os <<
" " << errmsg <<
"\n" 1966 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1967 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
1968 <<
" (" << Csca / Cext_data <<
").\n" 1969 <<
" Problem occurs for scattering element #" << i_se
1970 <<
" at " << f <<
".frequency and " << t
1971 <<
".temperature!\n";
1972 throw runtime_error(os.
str());
1987 Numeric Cext_data = extmat_tmp(f, 0, iza, 0, 0);
1989 Numeric Cabs_data = absvec_tmp(f, 0, iza, 0, 0);
1990 Numeric Csca_data = Cext_data - Cabs_data;
2007 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
2009 os <<
" Deviations in T-reduced scat_data too large:\n" 2010 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
2011 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
2012 <<
" (" << Csca / Cext_data <<
").\n" 2013 <<
" Problem occurs for scattering element #" << i_se
2014 <<
" at " << f <<
".frequency, and " << iza
2015 <<
". incident polar angle!\n";
2016 throw runtime_error(os.
str());
2025 if (
abs(Csca - Csca_data) / Cext_data > this_threshold) {
2027 os <<
" " << errmsg <<
"\n" 2028 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
2029 <<
" at nominal (actual) albedo of " 2030 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
2032 <<
" Problem occurs for scattering element #" << i_se
2033 <<
" at " << f <<
".frequency and " << t
2034 <<
".temperature, and " << iza
2035 <<
". incident polar angle!\n";
2036 throw runtime_error(os.
str());
2068 const Index& f_index,
2076 for (
Index h = 0; h < scat_data.
nelem(); h++) {
2080 scat_data[h][
i].f_grid,
2086 scat_data_mono.resize(scat_data.
nelem());
2089 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2093 scat_data_mono[i_ss].resize(N_se);
2096 for (
Index i_se = 0; i_se < N_se; i_se++) {
2106 scat_data_mono[i_ss][i_se].ptype =
PART_TYPE;
2107 scat_data_mono[i_ss][i_se].f_grid.resize(1);
2108 scat_data_mono[i_ss][i_se].f_grid = f_grid[f_index];
2109 scat_data_mono[i_ss][i_se].T_grid = scat_data[i_ss][i_se].T_grid;
2114 scat_data_mono[i_ss][i_se].pha_mat_data.resize(1,
2132 scat_data_mono[i_ss][i_se].pha_mat_data(
2133 0, t_index, i_za_sca, i_aa_sca, i_za_inc, i_aa_inc,
i) =
2149 scat_data_mono[i_ss][i_se].ext_mat_data.resize(1,
2161 scat_data_mono[i_ss][i_se].ext_mat_data(
2162 0, t_index, i_za_sca, i_aa_sca,
i) =
2170 scat_data_mono[i_ss][i_se].abs_vec_data.resize(1,
2182 scat_data_mono[i_ss][i_se].abs_vec_data(
2183 0, t_index, i_za_sca, i_aa_sca,
i) =
2198 const Index& f_index,
2201 scat_data_mono.resize(scat_data.
nelem());
2204 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2208 scat_data_mono[i_ss].resize(N_se);
2211 for (
Index i_se = 0; i_se < N_se; i_se++) {
2214 scat_data_mono[i_ss][i_se] = scat_data[i_ss][i_se];
2217 scat_data_mono[i_ss][i_se].ptype =
PART_TYPE;
2218 scat_data_mono[i_ss][i_se].T_grid =
T_DATAGRID;
2222 scat_data_mono[i_ss][i_se].f_grid.resize(1);
2223 scat_data_mono[i_ss][i_se].f_grid =
F_DATAGRID[f_index];
2235 this_f_index = (
PHA_MAT_DATA.nlibraries() == 1) ? 0 : f_index;
2236 scat_data_mono[i_ss][i_se].pha_mat_data =
PHA_MAT_DATA(
2244 this_f_index = (
EXT_MAT_DATA.nshelves() == 1) ? 0 : f_index;
2245 scat_data_mono[i_ss][i_se].ext_mat_data =
2253 this_f_index = (
ABS_VEC_DATA.nshelves() == 1) ? 0 : f_index;
2254 scat_data_mono[i_ss][i_se].abs_vec_data =
2269 const Index& za_index,
2270 const Index& aa_index,
2271 const Numeric& rtp_temperature,
2273 const Index& scat_p_index,
2274 const Index& scat_lat_index,
2275 const Index& scat_lon_index,
2278 const Index stokes_dim = ext_mat_spt[0].StokesDimensions();
2279 const Numeric za_sca = za_grid[za_index];
2280 const Numeric aa_sca = aa_grid[aa_index];
2282 if (stokes_dim > 4 or stokes_dim < 1) {
2283 throw runtime_error(
2284 "The dimension of the stokes vector \n" 2285 "must be 1,2,3 or 4");
2288 assert(ext_mat_spt.
nelem() == N_se_total);
2289 assert(abs_vec_spt.
nelem() == N_se_total);
2300 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
2302 os <<
"Scattering data seems to be *scat_data* (several freq points),\n" 2303 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
2304 throw runtime_error(os.
str());
2308 for (
auto&
pm : ext_mat_spt)
pm.SetZero();
2309 for (
auto& av : abs_vec_spt) av.SetZero();
2315 Index i_se_flat = 0;
2317 for (
Index i_ss = 0; i_ss < scat_data_mono.
nelem(); i_ss++) {
2319 for (
Index i_se = 0; i_se < scat_data_mono[i_ss].
nelem(); i_se++) {
2323 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
2334 Index ext_npages = scat_data_mono[i_ss][i_se].ext_mat_data.npages();
2335 Index ext_nrows = scat_data_mono[i_ss][i_se].ext_mat_data.nrows();
2336 Index ext_ncols = scat_data_mono[i_ss][i_se].ext_mat_data.ncols();
2337 Index abs_npages = scat_data_mono[i_ss][i_se].abs_vec_data.npages();
2338 Index abs_nrows = scat_data_mono[i_ss][i_se].abs_vec_data.nrows();
2339 Index abs_ncols = scat_data_mono[i_ss][i_se].abs_vec_data.ncols();
2344 if (t_grid.
nelem() > 1) {
2346 os <<
"In opt_prop_sptFromMonoData.\n" 2347 <<
"The temperature grid of the scattering data does not\n" 2348 <<
"cover the atmospheric temperature at cloud location.\n" 2349 <<
"The data should include the value T = " << rtp_temperature
2354 Tensor3 ext_mat_data1temp(ext_npages, ext_nrows, ext_ncols);
2355 gridpos(t_gp, t_grid, rtp_temperature);
2357 for (
Index i_p = 0; i_p < ext_npages; i_p++) {
2358 for (
Index i_r = 0; i_r < ext_nrows; i_r++) {
2359 for (
Index i_c = 0; i_c < ext_ncols; i_c++) {
2360 ext_mat_data1temp(i_p, i_r, i_c) =
2362 scat_data_mono[i_ss][i_se].ext_mat_data(
2363 0,
joker, i_p, i_r, i_c),
2370 scat_data_mono[i_ss][i_se].za_grid,
2371 scat_data_mono[i_ss][i_se].aa_grid,
2372 scat_data_mono[i_ss][i_se].ptype,
2378 scat_data_mono[i_ss][i_se].ext_mat_data(
2380 scat_data_mono[i_ss][i_se].za_grid,
2381 scat_data_mono[i_ss][i_se].aa_grid,
2382 scat_data_mono[i_ss][i_se].ptype,
2391 if (t_grid.
nelem() > 1) {
2392 Tensor3 abs_vec_data1temp(abs_npages, abs_nrows, abs_ncols);
2394 for (
Index i_p = 0; i_p < abs_npages; i_p++) {
2395 for (
Index i_r = 0; i_r < abs_nrows; i_r++) {
2396 for (
Index i_c = 0; i_c < abs_ncols; i_c++) {
2397 abs_vec_data1temp(i_p, i_r, i_c) =
2399 scat_data_mono[i_ss][i_se].abs_vec_data(
2400 0,
joker, i_p, i_r, i_c),
2407 scat_data_mono[i_ss][i_se].za_grid,
2408 scat_data_mono[i_ss][i_se].aa_grid,
2409 scat_data_mono[i_ss][i_se].ptype,
2415 scat_data_mono[i_ss][i_se].abs_vec_data(
2417 scat_data_mono[i_ss][i_se].za_grid,
2418 scat_data_mono[i_ss][i_se].aa_grid,
2419 scat_data_mono[i_ss][i_se].ptype,
2436 const Index& doit_za_grid_size,
2438 const Index& za_index,
2439 const Index& aa_index,
2440 const Numeric& rtp_temperature,
2442 const Index& scat_p_index,
2443 const Index& scat_lat_index,
2444 const Index& scat_lon_index,
2447 nlinspace(za_grid, 0, 180, doit_za_grid_size);
2450 if (N_se_total != pnd_field.
nbooks()) {
2452 os <<
"Total number of scattering elements in *scat_data_mono* " 2453 <<
"inconsistent with size of pnd_field.";
2454 throw runtime_error(os.
str());
2459 assert(pha_mat_spt.
nshelves() == N_se_total);
2461 const Index stokes_dim = pha_mat_spt.
ncols();
2462 if (stokes_dim > 4 || stokes_dim < 1) {
2463 throw runtime_error(
2464 "The dimension of the stokes vector \n" 2465 "must be 1,2,3 or 4");
2477 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
2479 os <<
"Scattering data seems to be *scat_data* (several freq points),\n" 2480 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
2481 throw runtime_error(os.
str());
2484 GridPos T_gp = {0, {0, 1}}, Tred_gp;
2490 Index i_se_flat = 0;
2491 for (
Index i_ss = 0; i_ss < scat_data_mono.
nelem(); i_ss++) {
2492 for (
Index i_se = 0; i_se < scat_data_mono[i_ss].
nelem(); i_se++) {
2496 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
2499 Index nT = scat_data_mono[i_ss][i_se].pha_mat_data.nvitrines();
2502 pha_mat_spt_tmp = 0.;
2508 }
else if (rtp_temperature < 0.)
2511 if (rtp_temperature > -10.)
2514 }
else if (rtp_temperature > -20.)
2523 os <<
"In pha_mat_sptFromMonoData.\n" 2524 <<
"The temperature grid of the scattering data does not\n" 2525 <<
"cover the atmospheric temperature at cloud location.\n" 2526 <<
"The data should include the value T = " << rtp_temperature
2529 os.
str(), scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
2532 gridpos(T_gp, scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
2540 for (
Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
2542 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
2546 for (
Index t_idx = 0; t_idx < 2; t_idx++) {
2549 scat_data_mono[i_ss][i_se].pha_mat_data(
2551 scat_data_mono[i_ss][i_se].za_grid,
2552 scat_data_mono[i_ss][i_se].aa_grid,
2553 scat_data_mono[i_ss][i_se].ptype,
2563 for (
Index i = 0;
i < stokes_dim;
i++) {
2564 for (
Index j = 0; j < stokes_dim; j++) {
2565 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
i, j) =
2572 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker),
2573 scat_data_mono[i_ss][i_se].pha_mat_data(
2575 scat_data_mono[i_ss][i_se].za_grid,
2576 scat_data_mono[i_ss][i_se].aa_grid,
2577 scat_data_mono[i_ss][i_se].ptype,
2600 const Index& scat_data_checked,
2603 const Index& za_index,
2604 const Index& aa_index,
2605 const Index& f_index,
2606 const Numeric& rtp_temperature,
2608 const Index& scat_p_index,
2609 const Index& scat_lat_index,
2610 const Index& scat_lon_index,
2612 if (scat_data_checked != 1)
2613 throw runtime_error(
2614 "The scattering data must be flagged to have " 2615 "passed a consistency check (scat_data_checked=1).");
2617 const Index stokes_dim = pha_mat_spt.
ncols();
2618 if (stokes_dim > 4 || stokes_dim < 1) {
2619 throw runtime_error(
2620 "The dimension of the stokes vector \n" 2621 "must be 1,2,3 or 4");
2626 if (N_se_total != pnd_field.
nbooks()) {
2628 os <<
"Total number of scattering elements in scat_data " 2629 <<
"inconsistent with size of pnd_field.";
2630 throw runtime_error(os.
str());
2635 assert(pha_mat_spt.
nshelves() == N_se_total);
2645 Index i_se_flat = 0;
2647 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
2651 for (
Index i_se = 0; i_se < N_se; i_se++) {
2656 i_se_flat, scat_p_index, scat_lat_index, scat_lon_index)) >
2674 Index this_T_index = -1;
2677 }
else if (rtp_temperature < 0.)
2680 if (rtp_temperature > -10.)
2683 }
else if (rtp_temperature > -20.)
2692 os <<
"In pha_mat_sptFromScat_data.\n" 2693 <<
"The temperature grid of the scattering data does not\n" 2694 <<
"cover the atmospheric temperature at cloud location.\n" 2695 <<
"The data should include the value T = " << rtp_temperature
2709 this_f_index = f_index;
2711 if (this_T_index < 0) {
2723 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc,
i) =
2755 for (
Index za_inc_idx = 0; za_inc_idx < za_grid.
nelem();
2757 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
2760 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker),
2786 Index& cloudbox_checked,
2788 const Index& atmosphere_dim,
2789 const Index& cloudbox_on,
2801 if (!cloudbox_checked)
2802 throw std::runtime_error(
2803 "You must call *cloudbox_checkedCalc* before this method.");
2806 cloudbox_checked = 0;
2808 if (atmosphere_dim != 1)
2809 throw std::runtime_error(
2810 "Merging scattering elements only works with a 1D atmoshere");
2815 pnd_field.
resize(0, 0, 0, 0);
2822 limits[0] = cloudbox_limits[0];
2823 limits[1] = cloudbox_limits[1] + 1;
2826 limits[1] - limits[0], limits[1] - limits[0], 1, 1, 0.);
2829 scat_data_merged.resize(1);
2830 scat_data_merged[0].resize(pnd_field_merged.
nbooks());
2832 scat_meta_merged.resize(1);
2833 scat_meta_merged[0].resize(pnd_field_merged.
nbooks());
2835 scat_species_merged.resize(1);
2836 scat_species_merged[0] =
"mergedfield-mergedpsd";
2837 for (
Index sp = 0; sp < scat_data_merged[0].
nelem(); sp++) {
2839 this_part.
ptype = scat_data[0][0].ptype;
2840 this_part.
description =
"Merged scattering elements";
2841 this_part.
f_grid = scat_data[0][0].f_grid;
2842 this_part.
za_grid = scat_data[0][0].za_grid;
2843 this_part.
aa_grid = scat_data[0][0].aa_grid;
2846 scat_data[0][0].pha_mat_data.nshelves(),
2847 scat_data[0][0].pha_mat_data.nbooks(),
2848 scat_data[0][0].pha_mat_data.npages(),
2849 scat_data[0][0].pha_mat_data.nrows(),
2850 scat_data[0][0].pha_mat_data.ncols());
2853 scat_data[0][0].ext_mat_data.npages(),
2854 scat_data[0][0].ext_mat_data.nrows(),
2855 scat_data[0][0].ext_mat_data.ncols());
2858 scat_data[0][0].abs_vec_data.npages(),
2859 scat_data[0][0].abs_vec_data.nrows(),
2860 scat_data[0][0].abs_vec_data.ncols());
2865 this_part.
T_grid[0] = t_field(sp, 0, 0);
2869 os <<
"Merged scattering element of cloudbox-level #" << sp;
2871 this_meta.
source =
"ARTS internal";
2873 this_meta.
mass = -1.;
2881 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2882 for (
Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
2886 throw std::runtime_error(
2887 "All scattering elements must have the same type");
2890 throw std::runtime_error(
2891 "All scattering elements must have the same f_grid");
2901 throw std::runtime_error(
2902 "All scattering elements must have the same pha_mat_data size" 2903 " (except for temperature).");
2910 throw std::runtime_error(
2911 "All scattering elements must have the same ext_mat_data size" 2912 " (except for temperature).");
2919 throw std::runtime_error(
2920 "All scattering elements must have the same abs_vec_data size" 2921 " (except for temperature).");
2932 for (
Index i_lv = 0; i_lv < nlevels - 1; i_lv++) {
2933 pnd_field_merged(i_lv, i_lv, 0, 0) = 1.;
2936 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2937 for (
Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
2944 if (pnd_field(pnd_index, i_lv, 0, 0) >
PND_LIMIT)
2949 os <<
"The temperature grid of the scattering data " 2950 <<
"does not cover the\n" 2951 <<
"atmospheric temperature at cloud location. " 2952 <<
"The data should\n" 2953 <<
"include the value T = " << temperature <<
" K.\n" 2954 <<
"Offending particle is scat_data[" << i_ss <<
"][" << i_se
2956 <<
"Description: " << orig_part.
description <<
"\n";
2979 v *= pnd_field(pnd_index, i_lv, 0, 0);
2983 v *= pnd_field(pnd_index, i_lv, 0, 0);
2989 pnd_field(pnd_index, i_lv, 0, 0) *
2998 pnd_field(pnd_index, i_lv, 0, 0) *
3011 for (
Index i_za_out = 0;
3015 for (
Index i_aa_out = 0;
3019 for (
Index i_za_inc = 0;
3023 for (
Index i_aa_inc = 0;
3035 v *= pnd_field(pnd_index, i_lv, 0, 0);
3054 pnd_field(pnd_index, i_lv, 0, 0) *
3080 if (z_field(cloudbox_limits[0], 0, 0) > z_surface(0, 0))
3081 pnd_field_merged(0, 0, 0, 0) = 0.;
3083 pnd_field = pnd_field_merged;
3084 scat_data = scat_data_merged;
3085 scat_meta = scat_meta_merged;
3086 scat_species = scat_species_merged;
3096 const Index& scat_species_index,
3098 if (scat_species_index < 0) {
3100 os <<
"scat_species_index can't be <0!";
3101 throw runtime_error(os.
str());
3107 if (!(nss > scat_species_index)) {
3109 os <<
"Can not extract data for scattering species #" << scat_species_index
3111 <<
"because scat_meta has only " << nss <<
" elements.";
3112 throw runtime_error(os.
str());
3115 const Index nse = scat_meta[scat_species_index].
nelem();
3119 if (meta_name ==
"mass")
3120 meta_param[
i] = scat_meta[scat_species_index][
i].mass;
3121 else if (meta_name ==
"diameter_max")
3122 meta_param[
i] = scat_meta[scat_species_index][
i].diameter_max;
3123 else if (meta_name ==
"diameter_volume_equ")
3124 meta_param[
i] = scat_meta[scat_species_index][
i].diameter_volume_equ;
3125 else if (meta_name ==
"diameter_area_equ_aerodynamical")
3127 scat_meta[scat_species_index][
i].diameter_area_equ_aerodynamical;
3130 os <<
"Meta parameter \"" << meta_name <<
"\"is unknown.";
3131 throw runtime_error(os.
str());
Index npages() const
Returns the number of pages.
INDEX Index
The type to use for all integer numbers and indices.
void pha_mat_sptFromData(Tensor5 &pha_mat_spt, const ArrayOfArrayOfSingleScatteringData &scat_data, const Vector &za_grid, const Vector &aa_grid, const Index &za_index, const Index &aa_index, const Index &f_index, const Vector &f_grid, const Numeric &rtp_temperature, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &verbosity)
WORKSPACE METHOD: pha_mat_sptFromData.
void MultiplyAndAdd(const Numeric x, const PropagationMatrix &y)
Add a scaled version of the input.
Index nrows() const
Returns the number of rows.
void opt_prop_bulkCalc(PropagationMatrix &ext_mat, StokesVector &abs_vec, const ArrayOfPropagationMatrix &ext_mat_spt, const ArrayOfStokesVector &abs_vec_spt, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &)
WORKSPACE METHOD: opt_prop_bulkCalc.
Index nelem() const
Number of elements.
void resize(Index s, Index b, Index p, Index r, Index c)
Resize function.
void scat_dataCheck(const ArrayOfArrayOfSingleScatteringData &scat_data, const String &check_type, const Numeric &threshold, const Verbosity &verbosity)
WORKSPACE METHOD: scat_dataCheck.
Declarations having to do with the four output streams.
void pha_mat_sptFromMonoData(Tensor5 &pha_mat_spt, const ArrayOfArrayOfSingleScatteringData &scat_data_mono, const Index &doit_za_grid_size, const Vector &aa_grid, const Index &za_index, const Index &aa_index, const Numeric &rtp_temperature, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &verbosity)
WORKSPACE METHOD: pha_mat_sptFromMonoData.
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
void scat_dataReduceT(ArrayOfArrayOfSingleScatteringData &scat_data, const Index &i_ss, const Numeric &T, const Index &interp_order, const Index &phamat_only, const Numeric &threshold, const Verbosity &)
WORKSPACE METHOD: scat_dataReduceT.
Index nrows() const
Returns the number of rows.
void opt_prop_sptFromData(ArrayOfPropagationMatrix &ext_mat_spt, ArrayOfStokesVector &abs_vec_spt, const ArrayOfArrayOfSingleScatteringData &scat_data, const Vector &za_grid, const Vector &aa_grid, const Index &za_index, const Index &aa_index, const Index &f_index, const Vector &f_grid, const Numeric &rtp_temperature, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &verbosity)
WORKSPACE METHOD: opt_prop_sptFromData.
This file contains basic functions to handle XML data files.
Header file for interpolation.cc.
Index nbooks() const
Returns the number of books.
Stokes vector is as Propagation matrix but only has 4 possible values.
Index nelem() const
Returns the number of elements.
Contains sorting routines.
Structure to store a grid position.
This file contains the definition of Array.
void opt_prop_sptFromMonoData(ArrayOfPropagationMatrix &ext_mat_spt, ArrayOfStokesVector &abs_vec_spt, const ArrayOfArrayOfSingleScatteringData &scat_data_mono, const Vector &za_grid, const Vector &aa_grid, const Index &za_index, const Index &aa_index, const Numeric &rtp_temperature, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &verbosity)
WORKSPACE METHOD: opt_prop_sptFromMonoData.
void pha_mat_spt_agendaExecute(Workspace &ws, Tensor5 &pha_mat_spt, const Index za_index, const Index scat_lat_index, const Index scat_lon_index, const Index scat_p_index, const Index aa_index, const Numeric rtp_temperature, const Agenda &input_agenda)
Index TotalNumberOfElements(const Array< Array< base > > &aa)
Determine total number of elements in an ArrayOfArray.
The global header file for ARTS.
Index nshelves() const
Returns the number of shelves.
void MultiplyAndAdd(const Numeric x, const PropagationMatrix &y)
Multiply input by scalar and add to this.
void ExtractFromMetaSingleScatSpecies(Vector &meta_param, const ArrayOfArrayOfScatteringMetaData &scat_meta, const String &meta_name, const Index &scat_species_index, const Verbosity &)
WORKSPACE METHOD: ExtractFromMetaSingleScatSpecies.
bool is_same_within_epsilon(const Numeric &a, const Numeric &b, const Numeric &epsilon)
Check, if two numbers agree within a given epsilon.
_CS_string_type str() const
void toupper()
Convert to upper case.
The declarations of all the exception classes.
void abs_vecAddGas(StokesVector &abs_vec, const ArrayOfPropagationMatrix &propmat_clearsky, const Verbosity &)
WORKSPACE METHOD: abs_vecAddGas.
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
void pha_mat_sptFromScat_data(Tensor5 &pha_mat_spt, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &scat_data_checked, const Vector &za_grid, const Vector &aa_grid, const Index &za_index, const Index &aa_index, const Index &f_index, const Numeric &rtp_temperature, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &verbosity)
WORKSPACE METHOD: pha_mat_sptFromScat_data.
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
NUMERIC Numeric
The type to use for all floating point numbers.
Index StokesDimensions() const
The stokes dimension of the propagation matrix.
Index nlibraries() const
Returns the number of libraries.
void gridpos_poly(ArrayOfGridPosPoly &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Index order, const Numeric &extpolfac)
The maximum difference from 1 that we allow for a sum check.
void gridpos_copy(GridPos &gp_new, const GridPos &gp_old)
gridpos_copy
void resize(Index p, Index r, Index c)
Resize function.
Header file for logic.cc.
Index NumberOfFrequencies() const
The number of frequencies of the propagation matrix.
This can be used to make arrays out of anything.
void opt_prop_sptFromScat_data(ArrayOfPropagationMatrix &ext_mat_spt, ArrayOfStokesVector &abs_vec_spt, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &scat_data_checked, const Vector &za_grid, const Vector &aa_grid, const Index &za_index, const Index &aa_index, const Index &f_index, const Numeric &rtp_temperature, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &verbosity)
WORKSPACE METHOD: opt_prop_sptFromScat_data.
void ext_matTransform(PropagationMatrix &ext_mat_lab, ConstTensor3View ext_mat_data, ConstVectorView za_datagrid, ConstVectorView aa_datagrid, const PType &ptype, const Numeric &za_sca, const Numeric &aa_sca, const Verbosity &verbosity)
Transformation of extinction matrix.
void ScatSpeciesMerge(Tensor4 &pnd_field, ArrayOfArrayOfSingleScatteringData &scat_data, ArrayOfArrayOfScatteringMetaData &scat_meta, ArrayOfString &scat_species, Index &cloudbox_checked, const Index &atmosphere_dim, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Tensor3 &t_field, const Tensor3 &z_field, const Matrix &z_surface, const Verbosity &)
WORKSPACE METHOD: ScatSpeciesMerge.
void resize(Index n)
Resize function.
void pha_matCalc(Tensor4 &pha_mat, const Tensor5 &pha_mat_spt, const Tensor4 &pnd_field, const Index &atmosphere_dim, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &)
WORKSPACE METHOD: pha_matCalc.
void scat_data_monoExtract(ArrayOfArrayOfSingleScatteringData &scat_data_mono, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &f_index, const Verbosity &)
WORKSPACE METHOD: scat_data_monoExtract.
void pha_matTransform(MatrixView pha_mat_lab, ConstTensor5View pha_mat_data, ConstVectorView za_datagrid, ConstVectorView aa_datagrid, const PType &ptype, const Index &za_sca_idx, const Index &aa_sca_idx, const Index &za_inc_idx, const Index &aa_inc_idx, ConstVectorView za_grid, ConstVectorView aa_grid, const Verbosity &verbosity)
Transformation of phase matrix.
A constant view of a Vector.
Index nshelves() const
Returns the number of shelves.
Index npages() const
Returns the number of pages.
Index nbooks() const
Returns the number of books.
Index FlattenedIndex(const Array< Array< base > > &aa, Index outer, Index inner=0)
Determine the index of an element in a flattened version of the array.
void scat_dataCalc(ArrayOfArrayOfSingleScatteringData &scat_data, const ArrayOfArrayOfSingleScatteringData &scat_data_raw, const Vector &f_grid, const Index &interp_order, const Verbosity &)
WORKSPACE METHOD: scat_dataCalc.
void SetZero()
Sets all data to zero.
Structure to store a grid position for higher order interpolation.
Index ncols() const
Returns the number of columns.
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
void DoitScatteringDataPrepare(Workspace &ws, ArrayOfTensor7 &pha_mat_sptDOITOpt, ArrayOfArrayOfSingleScatteringData &scat_data_mono, Tensor7 &pha_mat_doit, Vector &aa_grid, const Index &doit_za_grid_size, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &scat_data_checked, const Index &f_index, const Index &atmosphere_dim, const Index &stokes_dim, const Tensor3 &t_field, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const Agenda &pha_mat_spt_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: DoitScatteringDataPrepare.
void abs_vecTransform(StokesVector &abs_vec_lab, ConstTensor3View abs_vec_data, ConstVectorView za_datagrid, ConstVectorView aa_datagrid, const PType &ptype, const Numeric &za_sca, const Numeric &aa_sca, const Verbosity &verbosity)
Transformation of absorption vector.
Index ncols() const
Returns the number of columns.
void pha_mat_sptFromDataDOITOpt(Tensor5 &pha_mat_spt, const ArrayOfTensor7 &pha_mat_sptDOITOpt, const ArrayOfArrayOfSingleScatteringData &scat_data_mono, const Index &doit_za_grid_size, const Vector &aa_grid, const Index &za_index, const Index &aa_index, const Numeric &rtp_temperature, const Tensor4 &pnd_field, const Index &scat_p_index, const Index &scat_lat_index, const Index &scat_lon_index, const Verbosity &)
WORKSPACE METHOD: pha_mat_sptFromDataDOITOpt.
Index ncols() const
Returns the number of columns.
void ext_matAddGas(PropagationMatrix &ext_mat, const ArrayOfPropagationMatrix &propmat_clearsky, const Verbosity &)
WORKSPACE METHOD: ext_matAddGas.
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
void resize(Index l, Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
Scattering database structure and functions.
Index nbooks() const
Returns the number of books.
void scat_data_monoCalc(ArrayOfArrayOfSingleScatteringData &scat_data_mono, const ArrayOfArrayOfSingleScatteringData &scat_data, const Vector &f_grid, const Index &f_index, const Verbosity &)
WORKSPACE METHOD: scat_data_monoCalc.
void resize(Index b, Index p, Index r, Index c)
Resize function.
Numeric AngIntegrate_trapezoid(ConstMatrixView Integrand, ConstVectorView za_grid, ConstVectorView aa_grid)
AngIntegrate_trapezoid.