ARTS 2.5.11 (git: 6827797f)
check_input.cc
Go to the documentation of this file.
1/*===========================================================================
2 === File description
3 ===========================================================================*/
4
13/*===========================================================================
14 === External declarations
15 ===========================================================================*/
16
17#include "check_input.h"
18#include <cfloat>
19#include <cmath>
20#include <stdexcept>
21#include "array.h"
22#include "auto_md.h"
23#include "gridded_fields.h"
24#include "logic.h"
25
29
30/*===========================================================================
31 === Functions for Index
32 ===========================================================================*/
33
35
46void chk_if_bool(const String& x_name, const Index& x) {
47 ARTS_USER_ERROR_IF (!is_bool(x),
48 "The variable *", x_name, "* must be a boolean (0 or 1).\n"
49 "The present value of *", x_name, "* is ", x, ".")
50}
51
53
67void chk_if_in_range(const String& x_name,
68 const Index& x,
69 const Index& x_low,
70 const Index& x_high) {
71 ARTS_USER_ERROR_IF ((x < x_low) || (x > x_high),
72 "The variable *", x_name, "* must fulfill:\n"
73 , " ", x_low, " <= ", x_name, " <= ", x_high, "\n"
74 , "The present value of *", x_name, "* is ", x, ".")
75}
76
78
92void chk_if_increasing(const String& x_name, const ArrayOfIndex& x) {
93 ARTS_USER_ERROR_IF (!is_increasing(x),
94 "The ArrayOfIndex *", x_name, "* must have strictly\n"
95 "increasing values, but this is not the case.\n"
96 "x = ", x, "\n")
97}
98
99/*===========================================================================
100 === Functions for Numeric
101 ===========================================================================*/
102
104
115void chk_not_negative(const String& x_name, const Numeric& x) {
116 ARTS_USER_ERROR_IF (x < 0,
117 "The variable *", x_name, "* must be >= 0.\n"
118 "The present value of *", x_name, "* is ", x, ".")
119}
120
122
136void chk_if_in_range(const String& x_name,
137 const Numeric& x,
138 const Numeric& x_low,
139 const Numeric& x_high) {
140 ARTS_USER_ERROR_IF ((x < x_low) || (x > x_high),
141 "The variable *", x_name, "* must fulfill:\n"
142 " ", x_low, " <= ", x_name, " <= ", x_high, "\n"
143 "The present value of *", x_name, "* is ", x, ".")
144}
145
147
162 const Numeric& x,
163 const Numeric& x_low,
164 const Numeric& x_high) {
165 ARTS_USER_ERROR_IF ((x <= x_low) || (x > x_high),
166 "The variable *", x_name, "* must fulfill:\n"
167 " ", x_low, " < ", x_name, " <= ", x_high, "\n"
168 "The present value of *", x_name, "* is ", x, ".")
169}
170
172
187 const Numeric& x,
188 const Numeric& x_low,
189 const Numeric& x_high) {
190 ARTS_USER_ERROR_IF ((x < x_low) || (x >= x_high),
191 "The variable *", x_name, "* must fulfill:\n"
192 " ", x_low, " <= ", x_name, " < ", x_high, "\n"
193 "The present value of *", x_name, "* is ", x, ".")
194}
195
197
212 const Numeric& x,
213 const Numeric& x_low,
214 const Numeric& x_high) {
215 ARTS_USER_ERROR_IF ((x <= x_low) || (x >= x_high),
216 "The variable *", x_name, "* must fulfill:\n"
217 " ", x_low, " < ", x_name, " < ", x_high, "\n"
218 "The present value of *", x_name, "* is ", x, ".")
219}
220
221/*===========================================================================
222 === Functions for Vector
223 ===========================================================================*/
224
226
238void chk_vector_length(const String& x_name,
239 ConstVectorView x,
240 const Index& l) {
241 ARTS_USER_ERROR_IF (x.nelem() != l,
242 "The vector *", x_name, "* must have the length ", l, ".\n"
243 "The present length of *", x_name, "* is ", x.nelem(), ".")
244}
245
247
260void chk_vector_length(const String& x1_name,
261 const String& x2_name,
262 ConstVectorView x1,
263 ConstVectorView x2) {
264 ARTS_USER_ERROR_IF (x1.nelem() != x2.nelem(),
265 "The vectors *", x1_name, "* and *", x2_name,
266 "* must have the same length.\n"
267 "The length of *", x1_name, "* is ", x1.nelem(), ".\n"
268 "The length of *", x2_name, "* is ", x2.nelem(), ".")
269}
270
272
285void chk_if_increasing(const String& x_name, ConstVectorView x) {
286 ARTS_USER_ERROR_IF (!is_increasing(x),
287 "The vector *", x_name, "* must have strictly\n"
288 "increasing values, but this is not the case.\n"
289 "x = ", x, "\n")
290}
291
293
306void chk_if_decreasing(const String& x_name, ConstVectorView x) {
307 ARTS_USER_ERROR_IF (!is_decreasing(x),
308 "The vector *", x_name, "* must have strictly\ndecreasing "
309 "values, but this is not the case.\n")
310}
311
313
326void chk_if_equal(const String& x1_name,
327 const String& x2_name,
328 ConstVectorView v1,
329 ConstVectorView v2,
330 Numeric margin) {
331 chk_vector_length(x1_name, x2_name, v1, v2);
332
333 for (Index i = 0; i < v1.nelem(); i++) {
334 ARTS_USER_ERROR_IF (abs(v1[i] - v2[i]) > margin,
335 "Vectors ", x1_name, " and ", x2_name, " differ.\n",
336 x1_name, "[", i, "]"
337 , " = ", v1[i], "\n"
338 , x2_name, "[", i, "]"
339 , " = ", v2[i], "\n"
340 , "Difference should not exceed ", margin, "\n")
341 }
342}
343
344/*===========================================================================
345 === Functions for Matrix
346 ===========================================================================*/
347
349
361void chk_matrix_ncols(const String& x_name, ConstMatrixView x, const Index& l) {
362 ARTS_USER_ERROR_IF (x.ncols() != l,
363 "The matrix *", x_name, "* must have ", l, " columns,\n"
364 , "but the number of columns is ", x.ncols(), ".")
365}
366
368
380void chk_matrix_nrows(const String& x_name, ConstMatrixView x, const Index& l) {
381 ARTS_USER_ERROR_IF (x.nrows() != l,
382 "The matrix *", x_name, "* must have ", l, " rows,\n"
383 , "but the number of rows is ", x.nrows(), ".")
384}
385
386/*===========================================================================
387 === Functions for Tensors
388 ===========================================================================*/
389
391
402void chk_size(const String& x_name, ConstVectorView x, const Index& c) {
403 ARTS_USER_ERROR_IF (!is_size(x, c),
404 "The object *", x_name, "* does not have the right size.\n"
405 "Dimension should be:" " ", c, ",\nbut it is: " " ",
406 x.nelem(), ".")
407}
408
410
422void chk_size(const String& x_name,
423 ConstMatrixView x,
424 const Index& r,
425 const Index& c) {
426 ARTS_USER_ERROR_IF (!is_size(x, r, c),
427 "The object *", x_name, "* does not have the right size.\n"
428 , "Dimensions should be:"
429 , " ", r, " ", c, ",\nbut they are: "
430 , " ", x.nrows(), " ", x.ncols(), ".")
431}
432
434
447void chk_size(const String& x_name,
448 ConstTensor3View x,
449 const Index& p,
450 const Index& r,
451 const Index& c) {
452 ARTS_USER_ERROR_IF (!is_size(x, p, r, c),
453 "The object *", x_name, "* does not have the right size.\n"
454 , "Dimensions should be:"
455 , " ", p, " ", r, " ", c, ",\nbut they are: "
456 , " ", x.npages(), " ", x.nrows(), " ", x.ncols(), ".")
457}
458
460
474void chk_size(const String& x_name,
475 ConstTensor4View x,
476 const Index& b,
477 const Index& p,
478 const Index& r,
479 const Index& c) {
480 ARTS_USER_ERROR_IF (!is_size(x, b, p, r, c),
481 "The object *", x_name, "* does not have the right size.\n"
482 , "Dimensions should be:"
483 , " ", b, " ", p, " ", r, " ", c
484 , ",\nbut they are: "
485 , " ", x.nbooks(), " ", x.npages(), " ", x.nrows(), " "
486 , x.ncols(), ".")
487}
488
490
505void chk_size(const String& x_name,
506 ConstTensor5View x,
507 const Index& s,
508 const Index& b,
509 const Index& p,
510 const Index& r,
511 const Index& c) {
512 ARTS_USER_ERROR_IF (!is_size(x, s, b, p, r, c),
513 "The object *", x_name, "* does not have the right size.\n"
514 , "Dimensions should be:"
515 , " ", s, " ", b, " ", p, " ", r, " ", c
516 , ",\nbut they are: "
517 , " ", x.nshelves(), " ", x.nbooks(), " ", x.npages(), " "
518 , x.nrows(), " ", x.ncols(), ".")
519}
520
522
538void chk_size(const String& x_name,
539 ConstTensor6View x,
540 const Index& v,
541 const Index& s,
542 const Index& b,
543 const Index& p,
544 const Index& r,
545 const Index& c) {
546 ARTS_USER_ERROR_IF (!is_size(x, v, s, b, p, r, c),
547 "The object *", x_name, "* does not have the right size.\n"
548 , "Dimensions should be:"
549 , " ", v, " ", s, " ", b, " ", p, " ", r, " ", c
550 , ",\nbut they are: "
551 , " ", x.nvitrines(), " ", x.nshelves(), " ", x.nbooks()
552 , " ", x.npages(), " ", x.nrows(), " ", x.ncols(), ".")
553}
554
556
573void chk_size(const String& x_name,
574 ConstTensor7View x,
575 const Index& l,
576 const Index& v,
577 const Index& s,
578 const Index& b,
579 const Index& p,
580 const Index& r,
581 const Index& c) {
582 ARTS_USER_ERROR_IF (!is_size(x, l, v, s, b, p, r, c),
583 "The object *", x_name, "* does not have the right size.\n"
584 , "Dimensions should be:"
585 , " ", l, " ", v, " ", s, " ", b, " ", p, " ", r
586 , " ", c, ",\nbut they are: "
587 , " ", x.nlibraries(), " ", x.nvitrines(), " ", x.nshelves()
588 , " ", x.nbooks(), " ", x.npages(), " ", x.nrows(), " "
589 , x.ncols(), ".")
590}
591
592/*===========================================================================
593 === Functions for Agendas
594 ===========================================================================*/
595
597
608void chk_not_empty(const String& x_name, const Agenda& x) {
609 ARTS_USER_ERROR_IF (x.nelem() == 0,
610 "The agenda *", x_name, "* is empty.\nIt is not allowed \n"
611 , "that an empty agenda that is actually used.\n"
612 , "Empty agendas are only created of methods setting dummy values \n"
613 , "to variables.")
614}
615
616/*===========================================================================
617 === Functions for interpolation grids
618 ===========================================================================*/
619
621
647 Index& ing_max,
648 const String& which_interpolation,
649 ConstVectorView old_grid,
650 ConstVectorView new_grid,
651 ConstVectorView data,
652 const Index order) {
654 ing_min, ing_max, which_interpolation, old_grid, new_grid, order);
655
657 ing_min, ing_max, which_interpolation, old_grid, new_grid, data);
658}
659
661
685 Index& ing_min,
686 Index& ing_max,
687 const String& which_interpolation,
688 ConstVectorView old_grid,
689 ConstVectorView new_grid,
690 const Index order) {
691 const Index n_old = old_grid.nelem();
692
693 ARTS_USER_ERROR_IF (!new_grid.nelem(),
694 "The new grid is not allowed to be empty.");
695
696 // Old grid must have at least order+1 elements:
697 ARTS_USER_ERROR_IF (n_old < order + 1, "There is a problem with the grids for the following interpolation:\n",
698 which_interpolation, "\n",
699 "The original grid must have at least ", order + 1, " elements.")
700
701 // Decide whether we have an ascending or descending grid:
702 const bool ascending = (old_grid[0] <= old_grid[1]);
703
704 // Minimum and maximum allowed value from old grid. (Will include
705 // extrapolation tolerance.)
706 Numeric og_min, og_max;
707
708 ing_min = 0;
709 ing_max = new_grid.nelem() - 1;
710 if (ascending) {
711 // Old grid must be strictly increasing (no duplicate values.)
712 ARTS_USER_ERROR_IF (!is_increasing(old_grid), "There is a problem with the grids for the following interpolation:\n",
713 which_interpolation, "\n",
714 "The original grid must be strictly sorted\n"
715 , "(no duplicate values). Yours is:\n"
716 , old_grid, ".")
717
718 // Limits of extrapolation.
719 og_min = old_grid[0];
720 og_max = old_grid[n_old - 1];
721 } else {
722 // Old grid must be strictly decreasing (no duplicate values.)
723 ARTS_USER_ERROR_IF (!is_decreasing(old_grid), "There is a problem with the grids for the following interpolation:\n",
724 which_interpolation, "\n",
725 "The original grid must be strictly sorted\n"
726 , "(no duplicate values). Yours is:\n"
727 , old_grid, ".")
728
729 // The max is now the first point, the min the last point!
730 og_max = old_grid[0];
731 og_min = old_grid[n_old - 1];
732 }
733
734 // Min and max of new grid:
735 const Numeric ng_min = min(new_grid);
736 const Numeric ng_max = max(new_grid);
737
738 // If new grid is not inside old grid, determine the indexes of the range
739 // that is.
740
741 const Index iog_min = 0;
742 const Index iog_max = old_grid.nelem() - 1;
743
744 ing_min = 0;
745 ing_max = new_grid.nelem() - 1;
746
747 if (ascending) {
748 if (ng_max > og_max) {
749 while (ing_max > 0 && new_grid[ing_max] > old_grid[iog_max]) ing_max--;
750 }
751
752 if (ng_min < og_min) {
753 while (ing_min < new_grid.nelem() - 1 &&
754 new_grid[ing_min] < old_grid[iog_min])
755 ing_min++;
756 }
757 } else {
758 if (ng_min < og_min) {
759 while (ing_max > 0 && new_grid[ing_max] < old_grid[iog_max]) ing_max--;
760 }
761
762 if (ng_max > og_max) {
763 while (ing_min < new_grid.nelem() - 1 &&
764 new_grid[ing_min] > old_grid[iog_min])
765 ing_min++;
766 }
767 }
768}
769
771
795 Index& ing_min,
796 Index& ing_max,
797 const String& which_interpolation,
798 ConstVectorView old_pgrid,
799 ConstVectorView new_pgrid,
800 const Index order) {
801 // Local variable to store log of the pressure grids
802 Vector logold(old_pgrid.nelem());
803 Vector lognew(new_pgrid.nelem());
804
805 transform(logold, log, old_pgrid);
806 transform(lognew, log, new_pgrid);
807
809 ing_min, ing_max, which_interpolation, logold, lognew, order);
810}
811
813
835 Index& ing_max,
836 const String& which_interpolation,
837 ConstVectorView old_grid,
838 ConstVectorView new_grid,
839 ConstVectorView data) {
840 ARTS_USER_ERROR_IF (!new_grid.nelem(),
841 "The new grid is not allowed to be empty.");
842
843 // Decide whether we have an ascending or descending grid:
844 const bool ascending = (old_grid[0] <= old_grid[1]);
845
846 // If new grid is not inside old grid, determine the indexes of the range
847 // that is.
848
849 const Index iog_min = ascending ? old_grid.nelem() - 1 : 0;
850 const Index iog_max = ascending ? 0 : old_grid.nelem() - 1;
851
852 ARTS_USER_ERROR_IF (ing_min > 0 && data[iog_min] != 0, "There is a problem with the grids for the following interpolation:\n"
853 , which_interpolation, "\n",
854 "\nThe new grid is not fully inside the original grid.\n"
855 , "This is allowed if the corresponding boundary value of raw data is 0.\n"
856 , "New grid point: ", new_grid[ing_min], "\n"
857 , "Old grid point: ", old_grid[iog_min], "\n"
858 , "Boundary value: ", data[iog_min])
859
860 ARTS_USER_ERROR_IF (ing_max < new_grid.nelem() - 1 && data[iog_max] != 0, "There is a problem with the grids for the following interpolation:\n"
861 , which_interpolation, "\n",
862 "\nThe the new grid is not fully inside the original grid.\n"
863 , "This is allowed if the corresponding boundary value of raw data is 0.\n"
864 , "New grid point: ", new_grid[ing_max], "\n"
865 , "Old grid point: ", old_grid[iog_max], "\n"
866 , "Boundary value: ", data[iog_max])
867}
868
870
887void chk_interpolation_grids(const String& which_interpolation,
888 ConstVectorView old_grid,
889 ConstVectorView new_grid,
890 const Index order,
891 const Numeric& extpolfac,
892 const bool islog) {
893 const Index n_old = old_grid.nelem();
894
895 ARTS_USER_ERROR_IF (!new_grid.nelem(),
896 "The new grid is not allowed to be empty.");
897
898 ARTS_USER_ERROR_IF (order < 0,
899 "There is a problem with the grids for the following "
900 "interpolation:\n",
901 which_interpolation, "\n"
902 "Interpolation order must be 0 or larger (but your's is ", order,
903 ").")
904
905 // Old grid must have at least order+1 elements:
906 ARTS_USER_ERROR_IF (n_old < order + 1,
907 "There is a problem with the grids for the following "
908 , "interpolation:\n"
909 , which_interpolation, "\n"
910 , "For interpolation order ", order
911 , ", the original grid must have at least\n"
912 , order + 1, " elements (but your's has only ", n_old, ").")
913
914 // Decide whether we have an ascending or descending grid:
915 const bool ascending = ((n_old > 1) ? (old_grid[0] <= old_grid[1]) : true);
916
917 // Minimum and maximum allowed value from old grid. (Will include
918 // extrapolation tolerance.)
919 Numeric og_min = old_grid[0], og_max = old_grid[0];
920
921 if (ascending) {
922 // Old grid must be strictly increasing (no duplicate values.)
923 ARTS_USER_ERROR_IF (!is_increasing(old_grid),
924 "There is a problem with the grids for the "
925 , "following interpolation:\n"
926 , which_interpolation, "\n"
927 , "The original grid must be strictly sorted\n"
928 , "(no duplicate values). Yours is:\n"
929 , old_grid, ".")
930
931 // Limits of extrapolation.
932 if (n_old > 1) {
933 og_min = old_grid[0] - extpolfac * (old_grid[1] - old_grid[0]);
934 og_max = old_grid[n_old - 1] +
935 extpolfac * (old_grid[n_old - 1] - old_grid[n_old - 2]);
936 }
937 } else {
938 // Old grid must be strictly decreasing (no duplicate values.)
939 ARTS_USER_ERROR_IF (!is_decreasing(old_grid),
940 "There is a problem with the grids for the "
941 , "following interpolation:\n"
942 , which_interpolation, "\n"
943 , "The original grid must be strictly sorted\n"
944 , "(no duplicate values). Yours is:\n"
945 , old_grid, ".")
946
947 // The max is now the first point, the min the last point!
948 // I think the sign is right here...
949 if (n_old > 1) {
950 og_max = old_grid[0] - extpolfac * (old_grid[1] - old_grid[0]);
951 og_min = old_grid[n_old - 1] +
952 extpolfac * (old_grid[n_old - 1] - old_grid[n_old - 2]);
953 }
954 }
955
956 // Min and max of new grid:
957 const Numeric ng_min = min(new_grid);
958 const Numeric ng_max = max(new_grid);
959
960 // New grid must be inside old grid (plus extpolfac).
961 // (Values right on the edge (ng_min==og_min) are still allowed.)
962
963 if (n_old > 1) {
964 ARTS_USER_ERROR_IF (ng_min < og_min,
965 "There is a problem with the grids for the "
966 , "following interpolation:\n"
967 , which_interpolation, "\n"
968 , "The minimum of the new grid must be inside "
969 , "the original grid.\n(We allow a bit of extrapolation, "
970 , "but not so much).\n"
971 , "Minimum of original grid: ", min(old_grid),
972 islog ? var_string(" (", exp(min(old_grid)), ")") : var_string(),
973 "\nMinimum allowed value for new grid: ", og_min,
974 islog ? var_string(" (", exp(og_min), ")") : var_string(),
975 "\nActual minimum of new grid: ", ng_min,
976 islog ? var_string(" (", exp(ng_min), ")") : var_string())
977
978 ARTS_USER_ERROR_IF (ng_max > og_max,
979 "There is a problem with the grids for the "
980 , "following interpolation:\n"
981 , which_interpolation, "\n"
982 , "The maximum of the new grid must be inside\n"
983 , "the original grid. (We allow a bit of extrapolation,\n"
984 , "but not so much).\n"
985 , "Maximum of original grid: ", max(old_grid),
986 islog ? var_string(" (", exp(max(old_grid)), ")") : var_string(),
987 "\nMaximum allowed value for new grid: ", og_max,
988 islog ? var_string(" (", exp(og_max), ")") : var_string(),
989 "\nActual maximum of new grid: ", ng_max,
990 islog ? var_string(" (", exp(ng_max), ")") : var_string())
991 }
992
993 // If we get here, than everything should be fine.
994}
995
997
1019void chk_interpolation_grids(const String& which_interpolation,
1020 ConstVectorView old_grid,
1021 const Numeric& new_grid,
1022 const Index order,
1023 const Numeric& extpolfac) {
1024 const Vector v(1, new_grid);
1025 chk_interpolation_grids(which_interpolation, old_grid, v, order, extpolfac);
1026}
1027
1029
1046void chk_interpolation_pgrids(const String& which_interpolation,
1047 ConstVectorView old_pgrid,
1048 ConstVectorView new_pgrid,
1049 const Index order,
1050 const Numeric& extpolfac) {
1051 // Local variable to store log of the pressure grids
1052 Vector logold(old_pgrid.nelem());
1053 Vector lognew(new_pgrid.nelem());
1054
1055 transform(logold, log, old_pgrid);
1056 transform(lognew, log, new_pgrid);
1057
1059 which_interpolation, logold, lognew, order, extpolfac, true);
1060}
1061
1062/*===========================================================================
1063 === Functions related to atmospheric and surface grids and fields.
1064 ===========================================================================*/
1065
1067
1081void chk_atm_grids(const Index& dim,
1082 ConstVectorView p_grid,
1083 ConstVectorView lat_grid,
1084 ConstVectorView lon_grid) {
1085 // p_grid
1086 ARTS_USER_ERROR_IF (p_grid.nelem() < 2,
1087 "The length of *p_grid* must be >= 2.");
1088 chk_if_decreasing("p_grid", p_grid);
1089
1090 // lat_grid
1091 if (dim == 1) {
1092 ARTS_USER_ERROR_IF (lat_grid.nelem() > 0,
1093 "For dim=1, the length of *lat_grid* must be 0.");
1094 } else {
1095 ARTS_USER_ERROR_IF (lat_grid.nelem() < 2,
1096 "For dim>1, the length of *lat_grid* must be >= 2.");
1097 chk_if_increasing("lat_grid", lat_grid);
1098 }
1099
1100 // lon_grid
1101 if (dim < 3) {
1102 ARTS_USER_ERROR_IF (lon_grid.nelem() > 0,
1103 "For dim<3, the length of *lon_grid* must be 0.");
1104 } else {
1105 ARTS_USER_ERROR_IF (lon_grid.nelem() < 2,
1106 "For dim=3, the length of *lon_grid* must be >= 2.");
1107 chk_if_increasing("lon_grid", lon_grid);
1108 }
1109
1110 // Check that latitude and longitude grids are inside OK ranges for 3D
1111 if (dim == 3) {
1112 ARTS_USER_ERROR_IF (lat_grid[0] < -90,
1113 "The latitude grid cannot extend below -90 degrees for 3D");
1114 ARTS_USER_ERROR_IF (lat_grid[lat_grid.nelem() - 1] > 90,
1115 "The latitude grid cannot extend above 90 degrees for 3D");
1116 ARTS_USER_ERROR_IF (lon_grid[0] < -360,
1117 "No longitude (in lon_grid) can be below -360 degrees.");
1118 ARTS_USER_ERROR_IF (lon_grid[lon_grid.nelem() - 1] > 360,
1119 "No longitude (in lon_grid) can be above 360 degrees.");
1120 ARTS_USER_ERROR_IF (lon_grid[lon_grid.nelem() - 1] - lon_grid[0] > 360,
1121 "The longitude grid is not allowed to cover more than 360 degrees.");
1122 }
1123}
1124
1126
1143void chk_atm_field(const String& x_name,
1144 ConstTensor3View x,
1145 const Index& dim,
1146 ConstVectorView p_grid,
1147 ConstVectorView lat_grid,
1148 ConstVectorView lon_grid,
1149 const bool& chk_lat90) {
1150 // It is assumed that grids OK-ed through chk_atm_grids
1151 Index npages = p_grid.nelem(), nrows = 1, ncols = 1;
1152 if (dim > 1) nrows = lat_grid.nelem();
1153 if (dim > 2) ncols = lon_grid.nelem();
1154 ARTS_USER_ERROR_IF (x.ncols() != ncols || x.nrows() != nrows || x.npages() != npages,
1155 "The atmospheric field *", x_name, "* has wrong size.\n"
1156 , "Expected size is ", npages, " x ", nrows, " x ", ncols
1157 , ", while actual size is ", x.npages(), " x ", x.nrows(), " x "
1158 , x.ncols(), ".")
1159
1160 // NaNs are not allowed
1161 for (Index ip = 0; ip < npages; ip++) {
1162 for (Index ir = 0; ir < nrows; ir++) {
1163 for (Index ic = 0; ic < ncols; ic++) {
1164 ARTS_USER_ERROR_IF (std::isnan(x(ip, ir, ic)),
1165 "The variable *", x_name, "* contains one or "
1166 , "several NaNs. This is not allowed!")
1167 }
1168 }
1169 }
1170
1171 // Special 3D checks:
1172 if (dim == 3) {
1173 // If all lons are covered, check if cyclic
1174 if (is_lon_cyclic(lon_grid)) {
1175 const Index ic = ncols - 1;
1176 for (Index ip = 0; ip < npages; ip++) {
1177 for (Index ir = 0; ir < nrows; ir++) {
1178 ARTS_USER_ERROR_IF (!is_same_within_epsilon(
1179 x(ip, ir, ic), x(ip, ir, 0), 4 * DBL_EPSILON),
1180 "The variable *", x_name, "* covers 360 "
1181 , "degrees in the longitude direction, but the field "
1182 , "seems to deviate between first and last longitude "
1183 , "point. The field must be \"cyclic\".\n"
1184 , "Difference: ", setprecision(16)
1185 , x(ip, ir, ic) - x(ip, ir, 0), "\n"
1186 , "Epsilon : "
1187 , 4 * DBL_EPSILON * max(x(ip, ir, ic), x(ip, ir, 0)))
1188 }
1189 }
1190 }
1191
1192 chk_if_bool("chk_lat90", chk_lat90);
1193 if (chk_lat90) {
1194 // No variation at the South pole!
1195 if (lat_grid[0] == -90) {
1196 for (Index ip = 0; ip < npages; ip++) {
1197 for (Index ic = 1; ic < ncols; ic++) {
1198 ARTS_USER_ERROR_IF (!is_same_within_epsilon(
1199 x(ip, 0, ic), x(ip, 0, ic - 1), 2 * DBL_EPSILON),
1200 "The variable *", x_name, "* covers the South\n"
1201 , "pole. The data corresponding to the pole can not\n"
1202 , "vary with longitude, but this appears to be the\n"
1203 , "case.")
1204 /* , "case: at ", ip, ".th pressure it has val\n"
1205 , x(ip,0,ic-1), ", but ", x(ip,0,ic)
1206 , " (i.e., a diff of ", fabs(x(ip,0,ic)-x(ip,0,ic-1))
1207 , ") at ", ic-1, "th and ", ic, "th longitudes!\n";
1208*/
1209 }
1210 }
1211 }
1212 // No variation at the North pole!
1213 if (lat_grid[nrows - 1] == 90) {
1214 const Index ir = nrows - 1;
1215 for (Index ip = 0; ip < npages; ip++) {
1216 for (Index ic = 1; ic < ncols; ic++) {
1217 ARTS_USER_ERROR_IF (!is_same_within_epsilon(
1218 x(ip, ir, ic), x(ip, ir, ic - 1), 2 * DBL_EPSILON),
1219 "The variable *", x_name, "* covers the North\n"
1220 , "pole. The data corresponding to the pole can not\n"
1221 , "vary with longitude, but this appears to be the "
1222 , "case.")
1223 /* , "case: at ", ip, ".th pressure it has val\n"
1224 , x(ip,ir,ic-1), ", but ", x(ip,ir,ic)
1225 , " (i.e., a diff of ", fabs(x(ip,ir,ic)-x(ip,ir,ic-1))
1226 , ") at ", ic-1, "th and ", ic, "th longitudes!\n";
1227*/
1228 }
1229 }
1230 }
1231 }
1232 }
1233}
1234
1236
1254void chk_atm_field(const String& x_name,
1255 ConstTensor4View x,
1256 const Index& dim,
1257 const Index& nspecies,
1258 ConstVectorView p_grid,
1259 ConstVectorView lat_grid,
1260 ConstVectorView lon_grid,
1261 const bool& check_nan) {
1262 const Index nbooks = nspecies;
1263 //
1264 if (nbooks == 0) {
1265 ARTS_USER_ERROR_IF (x.nbooks(),
1266 "The atmospheric field *", x_name, "* should be empty.\n")
1267 return;
1268 }
1269
1270 Index npages = p_grid.nelem(), nrows = 1, ncols = 1;
1271 if (dim > 1) nrows = lat_grid.nelem();
1272 if (dim > 2) ncols = lon_grid.nelem();
1273
1274 ARTS_USER_ERROR_IF (x.ncols() != ncols || x.nrows() != nrows || x.npages() != npages ||
1275 x.nbooks() != nbooks,
1276 "The atmospheric field *", x_name, "* has wrong size.\n"
1277 , "Expected size is ", nbooks, " x ", npages, " x ", nrows
1278 , " x ", ncols, ",\n"
1279 , "while actual size is ", x.nbooks(), " x ", x.npages(), " x "
1280 , x.nrows(), " x ", x.ncols(), ".")
1281
1282 if (check_nan)
1283 // NaNs are not allowed
1284 {
1285 for (Index ib = 0; ib < nbooks; ib++) {
1286 for (Index ip = 0; ip < npages; ip++) {
1287 for (Index ir = 0; ir < nrows; ir++) {
1288 for (Index ic = 0; ic < ncols; ic++) {
1289 ARTS_USER_ERROR_IF (std::isnan(x(ib, ip, ir, ic)),
1290 "The variable *", x_name, "* contains one or "
1291 , "several NaNs. This is not allowed!")
1292 }
1293 }
1294 }
1295 }
1296 }
1297
1298 // Special 3D checks:
1299 if (dim == 3) {
1300 // If all lons are covered, check if cyclic
1301 if ((lon_grid[ncols - 1] - lon_grid[0]) == 360) {
1302 const Index ic = ncols - 1;
1303 for (Index is = 0; is < nspecies; is++) {
1304 for (Index ip = 0; ip < npages; ip++) {
1305 for (Index ir = 0; ir < nrows; ir++) {
1306 ARTS_USER_ERROR_IF (!is_same_within_epsilon(
1307 x(is, ip, ir, ic), x(is, ip, ir, 0), 2 * DBL_EPSILON),
1308 "The variable *", x_name, "* covers 360 "
1309 , "degrees in the longitude direction, but at least "
1310 , "one field seems to deviate between first and last "
1311 , "longitude point. The field must be \"cyclic\". "
1312 , "This was found for field with index ", is
1313 , " (0-based).")
1314 }
1315 }
1316 }
1317 }
1318 // No variation at the South pole!
1319 if (lat_grid[0] == -90) {
1320 for (Index is = 0; is < nspecies; is++) {
1321 for (Index ip = 0; ip < npages; ip++) {
1322 for (Index ic = 1; ic < ncols; ic++) {
1323 ARTS_USER_ERROR_IF (!is_same_within_epsilon(
1324 x(is, ip, 0, ic), x(is, ip, 0, ic - 1), 2 * DBL_EPSILON),
1325 "The variable *", x_name, "* covers the South "
1326 , "pole. The data corresponding to the pole can not "
1327 , "vary with longitude, but this appears to be the "
1328 , "case. This was found for field with index ", is
1329 , " (0-based).")
1330 }
1331 }
1332 }
1333 }
1334 // No variation at the North pole!
1335 if (lat_grid[nrows - 1] == 90) {
1336 const Index ir = nrows - 1;
1337 for (Index is = 0; is < nspecies; is++) {
1338 for (Index ip = 0; ip < npages; ip++) {
1339 for (Index ic = 1; ic < ncols; ic++) {
1340 ARTS_USER_ERROR_IF (!is_same_within_epsilon(x(is, ip, ir, ic),
1341 x(is, ip, ir, ic - 1),
1342 2 * DBL_EPSILON),
1343 "The variable *", x_name, "* covers the North "
1344 , "pole. The data corresponding to the pole can not "
1345 , "vary with longitude, but this appears to be the "
1346 , "case. This was found for field with index ", is
1347 , " (0-based).")
1348 }
1349 }
1350 }
1351 }
1352 }
1353}
1354
1356
1381void chk_atm_vecfield_lat90(const String& x1_name,
1382 ConstTensor3View x1,
1383 const String& x2_name,
1384 ConstTensor3View x2,
1385 const Index& dim,
1386 ConstVectorView lat_grid,
1387 const Numeric& threshold) {
1388 // It is assumed that grids OK-ed through chk_atm_grids and fields
1389 // individually OK-ed.
1390
1391 // We only need to check 3D cases. Else there is no variation in longitude
1392 // anyways.
1393 if (dim == 3) {
1394 Index npages = x1.npages();
1395 Index nrows = x1.nrows();
1396 Index ncols = x1.ncols();
1397
1398 // For safety check that both fields have identical dimensions
1399 ARTS_USER_ERROR_IF (x2.ncols() != ncols || x2.nrows() != nrows || x2.npages() != npages,
1400 "The atmospheric fields *", x1_name, "* and *", x2_name
1401 , "* do not match in size.\n"
1402 , "*", x1_name, "*'s size is ", npages, " x ", nrows
1403 , " x ", ncols, ", while *", x1_name, "*'s size is "
1404 , x2.npages(), " x ", x2.nrows(), " x ", x2.ncols(), ".")
1405
1406 // redefine ratio deviation threshold of vector lengths to ratio of
1407 // squared vector lengths, cause don't want to calc squareroot everytime.
1408 // (val1**2/val2**2 - 1) / (val1/val2 - 1) = val1/val2 + 1
1409 // and with val1~val2 = 2
1410 // i.e., (val1**2/val2**2 - 1) ~ 2 * (val1/val2 - 1)
1411 //
1412 // with val1/1 = sqrt(vec1/2), hence val1/2**2 = vec1/2
1413 // (vec1/vec2 - 1) ~ 2 * (sqrt(vec1)/sqrt(vec2) - 1)
1414 // (sqrt(vec1)/sqrt(vec2) - 1) ~ (vec1/vec2 - 1) / 2
1415 //
1416 // we want to check: sqrt(vec1)/sqrt(vec2) - 1. < threshold
1417 // i.e., with the above,
1418 // (vec1/vec2 - 1) / 2 < threshold
1419 // (vec1/vec2 - 1) < threshold*2
1420 Numeric th = threshold * 2.;
1421
1422 // No variation at the South pole!
1423 if (lat_grid[0] == -90) {
1424 Numeric vec1, vec2;
1425 for (Index ip = 0; ip < npages; ip++) {
1426 for (Index ic = 1; ic < ncols; ic++) {
1427 vec1 = x1(ip, 0, ic) * x1(ip, 0, ic) + x2(ip, 0, ic) * x2(ip, 0, ic);
1428 vec2 = x1(ip, 0, ic - 1) * x1(ip, 0, ic - 1) +
1429 x2(ip, 0, ic - 1) * x2(ip, 0, ic - 1);
1430 ARTS_USER_ERROR_IF (fabs(vec1 / vec2 - 1.) > th,
1431 "The variables *", x1_name, "* and *", x2_name
1432 , "* are assumed\n"
1433 , "to be two horizontal components of a vector field.\n"
1434 , "At the pole, the data (here: the total length of\n"
1435 , "the horizontal vector) can NOT vary with longitude,\n"
1436 , "but this appears to be the case on the South pole.\n"
1437 , "The threshold is ", threshold, ", but the actual\n"
1438 , "deviation at pressure level ", ip, " and longitude\n"
1439 , "points ", ic - 1, " and ", ic, " is "
1440 , sqrt(vec1) / sqrt(vec2) - 1.)
1441 }
1442 }
1443 }
1444 // No variation at the North pole!
1445 if (lat_grid[nrows - 1] == 90) {
1446 Numeric vec1, vec2;
1447 const Index ir = nrows - 1;
1448 for (Index ip = 0; ip < npages; ip++) {
1449 for (Index ic = 1; ic < ncols; ic++) {
1450 vec1 =
1451 x1(ip, ir, ic) * x1(ip, ir, ic) + x2(ip, ir, ic) * x2(ip, ir, ic);
1452 vec2 = x1(ip, ir, ic - 1) * x1(ip, ir, ic - 1) +
1453 x2(ip, ir, ic - 1) * x2(ip, ir, ic - 1);
1454 ARTS_USER_ERROR_IF (fabs(vec1 / vec2 - 1.) > th,
1455 "The variables *", x1_name, "* and *", x2_name
1456 , "* are assumed\n"
1457 , "to be two horizontal components of a vector field.\n"
1458 , "At the pole, the data (here: the total length of\n"
1459 , "the horizontal vector) can NOT vary with longitude,\n"
1460 , "but this appears to be the case on the North pole.\n"
1461 , "The threshold is ", threshold, ", but the actual\n"
1462 , "deviation at pressure level ", ip, " and longitude\n"
1463 , "points ", ic - 1, " and ", ic, " is "
1464 , sqrt(vec1) / sqrt(vec2) - 1.)
1465 }
1466 }
1467 }
1468 }
1469}
1470
1472
1484void chk_latlon_true(const Index& atmosphere_dim,
1485 ConstVectorView lat_grid,
1486 ConstVectorView lat_true,
1487 ConstVectorView lon_true) {
1488 if (atmosphere_dim == 1) {
1489 ARTS_USER_ERROR_IF (lat_true.nelem() != 1 || lon_true.nelem() != 1,
1490 "For 1D, the method requires that *lat_true* "
1491 "and *lon_true* have length 1.");
1492 }
1493 //
1494 if (atmosphere_dim == 2) {
1495 ARTS_USER_ERROR_IF (lat_true.nelem() != lat_grid.nelem() ||
1496 lon_true.nelem() != lat_grid.nelem(),
1497 "For 2D, the method requires that *lat_true* "
1498 "and *lon_true* have the same length as *lat_grid*.");
1499 }
1500}
1501
1503
1517void chk_atm_surface(const String& x_name,
1518 const Matrix& x,
1519 const Index& dim,
1520 ConstVectorView lat_grid,
1521 ConstVectorView lon_grid) {
1522 Index ncols = 1, nrows = 1;
1523 if (dim > 1) nrows = lat_grid.nelem();
1524 if (dim > 2) ncols = lon_grid.nelem();
1525 ARTS_USER_ERROR_IF (x.ncols() != ncols || x.nrows() != nrows,
1526 "The surface variable *", x_name, "* has wrong size.\n"
1527 , "Expected size is ", nrows, " x ", ncols, ","
1528 , " while actual size is ", x.nrows(), " x ", x.ncols(), ".")
1529
1530 // Special 3D checks:
1531 if (dim == 3) {
1532 // If all lons are covered, check if cyclic
1533 if ((lon_grid[ncols - 1] - lon_grid[0]) == 360) {
1534 const Index ic = ncols - 1;
1535 for (Index ir = 0; ir < nrows; ir++) {
1536 ARTS_USER_ERROR_IF (!is_same_within_epsilon(x(ir, ic), x(ir, 0), 2 * DBL_EPSILON),
1537 "The variable *", x_name, "* covers 360 "
1538 , "degrees in the longitude direction, but the field "
1539 , "seems to deviate between first and last longitude "
1540 , "point. The field must be \"cyclic\".")
1541 }
1542 }
1543
1544 // No variation at the South pole!
1545 if (lat_grid[0] == -90) {
1546 for (Index ic = 1; ic < ncols; ic++) {
1547 ARTS_USER_ERROR_IF (!is_same_within_epsilon(x(0, ic), x(0, ic - 1), 2 * DBL_EPSILON),
1548 "The variable *", x_name, "* covers the South "
1549 , "pole. The data corresponding to the pole can not "
1550 , "vary with longitude, but this appears to be the "
1551 , "case.")
1552 }
1553 }
1554 // No variation at the North pole!
1555 if (lat_grid[nrows - 1] == 90) {
1556 const Index ir = nrows - 1;
1557 for (Index ic = 1; ic < ncols; ic++) {
1558 ARTS_USER_ERROR_IF (!is_same_within_epsilon(
1559 x(ir, ic), x(ir, ic - 1), 2 * DBL_EPSILON),
1560 "The variable *", x_name, "* covers the North "
1561 , "pole. The data corresponding to the pole can not "
1562 , "vary with longitude, but this appears to be the "
1563 , "case.")
1564 }
1565 }
1566 }
1567}
1568
1569/*===========================================================================
1570 === Functions related to sensor variables.
1571 ===========================================================================*/
1572
1574
1586void chk_rte_pos(const Index& atmosphere_dim,
1587 ConstVectorView rte_pos,
1588 const bool& is_rte_pos2)
1589
1590{
1591 String vname = "*rte_pos*";
1592 if (is_rte_pos2) {
1593 vname = "*rte_pos2*";
1594 }
1595
1596 if (atmosphere_dim == 1) {
1597 if (!is_rte_pos2) {
1598 ARTS_USER_ERROR_IF (rte_pos.nelem() != 1,
1599 "For 1D, ", vname, " must have length 1.")
1600 } else {
1601 ARTS_USER_ERROR_IF (rte_pos.nelem() != 2,
1602 "For 1D, ", vname, " must have length 2.")
1603 ARTS_USER_ERROR_IF (rte_pos[1] < -180 || rte_pos[1] > 180,
1604 "For 1D, the latitude in ", vname, " must be in the "
1605 , "range [-180,180].")
1606 }
1607 } else if (atmosphere_dim == 2) {
1608 ARTS_USER_ERROR_IF (rte_pos.nelem() != 2,
1609 "For 2D, ", vname, " must have length 2.")
1610 } else {
1611 ARTS_USER_ERROR_IF (rte_pos.nelem() != 3,
1612 "For 3D, ", vname, " must have length 3.")
1613 ARTS_USER_ERROR_IF (rte_pos[1] < -90 || rte_pos[1] > 90,
1614 "The (3D) latitude in ", vname, " must be in the "
1615 , "range [-90,90].")
1616 ARTS_USER_ERROR_IF (rte_pos[2] < -360 || rte_pos[2] > 360,
1617 "The longitude in ", vname, " must be in the "
1618 , "range [-360,360].")
1619 }
1620}
1621
1623
1634void chk_rte_los(const Index& atmosphere_dim, ConstVectorView rte_los)
1635
1636{
1637 if (atmosphere_dim == 1) {
1638 ARTS_USER_ERROR_IF (rte_los.nelem() != 1,
1639 "For 1D, los-vectors must have length 1.");
1640 ARTS_USER_ERROR_IF (rte_los[0] < 0 || rte_los[0] > 180,
1641 "For 1D, the zenith angle of a los-vector must "
1642 "be in the range [0,180].");
1643 } else if (atmosphere_dim == 2) {
1644 ARTS_USER_ERROR_IF (rte_los.nelem() != 1,
1645 "For 2D, los-vectors must have length 1.");
1646 ARTS_USER_ERROR_IF (rte_los[0] < -180 || rte_los[0] > 180,
1647 "For 2D, the zenith angle of a los-vector must "
1648 "be in the range [-180,180].");
1649 } else {
1650 ARTS_USER_ERROR_IF (rte_los.nelem() != 2,
1651 "For 3D, los-vectors must have length 2.");
1652 ARTS_USER_ERROR_IF (rte_los[0] < 0 || rte_los[0] > 180,
1653 "For 3D, the zenith angle of a los-vector must "
1654 "be in the range [0,180].");
1655 ARTS_USER_ERROR_IF (rte_los[1] < -180 || rte_los[1] > 180,
1656 "For 3D, the azimuth angle of a los-vector must "
1657 "be in the range [-180,180].");
1658 }
1659}
1660
1661/*===========================================================================
1662 === Functions related to GriddedFields.
1663 ===========================================================================*/
1664
1666
1676 const Index gridindex,
1677 const String& gridname) {
1678 ARTS_USER_ERROR_IF (gf.get_dim() - 1 < gridindex,
1679 "Grid index ", gridindex, " exceeds dimension of GriddedField",
1680 (gf.get_name().nelem()) ? var_string(" \"", gf.get_name(), "\"") : var_string())
1681
1682 String gfgridnameupper = gf.get_grid_name(gridindex);
1683 gfgridnameupper.toupper();
1684
1685 String gridnameupper = gridname;
1686 gridnameupper.toupper();
1687
1688 ARTS_USER_ERROR_IF (gfgridnameupper != gridnameupper,
1689 "Name of grid ", gridindex, " in GriddedField",
1690 (gf.get_name().nelem()) ? var_string(" \"", gf.get_name(), "\"") : var_string(),
1691 " is \"", gf.get_grid_name(gridindex), "\".\n"
1692 , "The expected name is \"", gridname, "\".")
1693}
1694
1695/*===========================================================================
1696 === Functions checking sensor
1697 ===========================================================================*/
1698
1709void chk_met_mm_backend(const Matrix& mmb) {
1710 ARTS_USER_ERROR_IF (!mmb.nrows(),
1711 "No channels defined in *met_mm_backend*.");
1712
1713 ARTS_USER_ERROR_IF (mmb.ncols() != 4,
1714 "*met_mm_backend* must have 4 columns.");
1715
1716 for (Index ch = 0; ch < mmb.nrows(); ch++) {
1717 Numeric lo = mmb(ch, 0);
1718 Numeric offset1 = mmb(ch, 1);
1719 Numeric offset2 = mmb(ch, 2);
1720 Numeric bandwidth = mmb(ch, 3);
1721
1722 // Negative LO
1723 ARTS_USER_ERROR_IF (lo < 0.,
1724 "Error in channel ", ch + 1, " at row ", ch
1725 , " in *met_mm_backend*.\n"
1726 , "Center frequency is negative: ", mmb(ch, 0), " Hz")
1727
1728 // Negative offsets
1729 ARTS_USER_ERROR_IF (offset1 < 0. || offset2 < 0.,
1730 "Error in channel ", ch + 1, " at row ", ch
1731 , " in *met_mm_backend*.\n"
1732 , "Offset is negative:\n"
1733 , "offset1: ", offset1, " Hz\n"
1734 , "offset2: ", offset2, " Hz\n")
1735
1736 // First offset is smaller than second offset
1737 ARTS_USER_ERROR_IF (offset1 != 0. && offset1 <= offset2,
1738 "Error in channel ", ch + 1, " at row ", ch
1739 , " in *met_mm_backend*.\n"
1740 , "First passband offset is smaller than/equal to the second offset:\n"
1741 , "offset1: ", offset1, " Hz\n"
1742 , "offset2: ", offset2, " Hz\n")
1743
1744 // Bandwidth too wide, overlap with LO
1745 ARTS_USER_ERROR_IF (offset1 > 0 && offset1 - offset2 <= bandwidth / 2.,
1746 "Error in channel ", ch + 1, " at row ", ch
1747 , " in *met_mm_backend*.\n"
1748 , "Band touches or overlaps with the center frequency:\n"
1749 , "offset1 : ", offset1, " Hz\n"
1750 , "offset2 : ", offset2, " Hz\n"
1751 , "bandwidth : ", bandwidth, " Hz\n"
1752 , "offset1 - offset2 - bandwidth/2: "
1753 , offset1 - offset2 - bandwidth / 2., " Hz\n")
1754
1755 // Bandwidth too wide, passbands overlap
1756 ARTS_USER_ERROR_IF (offset2 > 0 && offset2 <= bandwidth / 2.,
1757 "Error in channel ", ch + 1, " at row ", ch
1758 , " in *met_mm_backend*.\n"
1759 , "Bands overlap or touch, offset2 > bandwidth/2:\n"
1760 , "offset2 : ", offset2, " Hz\n"
1761 , "bandwidth/2: ", bandwidth / 2., " Hz\n")
1762
1763 // Channel too wide, goes negative
1764 ARTS_USER_ERROR_IF (lo - offset1 - offset2 - bandwidth / 2. <= 0,
1765 "Error in channel ", ch + 1, " at row ", ch
1766 , " in *met_mm_backend*.\n"
1767 , "Band too wide, reaches/exceeds 0 Hz:\n"
1768 , "LO : ", lo, " Hz\n"
1769 , "offset1 : ", offset1, " Hz\n"
1770 , "offset2 : ", offset2, " Hz\n"
1771 , "bandwidth : ", bandwidth, " Hz\n"
1772 , "LO - offset1 - offset2 - bandwidth/2: "
1773 , lo - offset1 - offset2 - bandwidth / 2., " Hz\n")
1774 }
1775}
This file contains the definition of Array.
base max(const Array< base > &x)
Max function.
Definition: array.h:128
base min(const Array< base > &x)
Min function.
Definition: array.h:144
void chk_matrix_ncols(const String &x_name, ConstMatrixView x, const Index &l)
chk_matrix_ncols
Definition: check_input.cc:361
void chk_atm_surface(const String &x_name, const Matrix &x, const Index &dim, ConstVectorView lat_grid, ConstVectorView lon_grid)
chk_atm_surface
void chk_interpolation_pgrids(const String &which_interpolation, ConstVectorView old_pgrid, ConstVectorView new_pgrid, const Index order, const Numeric &extpolfac)
Check log pressure interpolation grids.
void chk_if_bool(const String &x_name, const Index &x)
chk_if_bool
Definition: check_input.cc:46
void chk_atm_grids(const Index &dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid)
chk_atm_grids
void chk_interpolation_grids(const String &which_interpolation, ConstVectorView old_grid, ConstVectorView new_grid, const Index order, const Numeric &extpolfac, const bool islog)
Check interpolation grids.
Definition: check_input.cc:887
void chk_met_mm_backend(const Matrix &mmb)
Check met_mm_backend.
void chk_rte_pos(const Index &atmosphere_dim, ConstVectorView rte_pos, const bool &is_rte_pos2)
chk_rte_pos
void chk_rte_los(const Index &atmosphere_dim, ConstVectorView rte_los)
chk_rte_los
void chk_not_empty(const String &x_name, const Agenda &x)
chk_not_empty
Definition: check_input.cc:608
void chk_size(const String &x_name, ConstVectorView x, const Index &c)
Runtime check for size of Vector.
Definition: check_input.cc:402
void chk_atm_vecfield_lat90(const String &x1_name, ConstTensor3View x1, const String &x2_name, ConstTensor3View x2, const Index &dim, ConstVectorView lat_grid, const Numeric &threshold)
chk_atm_vecfield_lat90
void chk_matrix_nrows(const String &x_name, ConstMatrixView x, const Index &l)
chk_matrix_nrows
Definition: check_input.cc:380
void chk_if_in_range_exclude_low(const String &x_name, const Numeric &x, const Numeric &x_low, const Numeric &x_high)
chk_if_in_range_exclude_low
Definition: check_input.cc:161
void chk_griddedfield_gridname(const GriddedField &gf, const Index gridindex, const String &gridname)
Check name of grid in GriddedField.
void chk_latlon_true(const Index &atmosphere_dim, ConstVectorView lat_grid, ConstVectorView lat_true, ConstVectorView lon_true)
chk_latlon_true
void chk_interpolation_pgrids_loose_no_data_check(Index &ing_min, Index &ing_max, const String &which_interpolation, ConstVectorView old_pgrid, ConstVectorView new_pgrid, const Index order)
Check log pressure interpolation grids.
Definition: check_input.cc:794
void chk_if_in_range(const String &x_name, const Index &x, const Index &x_low, const Index &x_high)
chk_if_in_range
Definition: check_input.cc:67
void chk_if_in_range_exclude(const String &x_name, const Numeric &x, const Numeric &x_low, const Numeric &x_high)
chk_if_in_range_exclude
Definition: check_input.cc:211
void chk_interpolation_grids_loose(Index &ing_min, Index &ing_max, const String &which_interpolation, ConstVectorView old_grid, ConstVectorView new_grid, ConstVectorView data, const Index order)
Check interpolation grids.
Definition: check_input.cc:646
void chk_if_equal(const String &x1_name, const String &x2_name, ConstVectorView v1, ConstVectorView v2, Numeric margin)
chk_if_equal
Definition: check_input.cc:326
void chk_if_decreasing(const String &x_name, ConstVectorView x)
chk_if_decreasing
Definition: check_input.cc:306
void chk_atm_field(const String &x_name, ConstTensor3View x, const Index &dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, const bool &chk_lat90)
chk_atm_field (simple fields)
void chk_if_increasing(const String &x_name, const ArrayOfIndex &x)
chk_if_increasing
Definition: check_input.cc:92
void chk_interpolation_grids_loose_no_data_check(Index &ing_min, Index &ing_max, const String &which_interpolation, ConstVectorView old_grid, ConstVectorView new_grid, const Index order)
Check interpolation grids.
Definition: check_input.cc:684
void chk_if_in_range_exclude_high(const String &x_name, const Numeric &x, const Numeric &x_low, const Numeric &x_high)
chk_if_in_range_exclude_high
Definition: check_input.cc:186
void chk_interpolation_grids_loose_check_data(Index &ing_min, Index &ing_max, const String &which_interpolation, ConstVectorView old_grid, ConstVectorView new_grid, ConstVectorView data)
Check interpolation grids.
Definition: check_input.cc:834
void chk_vector_length(const String &x_name, ConstVectorView x, const Index &l)
chk_vector_length
Definition: check_input.cc:238
void chk_not_negative(const String &x_name, const Numeric &x)
chk_not_negative
Definition: check_input.cc:115
The Agenda class.
Definition: agenda_class.h:52
Index nelem() const
Return the number of agenda elements.
const String & get_name() const
Get the name of this gridded field.
Index get_dim() const
Get the dimension of this gridded field.
const String & get_grid_name(Index i) const
Get grid name.
Index nelem() const
Definition: mystring.h:172
void toupper()
Convert to upper case.
Definition: mystring.h:130
std::string var_string(Args &&... args)
Definition: debug.h:18
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:135
Implementation of gridded fields.
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.
#define v
#define c
#define b