32#include "matpack_data.h"
43#define PART_TYPE scat_data[i_ss][i_se].ptype
44#define F_DATAGRID scat_data[i_ss][i_se].f_grid
45#define T_DATAGRID scat_data[i_ss][i_se].T_grid
46#define ZA_DATAGRID scat_data[i_ss][i_se].za_grid
47#define AA_DATAGRID scat_data[i_ss][i_se].aa_grid
48#define PHA_MAT_DATA scat_data[i_ss][i_se].pha_mat_data
49#define EXT_MAT_DATA scat_data[i_ss][i_se].ext_mat_data
50#define ABS_VEC_DATA scat_data[i_ss][i_se].abs_vec_data
54#define PND_LIMIT 1e-12
61 const Vector& za_grid,
62 const Vector& aa_grid,
63 const Index& za_index,
64 const Index& aa_index,
67 const Numeric& rtp_temperature,
68 const Tensor4& pnd_field,
69 const Index& scat_p_index,
70 const Index& scat_lat_index,
71 const Index& scat_lon_index,
73 const Index stokes_dim = pha_mat_spt.ncols();
74 if (stokes_dim > 4 || stokes_dim < 1) {
76 "The dimension of the stokes vector \n"
77 "must be 1,2,3 or 4");
82 if (N_se_total != pnd_field.nbooks()) {
84 os <<
"Total number of scattering elements in scat_data "
85 <<
"inconsistent with size of pnd_field.";
86 throw runtime_error(os.str());
100 if (scat_data[0][0].f_grid.
nelem() < 2) {
102 os <<
"Scattering data seems to be *scat_data_mono* (1 freq point only),\n"
103 <<
"but frequency interpolable data (*scat_data* with >=2 freq points) "
104 <<
"is expected here.";
105 throw runtime_error(os.str());
108 const Index N_ss = scat_data.
nelem();
112 Tensor5 pha_mat_data_int;
116 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
117 const Index N_se = scat_data[i_ss].
nelem();
120 for (Index i_se = 0; i_se < N_se; i_se++) {
124 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
150 }
else if (rtp_temperature < 0.)
153 if (rtp_temperature > -10.)
156 }
else if (rtp_temperature > -20.)
168 os <<
"In pha_mat_sptFromData.\n"
169 <<
"The temperature grid of the scattering data does not\n"
170 <<
"cover the atmospheric temperature at cloud location.\n"
171 <<
"The data should include the value T = " << rtp_temperature
181 for (Index i_za_sca = 0; i_za_sca <
PHA_MAT_DATA.nshelves();
183 for (Index i_aa_sca = 0; i_aa_sca <
PHA_MAT_DATA.nbooks();
185 for (Index i_za_inc = 0; i_za_inc <
PHA_MAT_DATA.npages();
187 for (Index i_aa_inc = 0; i_aa_inc <
PHA_MAT_DATA.nrows();
192 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
207 for (Index i_za_sca = 0; i_za_sca <
PHA_MAT_DATA.nshelves();
209 for (Index i_aa_sca = 0; i_aa_sca <
PHA_MAT_DATA.nbooks();
211 for (Index i_za_inc = 0; i_za_inc <
PHA_MAT_DATA.npages();
213 for (Index i_aa_inc = 0; i_aa_inc <
PHA_MAT_DATA.nrows();
218 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
231 for (Index za_inc_idx = 0; za_inc_idx < za_grid.nelem();
233 for (Index aa_inc_idx = 0; aa_inc_idx < aa_grid.nelem();
236 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, joker, joker),
258 Tensor5& pha_mat_spt,
260 const ArrayOfTensor7& pha_mat_sptDOITOpt,
262 const Index& doit_za_grid_size,
263 const Vector& aa_grid,
264 const Index& za_index,
265 const Index& aa_index,
266 const Numeric& rtp_temperature,
267 const Tensor4& pnd_field,
268 const Index& scat_p_index,
269 const Index& scat_lat_index,
270 const Index& scat_lon_index,
274 if (N_se_total != pnd_field.nbooks()) {
276 os <<
"Total number of scattering elements in scat_data_mono "
277 <<
"inconsistent with size of pnd_field.";
278 throw runtime_error(os.str());
286 if (pnd_field.ncols() > 1) {
287 ARTS_ASSERT(pha_mat_sptDOITOpt.nelem() == N_se_total);
291 scat_data_mono[0][0].T_grid.
nelem());
292 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
293 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nshelves() == aa_grid.nelem());
294 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
295 ARTS_ASSERT(pha_mat_sptDOITOpt[0].npages() == aa_grid.nelem());
299 else if (pnd_field.ncols() == 1) {
307 scat_data_mono[0][0].T_grid.
nelem());
308 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
309 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nshelves() == 1);
310 ARTS_ASSERT(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
311 ARTS_ASSERT(pha_mat_sptDOITOpt[0].npages() == aa_grid.nelem());
325 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
327 os <<
"Scattering data seems to be *scat_data* (several freq points),\n"
328 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
329 throw runtime_error(os.str());
334 nlinspace(za_grid, 0, 180, doit_za_grid_size);
336 const Index N_ss = scat_data_mono.
nelem();
337 const Index stokes_dim = pha_mat_spt.ncols();
339 if (stokes_dim > 4 || stokes_dim < 1) {
341 "The dimension of the stokes vector \n"
342 "must be 1,2,3 or 4");
354 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
355 const Index N_se = scat_data_mono[i_ss].
nelem();
357 for (Index i_se = 0; i_se < N_se; i_se++) {
361 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
364 Index nT = scat_data_mono[i_ss][i_se].pha_mat_data.nvitrines();
370 }
else if (rtp_temperature < 0.)
373 if (rtp_temperature > -10.)
376 }
else if (rtp_temperature > -20.)
385 os <<
"In pha_mat_sptFromDataDOITOpt.\n"
386 <<
"The temperature grid of the scattering data does not\n"
387 <<
"cover the atmospheric temperature at cloud location.\n"
388 <<
"The data should include the value T = " << rtp_temperature
391 os.str(), scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
394 gridpos(T_gp, scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
399 for (Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
401 for (Index aa_inc_idx = 0; aa_inc_idx < aa_grid.nelem();
405 for (Index i = 0; i < stokes_dim; i++) {
406 for (Index j = 0; j < stokes_dim; j++) {
407 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, i, j) =
409 pha_mat_sptDOITOpt[i_se_flat](joker,
420 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, joker, joker) =
421 pha_mat_sptDOITOpt[i_se_flat](ti,
440 ArrayOfPropagationMatrix& ext_mat_spt,
441 ArrayOfStokesVector& abs_vec_spt,
444 const Vector& za_grid,
445 const Vector& aa_grid,
446 const Index& za_index,
447 const Index& aa_index,
448 const Index& f_index,
449 const Vector& f_grid,
450 const Numeric& rtp_temperature,
451 const Tensor4& pnd_field,
452 const Index& scat_p_index,
453 const Index& scat_lat_index,
454 const Index& scat_lon_index,
456 const Index N_ss = scat_data.
nelem();
457 const Numeric za_sca = za_grid[za_index];
458 const Numeric aa_sca = aa_grid[aa_index];
462 ARTS_ASSERT(ext_mat_spt[0].NumberOfFrequencies() == N_se_total);
463 ARTS_ASSERT(abs_vec_spt[0].NumberOfFrequencies() == N_se_total);
473 if (scat_data[0][0].f_grid.
nelem() < 2) {
475 os <<
"Scattering data seems to be *scat_data_mono* (1 freq point only),\n"
476 <<
"but frequency interpolable data (*scat_data* with >=2 freq points) "
477 <<
"is expected here.";
478 throw runtime_error(os.str());
483 Tensor3 ext_mat_data_int;
484 Tensor3 abs_vec_data_int;
492 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
493 const Index N_se = scat_data[i_ss].
nelem();
496 for (Index i_se = 0; i_se < N_se; i_se++) {
501 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
513 ext_mat_data_int.resize(
516 abs_vec_data_int.resize(
527 os <<
"In opt_prop_sptFromData.\n"
528 <<
"The temperature grid of the scattering data does not\n"
529 <<
"cover the atmospheric temperature at cloud location.\n"
530 <<
"The data should include the value T = " << rtp_temperature
540 for (Index i_za_sca = 0; i_za_sca <
EXT_MAT_DATA.npages();
542 for (Index i_aa_sca = 0; i_aa_sca <
EXT_MAT_DATA.nrows();
548 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
557 for (Index i_za_sca = 0; i_za_sca <
ABS_VEC_DATA.npages();
559 for (Index i_aa_sca = 0; i_aa_sca <
ABS_VEC_DATA.nrows();
565 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
578 for (Index i_za_sca = 0; i_za_sca <
EXT_MAT_DATA.npages();
580 for (Index i_aa_sca = 0; i_aa_sca <
EXT_MAT_DATA.nrows();
586 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
594 for (Index i_za_sca = 0; i_za_sca <
ABS_VEC_DATA.npages();
596 for (Index i_aa_sca = 0; i_aa_sca <
ABS_VEC_DATA.nrows();
602 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
644 ArrayOfPropagationMatrix& ext_mat_spt,
645 ArrayOfStokesVector& abs_vec_spt,
648 const Index& scat_data_checked,
649 const Vector& za_grid,
650 const Vector& aa_grid,
651 const Index& za_index,
652 const Index& aa_index,
653 const Index& f_index,
654 const Numeric& rtp_temperature,
655 const Tensor4& pnd_field,
656 const Index& scat_p_index,
657 const Index& scat_lat_index,
658 const Index& scat_lon_index,
660 if (scat_data_checked != 1)
662 "The scattering data must be flagged to have "
663 "passed a consistency check (scat_data_checked=1).");
665 const Index N_ss = scat_data.
nelem();
666 const Index stokes_dim = ext_mat_spt[0].StokesDimensions();
667 const Numeric za_sca = za_grid[za_index];
668 const Numeric aa_sca = aa_grid[aa_index];
670 if (stokes_dim > 4 || stokes_dim < 1) {
672 "The dimension of the stokes vector \n"
673 "must be 1,2,3 or 4");
682 Tensor3 ext_mat_data_int;
683 Tensor3 abs_vec_data_int;
686 for (
auto& pm : ext_mat_spt) pm.SetZero();
687 for (
auto& sv : abs_vec_spt) sv.SetZero();
693 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
694 const Index N_se = scat_data[i_ss].
nelem();
697 for (Index i_se = 0; i_se < N_se; i_se++) {
702 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
709 ext_mat_data_int.resize(
711 abs_vec_data_int.resize(
719 os <<
"In opt_prop_sptFromScat_data.\n"
720 <<
"The temperature grid of the scattering data does not\n"
721 <<
"cover the atmospheric temperature at cloud location.\n"
722 <<
"The data should include the value T = " << rtp_temperature
738 this_f_index = f_index;
742 for (Index i_za_sca = 0; i_za_sca <
EXT_MAT_DATA.npages();
744 for (Index i_aa_sca = 0; i_aa_sca <
EXT_MAT_DATA.nrows();
747 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
interp(
749 EXT_MAT_DATA(this_f_index, joker, i_za_sca, i_aa_sca, i),
755 ext_mat_data_int =
EXT_MAT_DATA(this_f_index, 0, joker, joker, joker);
776 this_f_index = f_index;
780 for (Index i_za_sca = 0; i_za_sca <
ABS_VEC_DATA.npages();
782 for (Index i_aa_sca = 0; i_aa_sca <
ABS_VEC_DATA.nrows();
785 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
interp(
787 ABS_VEC_DATA(this_f_index, joker, i_za_sca, i_aa_sca, i),
793 abs_vec_data_int =
ABS_VEC_DATA(this_f_index, 0, joker, joker, joker);
840 PropagationMatrix& ext_mat,
841 StokesVector& abs_vec,
843 const ArrayOfPropagationMatrix& ext_mat_spt,
844 const ArrayOfStokesVector& abs_vec_spt,
845 const Tensor4& pnd_field,
846 const Index& scat_p_index,
847 const Index& scat_lat_index,
848 const Index& scat_lon_index,
850 Index N_se = abs_vec_spt.nelem();
852 if (ext_mat_spt.nelem() not_eq N_se) {
854 os <<
"Number of scattering elements in *abs_vec_spt* and *ext_mat_spt*\n"
855 <<
"does not agree.";
856 throw runtime_error(os.str());
859 Index stokes_dim = abs_vec_spt[0].StokesDimensions();
861 if (ext_mat_spt[0].StokesDimensions() not_eq stokes_dim) {
863 os <<
"*stokes_dim* of *abs_vec_spt* and *ext_mat_spt* does not agree.";
864 throw runtime_error(os.str());
866 if (stokes_dim > 4 || stokes_dim < 1) {
868 os <<
"The dimension of stokes vector can only be 1, 2, 3, or 4.";
869 throw runtime_error(os.str());
872 ext_mat = PropagationMatrix(1, stokes_dim);
874 abs_vec = StokesVector(1, stokes_dim);
877 PropagationMatrix ext_mat_part(1, stokes_dim);
878 ext_mat_part.SetZero();
879 StokesVector abs_vec_part(1, stokes_dim);
880 abs_vec_part.SetZero();
883 for (Index l = 0; l < N_se; l++) {
884 abs_vec_part.MultiplyAndAdd(
885 pnd_field(l, scat_p_index, scat_lat_index, scat_lon_index),
887 ext_mat_part.MultiplyAndAdd(
888 pnd_field(l, scat_p_index, scat_lat_index, scat_lon_index),
893 abs_vec += abs_vec_part;
895 ext_mat += ext_mat_part;
900 const PropagationMatrix& propmat_clearsky,
903 const Index stokes_dim = ext_mat.StokesDimensions();
908 "Col dimension of propmat_clearsky "
909 "inconsistent with col dimension in ext_mat.");
912 const Index f_dim = ext_mat.NumberOfFrequencies();
917 "Frequency dimension of ext_mat and propmat_clearsky\n"
918 "are inconsistent in ext_matAddGas.");
920 ext_mat += propmat_clearsky;
925 const PropagationMatrix& propmat_clearsky,
928 const Index f_dim = abs_vec.NumberOfFrequencies();
929 const Index stokes_dim = abs_vec.StokesDimensions();
934 "Frequency dimension of abs_vec and propmat_clearsky\n"
935 "are inconsistent in abs_vecAddGas.");
937 "Stokes dimension of abs_vec and propmat_clearsky\n"
938 "are inconsistent in abs_vecAddGas.");
942 abs_vec += propmat_clearsky;
993 const Tensor5& pha_mat_spt,
994 const Tensor4& pnd_field,
995 const Index& atmosphere_dim,
996 const Index& scat_p_index,
997 const Index& scat_lat_index,
998 const Index& scat_lon_index,
1000 Index N_se = pha_mat_spt.nshelves();
1001 Index Nza = pha_mat_spt.nbooks();
1002 Index Naa = pha_mat_spt.npages();
1003 Index stokes_dim = pha_mat_spt.nrows();
1005 pha_mat.resize(Nza, Naa, stokes_dim, stokes_dim);
1012 if (atmosphere_dim > 1) ilat = scat_lat_index;
1013 if (atmosphere_dim > 2) ilon = scat_lon_index;
1015 if (atmosphere_dim == 1) {
1020 Numeric grid_step_size_azimuth = 360. / (Numeric)(Naa - 1) *
DEG2RAD;
1023 for (Index pt_index = 0; pt_index < N_se; ++pt_index)
1025 for (Index za_index = 0; za_index < Nza; ++za_index)
1026 for (Index aa_index = 0; aa_index < Naa - 1; ++aa_index)
1028 for (Index stokes_index_1 = 0; stokes_index_1 < stokes_dim;
1030 for (Index stokes_index_2 = 0; stokes_index_2 < stokes_dim;
1034 pha_mat(za_index, 0, stokes_index_1, stokes_index_2) +=
1035 ((pha_mat_spt(pt_index,
1040 pha_mat_spt(pt_index,
1045 2 * grid_step_size_azimuth *
1046 pnd_field(pt_index, scat_p_index, ilat, ilon));
1049 for (Index pt_index = 0; pt_index < N_se; ++pt_index)
1051 for (Index za_index = 0; za_index < Nza; ++za_index)
1052 for (Index aa_index = 0; aa_index < Naa; ++aa_index)
1054 for (Index stokes_index_1 = 0; stokes_index_1 < stokes_dim;
1056 for (Index stokes_index_2 = 0; stokes_index_2 < stokes_dim;
1060 pha_mat(za_index, aa_index, stokes_index_1, stokes_index_2) +=
1061 (pha_mat_spt(pt_index,
1066 pnd_field(pt_index, scat_p_index, ilat, ilon));
1073 const String& check_type,
1074 const Numeric& threshold,
1086 const Index N_ss = scat_data.
nelem();
1093 out2 <<
" checking for negative values in Z11, K11, and a1, and for K11<a1\n";
1094 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
1095 const Index N_se = scat_data[i_ss].
nelem();
1098 for (Index i_se = 0; i_se < N_se; i_se++) {
1099 for (Index f = 0; f <
F_DATAGRID.nelem(); f++) {
1100 for (Index zai = 0; zai <
ABS_VEC_DATA.npages(); zai++)
1101 for (Index aai = 0; aai <
ABS_VEC_DATA.nrows(); aai++) {
1102 for (Index t = 0; t <
T_DATAGRID.nelem(); t++) {
1106 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1107 <<
" contains negative K11 or a1 at f#" << f <<
", T#" << t
1108 <<
", za#" << zai <<
", aa#" << aai <<
"\n";
1109 throw runtime_error(os.str());
1114 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1115 <<
" has K11<a1 at f#" << f <<
", T#" << t <<
", za#" << zai
1116 <<
", aa#" << aai <<
"\n";
1117 throw runtime_error(os.str());
1124 for (Index t = 0; t < nTpha; t++) {
1125 for (Index zas = 0; zas <
PHA_MAT_DATA.nshelves(); zas++)
1126 for (Index aas = 0; aas <
PHA_MAT_DATA.nbooks(); aas++)
1129 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1130 <<
" contains negative Z11 at f#" << f <<
", T#" << t
1131 <<
" (of " << nTpha <<
"), za_sca#" << zas <<
", aa_sca#"
1132 << aas <<
", za_inc#" << zai <<
", aa_inc#" << aai
1134 throw runtime_error(os.str());
1143 out2 <<
" checking for NaN anywhere in Z, K, and a\n";
1144 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
1145 const Index N_se = scat_data[i_ss].
nelem();
1148 for (Index i_se = 0; i_se < N_se; i_se++) {
1149 for (Index f = 0; f <
F_DATAGRID.nelem(); f++) {
1150 for (Index zai = 0; zai <
ABS_VEC_DATA.npages(); zai++)
1151 for (Index aai = 0; aai <
ABS_VEC_DATA.nrows(); aai++) {
1152 for (Index t = 0; t <
T_DATAGRID.nelem(); t++) {
1156 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1157 <<
" contains NaN in abs_vec at f#" << f <<
", T#" << t
1158 <<
", za#" << zai <<
", aa#" << aai <<
", stokes #" << st
1160 throw runtime_error(os.str());
1165 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1166 <<
" contains NaN in ext_mat at f#" << f <<
", T#" << t
1167 <<
", za#" << zai <<
", aa#" << aai <<
", stokes #" << st
1169 throw runtime_error(os.str());
1173 for (Index t = 0; t < nTpha; t++) {
1174 for (Index zas = 0; zas <
PHA_MAT_DATA.nshelves(); zas++)
1175 for (Index aas = 0; aas <
PHA_MAT_DATA.nbooks(); aas++)
1180 os <<
"Scatt. species #" << i_ss <<
" element #" << i_se
1181 <<
" contains NaN in pha_mat at f#" << f <<
", T#" << t
1182 <<
" (of " << nTpha <<
"), za_sca#" << zas
1183 <<
", aa_sca#" << aas <<
", za_inc#" << zai
1184 <<
", aa_inc#" << aai <<
", stokes #"
1186 throw runtime_error(os.str());
1194 if (check_type.
toupper() ==
"ALL") {
1196 out2 <<
" checking normalization of scattering matrix\n";
1197 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
1198 const Index N_se = scat_data[i_ss].
nelem();
1201 for (Index i_se = 0; i_se < N_se; i_se++)
1204 for (Index f = 0; f <
F_DATAGRID.nelem(); f++) {
1205 for (Index t = 0; t <
T_DATAGRID.nelem(); t++) {
1211 Numeric Csca_data = Cext_data - Cabs_data;
1229 if (abs(Csca - Csca_data) / Cext_data > threshold) {
1231 os <<
" Deviations in scat_data too large:\n"
1232 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1233 <<
" at nominal (actual) albedo of "
1234 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
1236 <<
" Check entry for scattering element " << i_se
1237 <<
" of scattering species " << i_ss <<
" at " << f
1238 <<
".frequency and " << t <<
".temperature!\n";
1239 throw runtime_error(os.str());
1247 for (Index f = 0; f <
F_DATAGRID.nelem(); f++) {
1248 for (Index t = 0; t <
T_DATAGRID.nelem(); t++) {
1249 for (Index iza = 0; iza <
ABS_VEC_DATA.npages(); iza++) {
1258 Numeric Csca_data = Cext_data - Cabs_data;
1276 if (abs(Csca - Csca_data) / Cext_data > threshold) {
1278 os <<
" Deviations in scat_data too large:\n"
1279 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1280 <<
" at nominal (actual) albedo of "
1281 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
1283 <<
" Check entry for scattering element " << i_se
1284 <<
" of scattering species " << i_ss <<
" at " << f
1285 <<
". frequency, " << t <<
". temperature, and " << iza
1286 <<
". incident polar angle!\n";
1287 throw runtime_error(os.str());
1298 <<
" scat_data consistency check not implemented (yet?!) for\n"
1303 out2 <<
" WARNING:\n"
1304 <<
" scat_data norm check can not be performed for pha_mat-only"
1305 <<
" T-reduced scattering elements\n"
1306 <<
" as found in scatt element #" << i_se
1307 <<
" of scatt species #" << i_ss <<
"!\n";
1309 }
else if (check_type.
toupper() ==
"SANE") {
1310 out1 <<
" WARNING:\n"
1311 <<
" Normalization check on pha_mat switched off.\n"
1312 <<
" Scattering solution might be wrong.\n";
1315 os <<
"Invalid value for argument *check_type*: '" << check_type <<
"'.\n";
1316 os <<
"Valid values are 'all' or 'none'.";
1317 throw runtime_error(os.str());
1324 ArrayOfTensor7& pha_mat_sptDOITOpt,
1326 Tensor7& pha_mat_doit,
1330 const Index& doit_za_grid_size,
1332 const Index& scat_data_checked,
1333 const Index& f_index,
1334 const Index& atmosphere_dim,
1335 const Index& stokes_dim,
1336 const Tensor3& t_field,
1338 const Tensor4& pnd_field,
1339 const Agenda& pha_mat_spt_agenda,
1341 if (scat_data_checked != 1)
1342 throw runtime_error(
1343 "The scattering data must be flagged to have "
1344 "passed a consistency check (scat_data_checked=1).");
1347 const Index Naa = aa_grid.nelem();
1348 Vector grid_stepsize(2);
1349 grid_stepsize[0] = 180. / (Numeric)(doit_za_grid_size - 1);
1353 Tensor5 pha_mat_spt_local(pnd_field.nbooks(),
1359 Tensor4 pha_mat_local(doit_za_grid_size, Naa, stokes_dim, stokes_dim, 0.);
1360 Tensor6 pha_mat_local_out(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1373 if (atmosphere_dim == 1)
1376 N_aa_sca = aa_grid.nelem();
1379 nlinspace(za_grid, 0, 180, doit_za_grid_size);
1383 const Index N_ss = scat_data.
nelem();
1388 Index i_se_flat = 0;
1389 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
1390 const Index N_se = scat_data[i_ss].
nelem();
1392 for (Index i_se = 0; i_se < N_se; i_se++) {
1393 Index N_T = scat_data_mono[i_ss][i_se].T_grid.
nelem();
1394 pha_mat_sptDOITOpt[i_se_flat].resize(N_T,
1403 pha_mat_sptDOITOpt[i_se_flat] = 0.;
1407 for (Index t_idx = 0; t_idx < N_T; t_idx++) {
1409 for (Index za_sca_idx = 0; za_sca_idx < doit_za_grid_size;
1411 for (Index aa_sca_idx = 0; aa_sca_idx < N_aa_sca; aa_sca_idx++) {
1413 for (Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
1415 for (Index aa_inc_idx = 0; aa_inc_idx < aa_grid.nelem();
1418 pha_mat_sptDOITOpt[i_se_flat](t_idx,
1425 scat_data_mono[i_ss][i_se].pha_mat_data(
1426 0, t_idx, joker, joker, joker, joker, joker),
1427 scat_data_mono[i_ss][i_se].za_grid,
1428 scat_data_mono[i_ss][i_se].aa_grid,
1429 scat_data_mono[i_ss][i_se].ptype,
1447 pha_mat_doit.resize(cloudbox_limits[1] - cloudbox_limits[0] + 1,
1456 if (atmosphere_dim == 1) {
1457 Index aa_index_local = 0;
1461 for (Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
1463 Numeric rtp_temperature_local =
1464 t_field(p_index + cloudbox_limits[0], 0, 0);
1466 for (Index za_index_local = 0;
1467 za_index_local < doit_za_grid_size;
1470 Index index_zero = 0;
1480 rtp_temperature_local,
1481 pha_mat_spt_agenda);
1493 p_index, za_index_local, 0, joker, joker, joker, joker) =
1508 const Vector& f_grid,
1509 const Index& interp_order,
1517 Index nf = f_grid.nelem();
1522 const String which_interpolation =
"scat_data_raw.f_grid to f_grid";
1523 for (Index i_ss = 0; i_ss < scat_data_raw.
nelem(); i_ss++) {
1524 for (Index i_se = 0; i_se < scat_data_raw[i_ss].
nelem(); i_se++) {
1527 if (scat_data_raw[i_ss][i_se].f_grid.
nelem() == 1 && nf == 1)
1528 if (!is_same_within_epsilon(scat_data_raw[i_ss][i_se].f_grid[0],
1532 os <<
"There is a problem with the grids for the following "
1533 <<
"interpolation:\n"
1534 << which_interpolation <<
"\n"
1535 <<
"If original grid has only 1 element, the new grid must also have\n"
1536 <<
"only a single element and hold the same value as the original grid.";
1537 throw runtime_error(os.str());
1542 scat_data_raw[i_ss][i_se].f_grid,
1549 scat_data.resize(scat_data_raw.
nelem());
1552 for (Index i_ss = 0; i_ss < scat_data_raw.
nelem(); i_ss++) {
1553 const Index N_se = scat_data_raw[i_ss].
nelem();
1556 scat_data[i_ss].resize(N_se);
1559 for (Index i_se = 0; i_se < N_se; i_se++) {
1561 PART_TYPE = scat_data_raw[i_ss][i_se].ptype;
1563 T_DATAGRID = scat_data_raw[i_ss][i_se].T_grid;
1569 scat_data_raw[i_ss][i_se].pha_mat_data.nvitrines(),
1570 scat_data_raw[i_ss][i_se].pha_mat_data.nshelves(),
1571 scat_data_raw[i_ss][i_se].pha_mat_data.nbooks(),
1572 scat_data_raw[i_ss][i_se].pha_mat_data.npages(),
1573 scat_data_raw[i_ss][i_se].pha_mat_data.nrows(),
1574 scat_data_raw[i_ss][i_se].pha_mat_data.ncols());
1576 scat_data_raw[i_ss][i_se].ext_mat_data.nbooks(),
1577 scat_data_raw[i_ss][i_se].ext_mat_data.npages(),
1578 scat_data_raw[i_ss][i_se].ext_mat_data.nrows(),
1579 scat_data_raw[i_ss][i_se].ext_mat_data.ncols());
1581 scat_data_raw[i_ss][i_se].abs_vec_data.nbooks(),
1582 scat_data_raw[i_ss][i_se].abs_vec_data.npages(),
1583 scat_data_raw[i_ss][i_se].abs_vec_data.nrows(),
1584 scat_data_raw[i_ss][i_se].abs_vec_data.ncols());
1586 const bool single_se_fgrid =
1587 (scat_data_raw[i_ss][i_se].f_grid.
nelem() == 1);
1588 if (!single_se_fgrid) {
1590 const auto lag_freq=my_interp::lagrange_interpolation_list<LagrangeInterpolation>(f_grid, scat_data_raw[i_ss][i_se].f_grid, interp_order);
1594 for (Index t_index = 0;
1595 t_index < scat_data_raw[i_ss][i_se].pha_mat_data.nvitrines();
1597 for (Index i_za_sca = 0;
1598 i_za_sca < scat_data_raw[i_ss][i_se].pha_mat_data.nshelves();
1600 for (Index i_aa_sca = 0;
1601 i_aa_sca < scat_data_raw[i_ss][i_se].pha_mat_data.nbooks();
1603 for (Index i_za_inc = 0;
1604 i_za_inc < scat_data_raw[i_ss][i_se].pha_mat_data.npages();
1606 for (Index i_aa_inc = 0;
1607 i_aa_inc < scat_data_raw[i_ss][i_se].pha_mat_data.nrows();
1610 i < scat_data_raw[i_ss][i_se].pha_mat_data.ncols();
1612 reinterp(scat_data[i_ss][i_se].pha_mat_data(joker,
1619 scat_data_raw[i_ss][i_se].pha_mat_data(joker,
1636 for (Index t_index = 0;
1637 t_index < scat_data_raw[i_ss][i_se].ext_mat_data.nbooks();
1639 for (Index i_za_sca = 0;
1640 i_za_sca < scat_data_raw[i_ss][i_se].ext_mat_data.npages();
1642 for (Index i_aa_sca = 0;
1643 i_aa_sca < scat_data_raw[i_ss][i_se].ext_mat_data.nrows();
1646 i < scat_data_raw[i_ss][i_se].ext_mat_data.ncols();
1648 reinterp(scat_data[i_ss][i_se].ext_mat_data(
1649 joker, t_index, i_za_sca, i_aa_sca, i),
1650 scat_data_raw[i_ss][i_se].ext_mat_data(
1651 joker, t_index, i_za_sca, i_aa_sca, i),
1660 for (Index t_index = 0;
1661 t_index < scat_data_raw[i_ss][i_se].abs_vec_data.nbooks();
1663 for (Index i_za_sca = 0;
1664 i_za_sca < scat_data_raw[i_ss][i_se].abs_vec_data.npages();
1666 for (Index i_aa_sca = 0;
1667 i_aa_sca < scat_data_raw[i_ss][i_se].abs_vec_data.nrows();
1670 i < scat_data_raw[i_ss][i_se].abs_vec_data.ncols();
1672 reinterp(scat_data[i_ss][i_se].abs_vec_data(
1673 joker, t_index, i_za_sca, i_aa_sca, i),
1674 scat_data_raw[i_ss][i_se].abs_vec_data(
1675 joker, t_index, i_za_sca, i_aa_sca, i),
1687 scat_data[i_ss][i_se].pha_mat_data =
1688 scat_data_raw[i_ss][i_se].pha_mat_data;
1689 scat_data[i_ss][i_se].ext_mat_data =
1690 scat_data_raw[i_ss][i_se].ext_mat_data;
1691 scat_data[i_ss][i_se].abs_vec_data =
1692 scat_data_raw[i_ss][i_se].abs_vec_data;
1702 const Index& interp_order,
1703 const Index& phamat_only,
1704 const Numeric& threshold,
1712 const Index nss = scat_data.
nelem();
1715 os <<
"Can not T-reduce scattering species #" << i_ss <<
".\n"
1716 <<
"*scat_data* contains only " << nss <<
" scattering species.";
1717 throw runtime_error(os.str());
1721 for (Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
1727 <<
" can be handled.\n"
1728 <<
"Scattering element #" << i_se <<
" has ptype " <<
PART_TYPE <<
".";
1729 throw runtime_error(os.str());
1742 os <<
"Single scattering data of scat element #" << i_se
1743 <<
" of scat species #" << i_ss <<
"\n"
1744 <<
"seems to have undergone some temperature grid manipulation in\n"
1745 <<
"*pha_mat_data* already. That can not be done twice!";
1746 throw runtime_error(os.str());
1756 ost <<
"Scattering data temperature interpolation for\n"
1757 <<
"scat element #" << i_se <<
" of scat species #" << i_ss <<
".";
1761 const LagrangeInterpolation lag_T(0, T,
T_DATAGRID, interp_order);
1791 for (Index i_f = 0; i_f <
PHA_MAT_DATA.nlibraries(); i_f++)
1792 for (Index i_za1 = 0; i_za1 <
PHA_MAT_DATA.nshelves(); i_za1++)
1793 for (Index i_aa1 = 0; i_aa1 <
PHA_MAT_DATA.nbooks(); i_aa1++)
1794 for (Index i_za2 = 0; i_za2 <
PHA_MAT_DATA.npages(); i_za2++)
1795 for (Index i_aa2 = 0; i_aa2 <
PHA_MAT_DATA.nrows(); i_aa2++)
1796 for (Index i_st = 0; i_st <
PHA_MAT_DATA.ncols(); i_st++)
1797 phamat_tmp(i_f, 0, i_za1, i_aa1, i_za2, i_aa2, i_st) =
1799 i_f, joker, i_za1, i_aa1, i_za2, i_aa2, i_st),
1806 for (Index i_f = 0; i_f <
EXT_MAT_DATA.nshelves(); i_f++)
1807 for (Index i_za = 0; i_za <
EXT_MAT_DATA.npages(); i_za++)
1808 for (Index i_aa = 0; i_aa <
EXT_MAT_DATA.nrows(); i_aa++) {
1809 for (Index i_st = 0; i_st <
EXT_MAT_DATA.ncols(); i_st++)
1810 extmat_tmp(i_f, 0, i_za, i_aa, i_st) =
1812 for (Index i_st = 0; i_st <
ABS_VEC_DATA.ncols(); i_st++)
1813 absvec_tmp(i_f, 0, i_za, i_aa, i_st) =
1862 Numeric this_threshold;
1865 this_threshold = threshold;
1867 "T-reduced *pha_mat_data* norm (=sca xs) deviates too "
1868 "much from non-reduced *ext_mat_data* and *abs_vec_data*:";
1870 this_threshold = 2 * threshold;
1872 "T-reduced *scat_data* deviates too much from original "
1884 for (Index f = 0; f <
F_DATAGRID.nelem(); f++) {
1887 phamat_tmp(f, 0, joker, 0, 0, 0, 0),
ZA_DATAGRID);
1888 Numeric Cext_data = extmat_tmp(f, 0, 0, 0, 0);
1890 Numeric Cabs_data = absvec_tmp(f, 0, 0, 0, 0);
1891 Numeric Csca_data = Cext_data - Cabs_data;
1908 if (abs(Csca - Csca_data) / Cext_data > threshold) {
1910 os <<
" Deviations in T-reduced scat_data too large:\n"
1911 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1912 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
1913 <<
" (" << Csca / Cext_data <<
").\n"
1914 <<
" Problem occurs for scattering element #" << i_se
1915 <<
" at " << f <<
".frequency!\n";
1916 throw runtime_error(os.str());
1918 Numeric norm_dev = (Csca - Csca) / Cext_data;
1923 for (Index t = 0; t <
T_DATAGRID.nelem(); t++) {
1926 Numeric xs_dev = (Csca - Csca_data) / Cext_data;
1927 if (abs(norm_dev + (Csca - Csca_data) / Cext_data) >
1929 cout <<
"Accumulated deviation (abs(" << norm_dev <<
"+"
1930 << xs_dev <<
")=" << abs(norm_dev + xs_dev)
1931 <<
" exceeding threshold (" << this_threshold <<
").\n";
1932 if (abs(Csca - Csca_data) / Cext_data > this_threshold) {
1934 os <<
" " << errmsg <<
"\n"
1935 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1936 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
1937 <<
" (" << Csca / Cext_data <<
").\n"
1938 <<
" Problem occurs for scattering element #" << i_se
1939 <<
" at " << f <<
".frequency and " << t
1940 <<
".temperature!\n";
1941 throw runtime_error(os.str());
1949 for (Index f = 0; f <
F_DATAGRID.nelem(); f++) {
1950 for (Index iza = 0; iza <
ABS_VEC_DATA.npages(); iza++) {
1953 phamat_tmp(f, 0, joker, joker, iza, 0, 0),
1956 Numeric Cext_data = extmat_tmp(f, 0, iza, 0, 0);
1958 Numeric Cabs_data = absvec_tmp(f, 0, iza, 0, 0);
1959 Numeric Csca_data = Cext_data - Cabs_data;
1976 if (abs(Csca - Csca_data) / Cext_data > threshold) {
1978 os <<
" Deviations in T-reduced scat_data too large:\n"
1979 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1980 <<
" at nominal (actual) albedo of " << Csca_data / Cext_data
1981 <<
" (" << Csca / Cext_data <<
").\n"
1982 <<
" Problem occurs for scattering element #" << i_se
1983 <<
" at " << f <<
".frequency, and " << iza
1984 <<
". incident polar angle!\n";
1985 throw runtime_error(os.str());
1991 for (Index t = 0; t <
T_DATAGRID.nelem(); t++) {
1994 if (abs(Csca - Csca_data) / Cext_data > this_threshold) {
1996 os <<
" " << errmsg <<
"\n"
1997 <<
" scat dev [%] " << 1e2 * Csca / Csca_data - 1e2
1998 <<
" at nominal (actual) albedo of "
1999 << Csca_data / Cext_data <<
" (" << Csca / Cext_data
2001 <<
" Problem occurs for scattering element #" << i_se
2002 <<
" at " << f <<
".frequency and " << t
2003 <<
".temperature, and " << iza
2004 <<
". incident polar angle!\n";
2005 throw runtime_error(os.str());
2036 const Vector& f_grid,
2037 const Index& f_index,
2045 for (Index h = 0; h < scat_data.
nelem(); h++) {
2046 for (Index i = 0; i < scat_data[h].
nelem(); i++) {
2049 scat_data[h][i].f_grid,
2055 scat_data_mono.resize(scat_data.
nelem());
2058 for (Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2059 const Index N_se = scat_data[i_ss].
nelem();
2062 scat_data_mono[i_ss].resize(N_se);
2065 for (Index i_se = 0; i_se < N_se; i_se++) {
2075 scat_data_mono[i_ss][i_se].ptype =
PART_TYPE;
2076 scat_data_mono[i_ss][i_se].f_grid.resize(1);
2077 scat_data_mono[i_ss][i_se].f_grid = f_grid[f_index];
2078 scat_data_mono[i_ss][i_se].T_grid = scat_data[i_ss][i_se].T_grid;
2083 scat_data_mono[i_ss][i_se].pha_mat_data.resize(1,
2091 for (Index t_index = 0; t_index <
PHA_MAT_DATA.nvitrines(); t_index++) {
2092 for (Index i_za_sca = 0; i_za_sca <
PHA_MAT_DATA.nshelves();
2094 for (Index i_aa_sca = 0; i_aa_sca <
PHA_MAT_DATA.nbooks();
2096 for (Index i_za_inc = 0; i_za_inc <
PHA_MAT_DATA.npages();
2098 for (Index i_aa_inc = 0; i_aa_inc <
PHA_MAT_DATA.nrows();
2101 scat_data_mono[i_ss][i_se].pha_mat_data(
2102 0, t_index, i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
2118 scat_data_mono[i_ss][i_se].ext_mat_data.resize(1,
2123 for (Index i_za_sca = 0; i_za_sca <
EXT_MAT_DATA.npages(); i_za_sca++) {
2124 for (Index i_aa_sca = 0; i_aa_sca <
EXT_MAT_DATA.nrows();
2130 scat_data_mono[i_ss][i_se].ext_mat_data(
2131 0, t_index, i_za_sca, i_aa_sca, i) =
2139 scat_data_mono[i_ss][i_se].abs_vec_data.resize(1,
2144 for (Index i_za_sca = 0; i_za_sca <
ABS_VEC_DATA.npages(); i_za_sca++) {
2145 for (Index i_aa_sca = 0; i_aa_sca <
ABS_VEC_DATA.nrows();
2151 scat_data_mono[i_ss][i_se].abs_vec_data(
2152 0, t_index, i_za_sca, i_aa_sca, i) =
2167 const Index& f_index,
2170 scat_data_mono.resize(scat_data.
nelem());
2173 for (Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2174 const Index N_se = scat_data[i_ss].
nelem();
2177 scat_data_mono[i_ss].resize(N_se);
2180 for (Index i_se = 0; i_se < N_se; i_se++) {
2183 scat_data_mono[i_ss][i_se] = scat_data[i_ss][i_se];
2186 scat_data_mono[i_ss][i_se].ptype =
PART_TYPE;
2187 scat_data_mono[i_ss][i_se].T_grid =
T_DATAGRID;
2191 scat_data_mono[i_ss][i_se].f_grid.resize(1);
2192 scat_data_mono[i_ss][i_se].f_grid =
F_DATAGRID[f_index];
2204 this_f_index = (
PHA_MAT_DATA.nlibraries() == 1) ? 0 : f_index;
2205 scat_data_mono[i_ss][i_se].pha_mat_data =
PHA_MAT_DATA(
2206 Range(this_f_index, 1), joker, joker, joker, joker, joker, joker);
2213 this_f_index = (
EXT_MAT_DATA.nshelves() == 1) ? 0 : f_index;
2214 scat_data_mono[i_ss][i_se].ext_mat_data =
2215 EXT_MAT_DATA(Range(this_f_index, 1), joker, joker, joker, joker);
2222 this_f_index = (
ABS_VEC_DATA.nshelves() == 1) ? 0 : f_index;
2223 scat_data_mono[i_ss][i_se].abs_vec_data =
2224 ABS_VEC_DATA(Range(this_f_index, 1), joker, joker, joker, joker);
2232 ArrayOfPropagationMatrix& ext_mat_spt,
2233 ArrayOfStokesVector& abs_vec_spt,
2236 const Vector& za_grid,
2237 const Vector& aa_grid,
2238 const Index& za_index,
2239 const Index& aa_index,
2240 const Numeric& rtp_temperature,
2241 const Tensor4& pnd_field,
2242 const Index& scat_p_index,
2243 const Index& scat_lat_index,
2244 const Index& scat_lon_index,
2247 const Index stokes_dim = ext_mat_spt[0].StokesDimensions();
2248 const Numeric za_sca = za_grid[za_index];
2249 const Numeric aa_sca = aa_grid[aa_index];
2251 if (stokes_dim > 4 or stokes_dim < 1) {
2252 throw runtime_error(
2253 "The dimension of the stokes vector \n"
2254 "must be 1,2,3 or 4");
2269 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
2271 os <<
"Scattering data seems to be *scat_data* (several freq points),\n"
2272 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
2273 throw runtime_error(os.str());
2277 for (
auto& pm : ext_mat_spt) pm.SetZero();
2278 for (
auto& av : abs_vec_spt) av.SetZero();
2284 Index i_se_flat = 0;
2286 for (Index i_ss = 0; i_ss < scat_data_mono.
nelem(); i_ss++) {
2288 for (Index i_se = 0; i_se < scat_data_mono[i_ss].
nelem(); i_se++) {
2292 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
2303 Index ext_npages = scat_data_mono[i_ss][i_se].ext_mat_data.npages();
2304 Index ext_nrows = scat_data_mono[i_ss][i_se].ext_mat_data.nrows();
2305 Index ext_ncols = scat_data_mono[i_ss][i_se].ext_mat_data.ncols();
2306 Index abs_npages = scat_data_mono[i_ss][i_se].abs_vec_data.npages();
2307 Index abs_nrows = scat_data_mono[i_ss][i_se].abs_vec_data.nrows();
2308 Index abs_ncols = scat_data_mono[i_ss][i_se].abs_vec_data.ncols();
2311 ConstVectorView t_grid = scat_data_mono[i_ss][i_se].T_grid;
2313 if (t_grid.nelem() > 1) {
2315 os <<
"In opt_prop_sptFromMonoData.\n"
2316 <<
"The temperature grid of the scattering data does not\n"
2317 <<
"cover the atmospheric temperature at cloud location.\n"
2318 <<
"The data should include the value T = " << rtp_temperature
2323 Tensor3 ext_mat_data1temp(ext_npages, ext_nrows, ext_ncols);
2324 gridpos(t_gp, t_grid, rtp_temperature);
2326 for (Index i_p = 0; i_p < ext_npages; i_p++) {
2327 for (Index i_r = 0; i_r < ext_nrows; i_r++) {
2328 for (Index i_c = 0; i_c < ext_ncols; i_c++) {
2329 ext_mat_data1temp(i_p, i_r, i_c) =
2331 scat_data_mono[i_ss][i_se].ext_mat_data(
2332 0, joker, i_p, i_r, i_c),
2339 scat_data_mono[i_ss][i_se].za_grid,
2340 scat_data_mono[i_ss][i_se].aa_grid,
2341 scat_data_mono[i_ss][i_se].ptype,
2347 scat_data_mono[i_ss][i_se].ext_mat_data(
2348 0, 0, joker, joker, joker),
2349 scat_data_mono[i_ss][i_se].za_grid,
2350 scat_data_mono[i_ss][i_se].aa_grid,
2351 scat_data_mono[i_ss][i_se].ptype,
2360 if (t_grid.nelem() > 1) {
2361 Tensor3 abs_vec_data1temp(abs_npages, abs_nrows, abs_ncols);
2363 for (Index i_p = 0; i_p < abs_npages; i_p++) {
2364 for (Index i_r = 0; i_r < abs_nrows; i_r++) {
2365 for (Index i_c = 0; i_c < abs_ncols; i_c++) {
2366 abs_vec_data1temp(i_p, i_r, i_c) =
2368 scat_data_mono[i_ss][i_se].abs_vec_data(
2369 0, joker, i_p, i_r, i_c),
2376 scat_data_mono[i_ss][i_se].za_grid,
2377 scat_data_mono[i_ss][i_se].aa_grid,
2378 scat_data_mono[i_ss][i_se].ptype,
2384 scat_data_mono[i_ss][i_se].abs_vec_data(
2385 0, 0, joker, joker, joker),
2386 scat_data_mono[i_ss][i_se].za_grid,
2387 scat_data_mono[i_ss][i_se].aa_grid,
2388 scat_data_mono[i_ss][i_se].ptype,
2402 Tensor5& pha_mat_spt,
2405 const Index& doit_za_grid_size,
2406 const Vector& aa_grid,
2407 const Index& za_index,
2408 const Index& aa_index,
2409 const Numeric& rtp_temperature,
2410 const Tensor4& pnd_field,
2411 const Index& scat_p_index,
2412 const Index& scat_lat_index,
2413 const Index& scat_lon_index,
2416 nlinspace(za_grid, 0, 180, doit_za_grid_size);
2419 if (N_se_total != pnd_field.nbooks()) {
2421 os <<
"Total number of scattering elements in *scat_data_mono* "
2422 <<
"inconsistent with size of pnd_field.";
2423 throw runtime_error(os.str());
2428 ARTS_ASSERT(pha_mat_spt.nshelves() == N_se_total);
2430 const Index stokes_dim = pha_mat_spt.ncols();
2431 if (stokes_dim > 4 || stokes_dim < 1) {
2432 throw runtime_error(
2433 "The dimension of the stokes vector \n"
2434 "must be 1,2,3 or 4");
2446 if (scat_data_mono[0][0].f_grid.
nelem() > 1) {
2448 os <<
"Scattering data seems to be *scat_data* (several freq points),\n"
2449 <<
"but *scat_data_mono* (1 freq point only) is expected here.";
2450 throw runtime_error(os.str());
2453 GridPos T_gp = {0, {0, 1}}, Tred_gp;
2459 Index i_se_flat = 0;
2460 for (Index i_ss = 0; i_ss < scat_data_mono.
nelem(); i_ss++) {
2461 for (Index i_se = 0; i_se < scat_data_mono[i_ss].
nelem(); i_se++) {
2465 if (pnd_field(i_se_flat, scat_p_index, scat_lat_index, scat_lon_index) >
2468 Index nT = scat_data_mono[i_ss][i_se].pha_mat_data.nvitrines();
2469 Tensor3 pha_mat_spt_tmp(nT, pha_mat_spt.nrows(), pha_mat_spt.ncols());
2471 pha_mat_spt_tmp = 0.;
2477 }
else if (rtp_temperature < 0.)
2480 if (rtp_temperature > -10.)
2483 }
else if (rtp_temperature > -20.)
2492 os <<
"In pha_mat_sptFromMonoData.\n"
2493 <<
"The temperature grid of the scattering data does not\n"
2494 <<
"cover the atmospheric temperature at cloud location.\n"
2495 <<
"The data should include the value T = " << rtp_temperature
2498 os.str(), scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
2501 gridpos(T_gp, scat_data_mono[i_ss][i_se].T_grid, rtp_temperature);
2509 for (Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
2511 for (Index aa_inc_idx = 0; aa_inc_idx < aa_grid.nelem();
2515 for (Index t_idx = 0; t_idx < 2; t_idx++) {
2517 pha_mat_spt_tmp(t_idx, joker, joker),
2518 scat_data_mono[i_ss][i_se].pha_mat_data(
2519 0, t_idx + T_gp.
idx, joker, joker, joker, joker, joker),
2520 scat_data_mono[i_ss][i_se].za_grid,
2521 scat_data_mono[i_ss][i_se].aa_grid,
2522 scat_data_mono[i_ss][i_se].ptype,
2532 for (Index i = 0; i < stokes_dim; i++) {
2533 for (Index j = 0; j < stokes_dim; j++) {
2534 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, i, j) =
2535 interp(itw, pha_mat_spt_tmp(joker, i, j), Tred_gp);
2541 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, joker, joker),
2542 scat_data_mono[i_ss][i_se].pha_mat_data(
2543 0, ti, joker, joker, joker, joker, joker),
2544 scat_data_mono[i_ss][i_se].za_grid,
2545 scat_data_mono[i_ss][i_se].aa_grid,
2546 scat_data_mono[i_ss][i_se].ptype,
2566 Tensor5& pha_mat_spt,
2569 const Index& scat_data_checked,
2570 const Vector& za_grid,
2571 const Vector& aa_grid,
2572 const Index& za_index,
2573 const Index& aa_index,
2574 const Index& f_index,
2575 const Numeric& rtp_temperature,
2576 const Tensor4& pnd_field,
2577 const Index& scat_p_index,
2578 const Index& scat_lat_index,
2579 const Index& scat_lon_index,
2581 if (scat_data_checked != 1)
2582 throw runtime_error(
2583 "The scattering data must be flagged to have "
2584 "passed a consistency check (scat_data_checked=1).");
2586 const Index stokes_dim = pha_mat_spt.ncols();
2587 if (stokes_dim > 4 || stokes_dim < 1) {
2588 throw runtime_error(
2589 "The dimension of the stokes vector \n"
2590 "must be 1,2,3 or 4");
2595 if (N_se_total != pnd_field.nbooks()) {
2597 os <<
"Total number of scattering elements in scat_data "
2598 <<
"inconsistent with size of pnd_field.";
2599 throw runtime_error(os.str());
2604 ARTS_ASSERT(pha_mat_spt.nshelves() == N_se_total);
2606 const Index N_ss = scat_data.
nelem();
2610 Tensor5 pha_mat_data_int;
2614 Index i_se_flat = 0;
2616 for (Index i_ss = 0; i_ss < N_ss; i_ss++) {
2617 const Index N_se = scat_data[i_ss].
nelem();
2620 for (Index i_se = 0; i_se < N_se; i_se++) {
2625 i_se_flat, scat_p_index, scat_lat_index, scat_lon_index)) >
2643 Index this_T_index = -1;
2646 }
else if (rtp_temperature < 0.)
2649 if (rtp_temperature > -10.)
2652 }
else if (rtp_temperature > -20.)
2661 os <<
"In pha_mat_sptFromScat_data.\n"
2662 <<
"The temperature grid of the scattering data does not\n"
2663 <<
"cover the atmospheric temperature at cloud location.\n"
2664 <<
"The data should include the value T = " << rtp_temperature
2678 this_f_index = f_index;
2680 if (this_T_index < 0) {
2682 for (Index i_za_sca = 0; i_za_sca <
PHA_MAT_DATA.nshelves();
2684 for (Index i_aa_sca = 0; i_aa_sca <
PHA_MAT_DATA.nbooks();
2686 for (Index i_za_inc = 0; i_za_inc <
PHA_MAT_DATA.npages();
2688 for (Index i_aa_inc = 0; i_aa_inc <
PHA_MAT_DATA.nrows();
2692 i_za_sca, i_aa_sca, i_za_inc, i_aa_inc, i) =
2704 this_f_index, this_T_index, joker, joker, joker, joker, joker);
2724 for (Index za_inc_idx = 0; za_inc_idx < za_grid.nelem();
2726 for (Index aa_inc_idx = 0; aa_inc_idx < aa_grid.nelem();
2729 pha_mat_spt(i_se_flat, za_inc_idx, aa_inc_idx, joker, joker),
2755 Index& cloudbox_checked,
2757 const Index& atmosphere_dim,
2758 const Index& cloudbox_on,
2760 const Tensor3& t_field,
2761 const Tensor3& z_field,
2762 const Matrix& z_surface,
2770 if (!cloudbox_checked)
2771 throw std::runtime_error(
2772 "You must call *cloudbox_checkedCalc* before this method.");
2775 cloudbox_checked = 0;
2777 if (atmosphere_dim != 1)
2778 throw std::runtime_error(
2779 "Merging scattering elements only works with a 1D atmoshere");
2784 pnd_field.resize(0, 0, 0, 0);
2791 limits[0] = cloudbox_limits[0];
2792 limits[1] = cloudbox_limits[1] + 1;
2794 Tensor4 pnd_field_merged(
2795 limits[1] - limits[0], limits[1] - limits[0], 1, 1, 0.);
2798 scat_data_merged.resize(1);
2799 scat_data_merged[0].resize(pnd_field_merged.nbooks());
2801 scat_meta_merged.resize(1);
2802 scat_meta_merged[0].resize(pnd_field_merged.nbooks());
2804 scat_species_merged.resize(1);
2805 scat_species_merged[0] =
"mergedfield-mergedpsd";
2806 for (Index sp = 0; sp < scat_data_merged[0].
nelem(); sp++) {
2808 this_part.
ptype = scat_data[0][0].ptype;
2809 this_part.
description =
"Merged scattering elements";
2810 this_part.
f_grid = scat_data[0][0].f_grid;
2811 this_part.
za_grid = scat_data[0][0].za_grid;
2812 this_part.
aa_grid = scat_data[0][0].aa_grid;
2813 this_part.
pha_mat_data.resize(scat_data[0][0].pha_mat_data.nlibraries(),
2815 scat_data[0][0].pha_mat_data.nshelves(),
2816 scat_data[0][0].pha_mat_data.nbooks(),
2817 scat_data[0][0].pha_mat_data.npages(),
2818 scat_data[0][0].pha_mat_data.nrows(),
2819 scat_data[0][0].pha_mat_data.ncols());
2820 this_part.
ext_mat_data.resize(scat_data[0][0].ext_mat_data.nshelves(),
2822 scat_data[0][0].ext_mat_data.npages(),
2823 scat_data[0][0].ext_mat_data.nrows(),
2824 scat_data[0][0].ext_mat_data.ncols());
2825 this_part.
abs_vec_data.resize(scat_data[0][0].abs_vec_data.nshelves(),
2827 scat_data[0][0].abs_vec_data.npages(),
2828 scat_data[0][0].abs_vec_data.nrows(),
2829 scat_data[0][0].abs_vec_data.ncols());
2833 this_part.
T_grid.resize(1);
2834 this_part.
T_grid[0] = t_field(sp, 0, 0);
2838 os <<
"Merged scattering element of cloudbox-level #" << sp;
2840 this_meta.
source =
"ARTS internal";
2842 this_meta.
mass = -1.;
2850 for (Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2851 for (Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
2855 throw std::runtime_error(
2856 "All scattering elements must have the same type");
2858 if (orig_part.
f_grid.nelem() != first_part.
f_grid.nelem())
2859 throw std::runtime_error(
2860 "All scattering elements must have the same f_grid");
2863 joker, 0, joker, joker, joker, joker, joker),
2870 throw std::runtime_error(
2871 "All scattering elements must have the same pha_mat_data size"
2872 " (except for temperature).");
2874 if (!is_size(orig_part.
ext_mat_data(joker, 0, joker, joker, joker),
2879 throw std::runtime_error(
2880 "All scattering elements must have the same ext_mat_data size"
2881 " (except for temperature).");
2883 if (!is_size(orig_part.
abs_vec_data(joker, 0, joker, joker, joker),
2888 throw std::runtime_error(
2889 "All scattering elements must have the same abs_vec_data size"
2890 " (except for temperature).");
2899 Index nlevels = pnd_field_merged.nbooks();
2901 for (Index i_lv = 0; i_lv < nlevels - 1; i_lv++) {
2902 pnd_field_merged(i_lv, i_lv, 0, 0) = 1.;
2905 for (Index i_ss = 0; i_ss < scat_data.
nelem(); i_ss++) {
2906 for (Index i_se = 0; i_se < scat_data[i_ss].
nelem(); i_se++) {
2913 if (pnd_field(pnd_index, i_lv, 0, 0) >
PND_LIMIT)
2915 Numeric temperature = this_part.
T_grid[0];
2916 if (orig_part.
T_grid.nelem() > 1) {
2918 os <<
"The temperature grid of the scattering data "
2919 <<
"does not cover the\n"
2920 <<
"atmospheric temperature at cloud location. "
2921 <<
"The data should\n"
2922 <<
"include the value T = " << temperature <<
" K.\n"
2923 <<
"Offending particle is scat_data[" << i_ss <<
"][" << i_se
2925 <<
"Description: " << orig_part.
description <<
"\n";
2937 for (Index i_f = 0; i_f < orig_part.
pha_mat_data.nlibraries();
2940 for (Index i_za = 0; i_za < orig_part.
ext_mat_data.npages();
2943 for (Index i_aa = 0; i_aa < orig_part.
ext_mat_data.nrows();
2946 if (orig_part.
T_grid.nelem() == 1) {
2947 Vector
v{orig_part.
ext_mat_data(i_f, 0, i_za, i_aa, joker)};
2948 v *= pnd_field(pnd_index, i_lv, 0, 0);
2952 v *= pnd_field(pnd_index, i_lv, 0, 0);
2955 for (Index i = 0; i < orig_part.
ext_mat_data.ncols(); i++) {
2958 pnd_field(pnd_index, i_lv, 0, 0) *
2964 for (Index i = 0; i < orig_part.
abs_vec_data.ncols(); i++) {
2967 pnd_field(pnd_index, i_lv, 0, 0) *
2980 for (Index i_za_out = 0;
2984 for (Index i_aa_out = 0;
2988 for (Index i_za_inc = 0;
2992 for (Index i_aa_inc = 0;
2996 if (orig_part.
T_grid.nelem() == 1) {
3004 v *= pnd_field(pnd_index, i_lv, 0, 0);
3023 pnd_field(pnd_index, i_lv, 0, 0) *
3049 if (z_field(cloudbox_limits[0], 0, 0) > z_surface(0, 0))
3050 pnd_field_merged(0, 0, 0, 0) = 0.;
3052 pnd_field = pnd_field_merged;
3053 scat_data = scat_data_merged;
3054 scat_meta = scat_meta_merged;
3055 scat_species = scat_species_merged;
3065 const Index& scat_species_index,
3067 if (scat_species_index < 0) {
3069 os <<
"scat_species_index can't be <0!";
3070 throw runtime_error(os.str());
3073 const Index nss = scat_meta.
nelem();
3076 if (!(nss > scat_species_index)) {
3078 os <<
"Can not extract data for scattering species #" << scat_species_index
3080 <<
"because scat_meta has only " << nss <<
" elements.";
3081 throw runtime_error(os.str());
3084 const Index nse = scat_meta[scat_species_index].
nelem();
3085 meta_param.resize(nse);
3087 for (Index i = 0; i < nse; i++) {
3088 if (meta_name ==
"mass")
3089 meta_param[i] = scat_meta[scat_species_index][i].mass;
3090 else if (meta_name ==
"diameter_max")
3091 meta_param[i] = scat_meta[scat_species_index][i].diameter_max;
3092 else if (meta_name ==
"diameter_volume_equ")
3093 meta_param[i] = scat_meta[scat_species_index][i].diameter_volume_equ;
3094 else if (meta_name ==
"diameter_area_equ_aerodynamical")
3096 scat_meta[scat_species_index][i].diameter_area_equ_aerodynamical;
3099 os <<
"Meta parameter \"" << meta_name <<
"\"is unknown.";
3100 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
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.
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.
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.
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.
This file contains basic functions to handle XML data files.