64#define PART_TYPE scat_data[i_ss][i_se].ptype
65#define F_DATAGRID scat_data[i_ss][i_se].f_grid
66#define T_DATAGRID scat_data[i_ss][i_se].T_grid
67#define ZA_DATAGRID scat_data[i_ss][i_se].za_grid
68#define AA_DATAGRID scat_data[i_ss][i_se].aa_grid
69#define PHA_MAT_DATA scat_data[i_ss][i_se].pha_mat_data
70#define EXT_MAT_DATA scat_data[i_ss][i_se].ext_mat_data
71#define ABS_VEC_DATA scat_data[i_ss][i_se].abs_vec_data
75#define PND_LIMIT 1e-12
84 const Index& za_index,
85 const Index& aa_index,
90 const Index& scat_p_index,
91 const Index& scat_lat_index,
92 const Index& scat_lon_index,
95 if (stokes_dim > 4 || stokes_dim < 1) {
97 "The dimension of the stokes vector \n"
98 "must be 1,2,3 or 4");
103 if (N_se_total != pnd_field.
nbooks()) {
105 os <<
"Total number of scattering elements in scat_data "
106 <<
"inconsistent with size of pnd_field.";
107 throw runtime_error(os.str());
121 if (scat_data[0][0].f_grid.
nelem() < 2) {
123 os <<
"Scattering data seems to be *scat_data_mono* (1 freq point only),\n"
124 <<
"but frequency interpolable data (*scat_data* with >=2 freq points) "
125 <<
"is expected here.";
126 throw runtime_error(os.str());
137 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
141 for (
Index i_se = 0; i_se < N_se; i_se++) {
145 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
171 }
else if (rtp_temperature < 0.)
174 if (rtp_temperature > -10.)
177 }
else if (rtp_temperature > -20.)
189 os <<
"In pha_mat_sptFromData.\n"
190 <<
"The temperature grid of the scattering data does not\n"
191 <<
"cover the atmospheric temperature at cloud location.\n"
192 <<
"The data should include the value T = " << rtp_temperature
213 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
239 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
252 for (
Index za_inc_idx = 0; za_inc_idx < za_grid.
nelem();
254 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
257 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker),
283 const Index& doit_za_grid_size,
285 const Index& za_index,
286 const Index& aa_index,
287 const Numeric& rtp_temperature,
289 const Index& scat_p_index,
290 const Index& scat_lat_index,
291 const Index& scat_lon_index,
295 if (N_se_total != pnd_field.
nbooks()) {
297 os <<
"Total number of scattering elements in scat_data_mono "
298 <<
"inconsistent with size of pnd_field.";
299 throw runtime_error(os.str());
307 if (pnd_field.
ncols() > 1) {
312 scat_data_mono[0][0].T_grid.
nelem());
313 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
315 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
320 else if (pnd_field.
ncols() == 1) {
328 scat_data_mono[0][0].T_grid.
nelem());
329 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
330 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nshelves() == 1);
331 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
346 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
348 os <<
"Scattering data seems to be *scat_data* (several freq points),\n"
349 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
350 throw runtime_error(os.str());
355 nlinspace(za_grid, 0, 180, doit_za_grid_size);
360 if (stokes_dim > 4 || stokes_dim < 1) {
362 "The dimension of the stokes vector \n"
363 "must be 1,2,3 or 4");
375 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
376 const Index N_se = scat_data_mono[i_ss].
nelem();
378 for (
Index i_se = 0; i_se < N_se; i_se++) {
382 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
385 Index nT = scat_data_mono[i_ss][i_se].pha_mat_data.nvitrines();
391 }
else if (rtp_temperature < 0.)
394 if (rtp_temperature > -10.)
397 }
else if (rtp_temperature > -20.)
406 os <<
"In pha_mat_sptFromDataDOITOpt.\n"
407 <<
"The temperature grid of the scattering data does not\n"
408 <<
"cover the atmospheric temperature at cloud location.\n"
409 <<
"The data should include the value T = " << rtp_temperature
412 os.str(), scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
415 gridpos(T_gp, scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
420 for (
Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
422 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
426 for (
Index i = 0; i < stokes_dim; i++) {
427 for (
Index j = 0; j < stokes_dim; j++) {
428 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, i, j) =
430 pha_mat_sptDOITOpt[i_se_flat](
joker,
441 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker) =
442 pha_mat_sptDOITOpt[i_se_flat](ti,
467 const Index& za_index,
468 const Index& aa_index,
469 const Index& f_index,
471 const Numeric& rtp_temperature,
473 const Index& scat_p_index,
474 const Index& scat_lat_index,
475 const Index& scat_lon_index,
478 const Numeric za_sca = za_grid[za_index];
479 const Numeric aa_sca = aa_grid[aa_index];
483 ARTS_ASSERT(ext_mat_spt[0].NumberOfFrequencies() == N_se_total);
484 ARTS_ASSERT(abs_vec_spt[0].NumberOfFrequencies() == N_se_total);
494 if (scat_data[0][0].f_grid.
nelem() < 2) {
496 os <<
"Scattering data seems to be *scat_data_mono* (1 freq point only),\n"
497 <<
"but frequency interpolable data (*scat_data* with >=2 freq points) "
498 <<
"is expected here.";
499 throw runtime_error(os.str());
513 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
517 for (
Index i_se = 0; i_se < N_se; i_se++) {
522 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
548 os <<
"In opt_prop_sptFromData.\n"
549 <<
"The temperature grid of the scattering data does not\n"
550 <<
"cover the atmospheric temperature at cloud location.\n"
551 <<
"The data should include the value T = " << rtp_temperature
569 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
586 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
607 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
623 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
669 const Index& scat_data_checked,
672 const Index& za_index,
673 const Index& aa_index,
674 const Index& f_index,
675 const Numeric& rtp_temperature,
677 const Index& scat_p_index,
678 const Index& scat_lat_index,
679 const Index& scat_lon_index,
681 if (scat_data_checked != 1)
683 "The scattering data must be flagged to have "
684 "passed a consistency check (scat_data_checked=1).");
687 const Index stokes_dim = ext_mat_spt[0].StokesDimensions();
688 const Numeric za_sca = za_grid[za_index];
689 const Numeric aa_sca = aa_grid[aa_index];
691 if (stokes_dim > 4 || stokes_dim < 1) {
693 "The dimension of the stokes vector \n"
694 "must be 1,2,3 or 4");
707 for (
auto& pm : ext_mat_spt) pm.SetZero();
708 for (
auto& sv : abs_vec_spt) sv.SetZero();
714 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
718 for (
Index i_se = 0; i_se < N_se; i_se++) {
723 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
740 os <<
"In opt_prop_sptFromScat_data.\n"
741 <<
"The temperature grid of the scattering data does not\n"
742 <<
"cover the atmospheric temperature at cloud location.\n"
743 <<
"The data should include the value T = " << rtp_temperature
759 this_f_index = f_index;
768 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
interp(
797 this_f_index = f_index;
806 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
interp(
867 const Index& scat_p_index,
868 const Index& scat_lat_index,
869 const Index& scat_lon_index,
873 if (ext_mat_spt.
nelem() not_eq N_se) {
875 os <<
"Number of scattering elements in *abs_vec_spt* and *ext_mat_spt*\n"
876 <<
"does not agree.";
877 throw runtime_error(os.str());
880 Index stokes_dim = abs_vec_spt[0].StokesDimensions();
882 if (ext_mat_spt[0].StokesDimensions() not_eq stokes_dim) {
884 os <<
"*stokes_dim* of *abs_vec_spt* and *ext_mat_spt* does not agree.";
885 throw runtime_error(os.str());
887 if (stokes_dim > 4 || stokes_dim < 1) {
889 os <<
"The dimension of stokes vector can only be 1, 2, 3, or 4.";
890 throw runtime_error(os.str());
904 for (
Index l = 0; l < N_se; l++) {
906 pnd_field(l, scat_p_index, scat_lat_index, scat_lon_index),
909 pnd_field(l, scat_p_index, scat_lat_index, scat_lon_index),
914 abs_vec += abs_vec_part;
916 ext_mat += ext_mat_part;
929 "Col dimension of propmat_clearsky "
930 "inconsistent with col dimension in ext_mat.");
938 "Frequency dimension of ext_mat and propmat_clearsky\n"
939 "are inconsistent in ext_matAddGas.");
941 ext_mat += propmat_clearsky;
955 "Frequency dimension of abs_vec and propmat_clearsky\n"
956 "are inconsistent in abs_vecAddGas.");
958 "Stokes dimension of abs_vec and propmat_clearsky\n"
959 "are inconsistent in abs_vecAddGas.");
963 abs_vec += propmat_clearsky;
1016 const Index& atmosphere_dim,
1017 const Index& scat_p_index,
1018 const Index& scat_lat_index,
1019 const Index& scat_lon_index,
1026 pha_mat.
resize(Nza, Naa, stokes_dim, stokes_dim);
1033 if (atmosphere_dim > 1) ilat = scat_lat_index;
1034 if (atmosphere_dim > 2) ilon = scat_lon_index;
1036 if (atmosphere_dim == 1) {
1044 for (
Index pt_index = 0; pt_index < N_se; ++pt_index)
1046 for (
Index za_index = 0; za_index < Nza; ++za_index)
1047 for (
Index aa_index = 0; aa_index < Naa - 1; ++aa_index)
1049 for (
Index stokes_index_1 = 0; stokes_index_1 < stokes_dim;
1051 for (
Index stokes_index_2 = 0; stokes_index_2 < stokes_dim;
1055 pha_mat(za_index, 0, stokes_index_1, stokes_index_2) +=
1056 ((pha_mat_spt(pt_index,
1061 pha_mat_spt(pt_index,
1066 2 * grid_step_size_azimuth *
1067 pnd_field(pt_index, scat_p_index, ilat, ilon));
1070 for (
Index pt_index = 0; pt_index < N_se; ++pt_index)
1072 for (
Index za_index = 0; za_index < Nza; ++za_index)
1073 for (
Index aa_index = 0; aa_index < Naa; ++aa_index)
1075 for (
Index stokes_index_1 = 0; stokes_index_1 < stokes_dim;
1077 for (
Index stokes_index_2 = 0; stokes_index_2 < stokes_dim;
1081 pha_mat(za_index, aa_index, stokes_index_1, stokes_index_2) +=
1082 (pha_mat_spt(pt_index,
1087 pnd_field(pt_index, scat_p_index, ilat, ilon));
1094 const String& check_type,
1114 out2 <<
" checking for negative values in Z11, K11, and a1, and for K11<a1\n";
1115 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1119 for (
Index i_se = 0; i_se < N_se; i_se++) {
1127 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1128 <<
" contains negative K11 or a1 at f#" << f <<
", T#" << t
1129 <<
", za#" << zai <<
", aa#" << aai <<
"\n";
1130 throw runtime_error(os.str());
1135 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1136 <<
" has K11<a1 at f#" << f <<
", T#" << t <<
", za#" << zai
1137 <<
", aa#" << aai <<
"\n";
1138 throw runtime_error(os.str());
1145 for (
Index t = 0; t < nTpha; t++) {
1150 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1151 <<
" contains negative Z11 at f#" << f <<
", T#" << t
1152 <<
" (of " << nTpha <<
"), za_sca#" << zas <<
", aa_sca#"
1153 << aas <<
", za_inc#" << zai <<
", aa_inc#" << aai
1155 throw runtime_error(os.str());
1164 out2 <<
" checking for NaN anywhere in Z, K, and a\n";
1165 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1169 for (
Index i_se = 0; i_se < N_se; i_se++) {
1177 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1178 <<
" contains NaN in abs_vec at f#" << f <<
", T#" << t
1179 <<
", za#" << zai <<
", aa#" << aai <<
", stokes #" << st
1181 throw runtime_error(os.str());
1186 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1187 <<
" contains NaN in ext_mat at f#" << f <<
", T#" << t
1188 <<
", za#" << zai <<
", aa#" << aai <<
", stokes #" << st
1190 throw runtime_error(os.str());
1194 for (
Index t = 0; t < nTpha; t++) {
1201 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1202 <<
" contains NaN in pha_mat at f#" << f <<
", T#" << t
1203 <<
" (of " << nTpha <<
"), za_sca#" << zas
1204 <<
", aa_sca#" << aas <<
", za_inc#" << zai
1205 <<
", aa_inc#" << aai <<
", stokes #"
1207 throw runtime_error(os.str());
1215 if (check_type.
toupper() ==
"ALL") {
1217 out2 <<
" checking normalization of scattering matrix\n";
1218 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1222 for (
Index i_se = 0; i_se < N_se; i_se++)
1232 Numeric Csca_data = Cext_data - Cabs_data;
1250 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
1252 os <<
" Deviations in scat_data too large:\n"
1253 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1254 <<
" at nominal (actual) albedo of "
1255 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
1257 <<
" Check entry for scattering element " << i_se
1258 <<
" of scattering species " << i_ss <<
" at " << f
1259 <<
".frequency and " << t <<
".temperature!\n";
1260 throw runtime_error(os.str());
1279 Numeric Csca_data = Cext_data - Cabs_data;
1297 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
1299 os <<
" Deviations in scat_data too large:\n"
1300 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1301 <<
" at nominal (actual) albedo of "
1302 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
1304 <<
" Check entry for scattering element " << i_se
1305 <<
" of scattering species " << i_ss <<
" at " << f
1306 <<
". frequency, " << t <<
". temperature, and " << iza
1307 <<
". incident polar angle!\n";
1308 throw runtime_error(os.str());
1319 <<
" scat_data consistency check not implemented (yet?!) for\n"
1324 out2 <<
" WARNING:\n"
1325 <<
" scat_data norm check can not be performed for pha_mat-only"
1326 <<
" T-reduced scattering elements\n"
1327 <<
" as found in scatt element #" << i_se
1328 <<
" of scatt species #" << i_ss <<
"!\n";
1330 }
else if (check_type.
toupper() ==
"SANE") {
1331 out1 <<
" WARNING:\n"
1332 <<
" Normalization check on pha_mat switched off.\n"
1333 <<
" Scattering solution might be wrong.\n";
1336 os <<
"Invalid value for argument *check_type*: '" << check_type <<
"'.\n";
1337 os <<
"Valid values are 'all' or 'none'.";
1338 throw runtime_error(os.str());
1351 const Index& doit_za_grid_size,
1353 const Index& scat_data_checked,
1354 const Index& f_index,
1355 const Index& atmosphere_dim,
1356 const Index& stokes_dim,
1360 const Agenda& pha_mat_spt_agenda,
1362 if (scat_data_checked != 1)
1363 throw runtime_error(
1364 "The scattering data must be flagged to have "
1365 "passed a consistency check (scat_data_checked=1).");
1370 grid_stepsize[0] = 180. / (
Numeric)(doit_za_grid_size - 1);
1380 Tensor4 pha_mat_local(doit_za_grid_size, Naa, stokes_dim, stokes_dim, 0.);
1381 Tensor6 pha_mat_local_out(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1394 if (atmosphere_dim == 1)
1397 N_aa_sca = aa_grid.
nelem();
1400 nlinspace(za_grid, 0, 180, doit_za_grid_size);
1409 Index i_se_flat = 0;
1410 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
1413 for (
Index i_se = 0; i_se < N_se; i_se++) {
1414 Index N_T = scat_data_mono[i_ss][i_se].T_grid.
nelem();
1415 pha_mat_sptDOITOpt[i_se_flat].resize(N_T,
1424 pha_mat_sptDOITOpt[i_se_flat] = 0.;
1428 for (
Index t_idx = 0; t_idx < N_T; t_idx++) {
1430 for (
Index za_sca_idx = 0; za_sca_idx < doit_za_grid_size;
1432 for (
Index aa_sca_idx = 0; aa_sca_idx < N_aa_sca; aa_sca_idx++) {
1434 for (
Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
1436 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
1439 pha_mat_sptDOITOpt[i_se_flat](t_idx,
1446 scat_data_mono[i_ss][i_se].pha_mat_data(
1448 scat_data_mono[i_ss][i_se].za_grid,
1449 scat_data_mono[i_ss][i_se].aa_grid,
1450 scat_data_mono[i_ss][i_se].ptype,
1468 pha_mat_doit.
resize(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1477 if (atmosphere_dim == 1) {
1478 Index aa_index_local = 0;
1482 for (
Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
1484 Numeric rtp_temperature_local =
1485 t_field(p_index + cloudbox_limits[0], 0, 0);
1487 for (
Index za_index_local = 0;
1488 za_index_local < doit_za_grid_size;
1491 Index index_zero = 0;
1501 rtp_temperature_local,
1502 pha_mat_spt_agenda);
1530 const Index& interp_order,
1543 const String which_interpolation =
"scat_data_raw.f_grid to f_grid";
1544 for (
Index i_ss = 0; i_ss < scat_data_raw.
nelem(); i_ss++) {
1545 for (
Index i_se = 0; i_se < scat_data_raw[i_ss].
nelem(); i_se++) {
1548 if (scat_data_raw[i_ss][i_se].f_grid.
nelem() == 1 && nf == 1)
1553 os <<
"There is a problem with the grids for the following "
1554 <<
"interpolation:\n"
1555 << which_interpolation <<
"\n"
1556 <<
"If original grid has only 1 element, the new grid must also have\n"
1557 <<
"only a single element and hold the same value as the original grid.";
1558 throw runtime_error(os.str());
1563 scat_data_raw[i_ss][i_se].f_grid,
1570 scat_data.resize(scat_data_raw.
nelem());
1573 for (
Index i_ss = 0; i_ss < scat_data_raw.
nelem(); i_ss++) {
1574 const Index N_se = scat_data_raw[i_ss].
nelem();
1577 scat_data[i_ss].resize(N_se);
1580 for (
Index i_se = 0; i_se < N_se; i_se++) {
1582 PART_TYPE = scat_data_raw[i_ss][i_se].ptype;
1584 T_DATAGRID = scat_data_raw[i_ss][i_se].T_grid;
1590 scat_data_raw[i_ss][i_se].pha_mat_data.nvitrines(),
1591 scat_data_raw[i_ss][i_se].pha_mat_data.nshelves(),
1592 scat_data_raw[i_ss][i_se].pha_mat_data.nbooks(),
1593 scat_data_raw[i_ss][i_se].pha_mat_data.npages(),
1594 scat_data_raw[i_ss][i_se].pha_mat_data.nrows(),
1595 scat_data_raw[i_ss][i_se].pha_mat_data.ncols());
1597 scat_data_raw[i_ss][i_se].ext_mat_data.nbooks(),
1598 scat_data_raw[i_ss][i_se].ext_mat_data.npages(),
1599 scat_data_raw[i_ss][i_se].ext_mat_data.nrows(),
1600 scat_data_raw[i_ss][i_se].ext_mat_data.ncols());
1602 scat_data_raw[i_ss][i_se].abs_vec_data.nbooks(),
1603 scat_data_raw[i_ss][i_se].abs_vec_data.npages(),
1604 scat_data_raw[i_ss][i_se].abs_vec_data.nrows(),
1605 scat_data_raw[i_ss][i_se].abs_vec_data.ncols());
1607 const bool single_se_fgrid =
1608 (scat_data_raw[i_ss][i_se].f_grid.
nelem() == 1);
1609 if (!single_se_fgrid) {
1615 for (
Index t_index = 0;
1616 t_index < scat_data_raw[i_ss][i_se].pha_mat_data.nvitrines();
1618 for (
Index i_za_sca = 0;
1619 i_za_sca < scat_data_raw[i_ss][i_se].pha_mat_data.nshelves();
1621 for (
Index i_aa_sca = 0;
1622 i_aa_sca < scat_data_raw[i_ss][i_se].pha_mat_data.nbooks();
1624 for (
Index i_za_inc = 0;
1625 i_za_inc < scat_data_raw[i_ss][i_se].pha_mat_data.npages();
1627 for (
Index i_aa_inc = 0;
1628 i_aa_inc < scat_data_raw[i_ss][i_se].pha_mat_data.nrows();
1631 i < scat_data_raw[i_ss][i_se].pha_mat_data.ncols();
1633 reinterp(scat_data[i_ss][i_se].pha_mat_data(
joker,
1640 scat_data_raw[i_ss][i_se].pha_mat_data(
joker,
1657 for (
Index t_index = 0;
1658 t_index < scat_data_raw[i_ss][i_se].ext_mat_data.nbooks();
1660 for (
Index i_za_sca = 0;
1661 i_za_sca < scat_data_raw[i_ss][i_se].ext_mat_data.npages();
1663 for (
Index i_aa_sca = 0;
1664 i_aa_sca < scat_data_raw[i_ss][i_se].ext_mat_data.nrows();
1667 i < scat_data_raw[i_ss][i_se].ext_mat_data.ncols();
1669 reinterp(scat_data[i_ss][i_se].ext_mat_data(
1670 joker, t_index, i_za_sca, i_aa_sca, i),
1671 scat_data_raw[i_ss][i_se].ext_mat_data(
1672 joker, t_index, i_za_sca, i_aa_sca, i),
1681 for (
Index t_index = 0;
1682 t_index < scat_data_raw[i_ss][i_se].abs_vec_data.nbooks();
1684 for (
Index i_za_sca = 0;
1685 i_za_sca < scat_data_raw[i_ss][i_se].abs_vec_data.npages();
1687 for (
Index i_aa_sca = 0;
1688 i_aa_sca < scat_data_raw[i_ss][i_se].abs_vec_data.nrows();
1691 i < scat_data_raw[i_ss][i_se].abs_vec_data.ncols();
1693 reinterp(scat_data[i_ss][i_se].abs_vec_data(
1694 joker, t_index, i_za_sca, i_aa_sca, i),
1695 scat_data_raw[i_ss][i_se].abs_vec_data(
1696 joker, t_index, i_za_sca, i_aa_sca, i),
1708 scat_data[i_ss][i_se].pha_mat_data =
1709 scat_data_raw[i_ss][i_se].pha_mat_data;
1710 scat_data[i_ss][i_se].ext_mat_data =
1711 scat_data_raw[i_ss][i_se].ext_mat_data;
1712 scat_data[i_ss][i_se].abs_vec_data =
1713 scat_data_raw[i_ss][i_se].abs_vec_data;
1723 const Index& interp_order,
1724 const Index& phamat_only,
1736 os <<
"Can not T-reduce scattering species #" << i_ss <<
".\n"
1737 <<
"*scat_data* contains only " << nss <<
" scattering species.";
1738 throw runtime_error(os.str());
1742 for (
Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
1748 <<
" can be handled.\n"
1749 <<
"Scattering element #" << i_se <<
" has ptype " <<
PART_TYPE <<
".";
1750 throw runtime_error(os.str());
1763 os <<
"Single scattering data of scat element #" << i_se
1764 <<
" of scat species #" << i_ss <<
"\n"
1765 <<
"seems to have undergone some temperature grid manipulation in\n"
1766 <<
"*pha_mat_data* already. That can not be done twice!";
1767 throw runtime_error(os.str());
1777 ost <<
"Scattering data temperature interpolation for\n"
1778 <<
"scat element #" << i_se <<
" of scat species #" << i_ss <<
".";
1818 phamat_tmp(i_f, 0, i_za1, i_aa1, i_za2, i_aa2, i_st) =
1820 i_f,
joker, i_za1, i_aa1, i_za2, i_aa2, i_st),
1831 extmat_tmp(i_f, 0, i_za, i_aa, i_st) =
1834 absvec_tmp(i_f, 0, i_za, i_aa, i_st) =
1886 this_threshold = threshold;
1888 "T-reduced *pha_mat_data* norm (=sca xs) deviates too "
1889 "much from non-reduced *ext_mat_data* and *abs_vec_data*:";
1891 this_threshold = 2 * threshold;
1893 "T-reduced *scat_data* deviates too much from original "
1909 Numeric Cext_data = extmat_tmp(f, 0, 0, 0, 0);
1911 Numeric Cabs_data = absvec_tmp(f, 0, 0, 0, 0);
1912 Numeric Csca_data = Cext_data - Cabs_data;
1929 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
1931 os <<
" Deviations in T-reduced scat_data too large:\n"
1932 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1933 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
1934 <<
" (" << Csca / Cext_data <<
").\n"
1935 <<
" Problem occurs for scattering element #" << i_se
1936 <<
" at " << f <<
".frequency!\n";
1937 throw runtime_error(os.str());
1939 Numeric norm_dev = (Csca - Csca) / Cext_data;
1947 Numeric xs_dev = (Csca - Csca_data) / Cext_data;
1948 if (
abs(norm_dev + (Csca - Csca_data) / Cext_data) >
1950 cout <<
"Accumulated deviation (abs(" << norm_dev <<
"+"
1951 << xs_dev <<
")=" <<
abs(norm_dev + xs_dev)
1952 <<
" exceeding threshold (" << this_threshold <<
").\n";
1953 if (
abs(Csca - Csca_data) / Cext_data > this_threshold) {
1955 os <<
" " << errmsg <<
"\n"
1956 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1957 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
1958 <<
" (" << Csca / Cext_data <<
").\n"
1959 <<
" Problem occurs for scattering element #" << i_se
1960 <<
" at " << f <<
".frequency and " << t
1961 <<
".temperature!\n";
1962 throw runtime_error(os.str());
1977 Numeric Cext_data = extmat_tmp(f, 0, iza, 0, 0);
1979 Numeric Cabs_data = absvec_tmp(f, 0, iza, 0, 0);
1980 Numeric Csca_data = Cext_data - Cabs_data;
1997 if (
abs(Csca - Csca_data) / Cext_data > threshold) {
1999 os <<
" Deviations in T-reduced scat_data too large:\n"
2000 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
2001 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
2002 <<
" (" << Csca / Cext_data <<
").\n"
2003 <<
" Problem occurs for scattering element #" << i_se
2004 <<
" at " << f <<
".frequency, and " << iza
2005 <<
". incident polar angle!\n";
2006 throw runtime_error(os.str());
2015 if (
abs(Csca - Csca_data) / Cext_data > this_threshold) {
2017 os <<
" " << errmsg <<
"\n"
2018 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
2019 <<
" at nominal (actual) albedo of "
2020 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
2022 <<
" Problem occurs for scattering element #" << i_se
2023 <<
" at " << f <<
".frequency and " << t
2024 <<
".temperature, and " << iza
2025 <<
". incident polar angle!\n";
2026 throw runtime_error(os.str());
2058 const Index& f_index,
2066 for (
Index h = 0; h < scat_data.
nelem(); h++) {
2067 for (
Index i = 0; i < scat_data[h].
nelem(); i++) {
2070 scat_data[h][i].f_grid,
2076 scat_data_mono.resize(scat_data.
nelem());
2079 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2083 scat_data_mono[i_ss].resize(N_se);
2086 for (
Index i_se = 0; i_se < N_se; i_se++) {
2096 scat_data_mono[i_ss][i_se].ptype =
PART_TYPE;
2097 scat_data_mono[i_ss][i_se].f_grid.resize(1);
2098 scat_data_mono[i_ss][i_se].f_grid = f_grid[f_index];
2099 scat_data_mono[i_ss][i_se].T_grid = scat_data[i_ss][i_se].T_grid;
2104 scat_data_mono[i_ss][i_se].pha_mat_data.resize(1,
2122 scat_data_mono[i_ss][i_se].pha_mat_data(
2123 0, t_index, i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
2139 scat_data_mono[i_ss][i_se].ext_mat_data.resize(1,
2151 scat_data_mono[i_ss][i_se].ext_mat_data(
2152 0, t_index, i_za_sca, i_aa_sca, i) =
2160 scat_data_mono[i_ss][i_se].abs_vec_data.resize(1,
2172 scat_data_mono[i_ss][i_se].abs_vec_data(
2173 0, t_index, i_za_sca, i_aa_sca, i) =
2188 const Index& f_index,
2191 scat_data_mono.resize(scat_data.
nelem());
2194 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2198 scat_data_mono[i_ss].resize(N_se);
2201 for (
Index i_se = 0; i_se < N_se; i_se++) {
2204 scat_data_mono[i_ss][i_se] = scat_data[i_ss][i_se];
2207 scat_data_mono[i_ss][i_se].ptype =
PART_TYPE;
2208 scat_data_mono[i_ss][i_se].T_grid =
T_DATAGRID;
2212 scat_data_mono[i_ss][i_se].f_grid.resize(1);
2213 scat_data_mono[i_ss][i_se].f_grid =
F_DATAGRID[f_index];
2225 this_f_index = (
PHA_MAT_DATA.nlibraries() == 1) ? 0 : f_index;
2226 scat_data_mono[i_ss][i_se].pha_mat_data =
PHA_MAT_DATA(
2234 this_f_index = (
EXT_MAT_DATA.nshelves() == 1) ? 0 : f_index;
2235 scat_data_mono[i_ss][i_se].ext_mat_data =
2243 this_f_index = (
ABS_VEC_DATA.nshelves() == 1) ? 0 : f_index;
2244 scat_data_mono[i_ss][i_se].abs_vec_data =
2259 const Index& za_index,
2260 const Index& aa_index,
2261 const Numeric& rtp_temperature,
2263 const Index& scat_p_index,
2264 const Index& scat_lat_index,
2265 const Index& scat_lon_index,
2268 const Index stokes_dim = ext_mat_spt[0].StokesDimensions();
2269 const Numeric za_sca = za_grid[za_index];
2270 const Numeric aa_sca = aa_grid[aa_index];
2272 if (stokes_dim > 4 or stokes_dim < 1) {
2273 throw runtime_error(
2274 "The dimension of the stokes vector \n"
2275 "must be 1,2,3 or 4");
2290 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
2292 os <<
"Scattering data seems to be *scat_data* (several freq points),\n"
2293 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
2294 throw runtime_error(os.str());
2298 for (
auto& pm : ext_mat_spt) pm.SetZero();
2299 for (
auto& av : abs_vec_spt) av.SetZero();
2305 Index i_se_flat = 0;
2307 for (
Index i_ss = 0; i_ss < scat_data_mono.
nelem(); i_ss++) {
2309 for (
Index i_se = 0; i_se < scat_data_mono[i_ss].
nelem(); i_se++) {
2313 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
2324 Index ext_npages = scat_data_mono[i_ss][i_se].ext_mat_data.npages();
2325 Index ext_nrows = scat_data_mono[i_ss][i_se].ext_mat_data.nrows();
2326 Index ext_ncols = scat_data_mono[i_ss][i_se].ext_mat_data.ncols();
2327 Index abs_npages = scat_data_mono[i_ss][i_se].abs_vec_data.npages();
2328 Index abs_nrows = scat_data_mono[i_ss][i_se].abs_vec_data.nrows();
2329 Index abs_ncols = scat_data_mono[i_ss][i_se].abs_vec_data.ncols();
2334 if (t_grid.
nelem() > 1) {
2336 os <<
"In opt_prop_sptFromMonoData.\n"
2337 <<
"The temperature grid of the scattering data does not\n"
2338 <<
"cover the atmospheric temperature at cloud location.\n"
2339 <<
"The data should include the value T = " << rtp_temperature
2344 Tensor3 ext_mat_data1temp(ext_npages, ext_nrows, ext_ncols);
2345 gridpos(t_gp, t_grid, rtp_temperature);
2347 for (
Index i_p = 0; i_p < ext_npages; i_p++) {
2348 for (
Index i_r = 0; i_r < ext_nrows; i_r++) {
2349 for (
Index i_c = 0; i_c < ext_ncols; i_c++) {
2350 ext_mat_data1temp(i_p, i_r, i_c) =
2352 scat_data_mono[i_ss][i_se].ext_mat_data(
2353 0,
joker, i_p, i_r, i_c),
2360 scat_data_mono[i_ss][i_se].za_grid,
2361 scat_data_mono[i_ss][i_se].aa_grid,
2362 scat_data_mono[i_ss][i_se].ptype,
2368 scat_data_mono[i_ss][i_se].ext_mat_data(
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,
2381 if (t_grid.
nelem() > 1) {
2382 Tensor3 abs_vec_data1temp(abs_npages, abs_nrows, abs_ncols);
2384 for (
Index i_p = 0; i_p < abs_npages; i_p++) {
2385 for (
Index i_r = 0; i_r < abs_nrows; i_r++) {
2386 for (
Index i_c = 0; i_c < abs_ncols; i_c++) {
2387 abs_vec_data1temp(i_p, i_r, i_c) =
2389 scat_data_mono[i_ss][i_se].abs_vec_data(
2390 0,
joker, i_p, i_r, i_c),
2397 scat_data_mono[i_ss][i_se].za_grid,
2398 scat_data_mono[i_ss][i_se].aa_grid,
2399 scat_data_mono[i_ss][i_se].ptype,
2405 scat_data_mono[i_ss][i_se].abs_vec_data(
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,
2426 const Index& doit_za_grid_size,
2428 const Index& za_index,
2429 const Index& aa_index,
2430 const Numeric& rtp_temperature,
2432 const Index& scat_p_index,
2433 const Index& scat_lat_index,
2434 const Index& scat_lon_index,
2437 nlinspace(za_grid, 0, 180, doit_za_grid_size);
2440 if (N_se_total != pnd_field.
nbooks()) {
2442 os <<
"Total number of scattering elements in *scat_data_mono* "
2443 <<
"inconsistent with size of pnd_field.";
2444 throw runtime_error(os.str());
2451 const Index stokes_dim = pha_mat_spt.
ncols();
2452 if (stokes_dim > 4 || stokes_dim < 1) {
2453 throw runtime_error(
2454 "The dimension of the stokes vector \n"
2455 "must be 1,2,3 or 4");
2467 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
2469 os <<
"Scattering data seems to be *scat_data* (several freq points),\n"
2470 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
2471 throw runtime_error(os.str());
2474 GridPos T_gp = {0, {0, 1}}, Tred_gp;
2480 Index i_se_flat = 0;
2481 for (
Index i_ss = 0; i_ss < scat_data_mono.
nelem(); i_ss++) {
2482 for (
Index i_se = 0; i_se < scat_data_mono[i_ss].
nelem(); i_se++) {
2486 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
2489 Index nT = scat_data_mono[i_ss][i_se].pha_mat_data.nvitrines();
2492 pha_mat_spt_tmp = 0.;
2498 }
else if (rtp_temperature < 0.)
2501 if (rtp_temperature > -10.)
2504 }
else if (rtp_temperature > -20.)
2513 os <<
"In pha_mat_sptFromMonoData.\n"
2514 <<
"The temperature grid of the scattering data does not\n"
2515 <<
"cover the atmospheric temperature at cloud location.\n"
2516 <<
"The data should include the value T = " << rtp_temperature
2519 os.str(), scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
2522 gridpos(T_gp, scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
2530 for (
Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
2532 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
2536 for (
Index t_idx = 0; t_idx < 2; t_idx++) {
2539 scat_data_mono[i_ss][i_se].pha_mat_data(
2541 scat_data_mono[i_ss][i_se].za_grid,
2542 scat_data_mono[i_ss][i_se].aa_grid,
2543 scat_data_mono[i_ss][i_se].ptype,
2553 for (
Index i = 0; i < stokes_dim; i++) {
2554 for (
Index j = 0; j < stokes_dim; j++) {
2555 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, i, j) =
2556 interp(itw, pha_mat_spt_tmp(
joker, i, j), Tred_gp);
2562 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker),
2563 scat_data_mono[i_ss][i_se].pha_mat_data(
2565 scat_data_mono[i_ss][i_se].za_grid,
2566 scat_data_mono[i_ss][i_se].aa_grid,
2567 scat_data_mono[i_ss][i_se].ptype,
2590 const Index& scat_data_checked,
2593 const Index& za_index,
2594 const Index& aa_index,
2595 const Index& f_index,
2596 const Numeric& rtp_temperature,
2598 const Index& scat_p_index,
2599 const Index& scat_lat_index,
2600 const Index& scat_lon_index,
2602 if (scat_data_checked != 1)
2603 throw runtime_error(
2604 "The scattering data must be flagged to have "
2605 "passed a consistency check (scat_data_checked=1).");
2607 const Index stokes_dim = pha_mat_spt.
ncols();
2608 if (stokes_dim > 4 || stokes_dim < 1) {
2609 throw runtime_error(
2610 "The dimension of the stokes vector \n"
2611 "must be 1,2,3 or 4");
2616 if (N_se_total != pnd_field.
nbooks()) {
2618 os <<
"Total number of scattering elements in scat_data "
2619 <<
"inconsistent with size of pnd_field.";
2620 throw runtime_error(os.str());
2635 Index i_se_flat = 0;
2637 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
2641 for (
Index i_se = 0; i_se < N_se; i_se++) {
2646 i_se_flat, scat_p_index, scat_lat_index, scat_lon_index)) >
2664 Index this_T_index = -1;
2667 }
else if (rtp_temperature < 0.)
2670 if (rtp_temperature > -10.)
2673 }
else if (rtp_temperature > -20.)
2682 os <<
"In pha_mat_sptFromScat_data.\n"
2683 <<
"The temperature grid of the scattering data does not\n"
2684 <<
"cover the atmospheric temperature at cloud location.\n"
2685 <<
"The data should include the value T = " << rtp_temperature
2699 this_f_index = f_index;
2701 if (this_T_index < 0) {
2713 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
2745 for (
Index za_inc_idx = 0; za_inc_idx < za_grid.
nelem();
2747 for (
Index aa_inc_idx = 0; aa_inc_idx < aa_grid.
nelem();
2750 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx,
joker,
joker),
2776 Index& cloudbox_checked,
2778 const Index& atmosphere_dim,
2779 const Index& cloudbox_on,
2791 if (!cloudbox_checked)
2792 throw std::runtime_error(
2793 "You must call *cloudbox_checkedCalc* before this method.");
2796 cloudbox_checked = 0;
2798 if (atmosphere_dim != 1)
2799 throw std::runtime_error(
2800 "Merging scattering elements only works with a 1D atmoshere");
2805 pnd_field.
resize(0, 0, 0, 0);
2812 limits[0] = cloudbox_limits[0];
2813 limits[1] = cloudbox_limits[1] + 1;
2816 limits[1] - limits[0], limits[1] - limits[0], 1, 1, 0.);
2819 scat_data_merged.resize(1);
2820 scat_data_merged[0].resize(pnd_field_merged.
nbooks());
2822 scat_meta_merged.resize(1);
2823 scat_meta_merged[0].resize(pnd_field_merged.
nbooks());
2825 scat_species_merged.resize(1);
2826 scat_species_merged[0] =
"mergedfield-mergedpsd";
2827 for (
Index sp = 0; sp < scat_data_merged[0].
nelem(); sp++) {
2829 this_part.
ptype = scat_data[0][0].ptype;
2830 this_part.
description =
"Merged scattering elements";
2831 this_part.
f_grid = scat_data[0][0].f_grid;
2832 this_part.
za_grid = scat_data[0][0].za_grid;
2833 this_part.
aa_grid = scat_data[0][0].aa_grid;
2836 scat_data[0][0].pha_mat_data.nshelves(),
2837 scat_data[0][0].pha_mat_data.nbooks(),
2838 scat_data[0][0].pha_mat_data.npages(),
2839 scat_data[0][0].pha_mat_data.nrows(),
2840 scat_data[0][0].pha_mat_data.ncols());
2843 scat_data[0][0].ext_mat_data.npages(),
2844 scat_data[0][0].ext_mat_data.nrows(),
2845 scat_data[0][0].ext_mat_data.ncols());
2848 scat_data[0][0].abs_vec_data.npages(),
2849 scat_data[0][0].abs_vec_data.nrows(),
2850 scat_data[0][0].abs_vec_data.ncols());
2855 this_part.
T_grid[0] = t_field(sp, 0, 0);
2859 os <<
"Merged scattering element of cloudbox-level #" << sp;
2861 this_meta.
source =
"ARTS internal";
2863 this_meta.
mass = -1.;
2871 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2872 for (
Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
2876 throw std::runtime_error(
2877 "All scattering elements must have the same type");
2880 throw std::runtime_error(
2881 "All scattering elements must have the same f_grid");
2891 throw std::runtime_error(
2892 "All scattering elements must have the same pha_mat_data size"
2893 " (except for temperature).");
2900 throw std::runtime_error(
2901 "All scattering elements must have the same ext_mat_data size"
2902 " (except for temperature).");
2909 throw std::runtime_error(
2910 "All scattering elements must have the same abs_vec_data size"
2911 " (except for temperature).");
2922 for (
Index i_lv = 0; i_lv < nlevels - 1; i_lv++) {
2923 pnd_field_merged(i_lv, i_lv, 0, 0) = 1.;
2926 for (
Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2927 for (
Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
2934 if (pnd_field(pnd_index, i_lv, 0, 0) >
PND_LIMIT)
2939 os <<
"The temperature grid of the scattering data "
2940 <<
"does not cover the\n"
2941 <<
"atmospheric temperature at cloud location. "
2942 <<
"The data should\n"
2943 <<
"include the value T = " << temperature <<
" K.\n"
2944 <<
"Offending particle is scat_data[" << i_ss <<
"][" << i_se
2946 <<
"Description: " << orig_part.
description <<
"\n";
2969 v *= pnd_field(pnd_index, i_lv, 0, 0);
2973 v *= pnd_field(pnd_index, i_lv, 0, 0);
2979 pnd_field(pnd_index, i_lv, 0, 0) *
2988 pnd_field(pnd_index, i_lv, 0, 0) *
3001 for (
Index i_za_out = 0;
3005 for (
Index i_aa_out = 0;
3009 for (
Index i_za_inc = 0;
3013 for (
Index i_aa_inc = 0;
3025 v *= pnd_field(pnd_index, i_lv, 0, 0);
3044 pnd_field(pnd_index, i_lv, 0, 0) *
3070 if (z_field(cloudbox_limits[0], 0, 0) > z_surface(0, 0))
3071 pnd_field_merged(0, 0, 0, 0) = 0.;
3073 pnd_field = pnd_field_merged;
3074 scat_data = scat_data_merged;
3075 scat_meta = scat_meta_merged;
3076 scat_species = scat_species_merged;
3086 const Index& scat_species_index,
3088 if (scat_species_index < 0) {
3090 os <<
"scat_species_index can't be <0!";
3091 throw runtime_error(os.str());
3097 if (!(nss > scat_species_index)) {
3099 os <<
"Can not extract data for scattering species #" << scat_species_index
3101 <<
"because scat_meta has only " << nss <<
" elements.";
3102 throw runtime_error(os.str());
3105 const Index nse = scat_meta[scat_species_index].
nelem();
3108 for (
Index i = 0; i < nse; i++) {
3109 if (meta_name ==
"mass")
3110 meta_param[i] = scat_meta[scat_species_index][i].mass;
3111 else if (meta_name ==
"diameter_max")
3112 meta_param[i] = scat_meta[scat_species_index][i].diameter_max;
3113 else if (meta_name ==
"diameter_volume_equ")
3114 meta_param[i] = scat_meta[scat_species_index][i].diameter_volume_equ;
3115 else if (meta_name ==
"diameter_area_equ_aerodynamical")
3117 scat_meta[scat_species_index][i].diameter_area_equ_aerodynamical;
3120 os <<
"Meta parameter \"" << meta_name <<
"\"is unknown.";
3121 throw runtime_error(os.str());
This file contains the definition of Array.
Index TotalNumberOfElements(const Array< Array< base > > &aa)
Determine total number of elements in an ArrayOfArray.
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.
The global header file for ARTS.
Constants of physical expressions as constexpr.
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)
This can be used to make arrays out of anything.
Index nelem() const ARTS_NOEXCEPT
Index ncols() const noexcept
Index nbooks() const noexcept
Index nrows() const noexcept
Index ncols() const noexcept
Index npages() const noexcept
Index nbooks() const noexcept
Index nshelves() const noexcept
Index ncols() const noexcept
Index npages() const noexcept
Index nrows() const noexcept
Index nlibraries() const noexcept
Index nshelves() const noexcept
Index nbooks() const noexcept
A constant view of a Vector.
Index nelem() const noexcept
Returns the number of elements.
Index NumberOfFrequencies() const
The number of frequencies of the propagation matrix.
void MultiplyAndAdd(const Numeric x, const PropagationMatrix &y)
Multiply input by scalar and add to this.
void SetZero()
Sets all data to zero.
Index StokesDimensions() const
The stokes dimension of the propagation matrix.
Stokes vector is as Propagation matrix but only has 4 possible values.
void MultiplyAndAdd(const Numeric x, const PropagationMatrix &y)
Add a scaled version of the input.
void resize(Index p, Index r, Index c)
Resize function.
void resize(Index b, Index p, Index r, Index c)
Resize function.
void resize(Index s, Index b, Index p, Index r, Index c)
Resize function.
void resize(Index l, Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
void resize(Index n)
Resize function.
void toupper()
Convert to upper case.
#define ARTS_ASSERT(condition,...)
#define ARTS_USER_ERROR_IF(condition,...)
The declarations of all the exception classes.
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.
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
void gridpos_copy(GridPos &gp_new, const GridPos &gp_old)
gridpos_copy
Header file for interpolation.cc.
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
bool is_same_within_epsilon(const Numeric &a, const Numeric &b, const Numeric &epsilon)
Check, if two numbers agree within a given epsilon.
Header file for logic.cc.
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 abs_vecAddGas(StokesVector &abs_vec, const PropagationMatrix &propmat_clearsky, const Verbosity &)
WORKSPACE METHOD: abs_vecAddGas.
void ext_matAddGas(PropagationMatrix &ext_mat, const PropagationMatrix &propmat_clearsky, const Verbosity &)
WORKSPACE METHOD: ext_matAddGas.
void scat_data_monoExtract(ArrayOfArrayOfSingleScatteringData &scat_data_mono, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &f_index, const Verbosity &)
WORKSPACE METHOD: scat_data_monoExtract.
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 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_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.
constexpr Numeric DEG2RAD
void ExtractFromMetaSingleScatSpecies(Vector &meta_param, const ArrayOfArrayOfScatteringMetaData &scat_meta, const String &meta_name, const Index &scat_species_index, const Verbosity &)
WORKSPACE METHOD: ExtractFromMetaSingleScatSpecies.
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_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.
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 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.
constexpr Numeric RAD2DEG
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.
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 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.
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 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 scat_dataCheck(const ArrayOfArrayOfSingleScatteringData &scat_data, const String &check_type, const Numeric &threshold, const Verbosity &verbosity)
WORKSPACE METHOD: scat_dataCheck.
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 nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
Numeric AngIntegrate_trapezoid(ConstMatrixView Integrand, ConstVectorView za_grid, ConstVectorView aa_grid)
AngIntegrate_trapezoid.
void abs(Sparse &A, const Sparse &B)
Absolute value of sparse matrix elements.
NUMERIC Numeric
The type to use for all floating point numbers.
INDEX Index
The type to use for all integer numbers and indices.
Declarations having to do with the four output streams.
constexpr Numeric pi
The following mathematical constants are generated in python Decimal package by the code:
constexpr auto deg2rad(auto x) noexcept
Converts degrees to radians.
constexpr auto rad2deg(auto x) noexcept
Converts radians to degrees.
Array< Lagrange > LagrangeVector(const ConstVectorView &xs, const ConstVectorView &xi, const Index polyorder, const Numeric extrapol, const bool do_derivs, const GridType type, const std::pair< Numeric, Numeric > cycle)
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.
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 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.
Scattering database structure and functions.
Contains sorting routines.
Structure to store a grid position.
A Lagrange interpolation computer.
This file contains basic functions to handle XML data files.