55 #define F11 pha_mat_int[0] 56 #define F12 pha_mat_int[1] 57 #define F22 pha_mat_int[2] 58 #define F33 pha_mat_int[3] 59 #define F34 pha_mat_int[4] 60 #define F44 pha_mat_int[5] 110 assert(ext_mat_ss.
nelem() == abs_vec_ss.
nelem());
112 ext_mat = ext_mat_ss[0];
113 abs_vec = abs_vec_ss[0];
115 for (
Index i_ss = 1; i_ss < ext_mat_ss.
nelem(); i_ss++) {
116 ext_mat += ext_mat_ss[i_ss];
117 abs_vec += abs_vec_ss[i_ss];
119 ptype =
max(ptypes_ss);
162 assert(ext_mat_se.
nelem() == abs_vec_se.
nelem());
165 const Index nf = abs_vec_se[0][0].nbooks();
166 const Index nDir = abs_vec_se[0][0].nrows();
167 const Index stokes_dim = abs_vec_se[0][0].ncols();
178 for (
Index i_ss = 0; i_ss < nss; i_ss++) {
179 assert(ext_mat_se[i_ss].
nelem() == abs_vec_se[i_ss].
nelem());
180 assert(nT == ext_mat_se[i_ss][0].nbooks());
181 assert(nT == abs_vec_se[i_ss][0].npages());
183 ext_mat[i_ss].resize(nf, nT, nDir, stokes_dim, stokes_dim);
185 abs_vec[i_ss].resize(nf, nT, nDir, stokes_dim);
188 for (
Index i_se = 0; i_se < ext_mat_se[i_ss].
nelem(); i_se++) {
189 assert(nT == ext_mat_se[i_ss][i_se].nbooks());
190 assert(nT == abs_vec_se[i_ss][i_se].npages());
192 for (
Index Tind = 0; Tind < nT; Tind++) {
193 if (pnds(i_se_flat, Tind) != 0.) {
194 if (t_ok(i_se_flat, Tind) > 0.) {
196 ext_tmp *= pnds(i_se_flat, Tind);
200 abs_tmp *= pnds(i_se_flat, Tind);
204 os <<
"Interpolation error for (flat-array) scattering element #" 206 <<
"at location/temperature point #" << Tind <<
"\n";
207 throw runtime_error(os.
str());
213 ptype[i_ss] =
max(ptypes_se[i_ss]);
255 const Index& stokes_dim,
258 const Index& f_index,
259 const Index& t_interp_order) {
262 nf = scat_data[0][0].ext_mat_data.nshelves();
267 if (scat_data[0][0].ext_mat_data.nshelves() == 1)
286 for (
Index i_ss = 0; i_ss < nss; i_ss++) {
288 ext_mat[i_ss].resize(nse);
289 abs_vec[i_ss].resize(nse);
290 ptypes[i_ss].resize(nse);
292 for (
Index i_se = 0; i_se < nse; i_se++) {
293 ext_mat[i_ss][i_se].resize(nf, nT, nDir, stokes_dim, stokes_dim);
294 abs_vec[i_ss][i_se].resize(nf, nT, nDir, stokes_dim);
299 t_ok(i_se_flat,
joker),
300 scat_data[i_ss][i_se],
308 assert(i_se_flat == Nse_all);
344 const Index& f_start,
345 const Index& t_interp_order) {
366 assert(abs_vec.
nbooks() == nf);
372 assert(ext_mat.
nbooks() == nTout);
373 assert(abs_vec.
npages() == nTout);
374 assert(t_ok.
nelem() == nTout);
377 assert(ext_mat.
npages() == nDir);
378 assert(abs_vec.
nrows() == nDir);
381 assert(ext_mat.
nrows() == stokes_dim);
382 assert(ext_mat.
ncols() == stokes_dim);
390 Index this_T_interp_order;
405 if (this_T_interp_order < 0)
409 Tensor3 ext_mat_tmp(nf, stokes_dim, stokes_dim);
410 Matrix abs_vec_tmp(nf, stokes_dim);
411 for (
Index find = 0; find < nf; find++) {
421 for (
Index Tind = 0; Tind < nTout; Tind++)
422 for (
Index dind = 0; dind < nDir; dind++) {
424 abs_vec(
joker, Tind, dind,
joker) = abs_vec_tmp;
429 Tensor4 ext_mat_tmp(nf, nTout, stokes_dim, stokes_dim);
430 Tensor3 abs_vec_tmp(nf, nTout, stokes_dim);
433 for (
Index find = 0; find < nf; find++) {
434 for (
Index nst = 0; nst < ext_mat_tmp_ssd.ncols(); nst++)
439 for (
Index Tind = 0; Tind < nTout; Tind++)
442 ext_mat_tmp_ssd(Tind,
joker),
448 for (
Index nst = 0; nst < abs_vec_tmp_ssd.ncols(); nst++)
453 for (
Index Tind = 0; Tind < nTout; Tind++)
456 abs_vec_tmp_ssd(Tind,
joker),
460 abs_vec_tmp(find, Tind,
joker) = 0.;
463 for (
Index dind = 0; dind < nDir; dind++) {
487 if (this_T_interp_order < 0)
489 Matrix ext_mat_tmp_ssd(nDir, next);
490 Matrix abs_vec_tmp_ssd(nDir, nabs);
491 Tensor4 ext_mat_tmp(nf, nDir, stokes_dim, stokes_dim);
492 Tensor3 abs_vec_tmp(nf, nDir, stokes_dim);
493 for (
Index find = 0; find < nf; find++) {
494 for (
Index nst = 0; nst < next; nst++)
499 for (
Index Dind = 0; Dind < nDir; Dind++)
501 ext_mat_tmp_ssd(Dind,
joker),
505 for (
Index nst = 0; nst < nabs; nst++)
510 for (
Index Dind = 0; Dind < nDir; Dind++)
512 abs_vec_tmp_ssd(Dind,
joker),
517 for (
Index Tind = 0; Tind < nTout; Tind++) {
524 Tensor3 ext_mat_tmp_ssd(nTin, nDir, next);
525 Tensor3 abs_vec_tmp_ssd(nTin, nDir, nabs);
526 Matrix ext_mat_tmp(nTout, next);
527 Matrix abs_vec_tmp(nTout, nabs);
529 for (
Index find = 0; find < nf; find++) {
530 for (
Index Tind = 0; Tind < nTin; Tind++) {
531 for (
Index nst = 0; nst < next; nst++)
536 for (
Index nst = 0; nst < nabs; nst++)
543 for (
Index Dind = 0; Dind < nDir; Dind++) {
544 for (
Index nst = 0; nst < next; nst++)
547 ext_mat_tmp_ssd(
joker, Dind, nst),
549 for (
Index Tind = 0; Tind < nTout; Tind++)
551 ext_mat_tmp(Tind,
joker),
555 for (
Index nst = 0; nst < nabs; nst++)
558 abs_vec_tmp_ssd(
joker, Dind, nst),
560 for (
Index Tind = 0; Tind < nTout; Tind++)
562 abs_vec_tmp(Tind,
joker),
589 const Index& stokes_dim,
590 const Index& ptype) {
597 for (
Index ist = 0; ist < stokes_dim; ist++) {
598 ext_mat_stokes(ist, ist) = ext_mat_ssd[0];
602 switch (stokes_dim) {
604 ext_mat_stokes(2, 3) = ext_mat_ssd[2];
605 ext_mat_stokes(3, 2) = -ext_mat_ssd[2];
612 ext_mat_stokes(0, 1) = ext_mat_ssd[1];
613 ext_mat_stokes(1, 0) = ext_mat_ssd[1];
637 const Index& stokes_dim,
638 const Index& ptype) {
645 abs_vec_stokes[0] = abs_vec_ssd[0];
648 abs_vec_stokes[1] = abs_vec_ssd[1];
676 pha_mat = pha_mat_ss[0];
678 for (
Index i_ss = 1; i_ss < pha_mat_ss.
nelem(); i_ss++)
679 pha_mat += pha_mat_ss[i_ss];
681 ptype =
max(ptypes_ss);
722 const Index nf = pha_mat_se[0][0].nvitrines();
723 const Index npDir = pha_mat_se[0][0].nbooks();
724 const Index niDir = pha_mat_se[0][0].npages();
725 const Index stokes_dim = pha_mat_se[0][0].ncols();
734 for (
Index i_ss = 0; i_ss < nss; i_ss++) {
735 assert(nT == pha_mat_se[i_ss][0].nshelves());
737 pha_mat[i_ss].resize(nf, nT, npDir, niDir, stokes_dim, stokes_dim);
740 for (
Index i_se = 0; i_se < pha_mat_se[i_ss].
nelem(); i_se++) {
741 assert(nT == pha_mat_se[i_ss][i_se].nshelves());
743 for (
Index Tind = 0; Tind < nT; Tind++) {
744 if (pnds(i_se_flat, Tind) != 0.) {
745 if (t_ok(i_se_flat, Tind) > 0.) {
748 pha_tmp *= pnds(i_se_flat, Tind);
752 os <<
"Interpolation error for (flat-array) scattering element #" 754 <<
"at location/temperature point #" << Tind <<
"\n";
755 throw runtime_error(os.
str());
761 ptype[i_ss] =
max(ptypes_se[i_ss]);
802 const Index& stokes_dim,
806 const Index& f_index,
807 const Index& t_interp_order) {
810 nf = scat_data[0][0].pha_mat_data.nlibraries();
815 if (scat_data[0][0].pha_mat_data.nlibraries() == 1)
834 for (
Index i_ss = 0; i_ss < nss; i_ss++) {
836 pha_mat[i_ss].resize(nse);
837 ptypes[i_ss].resize(nse);
839 for (
Index i_se = 0; i_se < nse; i_se++) {
840 pha_mat[i_ss][i_se].resize(nf, nT, npDir, niDir, stokes_dim, stokes_dim);
844 t_ok(i_se_flat,
joker),
845 scat_data[i_ss][i_se],
854 assert(i_se_flat == Nse_all);
890 const Index& f_start,
891 const Index& t_interp_order) {
900 assert(pha_mat.
nshelves() == nTout);
901 assert(t_ok.
nelem() == nTout);
904 assert(pha_mat.
nbooks() == npDir);
907 assert(pha_mat.
npages() == niDir);
910 assert(pha_mat.
nrows() == stokes_dim);
918 Index this_T_interp_order;
938 else if (stokes_dim < 4)
942 if (this_T_interp_order < 0)
946 for (
Index pdir = 0; pdir < npDir; pdir++)
947 for (
Index idir = 0; idir < niDir; idir++) {
952 idir_array(idir, 1));
960 Vector pha_mat_int(npha, 0.);
961 Matrix pha_mat_tmp(stokes_dim, stokes_dim);
962 for (
Index find = 0; find < nf; find++) {
964 for (
Index nst = 0; nst < npha; nst++)
965 pha_mat_int[nst] =
interp(
979 for (
Index Tind = 0; Tind < nTout; Tind++)
980 pha_mat(find, Tind, pdir, idir,
joker,
joker) = pha_mat_tmp;
985 for (
Index pdir = 0; pdir < npDir; pdir++)
986 for (
Index idir = 0; idir < niDir; idir++) {
991 idir_array(idir, 1));
999 Matrix pha_mat_int(nTin, npha, 0.);
1000 Matrix pha_mat_tmp(nTout, npha, 0.);
1001 for (
Index find = 0; find < nf; find++) {
1002 for (
Index Tind = 0; Tind < nTin; Tind++)
1004 for (
Index nst = 0; nst < npha; nst++) {
1005 pha_mat_int(Tind, nst) =
interp(
1011 for (
Index nst = 0; nst < npha; nst++) {
1014 pha_mat_int(
joker, nst),
1022 for (
Index Tind = 0; Tind < nTout; Tind++) {
1025 pha_mat_tmp(Tind,
joker),
1026 pdir_array(pdir, 0),
1027 pdir_array(pdir, 1),
1028 idir_array(idir, 0),
1029 idir_array(idir, 1),
1039 Index nDir = npDir * niDir;
1041 Matrix delta_aa(npDir, niDir);
1049 for (
Index pdir = 0; pdir < npDir; pdir++) {
1050 for (
Index idir = 0; idir < niDir; idir++) {
1051 delta_aa(pdir, idir) =
1052 pdir_array(pdir, 1) - idir_array(idir, 1) +
1053 (pdir_array(pdir, 1) - idir_array(idir, 1) < -180) * 360 -
1054 (pdir_array(pdir, 1) - idir_array(idir, 1) > 180) * 360;
1055 adelta_aa[j] =
abs(delta_aa(pdir, idir));
1056 pza_gp[j] = pza_gp_tmp[pdir];
1057 iza_gp[j] = iza_gp_tmp[idir];
1067 if (this_T_interp_order < 0)
1069 Tensor3 pha_mat_int(nDir, stokes_dim, stokes_dim, 0.);
1070 Tensor4 pha_mat_tmp(npDir, niDir, stokes_dim, stokes_dim);
1072 for (
Index find = 0; find < nf; find++) {
1076 for (
Index ist1 = 0; ist1 < stokes_dim; ist1++)
1077 for (
Index ist2 = 0; ist2 < stokes_dim; ist2++)
1079 pha_mat_int(
joker, ist1, ist2),
1090 for (
Index pdir = 0; pdir < npDir; pdir++)
1091 for (
Index idir = 0; idir < niDir; idir++) {
1097 if (stokes_dim > 2) {
1098 for (
Index pdir = 0; pdir < npDir; pdir++)
1099 for (
Index idir = 0; idir < niDir; idir++)
1100 if (delta_aa(pdir, idir) < 0.) {
1101 pha_mat_tmp(pdir, idir, 0, 2) *= -1;
1102 pha_mat_tmp(pdir, idir, 1, 2) *= -1;
1103 pha_mat_tmp(pdir, idir, 2, 0) *= -1;
1104 pha_mat_tmp(pdir, idir, 2, 1) *= -1;
1108 if (stokes_dim > 3) {
1109 for (
Index pdir = 0; pdir < npDir; pdir++)
1110 for (
Index idir = 0; idir < niDir; idir++)
1111 if (delta_aa(pdir, idir) < 0.) {
1112 pha_mat_tmp(pdir, idir, 0, 3) *= -1;
1113 pha_mat_tmp(pdir, idir, 1, 3) *= -1;
1114 pha_mat_tmp(pdir, idir, 3, 0) *= -1;
1115 pha_mat_tmp(pdir, idir, 3, 1) *= -1;
1119 for (
Index Tind = 0; Tind < nTout; Tind++)
1127 Tensor4 pha_mat_int(nTin, nDir, stokes_dim, stokes_dim, 0.);
1129 for (
Index find = 0; find < nf; find++) {
1132 for (
Index Tind = 0; Tind < nTin; Tind++) {
1133 for (
Index ist1 = 0; ist1 < stokes_dim; ist1++)
1134 for (
Index ist2 = 0; ist2 < stokes_dim; ist2++)
1153 for (
Index pdir = 0; pdir < npDir; pdir++)
1154 for (
Index idir = 0; idir < niDir; idir++) {
1155 for (
Index ist1 = 0; ist1 < stokes_dim; ist1++)
1156 for (
Index ist2 = 0; ist2 < stokes_dim; ist2++)
1157 interp(pha_mat(find,
joker, pdir, idir, ist1, ist2),
1159 pha_mat_int(
joker, i, ist1, ist2),
1164 if (stokes_dim > 2) {
1165 for (
Index pdir = 0; pdir < npDir; pdir++)
1166 for (
Index idir = 0; idir < niDir; idir++)
1167 if (delta_aa(pdir, idir) < 0.) {
1168 pha_mat(find,
joker, pdir, idir, 0, 2) *= -1;
1169 pha_mat(find,
joker, pdir, idir, 1, 2) *= -1;
1170 pha_mat(find,
joker, pdir, idir, 2, 0) *= -1;
1171 pha_mat(find,
joker, pdir, idir, 2, 1) *= -1;
1175 if (stokes_dim > 3) {
1176 for (
Index pdir = 0; pdir < npDir; pdir++)
1177 for (
Index idir = 0; idir < niDir; idir++)
1178 if (delta_aa(pdir, idir) < 0.) {
1179 pha_mat(find,
joker, pdir, idir, 0, 3) *= -1;
1180 pha_mat(find,
joker, pdir, idir, 1, 3) *= -1;
1181 pha_mat(find,
joker, pdir, idir, 3, 0) *= -1;
1182 pha_mat(find,
joker, pdir, idir, 3, 1) *= -1;
1225 const Vector& pdir_array,
1226 const Vector& idir_array,
1227 const Index& f_start,
1228 const Index& t_interp_order,
1229 const Index& naa_totran) {
1238 assert(pha_mat_fou.
nvitrines() == nTout);
1239 assert(t_ok.
nelem() == nTout);
1242 assert(pha_mat_fou.
nshelves() == npDir);
1244 assert(pha_mat_fou.
nbooks() == niDir);
1246 const Index stokes_dim = pha_mat_fou.
nrows();
1247 assert(pha_mat_fou.
npages() == stokes_dim);
1250 assert(stokes_dim < 3);
1255 assert(nmodes == 0);
1263 Index this_T_interp_order;
1267 this_T_interp_order,
1279 if (naa_totran < 3) {
1281 os <<
"Azimuth grid size for scatt matrix extraction" 1282 <<
" (*naa_totran*) must be >3.\n" 1283 <<
"Yours is " << naa_totran <<
".\n";
1284 throw runtime_error(os.
str());
1289 1. / float(naa_totran - 1);
1290 Vector theta(naa_totran);
1292 Matrix theta_itw(naa_totran, 2);
1295 if (stokes_dim == 1)
1297 else if (stokes_dim < 4)
1302 Matrix pha_mat(stokes_dim, stokes_dim);
1303 Matrix pha_mat_angint(naa_totran, npha);
1304 Tensor3 Fou_int(nTin, stokes_dim, stokes_dim);
1306 for (
Index idir = 0; idir < niDir; idir++)
1307 for (
Index pdir = 0; pdir < npDir; pdir++) {
1308 for (
Index iaa = 0; iaa < naa_totran; iaa++)
1311 scat_angle(pdir_array[pdir], aa_grid[iaa], idir_array[idir], 0.);
1317 for (
Index find = 0; find < nf; find++) {
1319 for (
Index Tind = 0; Tind < nTin; Tind++) {
1321 for (
Index nst = 0; nst < npha; nst++)
1323 pha_mat_angint(
joker, nst),
1327 for (
Index iaa = 0; iaa < naa_totran; iaa++) {
1330 pha_mat_angint(iaa,
joker),
1339 if (iaa == 0 || iaa == naa_totran - 1)
1340 pha_mat *= (daa_totran / 2.);
1342 pha_mat *= daa_totran;
1347 if (this_T_interp_order <
1350 for (
Index Tind = 0; Tind < nTout; Tind++)
1351 pha_mat_fou(find, Tind, pdir, idir,
joker,
joker, 0) =
1354 for (
Index ist1 = 0; ist1 < stokes_dim; ist1++)
1355 for (
Index ist2 = 0; ist2 < stokes_dim; ist2++)
1356 for (
Index im = 0; im < nmodes; im++)
1357 interp(pha_mat_fou(find,
joker, pdir, idir, ist1, ist2, im),
1359 Fou_int(
joker, ist1, ist2),
1372 assert(aa_datagrid[0] == 0.);
1373 assert(aa_datagrid[naa - 1] == 180.);
1381 daa[0] = (aa_datagrid[1] - aa_datagrid[0]) / 360.;
1382 for (
Index iaa = 1; iaa < naa - 1; iaa++)
1383 daa[iaa] = (aa_datagrid[iaa + 1] - aa_datagrid[iaa - 1]) / 360.;
1384 daa[naa - 1] = (aa_datagrid[naa - 1] - aa_datagrid[naa - 2]) / 360.;
1388 gridpos(pdir_za_gp, za_datagrid, pdir_array);
1389 gridpos(idir_za_gp, za_datagrid, idir_array);
1390 Tensor3 dir_itw(npDir, niDir, 4);
1393 Tensor4 Fou_ssd(nza, nza, stokes_dim, stokes_dim);
1394 Tensor5 Fou_angint(nTin, npDir, niDir, stokes_dim, stokes_dim);
1396 for (
Index find = 0; find < nf; find++) {
1397 for (
Index Tind = 0; Tind < nTin; Tind++) {
1402 for (
Index iza = 0; iza < nza; iza++)
1403 for (
Index sza = 0; sza < nza; sza++) {
1404 for (
Index iaa = 0; iaa < naa; iaa++) {
1407 for (
Index ist1 = 0; ist1 < stokes_dim; ist1++)
1408 for (
Index ist2 = 0; ist2 < stokes_dim; ist2++)
1409 Fou_ssd(sza, iza, ist1, ist2) +=
1421 for (
Index ist1 = 0; ist1 < stokes_dim; ist1++)
1422 for (
Index ist2 = 0; ist2 < stokes_dim; ist2++)
1431 if (this_T_interp_order <
1434 for (
Index Tind = 0; Tind < nTout; Tind++)
1438 for (
Index pdir = 0; pdir < npDir; pdir++)
1439 for (
Index idir = 0; idir < niDir; idir++)
1440 for (
Index ist1 = 0; ist1 < stokes_dim; ist1++)
1441 for (
Index ist2 = 0; ist2 < stokes_dim; ist2++)
1442 for (
Index im = 0; im < nmodes; im++)
1443 interp(pha_mat_fou(find,
joker, pdir, idir, ist1, ist2, im),
1445 Fou_angint(
joker, pdir, idir, ist1, ist2),
1487 if (stokes_dim > 4 || stokes_dim < 1) {
1488 throw runtime_error(
1489 "The dimension of the stokes vector \n" 1490 "must be 1,2,3 or 4");
1505 out0 <<
"Case PTYPE_GENERAL not yet implemented. \n";
1514 abs_vec_lab.
Kjj()[0] = abs_vec_data(0, 0, 0);
1520 assert(abs_vec_data.
ncols() == 2);
1530 gridpos(gp, za_datagrid, za_sca);
1537 if (stokes_dim == 1) {
1545 out0 <<
"Not all ptype cases are implemented\n";
1585 if (stokes_dim > 4 || stokes_dim < 1) {
1586 throw runtime_error(
1587 "The dimension of the stokes vector \n" 1588 "must be 1,2,3 or 4");
1603 out0 <<
"Case PTYPE_GENERAL not yet implemented. \n";
1607 assert(ext_mat_data.
ncols() == 1);
1615 ext_mat_lab.
Kjj() = ext_mat_data(0, 0, 0);
1621 assert(ext_mat_data.
ncols() == 3);
1634 gridpos(gp, za_datagrid, za_sca);
1640 ext_mat_lab.
Kjj() = Kjj;
1642 if (stokes_dim < 2) {
1647 ext_mat_lab.
K12()[0] = K12;
1649 if (stokes_dim < 4) {
1654 ext_mat_lab.
K34()[0] = K34;
1659 out0 <<
"Not all ptype cases are implemented\n";
1699 const Index& za_sca_idx,
1700 const Index& aa_sca_idx,
1701 const Index& za_inc_idx,
1702 const Index& aa_inc_idx,
1706 const Index stokes_dim = pha_mat_lab.
ncols();
1708 Numeric za_sca = za_grid[za_sca_idx];
1709 Numeric aa_sca = aa_grid[aa_sca_idx];
1710 Numeric za_inc = za_grid[za_inc_idx];
1711 Numeric aa_inc = aa_grid[aa_inc_idx];
1713 if (stokes_dim > 4 || stokes_dim < 1) {
1714 throw runtime_error(
1715 "The dimension of the stokes vector \n" 1716 "must be 1,2,3 or 4");
1731 out0 <<
"Case PTYPE_GENERAL not yet implemented. \n";
1745 pha_mat_lab, pha_mat_int, za_sca, aa_sca, za_inc, aa_inc, theta_rad);
1754 assert(pha_mat_data.
ncols() == 16);
1755 assert(pha_mat_data.
npages() == za_datagrid.
nelem());
1756 Numeric delta_aa = aa_sca - aa_inc + (aa_sca - aa_inc < -180) * 360 -
1757 (aa_sca - aa_inc > 180) *
1765 gridpos(delta_aa_gp, aa_datagrid,
abs(delta_aa));
1766 gridpos(za_inc_gp, za_datagrid, za_inc);
1767 gridpos(za_sca_gp, za_datagrid, za_sca);
1777 if (stokes_dim == 1) {
1798 if (stokes_dim == 2) {
1801 if (delta_aa >= 0) {
1802 pha_mat_lab(0, 2) =
interp(
1808 pha_mat_lab(1, 2) =
interp(
1814 pha_mat_lab(2, 0) =
interp(
1820 pha_mat_lab(2, 1) =
interp(
1827 pha_mat_lab(0, 2) = -
interp(
1833 pha_mat_lab(1, 2) = -
interp(
1839 pha_mat_lab(2, 0) = -
interp(
1845 pha_mat_lab(2, 1) = -
interp(
1852 pha_mat_lab(2, 2) =
interp(
1858 if (stokes_dim == 3) {
1861 if (delta_aa >= 0) {
1862 pha_mat_lab(0, 3) =
interp(
1868 pha_mat_lab(1, 3) =
interp(
1874 pha_mat_lab(3, 0) =
interp(
1880 pha_mat_lab(3, 1) =
interp(
1887 pha_mat_lab(0, 3) = -
interp(
1893 pha_mat_lab(1, 3) = -
interp(
1899 pha_mat_lab(3, 0) = -
interp(
1905 pha_mat_lab(3, 1) = -
interp(
1912 pha_mat_lab(2, 3) =
interp(
1918 pha_mat_lab(3, 2) =
interp(
1924 pha_mat_lab(3, 3) =
interp(
1935 out0 <<
"Not all ptype cases are implemented\n";
1973 const Index& stokes_dim) {
1974 assert(stokes_dim >= 1 && stokes_dim <= 4);
1975 assert(ext_mat.
nrows() == stokes_dim);
1976 assert(ext_mat.
ncols() == stokes_dim);
1977 assert(abs_vec.
nelem() == stokes_dim);
1980 for (
Index is = 0; is < stokes_dim; is++) {
1981 ext_mat(is, is) += abs_vec[0];
1984 for (
Index is = 1; is < stokes_dim; is++) {
1985 ext_mat(0, is) += abs_vec[is];
1986 ext_mat(is, 0) += abs_vec[is];
2010 Index& this_T_interp_order,
2016 const Index& t_interp_order) {
2020 this_T_interp_order = -1;
2023 this_T_interp_order =
min(t_interp_order, nTin - 1);
2024 T_itw.
resize(nTout, this_T_interp_order + 1);
2033 const Numeric extrapolfac = 0.5;
2034 const Numeric lowlim = T_grid[0] - extrapolfac * (T_grid[1] - T_grid[0]);
2036 T_grid[nTin - 1] + extrapolfac * (T_grid[nTin - 1] - T_grid[nTin - 2]);
2038 bool any_T_exceed =
false;
2039 for (
Index Tind = 0; Tind < nTout; Tind++) {
2040 if (T_array[Tind] < lowlim || T_array[Tind] > uplim) {
2042 any_T_exceed =
true;
2049 dummy_gp.
idx.resize(this_T_interp_order + 1);
2050 dummy_gp.
w.
resize(this_T_interp_order + 1);
2051 for (
Index i = 0;
i <= this_T_interp_order; ++
i) dummy_gp.
idx[
i] =
i;
2054 bool grid_unchecked =
true;
2056 for (
Index iT = 0; iT < nTout; iT++) {
2059 T_gp[iT] = dummy_gp;
2061 if (grid_unchecked) {
2063 "Temperature interpolation in pha_mat_1ScatElem",
2065 T_array[
Range(iT, 1)],
2066 this_T_interp_order);
2067 grid_unchecked =
false;
2070 T_gp[iT], T_grid, T_array[iT], this_T_interp_order, extrapolfac);
2074 gridpos_poly(T_gp, T_grid, T_array, this_T_interp_order, extrapolfac);
2109 if ((
abs(aa_sca - aa_inc) < ANG_TOL) ||
2110 (
abs(
abs(aa_sca - aa_inc) - 360) < ANG_TOL)) {
2112 }
else if (
abs(
abs(aa_sca - aa_inc) - 180) < ANG_TOL) {
2113 theta_rad =
DEG2RAD * (za_sca + za_inc);
2114 if (theta_rad >
PI) {
2115 theta_rad = 2 *
PI - theta_rad;
2124 acos(cos(za_sca_rad) * cos(za_inc_rad) +
2125 sin(za_sca_rad) * sin(za_inc_rad) * cos(aa_sca_rad - aa_inc_rad));
2161 gridpos(thet_gp, za_datagrid, theta);
2166 assert(pha_mat_data.
ncols() == 6);
2168 pha_mat_int[
i] =
interp(itw, pha_mat_data(
joker, 0, 0, 0,
i), thet_gp);
2207 const Index stokes_dim = pha_mat_lab.
ncols();
2209 if (std::isnan(
F11)) {
2210 throw runtime_error(
2211 "NaN value(s) detected in *pha_mat_labCalc* (0,0). Could the " 2212 "input data contain NaNs? Please check with *scat_dataCheck*. If " 2213 "input data are OK and you critically need the ongoing calculations, " 2214 "try to change the observation LOS slightly. If you can reproduce " 2215 "this error, please contact Patrick in order to help tracking down " 2216 "the reason to this problem. If you see this message occasionally " 2217 "when doing MC calculations, it should not be critical. This path " 2218 "sampling will be rejected and replaced with a new one.");
2222 pha_mat_lab(0, 0) =
F11;
2224 if (stokes_dim > 1) {
2230 const Numeric ANGTOL_RAD = 1e-6;
2238 if ((
abs(theta_rad) < ANGTOL_RAD)
2239 || (
abs(theta_rad -
PI) < ANGTOL_RAD)
2241 (
abs(aa_inc_rad - aa_sca_rad) < ANGTOL_RAD)
2242 || (
abs(
abs(aa_inc_rad - aa_sca_rad) - 360.) < ANGTOL_RAD)
2243 || (
abs(
abs(aa_inc_rad - aa_sca_rad) - 180.) < ANGTOL_RAD)
2245 pha_mat_lab(0, 1) =
F12;
2246 pha_mat_lab(1, 0) =
F12;
2247 pha_mat_lab(1, 1) =
F22;
2249 if (stokes_dim > 2) {
2250 pha_mat_lab(0, 2) = 0;
2251 pha_mat_lab(1, 2) = 0;
2252 pha_mat_lab(2, 0) = 0;
2253 pha_mat_lab(2, 1) = 0;
2254 pha_mat_lab(2, 2) =
F33;
2256 if (stokes_dim > 3) {
2257 pha_mat_lab(0, 3) = 0;
2258 pha_mat_lab(1, 3) = 0;
2259 pha_mat_lab(2, 3) =
F34;
2260 pha_mat_lab(3, 0) = 0;
2261 pha_mat_lab(3, 1) = 0;
2262 pha_mat_lab(3, 2) = -
F34;
2263 pha_mat_lab(3, 3) =
F44;
2276 if (za_inc_rad < ANGTOL_RAD) {
2277 sigma1 =
PI + aa_sca_rad - aa_inc_rad;
2279 }
else if (za_inc_rad >
PI - ANGTOL_RAD) {
2280 sigma1 = aa_sca_rad - aa_inc_rad;
2282 }
else if (za_sca_rad < ANGTOL_RAD) {
2284 sigma2 =
PI + aa_sca_rad - aa_inc_rad;
2285 }
else if (za_sca_rad >
PI - ANGTOL_RAD) {
2287 sigma2 = aa_sca_rad - aa_inc_rad;
2289 s1 = (cos(za_sca_rad) - cos(za_inc_rad) * cos(theta_rad)) /
2290 (sin(za_inc_rad) * sin(theta_rad));
2291 s2 = (cos(za_inc_rad) - cos(za_sca_rad) * cos(theta_rad)) /
2292 (sin(za_sca_rad) * sin(theta_rad));
2300 if (std::isnan(sigma1) || std::isnan(sigma2)) {
2301 if (
abs(s1 - 1) < ANGTOL_RAD) sigma1 = 0;
2302 if (
abs(s1 + 1) < ANGTOL_RAD) sigma1 =
PI;
2303 if (
abs(s2 - 1) < ANGTOL_RAD) sigma2 = 0;
2304 if (
abs(s2 + 1) < ANGTOL_RAD) sigma2 =
PI;
2308 const Numeric C1 = cos(2 * sigma1);
2309 const Numeric C2 = cos(2 * sigma2);
2311 const Numeric S1 = sin(2 * sigma1);
2312 const Numeric S2 = sin(2 * sigma2);
2314 pha_mat_lab(0, 1) = C1 *
F12;
2315 pha_mat_lab(1, 0) = C2 *
F12;
2316 pha_mat_lab(1, 1) = C1 * C2 *
F22 - S1 * S2 *
F33;
2321 if (std::isnan(pha_mat_lab(0, 1)) || std::isnan(pha_mat_lab(1, 0)) ||
2322 std::isnan(pha_mat_lab(1, 1))) {
2323 throw runtime_error(
2324 "NaN value(s) detected in *pha_mat_labCalc* (0/1,1). Could the " 2325 "input data contain NaNs? Please check with *scat_dataCheck*. If " 2326 "input data are OK and you critically need the ongoing calculations, " 2327 "try to change the observation LOS slightly. If you can reproduce " 2328 "this error, please contact Patrick in order to help tracking down " 2329 "the reason to this problem. If you see this message occasionally " 2330 "when doing MC calculations, it should not be critical. This path " 2331 "sampling will be rejected and replaced with a new one.");
2334 if (stokes_dim > 2) {
2344 Numeric delta_aa = aa_sca - aa_inc + (aa_sca - aa_inc < -180) * 360 -
2345 (aa_sca - aa_inc > 180) * 360;
2346 if (delta_aa >= 0) {
2347 pha_mat_lab(0, 2) = S1 *
F12;
2348 pha_mat_lab(1, 2) = S1 * C2 *
F22 + C1 * S2 *
F33;
2349 pha_mat_lab(2, 0) = -S2 *
F12;
2350 pha_mat_lab(2, 1) = -C1 * S2 *
F22 - S1 * C2 *
F33;
2352 pha_mat_lab(0, 2) = -S1 *
F12;
2353 pha_mat_lab(1, 2) = -S1 * C2 *
F22 - C1 * S2 *
F33;
2354 pha_mat_lab(2, 0) = S2 *
F12;
2355 pha_mat_lab(2, 1) = C1 * S2 *
F22 + S1 * C2 *
F33;
2357 pha_mat_lab(2, 2) = -S1 * S2 *
F22 + C1 * C2 *
F33;
2359 if (stokes_dim > 3) {
2360 if (delta_aa >= 0) {
2361 pha_mat_lab(1, 3) = S2 *
F34;
2362 pha_mat_lab(3, 1) = S1 *
F34;
2364 pha_mat_lab(1, 3) = -S2 *
F34;
2365 pha_mat_lab(3, 1) = -S1 *
F34;
2367 pha_mat_lab(0, 3) = 0;
2368 pha_mat_lab(2, 3) = C2 *
F34;
2369 pha_mat_lab(3, 0) = 0;
2370 pha_mat_lab(3, 2) = -C1 *
F34;
2371 pha_mat_lab(3, 3) =
F44;
2379 os <<
"SingleScatteringData: Output operator not implemented";
2384 os <<
"ArrayOfSingleScatteringData: Output operator not implemented";
2389 os <<
"ScatteringMetaData: Output operator not implemented";
2394 os <<
"ArrayOfScatteringMetaData: Output operator not implemented";
2419 Index stokes_dim, freq_dim;
2421 if (propmat_clearsky.
nelem() > 1) {
2422 stokes_dim = propmat_clearsky[0].StokesDimensions();
2423 freq_dim = propmat_clearsky[0].NumberOfFrequencies();
2437 for (
auto&
pm : propmat_clearsky) {
2456 if (ptype_string ==
"general")
2458 else if (ptype_string ==
"totally_random")
2460 else if (ptype_string ==
"azimuthally_random")
2464 os <<
"Unknown ptype: " << ptype_string << endl
2465 <<
"Valid types are: general, totally_random and " 2466 <<
"azimuthally_random.";
2467 throw std::runtime_error(os.
str());
2486 if (ptype_string ==
"general")
2488 else if (ptype_string ==
"macroscopically_isotropic")
2490 else if (ptype_string ==
"horizontally_aligned")
2494 os <<
"Unknown ptype: " << ptype_string << endl
2495 <<
"Valid types are: general, macroscopically_isotropic and " 2496 <<
"horizontally_aligned.";
2497 throw std::runtime_error(os.
str());
2517 ptype_string =
"general";
2520 ptype_string =
"totally_random";
2523 ptype_string =
"azimuthally_random";
2527 os <<
"Internal error: Cannot map PType enum value " << ptype
2529 throw std::runtime_error(os.
str());
2533 return ptype_string;
2548 for (
Index i = 0;
i < nza / 2;
i++) {
2552 os <<
"Zenith grid of azimuthally_random single scattering data\n" 2553 <<
"is not symmetric with respect to 90degree.";
2554 throw std::runtime_error(os.
str());
2559 os <<
"Zenith grid of azimuthally_random single scattering data\n" 2560 <<
"does not contain 90 degree grid point.";
2561 throw std::runtime_error(os.
str());
2566 os_pha_mat <<
"pha_mat ";
2568 os_ext_mat <<
"ext_mat ";
2570 os_abs_vec <<
"abs_vec ";
2606 for (
Index i = 0;
i < nza / 2;
i++) {
2618 for (
Index i = 0;
i < nza / 2;
i++) {
2642 for (
Index i = 0;
i < nza / 2;
i++)
2643 for (
Index j = 0; j < nza; j++)
2659 const String& particle_ssdmethod_string) {
2661 if (particle_ssdmethod_string ==
"tmatrix")
2665 os <<
"Unknown particle SSD method: " << particle_ssdmethod_string << endl
2666 <<
"Valid methods: tmatrix";
2667 throw std::runtime_error(os.
str());
2670 return particle_ssdmethod;
2683 String particle_ssdmethod_string;
2685 switch (particle_ssdmethod) {
2687 particle_ssdmethod_string =
"tmatrix";
2691 os <<
"Internal error: Cannot map ParticleSSDMethod enum value " 2692 << particle_ssdmethod <<
" to String.";
2693 throw std::runtime_error(os.
str());
2697 return particle_ssdmethod_string;
Index npages() const
Returns the number of pages.
INDEX Index
The type to use for all integer numbers and indices.
Index nrows() const
Returns the number of rows.
void pha_mat_labCalc(MatrixView pha_mat_lab, ConstVectorView pha_mat_int, const Numeric &za_sca, const Numeric &aa_sca, const Numeric &za_inc, const Numeric &aa_inc, const Numeric &theta_rad)
Calculate phase matrix in laboratory coordinate system.
Index nelem() const
Number of elements.
void resize(Index s, Index b, Index p, Index r, Index c)
Resize function.
void pha_mat_NScatElems(ArrayOfArrayOfTensor6 &pha_mat, ArrayOfArrayOfIndex &ptypes, Matrix &t_ok, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &stokes_dim, const Vector &T_array, const Matrix &pdir_array, const Matrix &idir_array, const Index &f_index, const Index &t_interp_order)
Phase matrices from all scattering elements.
Declarations having to do with the four output streams.
Index nvitrines() const
Returns the number of vitrines.
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
void opt_prop_1ScatElem(Tensor5View ext_mat, Tensor4View abs_vec, Index &ptype, VectorView t_ok, const SingleScatteringData &ssd, const Vector &T_array, const Matrix &dir_array, const Index &f_start, const Index &t_interp_order)
Preparing extinction and absorption from one scattering element.
Index nrows() const
Returns the number of rows.
Index npages() const
Returns the number of pages.
void opt_prop_Bulk(Tensor5 &ext_mat, Tensor4 &abs_vec, Index &ptype, const ArrayOfTensor5 &ext_mat_ss, const ArrayOfTensor4 &abs_vec_ss, const ArrayOfIndex &ptypes_ss)
one-line descript
This file contains basic functions to handle XML data files.
Header file for interpolation.cc.
Index nbooks() const
Returns the number of books.
Stokes vector is as Propagation matrix but only has 4 possible values.
void opt_prop_sum_propmat_clearsky(PropagationMatrix &ext_mat, StokesVector &abs_vec, const ArrayOfPropagationMatrix &propmat_clearsky)
Get optical properties from propmat_clearsky.
Index nrows() const
Returns the number of rows.
void ConvertAzimuthallyRandomSingleScatteringData(SingleScatteringData &ssd)
Convert azimuthally-random oriented SingleScatteringData to latest version.
Index nelem() const
Returns the number of elements.
Structure to store a grid position.
This file contains the definition of Array.
Index ncols() const
Returns the number of columns.
VectorView K12(const Index iz=0, const Index ia=0)
Vector view to K(0, 1) elements.
Index TotalNumberOfElements(const Array< Array< base > > &aa)
Determine total number of elements in an ArrayOfArray.
The global header file for ARTS.
Index nshelves() const
Returns the number of shelves.
void pha_mat_ScatSpecBulk(ArrayOfTensor6 &pha_mat, ArrayOfIndex &ptype, const ArrayOfArrayOfTensor6 &pha_mat_se, const ArrayOfArrayOfIndex &ptypes_se, ConstMatrixView pnds, ConstMatrixView t_ok)
Scattering species bulk phase matrices.
ParticleSSDMethod ParticleSSDMethodFromString(const String &particle_ssdmethod_string)
Convert particle ssd method name to enum value.
VectorView K34(const Index iz=0, const Index ia=0)
Vector view to K(2, 3) elements.
bool is_same_within_epsilon(const Numeric &a, const Numeric &b, const Numeric &epsilon)
Check, if two numbers agree within a given epsilon.
_CS_string_type str() const
void abs_vec_SSD2Stokes(VectorView abs_vec_stokes, ConstVectorView abs_vec_ssd, const Index &stokes_dim, const Index &ptype)
Absorption vector scat_data to stokes format conversion.
Index ncols() const
Returns the number of columns.
PType
An attribute to classify the particle type (ptype) of a SingleScatteringData.
PType PTypeFromString(const String &ptype_string)
Convert ptype name to enum value.
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
void pha_mat_1ScatElem(Tensor6View pha_mat, Index &ptype, VectorView t_ok, const SingleScatteringData &ssd, const Vector &T_array, const Matrix &pdir_array, const Matrix &idir_array, const Index &f_start, const Index &t_interp_order)
Preparing phase matrix from one scattering element.
Index nrows() const
Returns the number of rows.
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
A constant view of a Tensor5.
NUMERIC Numeric
The type to use for all floating point numbers.
Index StokesDimensions() const
The stokes dimension of the propagation matrix.
Index nlibraries() const
Returns the number of libraries.
void gridpos_poly(ArrayOfGridPosPoly &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Index order, const Numeric &extpolfac)
The maximum difference from 1 that we allow for a sum check.
ParticleSSDMethod
An attribute to classify the method to be used for SingleScatteringData.
Header file for logic.cc.
Index NumberOfFrequencies() const
The number of frequencies of the propagation matrix.
This can be used to make arrays out of anything.
Index nshelves() const
Returns the number of shelves.
Index ncols() const
Returns the number of columns.
void opt_prop_ScatSpecBulk(ArrayOfTensor5 &ext_mat, ArrayOfTensor4 &abs_vec, ArrayOfIndex &ptype, const ArrayOfArrayOfTensor5 &ext_mat_se, const ArrayOfArrayOfTensor4 &abs_vec_se, const ArrayOfArrayOfIndex &ptypes_se, ConstMatrixView pnds, ConstMatrixView t_ok)
Scattering species bulk extinction and absorption.
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.
VectorView Kjj(const Index iz=0, const Index ia=0)
Vector view to diagonal elements.
void resize(Index n)
Resize function.
A constant view of a Tensor3.
void pha_matTransform(MatrixView pha_mat_lab, ConstTensor5View pha_mat_data, ConstVectorView za_datagrid, ConstVectorView aa_datagrid, const PType &ptype, const Index &za_sca_idx, const Index &aa_sca_idx, const Index &za_inc_idx, const Index &aa_inc_idx, ConstVectorView za_grid, ConstVectorView aa_grid, const Verbosity &verbosity)
Transformation of phase matrix.
A constant view of a Vector.
void FouComp_1ScatElem(Tensor7View pha_mat_fou, Index &ptype, VectorView t_ok, const SingleScatteringData &ssd, const Vector &T_array, const Vector &pdir_array, const Vector &idir_array, const Index &f_start, const Index &t_interp_order, const Index &naa_totran)
Preparing phase matrix fourier series components for one scattering element.
Index npages() const
Returns the number of pages.
Index nshelves() const
Returns the number of shelves.
Index nelem(const Lines &l)
Number of lines.
String PTypeToString(const PType &ptype)
Convert particle type enum value to String.
A constant view of a Matrix.
PType PType2FromString(const String &ptype_string)
Convert ptype name to enum value.
Index npages() const
Returns the number of pages.
Index nbooks() const
Returns the number of books.
void ssd_tinterp_parameters(VectorView t_ok, Index &this_T_interp_order, ArrayOfGridPosPoly &T_gp, Matrix &T_itw, ConstVectorView T_grid, const Vector &T_array, const Index &t_interp_order)
Determine T-interpol parameters for a specific scattering element.
void SetZero()
Sets all data to zero.
Structure to store a grid position for higher order interpolation.
void opt_prop_NScatElems(ArrayOfArrayOfTensor5 &ext_mat, ArrayOfArrayOfTensor4 &abs_vec, ArrayOfArrayOfIndex &ptypes, Matrix &t_ok, const ArrayOfArrayOfSingleScatteringData &scat_data, const Index &stokes_dim, const Vector &T_array, const Matrix &dir_array, const Index &f_index, const Index &t_interp_order)
Extinction and absorption from all scattering elements.
Index ncols() const
Returns the number of columns.
void pha_mat_Bulk(Tensor6 &pha_mat, Index &ptype, const ArrayOfTensor6 &pha_mat_ss, const ArrayOfIndex &ptypes_ss)
Scattering species bulk phase matrix.
void ext_mat_SSD2Stokes(MatrixView ext_mat_stokes, ConstVectorView ext_mat_ssd, const Index &stokes_dim, const Index &ptype)
Extinction matrix scat_data to stokes format conversion.
void interpolate_scat_angle(VectorView pha_mat_int, ConstTensor5View pha_mat_data, ConstVectorView za_datagrid, const Numeric theta)
Interpolate data on the scattering angle.
Index nvitrines() const
Returns the number of vitrines.
void abs_vecTransform(StokesVector &abs_vec_lab, ConstTensor3View abs_vec_data, ConstVectorView za_datagrid, ConstVectorView aa_datagrid, const PType &ptype, const Numeric &za_sca, const Numeric &aa_sca, const Verbosity &verbosity)
Transformation of absorption vector.
Index ncols() const
Returns the number of columns.
Index ncols() const
Returns the number of columns.
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
void resize(Index l, Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
Scattering database structure and functions.
void ext_matFromabs_vec(MatrixView ext_mat, ConstVectorView abs_vec, const Index &stokes_dim)
Derive extinction matrix from absorption vector.
Index nrows() const
Returns the number of rows.
Index nbooks() const
Returns the number of books.
ostream & operator<<(ostream &os, const SingleScatteringData &)
Numeric scat_angle(const Numeric &za_sca, const Numeric &aa_sca, const Numeric &za_inc, const Numeric &aa_inc)
Calculates the scattering angle.
void resize(Index r, Index c)
Resize function.
Index nbooks() const
Returns the number of books.