63 Index& ppath_inside_cloudbox_do,
65 Agenda& iy_cloudbox_agenda,
67 ArrayOfTensor4& dpnd_field_dx,
71 Index& scat_data_checked,
72 Matrix& particle_masses,
76 ppath_inside_cloudbox_do = 0;
77 cloudbox_limits.resize(0);
78 iy_cloudbox_agenda =
Agenda{ws};
79 iy_cloudbox_agenda.
set_name(
"iy_cloudbox_agenda");
80 pnd_field.resize(0, 0, 0, 0);
82 dpnd_field_dx.resize(jacobian_quantities.
nelem());
84 scat_species.resize(0);
87 scat_data_raw.resize(0);
88 scat_data_checked = 0;
89 particle_masses.resize(0, 0);
99 const Index& atmosphere_dim,
100 const Vector& p_grid,
101 const Vector& lat_grid,
102 const Vector& lon_grid,
103 const Tensor4& particle_field,
105 const Numeric& cloudbox_margin,
115 "cloudboxSetAutomatically not yet available for 2D and 3D cases.")
117 Index np = p_grid.nelem();
120 cloudbox_limits.resize(atmosphere_dim * 2);
123 Index p1 = np - 1, p2 = 0;
139 bool any_not_empty =
false;
141 if (!particle_field.empty()) {
142 bool one_not_empty =
false;
143 Index nss = particle_field.nbooks();
146 for (Index l = 0; l < nss; l++) {
151 Tensor3{particle_field(l, joker, joker, joker)},
160 any_not_empty =
true;
163 Tensor3{particle_field(l, joker, joker, joker)},
173 p1 =
max(p1 - 1, Index(0));
180 while ((p_grid[p1] < p_margin1) && (p1 > 0)) p1--;
181 cloudbox_limits[0] = p1;
185 p2 =
min(p2 + 1, np - 1);
190 out2 <<
"The cloud reaches to TOA!\n"
191 <<
"Check your *particle_field* data, if realistic!\n";
193 cloudbox_limits[1] = p2;
200 ARTS_ASSERT(p_grid[p1] > p_grid[p_grid.nelem() - 1]);
234 out0 <<
"Cloudbox is switched off!\n";
244 const Index& atmosphere_dim,
245 const Vector& p_grid,
246 const Vector& lat_grid,
247 const Vector& lon_grid,
248 const Index& fullfull,
251 cloudbox_limits.resize(2 * atmosphere_dim);
253 cloudbox_limits[0] = 0;
254 cloudbox_limits[1] = p_grid.
nelem() - 1;
256 if (atmosphere_dim > 1) {
258 cloudbox_limits[2] = 0;
259 cloudbox_limits[3] = lat_grid.
nelem() - 1;
261 Index last_lat = lat_grid.nelem() - 1;
265 while ((i < last_lat - 1) && (lat_grid[i] - lat_grid[0] < LAT_LON_MIN)) i++;
267 "Can not define lower latitude edge of cloudbox:\n"
268 "Extend of atmosphere too small. Distance to minimum latitude\n"
269 "has to be at least ", LAT_LON_MIN,
"deg, but only ",
270 lat_grid[i - 1] - lat_grid[0],
" available here.")
271 cloudbox_limits[2] = i;
275 Index j = last_lat - 1;
276 while ((j > i) && (lat_grid[last_lat] - lat_grid[j] < LAT_LON_MIN)) j--;
278 "Can not define upper latitude edge of cloudbox:\n"
279 "Extend of atmosphere too small. Distance to maximum latitude\n"
280 "has to be at least ", LAT_LON_MIN,
"deg, but only ",
281 lat_grid[last_lat] - lat_grid[j + 1],
" available here.")
282 cloudbox_limits[3] = j;
286 if (atmosphere_dim > 2) {
288 cloudbox_limits[4] = 0;
289 cloudbox_limits[5] = lon_grid.
nelem() - 1;
291 const Numeric latmax =
max(abs(lat_grid[cloudbox_limits[2]]),
292 abs(lat_grid[cloudbox_limits[3]]));
293 const Numeric lfac = 1 / cos(
DEG2RAD * latmax);
294 Index last_lon = lon_grid.nelem() - 1;
298 while ((i < last_lon - 1) &&
299 (lon_grid[i] - lon_grid[0] < LAT_LON_MIN / lfac))
302 "Can not define lower longitude edge of cloudbox:\n"
303 "Extend of atmosphere too small. Distance to minimum longitude\n"
304 "has to be at least ", LAT_LON_MIN / lfac,
"deg, but only ",
305 lon_grid[i - 1] - lon_grid[0],
" available here.")
306 cloudbox_limits[4] = i;
310 Index j = last_lon - 1;
311 while ((j > i) && (lon_grid[last_lon] - lon_grid[j] < LAT_LON_MIN / lfac))
314 "Can not define upper longitude edge of cloudbox:\n"
315 "Extend of atmosphere too small. Distance to maximum longitude\n"
316 "has to be at least ", LAT_LON_MIN / lfac,
"deg, but only ",
317 lon_grid[last_lon] - lon_grid[j + 1],
" available here.")
327 const Index& atmosphere_dim,
328 const Vector& p_grid,
329 const Vector& lat_grid,
330 const Vector& lon_grid,
345 "The pressure in *p1* must be bigger than the "
346 "pressure in *p2*.");
348 "The pressure in *p1* must be larger than the "
349 "last value in *p_grid*.");
351 "The pressure in *p2* must be smaller than the "
352 "first value in *p_grid*.");
353 if (atmosphere_dim >= 2) {
355 "The latitude in *lat2* must be bigger than the "
356 "latitude in *lat1*.");
358 "The latitude in *lat1* must be >= the "
359 "second value in *lat_grid*.");
361 "The latitude in *lat2* must be <= the "
362 "next to last value in *lat_grid*.");
364 if (atmosphere_dim == 3) {
366 "The longitude in *lon2* must be bigger than the "
367 "longitude in *lon1*.");
369 "The longitude in *lon1* must be >= the "
370 "second value in *lon_grid*.");
372 "The longitude in *lon2* must be <= the "
373 "next to last value in *lon_grid*.");
380 cloudbox_limits.resize(atmosphere_dim * 2);
383 if (p1 > p_grid[1]) {
384 cloudbox_limits[0] = 0;
386 for (cloudbox_limits[0] = 1; p_grid[cloudbox_limits[0] + 1] >= p1;
387 cloudbox_limits[0]++) {
390 if (p2 < p_grid[p_grid.nelem() - 2]) {
391 cloudbox_limits[1] = p_grid.
nelem() - 1;
393 for (cloudbox_limits[1] = p_grid.
nelem() - 2;
394 p_grid[cloudbox_limits[1] - 1] <= p2;
395 cloudbox_limits[1]--) {
400 if (atmosphere_dim >= 2) {
401 for (cloudbox_limits[2] = 1; lat_grid[cloudbox_limits[2] + 1] <= lat1;
402 cloudbox_limits[2]++) {
404 for (cloudbox_limits[3] = lat_grid.nelem() - 2;
405 lat_grid[cloudbox_limits[3] - 1] >= lat2;
406 cloudbox_limits[3]--) {
411 if (atmosphere_dim == 3) {
412 for (cloudbox_limits[4] = 1; lon_grid[cloudbox_limits[4] + 1] <= lon1;
413 cloudbox_limits[4]++) {
415 for (cloudbox_limits[5] = lon_grid.nelem() - 2;
416 lon_grid[cloudbox_limits[5] - 1] >= lon2;
417 cloudbox_limits[5]--) {
427 const Index& atmosphere_dim,
428 const Tensor3& z_field,
429 const Vector& lat_grid,
430 const Vector& lon_grid,
444 "The altitude in *z1* must be smaller than the "
445 "altitude in *z2*.");
454 if (atmosphere_dim == 3) {
456 "The latitude in *lat2* must be bigger than the "
457 " latitude in *lat1*.");
459 "The latitude in *lat1* must be >= the "
460 "second value in *lat_grid*.");
462 "The latitude in *lat2* must be <= the "
463 "next to last value in *lat_grid*.");
465 "The longitude in *lon2* must be bigger than the "
466 "longitude in *lon1*.");
468 "The longitude in *lon1* must be >= the "
469 "second value in *lon_grid*.");
471 "The longitude in *lon2* must be <= the "
472 "next to last value in *lon_grid*.");
479 cloudbox_limits.resize(atmosphere_dim * 2);
482 if (z1 < z_field(1, 0, 0)) {
483 cloudbox_limits[0] = 0;
485 for (cloudbox_limits[0] = 1; z_field(cloudbox_limits[0] + 1, 0, 0) <= z1;
486 cloudbox_limits[0]++) {
489 if (z2 > z_field(z_field.npages() - 2, 0, 0)) {
490 cloudbox_limits[1] = z_field.npages() - 1;
492 for (cloudbox_limits[1] = z_field.npages() - 2;
493 z_field(cloudbox_limits[1] - 1, 0, 0) >= z2;
494 cloudbox_limits[1]--) {
499 if (atmosphere_dim >= 2) {
500 for (cloudbox_limits[2] = 1; lat_grid[cloudbox_limits[2] + 1] <= lat1;
501 cloudbox_limits[2]++) {
503 for (cloudbox_limits[3] = lat_grid.nelem() - 2;
504 lat_grid[cloudbox_limits[3] - 1] >= lat2;
505 cloudbox_limits[3]--) {
510 if (atmosphere_dim == 3) {
511 for (cloudbox_limits[4] = 1; lon_grid[cloudbox_limits[4] + 1] <= lon1;
512 cloudbox_limits[4]++) {
514 for (cloudbox_limits[5] = lon_grid.nelem() - 2;
515 lon_grid[cloudbox_limits[5] - 1] >= lon2;
516 cloudbox_limits[5]--) {
523 const Tensor7& cloudbox_field,
524 const Vector& rte_pos,
525 const Vector& rte_los,
526 const Index& jacobian_do,
527 const Index& cloudbox_on,
529 const Index& atmosphere_dim,
530 const Vector& p_grid,
531 const Vector& lat_grid,
532 const Vector& lon_grid,
533 const Tensor3& z_field,
534 const Matrix& z_surface,
535 const Index& stokes_dim,
536 const Vector& za_grid,
537 const Vector& aa_grid,
538 const Vector& f_grid,
540 const Index& za_interp_order,
541 const Index& za_restrict,
542 const Index& cos_za_interp,
543 const Numeric& za_extpolfac,
544 const Index& aa_interp_order,
548 "The atmospheric dimensionality must be 1 or 3.");
550 "This method does not support jacobians (jacobian_do must be 0)");
552 "The cloud box is not activated and no outgoing "
553 "field can be returned.");
555 "*cloudbox_limits* is a vector which contains the upper and lower\n"
556 "limit of the cloud for all atmospheric dimensions.\n"
557 "So its length must be 2 x *atmosphere_dim*");
559 "The variable *za_grid* is empty. Are dummy "
560 "values from *cloudboxOff used?");
562 "Zenith angle interpolation order *za_interp_order*"
564 "than number of angles in *za_grid*.");
566 "Azimuth angle interpolation order *aa_interp_order*"
568 "than number of angles in *aa_grid*.");
570 "Inconsistency in size between f_grid and cloudbox_field! "
571 "(This method does not yet handle dispersion type calculations.)");
576 Tensor3 z_with_surface = z_field;
577 for (Index ilat = 0; ilat < z_surface.nrows(); ilat++) {
578 for (Index ilon = 0; ilon < z_surface.ncols(); ilon++) {
580 while (z_surface(ilat, ilon) >= z_field(ip + 1, ilat, ilon)) {
583 z_with_surface(ip, ilat, ilon) = z_surface(ilat, ilon);
611 }
else if (atmosphere_dim > 1) {
616 }
else if (atmosphere_dim > 2) {
635 if (fgp < Numeric(cloudbox_limits[0]) ||
636 fgp > Numeric(cloudbox_limits[1])) {
641 if (atmosphere_dim == 3 && inside) {
643 if (fgp < Numeric(cloudbox_limits[2]) ||
644 fgp > Numeric(cloudbox_limits[3])) {
648 if (fgp < Numeric(cloudbox_limits[4]) ||
649 fgp > Numeric(cloudbox_limits[5])) {
661 "Given position has been found to be outside the cloudbox.");
664 const Index nf = f_grid.nelem();
665 DEBUG_ONLY(
const Index np = cloudbox_limits[1] - cloudbox_limits[0] + 1);
666 const Index nza = za_grid.nelem();
667 const Index naa = cloudbox_field.nrows();
670 iy.resize(nf, stokes_dim);
673 Tensor4 i_field_local(nf, nza, naa, stokes_dim);
680 border_index = cloudbox_limits[border] - cloudbox_limits[border - 1];
688 "Radiation extraction for a position inside cloudbox\n"
689 "is not yet implemented for 3D cases.\n");
692 ARTS_ASSERT(is_size(cloudbox_field, nf, np, 1, 1, nza, 1, stokes_dim));
695 gp_p.
idx = gp_p.
idx - cloudbox_limits[0];
700 for (Index is = 0; is < stokes_dim; is++)
701 for (Index iv = 0; iv < nf; iv++)
702 for (Index i_za = 0; i_za < nza; i_za++)
703 i_field_local(iv, i_za, 0, is) =
interp(
704 itw_p, cloudbox_field(iv, joker, 0, 0, i_za, 0, is), gp_p);
710 else if (atmosphere_dim == 1) {
712 cloudbox_field(joker, border_index, 0, 0, joker, joker, joker);
719 cloudbox_field.nvitrines(),
720 cloudbox_field.nshelves(),
721 cloudbox_field.nbooks(),
735 cb_gp_lat.
idx -= cloudbox_limits[2];
736 cb_gp_lon.
idx -= cloudbox_limits[4];
739 cloudbox_limits[3] - cloudbox_limits[2]);
741 cloudbox_limits[5] - cloudbox_limits[4]);
745 for (Index is = 0; is < stokes_dim; is++)
746 for (Index iv = 0; iv < nf; iv++)
747 for (Index i_za = 0; i_za < nza; i_za++)
748 for (Index i_aa = 0; i_aa < naa; i_aa++)
749 i_field_local(iv, i_za, i_aa, is) =
752 iv, border_index, joker, joker, i_za, i_aa, is),
758 else if (border <= 3) {
763 cb_gp_p.
idx -= cloudbox_limits[0];
764 cb_gp_lon.
idx -= cloudbox_limits[4];
768 cloudbox_limits[5] - cloudbox_limits[4]);
772 for (Index is = 0; is < stokes_dim; is++)
773 for (Index iv = 0; iv < nf; iv++)
774 for (Index i_za = 0; i_za < nza; i_za++)
775 for (Index i_aa = 0; i_aa < naa; i_aa++)
776 i_field_local(iv, i_za, i_aa, is) =
779 iv, joker, border_index, joker, i_za, i_aa, is),
790 cb_gp_p.
idx -= cloudbox_limits[0];
791 cb_gp_lat.
idx -= cloudbox_limits[2];
795 cloudbox_limits[3] - cloudbox_limits[2]);
799 for (Index is = 0; is < stokes_dim; is++)
800 for (Index iv = 0; iv < nf; iv++)
801 for (Index i_za = 0; i_za < nza; i_za++)
802 for (Index i_aa = 0; i_aa < naa; i_aa++)
803 i_field_local(iv, i_za, i_aa, is) =
806 iv, joker, joker, border_index, i_za, i_aa, is),
821 Index za_extend = za_grid.nelem();
827 "Hemisphere-restricted zenith angle interpolation not allowed\n"
828 "for 90degree views.");
829 if (rte_los[0] > 90) {
833 while (za_start < za_grid.nelem() && za_grid[za_start] < 90.) {
837 "No za_grid grid point found in 90-180deg hemisphere.\n"
838 "No hemispheric interpolation possible.");
839 za_extend -= za_start;
844 while (za_extend > 0 && za_grid[za_extend - 1] > 90.) {
848 "No za_grid grid point found in 0-90deg hemisphere.\n"
849 "No hemispheric interpolation possible.");
852 "Zenith angle interpolation order *za_interp_order* (",
853 za_interp_order,
") must be smaller\n"
854 "than number of angles in respective hemisphere (", za_extend,
858 const auto range = Range(za_start, za_extend);
859 const ConstVectorView za_g(za_grid[range]);
862 LagrangeInterpolation::check(za_g, za_interp_order, rte_los[0], za_extpolfac);
865 const auto lag_aa = (atmosphere_dim > 1) ?
866 my_interp::Lagrange<-1, false, my_interp::GridType::Cyclic, my_interp::cycle_m180_p180>(0, rte_los[1], aa_grid, aa_interp_order) :
867 my_interp::Lagrange<-1,
false, my_interp::GridType::Cyclic, my_interp::cycle_m180_p180>();
871 const auto lag_za = my_interp::Lagrange<-1,
false, my_interp::GridType::CosDeg>(0, rte_los[0], za_g, za_interp_order);
876 for (Index is = 0; is < stokes_dim; is++) {
877 for (Index iv = 0; iv < nf; iv++) {
879 interp(i_field_local(iv, range, joker, is),
886 const auto lag_za = LagrangeInterpolation(0, rte_los[0], za_g, za_interp_order);
891 for (Index is = 0; is < stokes_dim; is++) {
892 for (Index iv = 0; iv < nf; iv++) {
894 interp(i_field_local(iv, range, joker, is),
905 Tensor7& cloudbox_field,
906 const Index& cloudbox_on,
907 const Vector& aa_grid,
908 const Numeric& local_los_azimuth_angle,
909 const Index& aa_interp_order,
913 "No need to use this method with cloudbox=0.");
915 "Azimuth angle interpolation order *aa_interp_order*"
917 "than number of angles in *aa_grid*.");
920 if (cloudbox_field.nrows()>1 && aa_grid.nelem()==cloudbox_field.nrows()){
921 Index nf = cloudbox_field.nlibraries();
922 Index np = cloudbox_field.nvitrines();
923 Index nla= cloudbox_field.nshelves();
924 Index nlo= cloudbox_field.nbooks();
925 Index nz = cloudbox_field.npages();
926 Index ns = cloudbox_field.ncols();
928 const Tensor7 cloudbox_field_in = std::move(cloudbox_field);
929 Numeric azimuth_los = local_los_azimuth_angle;
932 if (azimuth_los<0) azimuth_los+=360;
934 cloudbox_field.resize(nf,np,1,1,nz,1,ns);
937 const auto lag_aa = LagrangeCyclic0to360Interpolation(0,
945 for (Index jf = 0; jf < nf; jf++) {
946 for (Index jp = 0; jp < np; jp++) {
947 for (Index jla = 0; jla < nla; jla++) {
948 for (Index jlo = 0; jlo < nlo; jlo++) {
949 for (Index jz = 0; jz < nz; jz++) {
950 for (Index js = 0; js < ns; js++) {
951 cloudbox_field(jf, jp, jla, jlo, jz, 0, js) =
952 interp(cloudbox_field_in(jf, jp, jla, jlo, jz, joker, js),
967 const Index& atmosphere_dim,
968 const Index& cloudbox_on,
969 const Index& new_limit0,
970 const Index& new_limit1,
971 const Index& new_limit2,
972 const Index& new_limit3,
973 const Index& new_limit4,
974 const Index& new_limit5,
977 "No need to use this method with cloudbox=0.");
979 "new_limits0 < cloudbox_limits[0], not allowed!");
981 "new_limits1 > cloudbox_limits[1], not allowed!");
983 Tensor7 fcopy = cloudbox_field;
985 if (atmosphere_dim == 1) {
986 cloudbox_field = fcopy(
988 Range(new_limit0 - cloudbox_limits[0], new_limit1 - new_limit0 + 1),
994 cloudbox_limits[0] = new_limit0;
995 cloudbox_limits[1] = new_limit1;
998 "new_limits2 < cloudbox_limits[2], not allowed!");
1000 "new_limits3 > cloudbox_limits[3], not allowed!");
1002 if (atmosphere_dim == 2) {
1003 cloudbox_field = fcopy(
1005 Range(new_limit0 - cloudbox_limits[0], new_limit1 - new_limit0 + 1),
1006 Range(new_limit2 - cloudbox_limits[2], new_limit3 - new_limit2 - 1),
1011 cloudbox_limits[0] = new_limit0;
1012 cloudbox_limits[1] = new_limit1;
1013 cloudbox_limits[2] = new_limit2;
1014 cloudbox_limits[3] = new_limit3;
1017 "new_limits4 < cloudbox_limits[4], not allowed!");
1019 "new_limits5 > cloudbox_limits[5], not allowed!");
1020 cloudbox_field = fcopy(
1022 Range(new_limit0 - cloudbox_limits[0], new_limit1 - new_limit0 + 1),
1023 Range(new_limit2 - cloudbox_limits[2], new_limit3 - new_limit2 + 1),
1024 Range(new_limit4 - cloudbox_limits[4], new_limit5 - new_limit4 + 1),
1028 cloudbox_limits[0] = new_limit0;
1029 cloudbox_limits[1] = new_limit1;
1030 cloudbox_limits[2] = new_limit2;
1031 cloudbox_limits[3] = new_limit3;
1032 cloudbox_limits[4] = new_limit4;
1033 cloudbox_limits[5] = new_limit5;
1040 Tensor4& particle_field_out,
1042 const Tensor4& particle_field_in,
1043 const Numeric& threshold,
1045 if (&particle_field_out != &particle_field_in) {
1046 particle_field_out = particle_field_in;
1051 for (Index i = 0; i < particle_field_out.nbooks(); i++) {
1052 for (Index j = 0; j < particle_field_out.npages(); j++) {
1053 for (Index k = 0; k < particle_field_out.nrows(); k++) {
1054 for (Index l = 0; l < particle_field_out.ncols(); l++) {
1055 if (particle_field_out(i, j, k, l) < threshold) {
1056 particle_field_out(i, j, k, l) = 0.0;
1069 Index& scat_data_checked,
1072 scat_species.resize(0);
1073 scat_data_raw.resize(0);
1074 scat_meta.resize(0);
1075 pnd_field_raw.resize(0);
1076 scat_data_checked = 0;
1084 const Index& atmosphere_dim,
1100 "Number of elements in scat_data and pnd_field filelists is"
1103 Index last_species = scat_data_raw.
nelem() - 1;
1104 if (last_species == -1) {
1105 scat_data_raw.resize(1);
1113 for (Index i = 0; i < scat_data_files.
nelem(); i++) {
1115 scat_data_raw[last_species].push_back(scat_data_single);
1116 pnd_field_raw.push_back(pnd_field_data);
1118 out2 <<
" Read single scattering data file " << scat_data_files[i] <<
"\n";
1121 scat_data_raw[last_species][scat_data_raw[last_species].nelem() - 1],
1124 out2 <<
" Read particle number density field\n";
1125 if (pnd_field_files[i].nelem() < 1) {
1127 out1 <<
"Warning: No pnd_field_file specified. Ignored here,\n"
1128 <<
"but user HAS TO add that later on!. \n";
1131 pnd_field_raw[pnd_field_raw.
nelem() - 1],
1147 const Index& atmosphere_dim,
1150 const String& pnd_fieldarray_file,
1162 arr_ssd.resize(scat_data_files.
nelem());
1164 for (Index i = 0; i < scat_data_files.
nelem(); i++) {
1165 out2 <<
" Read single scattering data file " << scat_data_files[i] <<
"\n";
1170 if (scat_data_raw.
nelem() == 0) {
1171 scat_data_raw.resize(1);
1172 scat_data_raw[0] = arr_ssd;
1174 scat_data_raw.push_back(arr_ssd);
1176 out2 <<
" Read particle number density data \n";
1183 for (Index i = 0; i < pnd_tmp.
nelem(); ++i)
1184 pnd_field_raw.push_back(pnd_tmp[i]);
1192 Index& propmat_clearsky_agenda_checked,
1194 const Index& atmosphere_dim,
1195 const Vector& f_grid,
1215 "Number of elements in scat_data and pnd_field filelists is"
1218 Index last_species = scat_data_raw.
nelem() - 1;
1219 if (last_species == -1) {
1220 scat_data_raw.resize(1);
1228 species[0] =
"particles";
1230 for (Index i = 0; i < scat_data_files.
nelem(); i++) {
1232 scat_data_raw[last_species].push_back(scat_data_single);
1233 vmr_field_raw.push_back(pnd_field_data);
1235 out2 <<
" Read single scattering data file " << scat_data_files[i] <<
"\n";
1238 scat_data_raw[last_species][scat_data_raw[last_species].nelem() - 1],
1241 out2 <<
" Check single scattering properties\n";
1243 "scat_data_single.f_grid to f_grid",
1244 scat_data_raw[last_species][scat_data_raw[last_species].nelem() - 1]
1248 out2 <<
" Read particle number density field\n";
1249 if (pnd_field_files[i].nelem() < 1) {
1251 out1 <<
"Warning: No pnd_field_file specified. Ignored here,\n"
1252 <<
"but user HAS TO add that later on!\n";
1256 vmr_field_raw[vmr_field_raw.
nelem() - 1],
1262 if (tmp.
nelem() == 1) {
1263 vmr_field_raw[vmr_field_raw.
nelem() - 1] = tmp[0];
1266 "The file ", pnd_field_files[i],
"\n"
1267 "is neither GriddedField3 nor a 1-long ArrayOfGriddedField3.\n")
1271 "The file ", pnd_field_files[i],
" does not exist or\n"
1272 "its type is neither GriddedField3 nor a 1-long ArrayOfGriddedField3.\n")
1282 out2 <<
" Append 'particle' field to abs_species\n";
1284 propmat_clearsky_agenda_checked,
1305 arr_ssd.resize(scat_data_files.
nelem());
1306 arr_smd.resize(scat_data_files.
nelem());
1308 Index meta_naming_conv = 0;
1310 for (Index i = 0; i < 1 && i < scat_data_files.
nelem(); i++) {
1311 out3 <<
" Read single scattering data file " << scat_data_files[i] <<
"\n";
1319 scat_data_files[i].
split(strarr,
".xml");
1320 scat_meta_file = strarr[0] +
".meta.xml";
1324 }
catch (
const runtime_error&) {
1328 out3 <<
" Read scattering meta data\n";
1332 meta_naming_conv = 1;
1335 scat_data_files[i].split(strarr,
"scat_data");
1337 "Splitting scattering data filename up at 'scat_data' also failed.");
1338 scat_meta_file = strarr[0] +
"scat_meta" + strarr[1];
1340 out3 <<
" Read scattering meta data\n";
1343 meta_naming_conv = 2;
1344 }
catch (
const std::runtime_error& e) {
1346 "No meta data file following one of the allowed naming "
1347 "conventions was found.\n"
1349 "*.meta.xml from *.xml and "
1350 "*scat_meta* from *scat_data*\n"
1351 "Scattering meta data file not found: ", scat_meta_file,
1361#pragma omp parallel for if (!arts_omp_in_parallel() && \
1362 scat_data_files.nelem() > 1) \
1363 num_threads(arts_omp_get_max_threads() > 16 ? 16 \
1364 : arts_omp_get_max_threads()) \
1365 shared(out3, scat_data_files, arr_ssd, arr_smd)
1366 for (Index i = 1; i < scat_data_files.
nelem(); i++) {
1374 out3 <<
" Read single scattering data file " << scat_data_files[i]
1378 scat_data_files[i].split(strarr,
".xml");
1379 scat_meta_file = strarr[0] +
".meta.xml";
1381 if (meta_naming_conv == 1) {
1382 scat_data_files[i].split(strarr,
".xml");
1383 scat_meta_file = strarr[0] +
".meta.xml";
1385 out3 <<
" Read scattering meta data\n";
1388 scat_data_files[i].split(strarr,
"scat_data");
1389 scat_meta_file = strarr[0] +
"scat_meta" + strarr[1];
1391 out3 <<
" Read scattering meta data\n";
1394 }
catch (
const std::exception& e) {
1396 os <<
"Run-time error reading scattering data : \n" << e.what();
1397#pragma omp critical(ybatchCalc_push_fail_msg)
1398 fail_msg.push_back(os.str());
1404#pragma omp critical(ScatSpeciesScatAndMetaRead_assign_ssd)
1405 arr_ssd[i] = std::move(ssd);
1406#pragma omp critical(ScatSpeciesScatAndMetaRead_assign_smd)
1407 arr_smd[i] = std::move(smd);
1410 if (fail_msg.
nelem()) {
1411 std::ostringstream os;
1412 for (
auto& msg : fail_msg) os << msg <<
'\n';
1421 scat_data_raw.push_back(std::move(arr_ssd));
1422 scat_meta.push_back(std::move(arr_smd));
1433 const Numeric& sizemin,
1434 const Numeric& sizemax,
1435 const Numeric& tolerance,
1439 Index nspecies = scat_species.
nelem();
1441 "Number of scattering species specified by scat_species does\n"
1442 "not agree with number of scattering species in\n"
1443 "scat_data_raw or scat_meta:\n"
1444 "scat_species has ", nspecies,
1445 " entries, while scat_data_raw has ", scat_data_raw.
nelem(),
1446 " and scat_meta has ", scat_meta.
nelem(),
".")
1456 for (Index i = 0; i < scat_species.
nelem(); i++) {
1458 if (partfield_name == species) i_ss = i;
1461 "Scattering species ", species,
" not found among scat_species.")
1464 if (sizeparam ==
"diameter_max")
1465 for (Index i_se = 0; i_se < scat_meta[i_ss].
nelem(); i_se++) {
1470 if (scat_meta[i_ss][i_se].diameter_max > sizemin - sizemin * tolerance &&
1471 (sizemax + sizemax * tolerance > scat_meta[i_ss][i_se].diameter_max ||
1474 scat_data_raw_tmp.push_back(scat_data_raw[i_ss][i_se]);
1475 scat_meta_tmp.push_back(scat_meta[i_ss][i_se]);
1478 else if (sizeparam ==
"diameter_volume_equ")
1479 for (Index i_se = 0; i_se < scat_meta[i_ss].
nelem(); i_se++) {
1480 if (scat_meta[i_ss][i_se].diameter_volume_equ >
1481 sizemin - sizemin * tolerance &&
1482 (sizemax + sizemax * tolerance >
1483 scat_meta[i_ss][i_se].diameter_volume_equ ||
1486 scat_data_raw_tmp.push_back(scat_data_raw[i_ss][i_se]);
1487 scat_meta_tmp.push_back(scat_meta[i_ss][i_se]);
1490 else if (sizeparam ==
"diameter_area_equ_aerodynamical")
1491 for (Index i_se = 0; i_se < scat_meta[i_ss].
nelem(); i_se++) {
1492 if (scat_meta[i_ss][i_se].diameter_area_equ_aerodynamical >
1493 sizemin - sizemin * tolerance &&
1494 (sizemax + sizemax * tolerance >
1495 scat_meta[i_ss][i_se].diameter_area_equ_aerodynamical ||
1498 scat_data_raw_tmp.push_back(scat_data_raw[i_ss][i_se]);
1499 scat_meta_tmp.push_back(scat_meta[i_ss][i_se]);
1504 "Size parameter ", sizeparam,
"is unknown.")
1511 "For scattering species ", species,
" no scattering "
1512 "element matching the requested size range found.\n"
1513 "Check *scat_data_raw* and *scat_meta* input as well as your size limit "
1516 scat_meta[i_ss] = std::move(scat_meta_tmp);
1517 scat_data_raw[i_ss] = std::move(scat_data_raw_tmp);
1531 const String& scat_species_delim,
1532 const Numeric& T_low,
1533 const Numeric& T_high,
1535 const bool do_tl = (T_low >= 0.);
1536 const bool do_th = (T_high >= 0.);
1538 if (do_tl || do_th) {
1540 if (species ==
"") {
1541 i_ss = scat_data_raw.
nelem() - 1;
1543 "No *scat_data* available. Can not extend temperature range on "
1547 Index nspecies = scat_species.
nelem();
1549 "Number of scattering species specified by scat_species does\n"
1550 "not agree with number of scattering species in *scat_data*:\n"
1551 "scat_species has ", nspecies,
1552 " entries, while *scat_data* has ", scat_data_raw.
nelem(),
1557 for (Index i = 0; i < scat_species.
nelem(); i++) {
1559 partfield_name, scat_species[i], scat_species_delim);
1560 if (partfield_name == species) i_ss = i;
1563 "Scattering species ", species,
" not found among scat_species.")
1566 for (Index i_se = 0; i_se < scat_data_raw[i_ss].
nelem(); i_se++) {
1568 const Index nTo = ssdo.
T_grid.nelem();
1570 bool do_htl, do_hth;
1572 do_htl = (do_tl && (T_low < ssdo.
T_grid[0]));
1573 do_hth = (do_th && (T_high >
last(ssdo.
T_grid)));
1579 if (do_htl || do_hth) {
1585 if (do_htl) nTn += 1;
1586 if (do_hth) nTn += 1;
1587 Vector T_grid_new(nTn);
1589 T_grid_new[0] = T_low;
1594 for (Index iT = 0; iT < nTo; iT++)
1595 T_grid_new[iT + iToff] = scat_data_raw[i_ss][i_se].T_grid[iT];
1596 if (do_hth) T_grid_new[nTo + iToff] = T_high;
1597 ssdn.
T_grid = std::move(T_grid_new);
1601 ostringstream description;
1609 const Index nf = ssdo.
f_grid.nelem();
1619 ssdn.
pha_mat_data.resize(nf, nTn, nzas, naas, nzai, naai, nmep);
1624 for (Index iT = 0; iT < nTo; iT++) {
1626 joker, iT + iToff, joker, joker, joker, joker, joker) =
1627 ssdo.
pha_mat_data(joker, iT, joker, joker, joker, joker, joker);
1628 ssdn.
ext_mat_data(joker, iT + iToff, joker, joker, joker) =
1630 ssdn.
abs_vec_data(joker, iT + iToff, joker, joker, joker) =
1636 ssdn.
pha_mat_data(joker, 0, joker, joker, joker, joker, joker) =
1637 ssdn.
pha_mat_data(joker, 1, joker, joker, joker, joker, joker);
1643 <<
"Low temperature limit extended by"
1644 <<
" duplicating previous low temperature limit"
1645 <<
" single scattering properties.";
1648 ssdn.
pha_mat_data(joker, nTn - 1, joker, joker, joker, joker, joker) =
1650 joker, nTn - 2, joker, joker, joker, joker, joker);
1651 ssdn.
ext_mat_data(joker, nTn - 1, joker, joker, joker) =
1652 ssdn.
ext_mat_data(joker, nTn - 2, joker, joker, joker);
1653 ssdn.
abs_vec_data(joker, nTn - 1, joker, joker, joker) =
1654 ssdn.
abs_vec_data(joker, nTn - 2, joker, joker, joker);
1656 <<
"High temperature limit extended by"
1657 <<
" duplicating previous high temperature limit"
1658 <<
" single scattering properties.";
1661 scat_data_raw[i_ss][i_se] = std::move(ssdn);
1670 ArrayOfTensor4& dpnd_field_dx,
1672 const Vector& p_grid,
1673 const Vector& lat_grid,
1674 const Vector& lon_grid,
1676 const Index& atmosphere_dim,
1679 const Index& zeropadding,
1686 "No particle number density data given. Please use WSMs\n"
1687 "*ParticleTypeInit* and *ParticleTypeAdd(All)* for reading\n"
1688 "scattering element data.\n")
1719 "*cloudbox_limits* is a vector which contains the"
1720 "upper and lower limit of the cloud for all "
1721 "atmospheric dimensions. So its dimension must"
1722 "be 2 x *atmosphere_dim*");
1723 cloudbox_limits_tmp = cloudbox_limits;
1728 for (Index
d = 0;
d < atmosphere_dim;
d++) {
1729 for (Index i = 0; i < pnd_field_raw.
nelem(); i++) {
1731 "Error in pnd_field_raw data. "
1732 "Dimension ",
d,
" (name: \"",
1733 pnd_field_raw[i].get_grid_name(
d),
1735 pnd_field_raw[i].get_grid_size(
d),
1737 ((pnd_field_raw[i].get_grid_size(
d) == 1) ?
"" :
"s"),
1738 ". Must be at least 2.")
1741 const Index Np_cloud = cloudbox_limits_tmp[1] - cloudbox_limits_tmp[0] + 1;
1743 ConstVectorView p_grid_cloud =
1744 p_grid[Range(cloudbox_limits_tmp[0], Np_cloud)];
1752 cloudbox_limits_tmp);
1755 if (atmosphere_dim == 1) {
1759 pnd_field_tmp, Vector{p_grid_cloud}, pnd_field_raw, 1, zeropadding, verbosity);
1762 Vector{p_grid_cloud},
1763 pnd_field_tmp[0].get_numeric_grid(1),
1764 pnd_field_tmp[0].get_numeric_grid(2),
1767 }
else if (atmosphere_dim == 2) {
1768 const Index Nlat_cloud =
1769 cloudbox_limits_tmp[3] - cloudbox_limits_tmp[2] + 1;
1771 ConstVectorView lat_grid_cloud =
1772 lat_grid[Range(cloudbox_limits_tmp[2], Nlat_cloud)];
1777 out0 <<
"WARNING: zeropadding currently only supported for 1D.";
1781 pnd_field.resize(pnd_field_raw.
nelem(), Np_cloud, Nlat_cloud, 1);
1789 for (Index i = 0; i < pnd_field_raw.
nelem(); ++i) {
1792 pnd_field_raw[i].get_numeric_grid(GFIELD3_P_GRID),
1795 pnd_field_raw[i].get_numeric_grid(GFIELD3_LAT_GRID),
1799 Tensor3 itw(Np_cloud, Nlat_cloud, 4);
1803 interp(pnd_field(i, joker, joker, 0),
1805 pnd_field_raw[i].data(joker, joker, 0),
1810 const Index Nlat_cloud =
1811 cloudbox_limits_tmp[3] - cloudbox_limits_tmp[2] + 1;
1812 const Index Nlon_cloud =
1813 cloudbox_limits_tmp[5] - cloudbox_limits_tmp[4] + 1;
1818 out0 <<
"WARNING: zeropadding currently only supported for 1D.";
1821 ConstVectorView lat_grid_cloud =
1822 lat_grid[Range(cloudbox_limits_tmp[2], Nlat_cloud)];
1823 ConstVectorView lon_grid_cloud =
1824 lon_grid[Range(cloudbox_limits_tmp[4], Nlon_cloud)];
1827 pnd_field.resize(pnd_field_raw.
nelem(), Np_cloud, Nlat_cloud, Nlon_cloud);
1836 for (Index i = 0; i < pnd_field_raw.
nelem(); ++i) {
1839 pnd_field_raw[i].get_numeric_grid(GFIELD3_P_GRID),
1842 pnd_field_raw[i].get_numeric_grid(GFIELD3_LAT_GRID),
1845 pnd_field_raw[i].get_numeric_grid(GFIELD3_LON_GRID),
1849 Tensor4 itw(Np_cloud, Nlat_cloud, Nlon_cloud, 8);
1853 interp(pnd_field(i, joker, joker, joker),
1855 pnd_field_raw[i].data,
1864 dpnd_field_dx.resize(jacobian_quantities.
nelem());
1869 const Index& atmosphere_dim,
1870 const Index& cloudbox_on,
1879 "No use in calling this method for 1D.");
1881 "No use in calling this method with cloudbox off.");
1883 "The argument *nzero* must be > 0.");
1886 const Index npart = pnd_field.nbooks();
1887 const Index np = cloudbox_limits[1] - cloudbox_limits[0] + 1;
1888 const Index nlat = cloudbox_limits[3] - cloudbox_limits[2] + 1;
1890 if (atmosphere_dim == 3) {
1891 nlon = cloudbox_limits[5] - cloudbox_limits[4] + 1;
1895 pnd_field.nrows() != 1 ||
1896 pnd_field.ncols() != 1,
1897 "The input *pnd_field* is either not 1D or does not "
1898 "match pressure size of cloudbox.");
1901 Tensor4 pnd_temp = pnd_field;
1904 pnd_field.resize(npart, np, nlat, nlon);
1907 for (Index ilon = nzero; ilon < nlon - nzero; ilon++) {
1908 for (Index ilat = nzero; ilat < nlat - nzero; ilat++) {
1909 for (Index ip = 0; ip < np; ip++) {
1910 for (Index is = 0; is < npart; is++) {
1911 pnd_field(is, ip, ilat, ilon) = pnd_temp(is, ip, 0, 0);
1921 ArrayOfTensor4& dpnd_field_dx,
1924 const Index& atmosphere_dim,
1925 const Vector& f_grid,
1932 "*cloudbox_limits* is a vector which contains the"
1933 "upper and lower limit of the cloud for all "
1934 "atmospheric dimensions. So its dimension must"
1935 "be 2 x *atmosphere_dim*");
1938 Index np = cloudbox_limits[1] - cloudbox_limits[0] + 1;
1939 Index nlat = 1, nlon = 1;
1940 if (atmosphere_dim > 1) {
1941 nlat = cloudbox_limits[3] - cloudbox_limits[2] + 1;
1942 if (atmosphere_dim > 2) {
1943 nlon = cloudbox_limits[5] - cloudbox_limits[4] + 1;
1949 dpnd_field_dx.resize(jacobian_quantities.
nelem());
1957 pnd_field.resize(N_se, np, nlat, nlon);
1959 pnd_field.resize(1, np, nlat, nlon);
1963 scat_data.resize(1);
1964 scat_data[0].resize(1);
1966 scat_data[0][0].description =
" ";
1968 Index nf = f_grid.
nelem();
1969 scat_data[0][0].f_grid.resize(nf);
1970 scat_data[0][0].f_grid = f_grid;
1972 scat_data[0][0].T_grid.resize(nT);
1973 scat_data[0][0].T_grid = 270.;
1975 nlinspace(scat_data[0][0].za_grid, 0, 180, nza);
1977 scat_data[0][0].pha_mat_data.resize(nf, nT, nza, 1, 1, 1, 6);
1978 scat_data[0][0].pha_mat_data = 0.;
1979 scat_data[0][0].ext_mat_data.resize(nf, nT, 1, 1, 1);
1980 scat_data[0][0].ext_mat_data = 0.;
1981 scat_data[0][0].abs_vec_data.resize(nf, nT, 1, 1, 1);
1982 scat_data[0][0].abs_vec_data = 0.;
This file contains the definition of Array.
Index TotalNumberOfElements(const Array< Array< base > > &aa)
Determine total number of elements in an ArrayOfArray.
base max(const Array< base > &x)
Max function.
base min(const Array< base > &x)
Min function.
The global header file for ARTS.
Constants of physical expressions as constexpr.
void set_name(const String &nname)
Set agenda name.
Index nelem() const ARTS_NOEXCEPT
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
void chk_scat_species_field(bool &empty_flag, const Tensor3 &scat_species_field, const String &fieldname, const Index &dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid)
Check whether field of a specific scattering species zero everywhere.
void chk_scattering_meta_data(const ScatteringMetaData &scat_meta_single, const String &scat_meta_file, const Verbosity &verbosity)
Check scattering data meta.
void find_cloudlimits(Index &lower, Index &upper, const Tensor3 &scat_species_field, const Index &atmosphere_dim, const Numeric &cloudbox_margin)
Adjust uppermost and lowermost cloudy level for one scat_species_*_*_field.
void chk_pnd_field_raw_only_in_cloudbox(const Index &dim, const ArrayOfGriddedField3 &pnd_field_raw, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, const ArrayOfIndex &cloudbox_limits)
chk_pnd_field_raw_only_in_cloudbox
void parse_partfield_name(String &partfield_name, const String &part_string, const String &delim)
void chk_pnd_raw_data(const ArrayOfGriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files (pnd_field_raw)
void chk_scattering_data(const ArrayOfSingleScatteringData &scat_data, const ArrayOfScatteringMetaData &scat_meta, const Verbosity &)
Check scattering data general.
void chk_pnd_data(const GriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files.
Internal cloudbox functions.
#define ARTS_ASSERT(condition,...)
#define ARTS_USER_ERROR(...)
#define ARTS_USER_ERROR_IF(condition,...)
void find_xml_file(String &filename, const Verbosity &verbosity)
Find an xml file.
bool file_exists(const std::string_view filename)
Checks if the given file exists.
This file contains basic functions to handle ASCII files.
Implementation of gridded fields.
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
void gridpos_upperend_check(GridPos &gp, const Index &ie)
gridpos_upperend_check
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
bool is_gridpos_at_index_i(const GridPos &gp, const Index &i, const bool &strict)
is_gridpos_at_index_i
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
Numeric fractional_gp(const GridPos &gp)
fractional_gp
Header file for interpolation.cc.
void abs_speciesAdd(ArrayOfArrayOfSpeciesTag &abs_species, Index &propmat_clearsky_agenda_checked, const ArrayOfString &names, const Verbosity &verbosity)
WORKSPACE METHOD: abs_speciesAdd.
void GriddedFieldPRegrid(GriddedField3 &gfraw_out, const Vector &p_grid, const GriddedField3 &gfraw_in_orig, const Index &interp_order, const Index &zeropadding, const Verbosity &verbosity)
WORKSPACE METHOD: GriddedFieldPRegrid.
void FieldFromGriddedField(Matrix &field_out, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const GriddedField2 &gfraw_in, const Verbosity &)
WORKSPACE METHOD: FieldFromGriddedField.
void cloudbox_fieldCrop(Tensor7 &cloudbox_field, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Index &cloudbox_on, const Index &new_limit0, const Index &new_limit1, const Index &new_limit2, const Index &new_limit3, const Index &new_limit4, const Index &new_limit5, const Verbosity &)
WORKSPACE METHOD: cloudbox_fieldCrop.
void cloudboxSetManually(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Numeric &p1, const Numeric &p2, const Numeric &lat1, const Numeric &lat2, const Numeric &lon1, const Numeric &lon2, const Verbosity &)
WORKSPACE METHOD: cloudboxSetManually.
void cloudboxOff(Workspace &ws, Index &cloudbox_on, Index &ppath_inside_cloudbox_do, ArrayOfIndex &cloudbox_limits, Agenda &iy_cloudbox_agenda, Tensor4 &pnd_field, ArrayOfTensor4 &dpnd_field_dx, ArrayOfString &scat_species, ArrayOfArrayOfSingleScatteringData &scat_data, ArrayOfArrayOfSingleScatteringData &scat_data_raw, Index &scat_data_checked, Matrix &particle_masses, const ArrayOfRetrievalQuantity &jacobian_quantities, const Verbosity &)
WORKSPACE METHOD: cloudboxOff.
void ScatSpeciesExtendTemperature(ArrayOfArrayOfSingleScatteringData &scat_data_raw, const ArrayOfString &scat_species, const String &species, const String &scat_species_delim, const Numeric &T_low, const Numeric &T_high, const Verbosity &)
WORKSPACE METHOD: ScatSpeciesExtendTemperature.
void cloudboxSetAutomatically(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor4 &particle_field, const Numeric &cloudbox_margin, const Verbosity &verbosity)
WORKSPACE METHOD: cloudboxSetAutomatically.
void ScatElementsToabs_speciesAdd(ArrayOfArrayOfSingleScatteringData &scat_data_raw, ArrayOfGriddedField3 &vmr_field_raw, ArrayOfArrayOfSpeciesTag &abs_species, Index &propmat_clearsky_agenda_checked, const Index &atmosphere_dim, const Vector &f_grid, const ArrayOfString &scat_data_files, const ArrayOfString &pnd_field_files, const Verbosity &verbosity)
WORKSPACE METHOD: ScatElementsToabs_speciesAdd.
constexpr Numeric DEG2RAD
void ScatSpeciesPndAndScatAdd(ArrayOfArrayOfSingleScatteringData &scat_data_raw, ArrayOfGriddedField3 &pnd_field_raw, const Index &atmosphere_dim, const ArrayOfString &scat_data_files, const String &pnd_fieldarray_file, const Verbosity &verbosity)
WORKSPACE METHOD: ScatSpeciesPndAndScatAdd.
void iyInterpCloudboxField(Matrix &iy, const Tensor7 &cloudbox_field, const Vector &rte_pos, const Vector &rte_los, const Index &jacobian_do, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &z_surface, const Index &stokes_dim, const Vector &za_grid, const Vector &aa_grid, const Vector &f_grid, const Index &za_interp_order, const Index &za_restrict, const Index &cos_za_interp, const Numeric &za_extpolfac, const Index &aa_interp_order, const Verbosity &)
WORKSPACE METHOD: iyInterpCloudboxField.
void ScatElementsSelect(ArrayOfArrayOfSingleScatteringData &scat_data_raw, ArrayOfArrayOfScatteringMetaData &scat_meta, const ArrayOfString &scat_species, const String &species, const String &sizeparam, const Numeric &sizemin, const Numeric &sizemax, const Numeric &tolerance, const String &delim, const Verbosity &)
WORKSPACE METHOD: ScatElementsSelect.
void ScatSpeciesScatAndMetaRead(ArrayOfArrayOfSingleScatteringData &scat_data_raw, ArrayOfArrayOfScatteringMetaData &scat_meta, const ArrayOfString &scat_data_files, const Verbosity &verbosity)
WORKSPACE METHOD: ScatSpeciesScatAndMetaRead.
void ScatElementsPndAndScatAdd(ArrayOfArrayOfSingleScatteringData &scat_data_raw, ArrayOfGriddedField3 &pnd_field_raw, const Index &atmosphere_dim, const ArrayOfString &scat_data_files, const ArrayOfString &pnd_field_files, const Verbosity &verbosity)
WORKSPACE METHOD: ScatElementsPndAndScatAdd.
constexpr Numeric DENSITY_OF_ICE
void particle_fieldCleanup(Tensor4 &particle_field_out, const Tensor4 &particle_field_in, const Numeric &threshold, const Verbosity &)
WORKSPACE METHOD: particle_fieldCleanup.
void pnd_fieldExpand1D(Tensor4 &pnd_field, const Index &atmosphere_dim, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &nzero, const Verbosity &)
WORKSPACE METHOD: pnd_fieldExpand1D.
constexpr Numeric RAD2DEG
void cloudboxSetFullAtm(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Index &fullfull, const Verbosity &)
WORKSPACE METHOD: cloudboxSetFullAtm.
void pnd_fieldZero(Tensor4 &pnd_field, ArrayOfTensor4 &dpnd_field_dx, ArrayOfArrayOfSingleScatteringData &scat_data, const Index &atmosphere_dim, const Vector &f_grid, const ArrayOfIndex &cloudbox_limits, const ArrayOfRetrievalQuantity &jacobian_quantities, const Verbosity &)
WORKSPACE METHOD: pnd_fieldZero.
void cloudboxSetManuallyAltitude(Index &cloudbox_on, ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Tensor3 &z_field, const Vector &lat_grid, const Vector &lon_grid, const Numeric &z1, const Numeric &z2, const Numeric &lat1, const Numeric &lat2, const Numeric &lon1, const Numeric &lon2, const Verbosity &)
WORKSPACE METHOD: cloudboxSetManuallyAltitude.
void pnd_fieldCalcFrompnd_field_raw(Tensor4 &pnd_field, ArrayOfTensor4 &dpnd_field_dx, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfGriddedField3 &pnd_field_raw, const Index &atmosphere_dim, const ArrayOfIndex &cloudbox_limits, const ArrayOfRetrievalQuantity &jacobian_quantities, const Index &zeropadding, const Verbosity &verbosity)
WORKSPACE METHOD: pnd_fieldCalcFrompnd_field_raw.
void cloudbox_fieldInterp2Azimuth(Tensor7 &cloudbox_field, const Index &cloudbox_on, const Vector &aa_grid, const Numeric &local_los_azimuth_angle, const Index &aa_interp_order, const Verbosity &)
WORKSPACE METHOD: cloudbox_fieldInterp2Azimuth.
void ScatSpeciesInit(ArrayOfString &scat_species, ArrayOfArrayOfSingleScatteringData &scat_data_raw, ArrayOfArrayOfScatteringMetaData &scat_meta, Index &scat_data_checked, ArrayOfGriddedField3 &pnd_field_raw, const Verbosity &)
WORKSPACE METHOD: ScatSpeciesInit.
void scat_dataCheck(const ArrayOfArrayOfSingleScatteringData &scat_data, const String &check_type, const Numeric &threshold, const Verbosity &verbosity)
WORKSPACE METHOD: scat_dataCheck.
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
Numeric last(ConstVectorView x)
last
Declarations having to do with the four output streams.
Internal functions for microphysics calculations (size distributions etc.)
constexpr Numeric LAT_LON_MIN
Global constant, minimum distance of cloudbox to lat/lon_grid edges.
constexpr Numeric pi
The following mathematical constants are generated in python Decimal package by the code:
constexpr Numeric density_of_ice_at_0c
Global constant, Density of water ice at 0C [kg/m3] source: http://en.wikipedia.org/wiki/Ice.
constexpr auto deg2rad(auto x) noexcept
Converts degrees to radians.
constexpr auto rad2deg(auto x) noexcept
Converts radians to degrees.
constexpr Index GFIELD3_LON_GRID
Global constant, Index of the longitude grid in GriddedField3.
constexpr Index GFIELD3_P_GRID
Global constant, Index of the pressure grid in GriddedField3.
constexpr Index GFIELD3_LAT_GRID
Global constant, Index of the latitude grid in GriddedField3.
Scattering database structure and functions.
This file contains header information for the dealing with command line parameters.
Numeric barometric_heightformula(const Numeric &p, const Numeric &dh)
barometric_heightformula
This file contains declerations of functions of physical character.
Declaration of functions in rte.cc.
Contains sorting routines.
void p2gridpos(ArrayOfGridPos &gp, ConstVectorView old_pgrid, ConstVectorView new_pgrid, const Numeric &extpolfac)
Calculates grid positions for pressure values.
void rte_pos2gridpos(GridPos &gp_p, GridPos &gp_lat, GridPos &gp_lon, const Index &atmosphere_dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView rte_pos)
Converts a geographical position (rte_pos) to grid positions for p, lat and lon.
Header file for special_interp.cc.
Structure to store a grid position.
This file contains basic functions to handle XML data files.
void xml_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads data from XML file.