48 Index& abs_xsec_agenda_checked,
51 const Agenda& abs_xsec_agenda,
53 bool needs_continua =
false;
54 bool needs_cia =
false;
57 for (
Index sp = 0; sp < abs_species.
nelem(); sp++) {
58 for (
Index tgs = 0; tgs < abs_species[sp].
nelem(); tgs++) {
59 switch (abs_species[sp][tgs].Type()) {
60 case Species::TagType::Plain:
62 case Species::TagType::Zeeman:
64 case Species::TagType::Predefined:
66 case Species::TagType::Cia:
69 case Species::TagType::FreeElectrons:
71 case Species::TagType::Particles:
73 case Species::TagType::XsecFit:
84 !abs_xsec_agenda.
has_method(
"abs_xsec_per_speciesAddConts"),
85 "*abs_species* contains continuum species but *abs_xsec_agenda*\n"
86 "does not contain *abs_xsec_per_speciesAddConts*.");
89 "*abs_species* contains CIA species but *abs_xsec_agenda*\n"
90 "does not contain *abs_xsec_per_speciesAddCIA*.");
93 abs_xsec_agenda_checked = 1;
98 const Index& atmosphere_dim,
111 const Index& abs_f_interp_order,
112 const Index& negative_vmr_ok,
117 chk_atm_field(
"t_field", t_field, atmosphere_dim, p_grid, lat_grid, lon_grid);
128 "All values in *vmr_field* must be >= 0.");
132 "All temperatures in *t_field* must be > 0.");
135 if (wind_w_field.
npages() > 0) {
143 if (atmosphere_dim < 3 && wind_v_field.
npages() > 0) {
151 if (atmosphere_dim > 2) {
152 if (wind_u_field.
npages() > 0) {
153 if (wind_v_field.
npages() > 0) {
154 bool chk_poles =
false;
184 if (wind_v_field.
npages() > 0) {
196 if (wind_u_field.
npages() > 0 || wind_v_field.
npages() > 0 ||
197 wind_w_field.
npages() > 0) {
199 "You have a wind field set, but abs_f_interp_order zero.\n"
200 "This is not allowed. Though abs_f_interp_order only is\n"
201 "required and has an effect if absorption lookup tables\n"
202 "are used, for safety reasons you also have to set it >0\n"
203 "in case of on-the-fly absorption.")
207 if (mag_w_field.
npages() > 0) {
215 if (mag_u_field.
npages() > 0) {
216 if (mag_v_field.
npages() > 0) {
217 bool chk_poles =
false;
247 if (mag_v_field.
npages() > 0) {
258 atmfields_checked = 1;
263 const Index& atmosphere_dim,
268 const Vector& refellipsoid,
272 const Numeric& max500hpa_gradient,
281 "The WSV *refellispoid* must be a vector of "
284 "The first element of *refellipsoid* must "
287 "The second element of *refellipsoid* must be "
290 "For 1D, the second element of *refellipsoid* "
291 "(the eccentricity) must be 0.");
293 chk_atm_field(
"z_field", z_field, atmosphere_dim, p_grid, lat_grid, lon_grid);
294 chk_atm_surface(
"z_surface", z_surface, atmosphere_dim, lat_grid, lon_grid);
297 for (
Index row = 0; row < z_field.
nrows(); row++) {
298 for (
Index col = 0; col < z_field.
ncols(); col++) {
300 os <<
"z_field (for latitude nr " << row <<
" and longitude nr " << col
310 for (
Index row = 0; row < z_surface.
nrows(); row++) {
311 for (
Index col = 0; col < z_surface.
ncols(); col++) {
313 z_surface(row, col) >= z_field(z_field.
npages() - 1, row, col),
314 "The surface altitude (*z_surface*) cannot be outside\n"
315 "of the altitudes in *z_field*.\n"
316 "z_surface: ", z_surface(row, col),
"\n"
317 "min of z_field: ", z_field(0, row, col),
"\n"
318 "max of z_field: ", z_field(z_field.
npages() - 1, row, col),
320 (atmosphere_dim > 1) ?
var_string(
"\nThis was found to be the case for:\n",
"latitude ", lat_grid[row]) :
var_string(),
328 if (atmosphere_dim > 1) {
339 for (
Index ilon=0; ilon<
max(1,lon_grid.
nelem()); ilon += 10) {
340 for (
Index ilat=1; ilat<lat_grid.
nelem(); ilat++) {
341 const Numeric grad =
abs((z_field(ip,ilat,ilon)-z_field(ip,ilat-1,ilon)) /
342 (lat_grid[ilat]-lat_grid[ilat-1]));
348 maxgrad *= 100.0/111.0;
349 if (maxgrad > max500hpa_gradient) {
351 os <<
"A check of the altitude of the " << p_grid[ip]/100
352 <<
" hPa level has been made.\nThe maximum gradient found matches "
353 << maxgrad <<
" m/100km, that exceeds\nthe set limit of "
354 << max500hpa_gradient <<
" m/100km (by GIN *max500hpa_gradient*).\n"
355 <<
"Please check the smoothness of *z_field*.";
356 throw runtime_error(os.str());
361 if (atmosphere_dim < 3 && (lat_true.
nelem() || lon_true.
nelem())) {
362 if (atmosphere_dim == 1) {
364 "For 1D, *lat_true* must have length 1.");
366 "For 1D, *lon_true* must have length 1.");
367 }
else if (atmosphere_dim == 2) {
369 "For 2D, *lat_true* must have same length as *lat_grid*.");
371 "For 2D, *lon_true* must have same length as *lat_grid*.");
374 "If *lat_true* is set, also *lon_true* must be "
375 "set (and have the same length).");
377 "Values in *lat_true* must be inside [-90,90].");
379 "Values in *lon_true* must be inside [-180,360].");
388 const Index& atmfields_checked,
389 const Index& atmosphere_dim,
398 const Index& cloudbox_on,
405 const Matrix& particle_masses,
407 const Index& demand_latlon_margin,
408 const Index& negative_pnd_ok,
411 "The atmospheric fields must be flagged to have "
412 "passed a consistency check (atmfields_checked=1).");
419 !wind_v_field.
empty() ||
420 !wind_u_field.
empty(),
421 "The scattering methods are not (yet?) handling winds. For this\n"
422 "reason, the WSVs for wind fields must all be empty with an\n."
428 Index has_absparticles = 0;
429 for (
Index sp = 0; sp < abs_species.
nelem() && has_absparticles < 1; sp++) {
430 if (abs_species[sp].Particles()) {
431 has_absparticles = 1;
435 "For scattering calculations (cloudbox is on),"
436 "abs_species is not allowed to contain\n"
437 "'particles' (absorbing-only particles)!");
441 "The array *cloudbox_limits* has incorrect length.\n"
442 "For atmospheric dim. = ", atmosphere_dim,
443 " the length shall be ", atmosphere_dim * 2,
" but it is ",
444 cloudbox_limits.
nelem(),
".")
445 ARTS_USER_ERROR_IF (cloudbox_limits[1] <= cloudbox_limits[0] || cloudbox_limits[0] < 0 ||
446 cloudbox_limits[1] >= p_grid.
nelem(),
447 "Incorrect value(s) for cloud box pressure limit(s) found."
448 "\nValues are either out of range or upper limit is not "
449 "greater than lower limit.\nWith present length of "
450 "*p_grid*, OK values are 0 - ", p_grid.
nelem() - 1,
451 ".\nThe pressure index limits are set to ", cloudbox_limits[0],
452 " - ", cloudbox_limits[1],
".")
454 Index nlat = 1, nlon = 1;
456 if (atmosphere_dim > 1) {
457 nlat = lat_grid.
nelem();
458 if (demand_latlon_margin) {
460 cloudbox_limits[2] < 1 ||
461 cloudbox_limits[3] >= nlat - 1,
462 "Incorrect value(s) for cloud box latitude limit(s) found."
463 "\nValues are either out of range or upper limit is not "
464 "greater than lower limit.\nWith present length of "
465 "*lat_grid* and demand_latlon_margin set to true, "
466 "OK values are 1 - ", nlat - 2,
467 ".\nThe latitude index limits are set to ", cloudbox_limits[2],
468 " - ", cloudbox_limits[3],
".")
470 lat_grid[0] < LAT_LON_MIN) &&
471 (atmosphere_dim == 2 ||
472 (atmosphere_dim == 3 && lat_grid[0] > -90)),
473 "Too small distance between cloudbox and lower end of "
475 "This distance must be ", LAT_LON_MIN,
" degrees.\n"
476 "Cloudbox ends at ", lat_grid[cloudbox_limits[2]],
477 " and latitude grid starts at ", lat_grid[0],
".")
479 lat_grid[cloudbox_limits[3]] < LAT_LON_MIN) &&
480 (atmosphere_dim == 2 ||
481 (atmosphere_dim == 3 && lat_grid[nlat - 1] < 90)),
482 "Too small distance between cloudbox and upper end of "
484 "This distance must be ", LAT_LON_MIN,
" degrees.\n"
485 "Cloudbox ends at ", lat_grid[cloudbox_limits[3]],
486 " and latitude grid ends at ", lat_grid[nlat - 1],
".")
489 cloudbox_limits[2] < 0 ||
490 cloudbox_limits[3] >= nlat,
491 "Incorrect value(s) for cloud box latitude limit(s) found."
492 "\nValues are either out of range or upper limit is not "
493 "greater than lower limit.\nWith present length of "
494 "*lat_grid* and demand_latlon_margin set to false, "
495 "OK values are 0 - ", nlat - 1,
496 ".\nThe latitude index limits are set to ", cloudbox_limits[2],
497 " - ", cloudbox_limits[3],
".")
501 if (atmosphere_dim > 2) {
502 nlon = lon_grid.
nelem();
503 if (demand_latlon_margin) {
505 cloudbox_limits[4] < 1 ||
506 cloudbox_limits[5] >= nlon - 1,
507 "Incorrect value(s) for cloud box longitude limit(s) found"
508 ".\nValues are either out of range or upper limit is not "
509 "greater than lower limit.\nWith present length of "
510 "*lon_grid* and demand_latlon_margin set to true,"
511 "OK values are 1 - ", nlon - 2,
512 ".\nThe longitude limits are set to ", cloudbox_limits[4],
513 " - ", cloudbox_limits[5],
".")
514 if (lon_grid[nlon - 1] - lon_grid[0] < 360) {
515 const Numeric latmax =
max(
abs(lat_grid[cloudbox_limits[2]]),
516 abs(lat_grid[cloudbox_limits[3]]));
520 "Too small distance between cloudbox and lower end of"
521 "the longitude\ngrid. This distance must here be ",
522 LAT_LON_MIN / lfac,
" degrees.")
525 "Too small distance between cloudbox and upper end of"
526 "the longitude\ngrid. This distance must here be ",
527 LAT_LON_MIN / lfac,
" degrees.")
531 cloudbox_limits[4] < 0 ||
532 cloudbox_limits[5] >= nlon,
533 "Incorrect value(s) for cloud box longitude limit(s) found"
534 ".\nValues are either out of range or upper limit is not "
535 "greater than lower limit.\nWith present length of "
536 "*lon_grid* and demand_latlon_margin set to false,"
537 "OK values are 0 - ", nlon - 1,
538 ".\nThe longitude limits are set to ", cloudbox_limits[4],
539 " - ", cloudbox_limits[5],
".")
544 for (
Index o = 0; o < nlon; o++) {
547 "The upper vertical limit of the cloudbox must be above "
548 "the surface altitude (for all latitudes and longitudes).");
556 Vector g1(cloudbox_limits[1] - cloudbox_limits[0] + 1), g2(0), g3(0);
557 if (atmosphere_dim > 1) {
558 g2.resize(cloudbox_limits[3] - cloudbox_limits[2] + 1);
560 if (atmosphere_dim > 2) {
561 g3.
resize(cloudbox_limits[5] - cloudbox_limits[4] + 1);
564 chk_atm_field(
"pnd_field", pnd_field, atmosphere_dim, np, g1, g2, g3);
567 "Negative values in *pnd_field* not allowed.");
571 for (
Index a = 0;
a < g2.nelem();
a++) {
574 z_field(cloudbox_limits[0],
a, o) > z_surface(
a, o),
575 "A non-zero value found in *pnd_field* at the"
576 " lower altitude limit of the cloudbox (but the "
577 "position is not at or below the surface altitude).");
583 if (cloudbox_limits[1] != p_grid.
nelem() - 1)
585 "A non-zero value found in *pnd_field* at "
586 "upper altitude limit of the cloudbox.");
587 if (atmosphere_dim >= 2) {
589 "A non-zero value found in *pnd_field* at "
590 "lower latitude limit of the cloudbox.");
592 "A non-zero value found in *pnd_field* at "
593 "upper latitude limit of the cloudbox.");
595 if (atmosphere_dim == 3) {
597 "A non-zero value found in *pnd_field* at "
598 "lower longitude limit of the cloudbox.");
600 "A non-zero value found in *pnd_field* at "
601 "upper longitude limit of the cloudbox.");
606 "Size of *dpnd_field_dx* inconsistent with number "
607 "of *jacobian_quantities*.");
613 if (scat_species.
nelem() > 0)
615 "Number of scattering species specified by scat_species does\n"
616 "not agree with number of scattering species in scat_data:\n"
617 "scat_species has ", scat_species.
nelem(),
618 " entries, while scat_data has ", scat_data.
nelem(),
".")
621 if (!particle_masses.
empty()) {
623 "The WSV *particle_masses* must either be "
624 "empty or have a row size matching the "
625 "length of *scat_data*.");
627 "All values in *particles_masses* must be >= 0.");
632 cloudbox_checked = 1;
639 const Numeric& dfrel_threshold,
640 const String& check_level,
641 const Numeric& sca_mat_threshold,
649 "*dfrel_threshold* too large (max. allowed: 0.5, your's: ",
650 dfrel_threshold,
").")
658 for (
Index i_ss = 0; i_ss < N_ss; i_ss++) {
660 for (
Index i_se = 0; i_se < N_se; i_se++) {
665 Index nf_se = scat_data[i_ss][i_se].f_grid.
nelem();
668 "*scat_data* must have either one or *f_grid* (=", nf,
669 ") frequency entries,\n"
670 "but scattering element #", i_se,
" in scattering species #",
671 i_ss,
" has ", nf_se,
".")
672 for (
Index f = 0; f < nf_se; f++) {
674 scat_data[i_ss][i_se].f_grid[f], f_grid[f], 0.5e-9),
675 "*scat_data* frequency grid has to be identical to *f_grid*\n"
676 "(or contain only a single entry),\n"
677 "but scattering element #", i_se,
678 " in scattering species #", i_ss,
679 " deviates for f_index ", f,
".")
684 (
abs(1. - scat_data[i_ss][i_se].f_grid[0] / f_grid[nf - 1]) >
686 "Frequency entry (f=", scat_data[i_ss][i_se].f_grid[0],
687 "Hz) of scattering element #", i_se,
"\n"
688 "in scattering species #", i_ss,
" is too far (>",
689 dfrel_threshold * 1e2,
"%) from one or more\n"
690 "of the f_grid limits (fmin=", f_grid[0],
691 "Hz, fmax=", f_grid[nf - 1],
"Hz).")
699 ostringstream bs1, bs2;
700 bs1 <<
"Frequency dimension of ";
702 bs2 <<
" must be ssd.f_grid.nelem() (=" << nf_se <<
"),\n"
703 <<
"but scattering element #" << i_se <<
" in scattering species #"
705 Index nf_sd = scat_data[i_ss][i_se].pha_mat_data.nlibraries();
707 bs1.str(),
"pha_mat_data", bs2.str(), nf_se,
".")
708 nf_sd = scat_data[i_ss][i_se].ext_mat_data.nshelves();
710 bs1.str(),
"ext_mat_data", bs2.str(), nf_se,
".")
711 nf_sd = scat_data[i_ss][i_se].abs_vec_data.nshelves();
713 bs1.str(),
"abs_vec_data", bs2.str(), nf_se,
".")
719 ostringstream bs1, bs2;
720 Index nt_se = scat_data[i_ss][i_se].T_grid.
nelem();
721 bs1 <<
"Temperature dimension of ";
723 bs2 <<
" must be ssd.T_grid.nelem() (=" << nt_se <<
"),\n"
724 <<
"but for scattering element #" << i_se
725 <<
" in scattering species #" << i_ss <<
" it is ";
726 Index nt_sd = scat_data[i_ss][i_se].pha_mat_data.nvitrines();
728 bs1.str(),
"pha_mat_data", bs2.str(), nt_sd,
".")
729 nt_sd = scat_data[i_ss][i_se].ext_mat_data.nbooks();
731 bs1.str(),
"ext_mat_data", bs2.str(), nt_se,
".")
732 nt_sd = scat_data[i_ss][i_se].abs_vec_data.nbooks();
734 bs1.str(),
"abs_vec_data", bs2.str(), nt_se,
".")
739 if (check_level.
toupper() !=
"NONE") {
746 scat_dataCheck(scat_data, check_level, sca_mat_threshold, verbosity);
750 scat_data_checked = 1;
766 "abs_lines_per_species and abs_species must have same length.\n"
767 "Instead len(abs_lines_per_species) = ",
768 abs_lines_per_species.
nelem(),
769 " and len(abs_species) = ",
774 auto& specs = abs_species[i];
775 auto& lines = abs_lines_per_species[i];
777 if (not specs.nelem()) {
778 if (not lines.nelem()) {
784 const bool any_zeeman = std::any_of(specs.cbegin(), specs.cend(), [](
auto& x){return x.Type() == Species::TagType::Zeeman;});
785 ARTS_USER_ERROR_IF (any_zeeman and (not std::all_of(specs.cbegin(), specs.cend(), [](
auto& x){return x.Type() == Species::TagType::Zeeman;})),
786 "Zeeman species found but not all sub-species tags support Zeeman effect.\n"
787 "Offending tag: ", specs,
'\n')
790 for (
auto& band: lines) {
792 "Zeeman effects are not symmetric, you cannot use cutoff.\n");
793 for (
Index k=0; k<band.NumLines(); k++) {
794 bool hasJ = band.lines[k].localquanta.val.has(QuantumNumberType::J);
795 bool hasF = band.lines[k].localquanta.val.has(QuantumNumberType::F);
797 "No J(s) or F(s) yet declared Zeeman splitting.\n");
799 auto& qn = hasF ? band.lines[k].localquanta.val[QuantumNumberType::F] : band.lines[k].localquanta.val[QuantumNumberType::J];
801 "Bad Wigner numbers for upper state F or J. Try increasing the Wigner memory allocation.\n");
803 "Bad Wigner numbers for lower state F or J. Try increasing the Wigner memory allocation.\n");
805 auto Ze = band.lines[k].zeeman;
807 "Bad value(s) in the upper Zeeman data not allowed when modeling Zeeman effect.\n");
809 "Bad value(s) in the lower Zeeman data not allowed when modeling Zeeman effect.\n");
816 for (
auto& band: lines) {
818 std::any_of(band.lines.cbegin(), band.lines.cend(),
819 [](
auto& x){return x.F0 <= 0;}),
820 "Negative or zero frequency in non-Manual mirrored band.\n");
824 for (
auto& lines: abs_lines_per_species) {
825 for (
auto& band: lines) {
828 for (
auto& line: band.lines) {
829 if (band.mirroring == Absorption::MirroringType::Manual) {
831 "Must have negative frequency, finds " , line.F0)
834 "Must have positive frequency, finds " , line.F0)
839 switch (band.cutoff) {
840 case Absorption::CutoffType::None:
break;
841 case Absorption::CutoffType::ByLine: {
843 band.mirroring == Absorption::MirroringType::Manual),
844 "Cutoff only possible with symmetric mirroring types")
846 "Cannot have relaxation matrix line mixing with cutoff calculations")
848 band.lineshapetype == LineShape::Type::LP or
849 band.lineshapetype == LineShape::Type::VP),
850 "Cutoff only possible with symmetric line shape types")
851 for (
auto& line: band.lines) {
852 for (
auto& single_data: line.lineshape.Data()) {
855 single_data.Y().type not_eq LineShape::TemperatureModel::None or
856 single_data.DV().type not_eq LineShape::TemperatureModel::None,
857 "Cannot have Rosenkranz-style line mixing with cutoff calculations\n"
858 "Note that abs_lines_per_speciesTurnOffLineMixing will make this error go away by modifying the data\n"
863 case Absorption::CutoffType::FINAL:
ARTS_USER_ERROR(
"You have a band with undefined cutoff type.")
874 Index& propmat_clearsky_agenda_checked,
877 const Agenda& propmat_clearsky_agenda,
879 bool needs_lines =
false;
880 bool needs_zeeman =
false;
881 bool needs_predefined =
false;
882 bool needs_continua =
false;
883 bool needs_cia =
false;
884 bool needs_free_electrons =
false;
885 bool needs_particles =
false;
886 bool needs_hxsec =
false;
888 for (
auto& tag_groups: abs_species) {
889 for (
auto& tag: tag_groups) {
890 switch (tag.Type()) {
891 case Species::TagType::Plain:
894 case Species::TagType::Zeeman:
897 case Species::TagType::Predefined:
898 needs_predefined =
true;
900 case Species::TagType::Cia:
903 case Species::TagType::FreeElectrons:
904 needs_free_electrons =
true;
906 case Species::TagType::Particles:
907 needs_particles =
true;
909 case Species::TagType::XsecFit:
913 ARTS_ASSERT(
false,
"Unknown species type: ", tag.Type())
921 not(propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddLines") or
923 "propmat_clearskyAddFromLookup")),
924 "*abs_species* contains normal lines species but *propmat_clearsky_agenda*\n"
925 "cannot support lines.");
930 "propmat_clearskyAddXsecAgenda") or
931 propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddConts") or
933 "propmat_clearskyAddFromLookup")),
934 "*abs_species* contains legacy continua but *propmat_clearsky_agenda*\n"
935 "cannot support these.");
940 "propmat_clearskyAddXsecAgenda") or
941 propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddCIA") or
943 "propmat_clearskyAddFromLookup")),
944 "*abs_species* contains CIA models but *propmat_clearsky_agenda*\n"
945 "cannot support these.");
949 not(propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddXsecAgenda") or
950 propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddXsecFit") or
952 "propmat_clearskyAddFromLookup")),
953 "*abs_species* contains Hitran XSEC models but *propmat_clearsky_agenda*\n"
954 "cannot support these.");
958 not(propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddPredefined") or
960 "propmat_clearskyAddFromLookup")),
961 "*abs_species* contains modern continua models but *propmat_clearsky_agenda*\n"
962 "cannot support these.");
965 not propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddZeeman"),
966 "*abs_species* contains Zeeman species but *propmat_clearsky_agenda*\n"
967 "does not contain *propmat_clearskyAddZeeman*.");
970 not propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddFaraday"),
971 "*abs_species* contains Zeeman species but *propmat_clearsky_agenda*\n"
972 "does not contain *propmat_clearskyAddFaraday*.");
975 !(propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddParticles")),
976 "*abs_species* contains particles but *propmat_clearsky_agenda*\n"
977 "does not contain *propmat_clearskyAddParticles*.");
979 propmat_clearsky_agenda_checked = 1;
984 const Index& atmosphere_dim,
985 const Index& stokes_dim,
989 const Matrix& transmitter_pos,
990 const Matrix& mblock_dlos,
991 const Sparse& sensor_response,
992 const Vector& sensor_response_f,
994 const Matrix& sensor_response_dlos,
1001 const Index niyb = nf * nlos * stokes_dim;
1006 "*f_grid* must be a strictly increasing vector.");
1011 "*sensor_pos* is empty. This is not allowed.");
1013 "*sensor_los* is empty. This is not allowed.");
1016 "The number of columns of sensor_pos must be "
1017 "equal to the atmospheric dimensionality.");
1019 "For 1D and 2D, sensor_los shall have one column.");
1021 "For 3D, sensor_los shall have two columns.");
1023 "The number of rows of sensor_pos and sensor_los must be "
1024 "identical, but sensor_pos has ", nmblock,
" rows,\n"
1025 "while sensor_los has ", sensor_los.
nrows(),
" rows.")
1027 "First column of *sensor_los* is not allowed to have values above 180.");
1028 if (atmosphere_dim == 2) {
1030 "For atmosphere_dim = 2, first column of "
1031 "*sensor_los* is not allowed to have values below -180.");
1034 "For atmosphere_dim != 2, first column of "
1035 "*sensor_los* is not allowed to have values below 0.");
1037 if (atmosphere_dim == 3) {
1039 "Second column of *sensor_los* is not allowed to have values above 180.");
1041 "Second column of *sensor_los* is not allowed to have values below -180.");
1045 if (!transmitter_pos.
empty()) {
1047 "*transmitter_pos* must either be empty or have "
1048 "the same number of rows as *sensor_pos*.");
1050 "*transmitter_pos* must either be empty, have "
1051 "2 for 1D/2D or 3 columns for 3D.");
1057 "*mblock_dlos* is empty.");
1059 "The maximum number of columns in *mblock_dlos* is two.");
1060 if (atmosphere_dim < 3) {
1062 "For 1D and 2D *mblock_dlos* must have exactly one column.");
1068 "The *sensor_response* matrix does not have the right size,\n"
1069 "either the method *sensor_responseInit* has not been run or some\n"
1070 "of the other sensor response methods has not been correctly\n"
1076 n1y != sensor_response_dlos.
nrows(),
1077 "Sensor auxiliary variables do not have the correct size.\n"
1078 "The following variables should all have same size:\n"
1079 "length of y for one block : ", n1y,
"\n"
1080 "sensor_response_f.nelem() : ", sensor_response_f.
nelem(),
1081 "\nsensor_response_pol.nelem() : ", sensor_response_pol.
nelem(),
1082 "\nsensor_response_dlos.nrows(): ", sensor_response_dlos.
nrows(),
void checkIsotopologueRatios(const ArrayOfArrayOfAbsorptionLines &abs_lines_per_species, const Species::IsotopologueRatios &isoratios)
Check that isotopologue ratios for the given species are correctly defined.
void checkPartitionFunctions(const ArrayOfArrayOfAbsorptionLines &abs_lines_per_species)
Check that ARTS was compiled for all requested species tags.
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.
bool has_method(const String &methodname) const
Check if method is in Agenda.
Index nelem() const ARTS_NOEXCEPT
bool empty() const noexcept
Index nrows() const noexcept
Index ncols() const noexcept
bool empty() const noexcept
Index npages() const
Returns the number of pages.
Index nrows() const
Returns the number of rows.
Index ncols() const
Returns the number of columns.
Index nelem() const noexcept
Returns the number of elements.
bool empty() const noexcept
Returns true if variable size is zero.
void resize(Index n)
Resize function.
void toupper()
Convert to upper case.
Internal cloudbox functions.
#define ARTS_ASSERT(condition,...)
#define ARTS_USER_ERROR(...)
std::string var_string(Args &&... args)
#define ARTS_USER_ERROR_IF(condition,...)
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
bool is_same_within_epsilon(const Numeric &a, const Numeric &b, const Numeric &epsilon)
Check, if two numbers agree within a given epsilon.
void abs_xsec_agenda_checkedCalc(Workspace &ws, Index &abs_xsec_agenda_checked, const ArrayOfArrayOfSpeciesTag &abs_species, const Agenda &abs_xsec_agenda, const Verbosity &)
void atmfields_checkedCalc(Index &atmfields_checked, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &t_field, const Tensor4 &vmr_field, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Index &abs_f_interp_order, const Index &negative_vmr_ok, const Verbosity &)
WORKSPACE METHOD: atmfields_checkedCalc.
constexpr Numeric DEG2RAD
void cloudbox_checkedCalc(Index &cloudbox_checked, const Index &atmfields_checked, 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 Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfArrayOfSingleScatteringData &scat_data, const ArrayOfString &scat_species, const Matrix &particle_masses, const ArrayOfArrayOfSpeciesTag &abs_species, const Index &demand_latlon_margin, const Index &negative_pnd_ok, const Verbosity &)
WORKSPACE METHOD: cloudbox_checkedCalc.
void propmat_clearsky_agenda_checkedCalc(Workspace &ws, Index &propmat_clearsky_agenda_checked, const ArrayOfArrayOfSpeciesTag &abs_species, const Agenda &propmat_clearsky_agenda, const Verbosity &)
WORKSPACE METHOD: propmat_clearsky_agenda_checkedCalc.
void scat_data_checkedCalc(Index &scat_data_checked, const ArrayOfArrayOfSingleScatteringData &scat_data, const Vector &f_grid, const Numeric &dfrel_threshold, const String &check_level, const Numeric &sca_mat_threshold, const Verbosity &verbosity)
WORKSPACE METHOD: scat_data_checkedCalc.
void lbl_checkedCalc(Index &lbl_checked, const ArrayOfArrayOfAbsorptionLines &abs_lines_per_species, const ArrayOfArrayOfSpeciesTag &abs_species, const SpeciesIsotopologueRatios &isotopologue_ratios, const Verbosity &)
WORKSPACE METHOD: lbl_checkedCalc.
void atmgeom_checkedCalc(Index &atmgeom_checked, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Vector &refellipsoid, const Matrix &z_surface, const Vector &lat_true, const Vector &lon_true, const Numeric &max500hpa_gradient, const Verbosity &)
WORKSPACE METHOD: atmgeom_checkedCalc.
void sensor_checkedCalc(Index &sensor_checked, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &f_grid, const Matrix &sensor_pos, const Matrix &sensor_los, const Matrix &transmitter_pos, const Matrix &mblock_dlos, const Sparse &sensor_response, const Vector &sensor_response_f, const ArrayOfIndex &sensor_response_pol, const Matrix &sensor_response_dlos, const Verbosity &)
WORKSPACE METHOD: sensor_checkedCalc.
void scat_dataCheck(const ArrayOfArrayOfSingleScatteringData &scat_data, const String &check_type, const Numeric &threshold, const Verbosity &verbosity)
WORKSPACE METHOD: scat_dataCheck.
void abs(Sparse &A, const Sparse &B)
Absolute value of sparse matrix elements.
Implementation of Matrix, Vector, and such stuff.
NUMERIC Numeric
The type to use for all floating point numbers.
INDEX Index
The type to use for all integer numbers and indices.
constexpr bool relaxationtype_relmat(PopulationType in) noexcept
constexpr Numeric LAT_LON_MIN
Global constant, minimum distance of cloudbox to lat/lon_grid edges.
constexpr auto deg2rad(auto x) noexcept
Converts degrees to radians.
Index nrows() const
Returns the number of rows.
Index ncols() const
Returns the number of columns.
bool is_wigner3_ready(const Rational &J)
Tells if the function is ready for Wigner 3J calculations.
Wigner symbol interactions.