ARTS  2.2.66
check_input.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2012
2  Patrick Eriksson <patrick.eriksson@chalmers.se>
3  Stefan Buehler <sbuehler@ltu.se>
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation; either version 2, or (at your option) any
8  later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18  USA. */
19 
20 
21 
22 /*===========================================================================
23  === File description
24  ===========================================================================*/
25 
36 /*===========================================================================
37  === External declarations
38  ===========================================================================*/
39 
40 #include <cmath>
41 #include <stdexcept>
42 #include "auto_md.h"
43 #include "check_input.h"
44 #include "array.h"
45 #include "logic.h"
46 #include "gridded_fields.h"
47 #include <cfloat>
48 
49 extern const Index GFIELD3_P_GRID;
50 extern const Index GFIELD3_LAT_GRID;
51 extern const Index GFIELD3_LON_GRID;
52 
53 
54 
55 
56 
57 /*===========================================================================
58  === Functions for Index
59  ===========================================================================*/
60 
62 
74  const String& x_name,
75  const Index& x )
76 {
77  if ( !is_bool(x) )
78  {
79  ostringstream os;
80  os << "The variable *" << x_name << "* must be a boolean (0 or 1).\n"
81  << "The present value of *"<< x_name << "* is " << x << ".";
82  throw runtime_error( os.str() );
83  }
84 }
85 
87 
102  const String& x_name,
103  const Index& x,
104  const Index& x_low,
105  const Index& x_high )
106 {
107  if ( (x<x_low) || (x>x_high) )
108  {
109  ostringstream os;
110  os << "The variable *" << x_name << "* must fulfill:\n"
111  << " " << x_low << " <= " << x_name << " <= " << x_high << "\n"
112  << "The present value of *"<< x_name << "* is " << x << ".";
113  throw runtime_error( os.str() );
114  }
115 }
116 
118 
133  const String& x_name,
134  const ArrayOfIndex& x )
135 {
136  if ( !is_increasing(x) )
137  {
138  ostringstream os;
139  os << "The ArrayOfIndex *" << x_name << "* must have strictly\n"
140  << "increasing values, but this is not the case.\n";
141  os << "x = " << x << "\n";
142  throw runtime_error( os.str() );
143  }
144 }
145 
146 
147 
148 
149 
150 /*===========================================================================
151  === Functions for Numeric
152  ===========================================================================*/
153 
155 
167  const String& x_name,
168  const Numeric& x )
169 {
170  if ( x < 0 )
171  {
172  ostringstream os;
173  os << "The variable *" << x_name << "* must be >= 0.\n"
174  << "The present value of *"<< x_name << "* is " << x << ".";
175  throw runtime_error( os.str() );
176  }
177 }
178 
179 
180 
182 
197  const String& x_name,
198  const Numeric& x,
199  const Numeric& x_low,
200  const Numeric& x_high )
201 {
202  if ( (x<x_low) || (x>x_high) )
203  {
204  ostringstream os;
205  os << "The variable *" << x_name << "* must fulfill:\n"
206  << " " << x_low << " <= " << x_name << " <= " << x_high << "\n"
207  << "The present value of *"<< x_name << "* is " << x << ".";
208  throw runtime_error( os.str() );
209  }
210 }
211 
212 
213 
214 
215 
216 /*===========================================================================
217  === Functions for Vector
218  ===========================================================================*/
219 
221 
234  const String& x_name,
235  ConstVectorView x,
236  const Index& l )
237 {
238  if ( x.nelem() != l )
239  {
240  ostringstream os;
241  os << "The vector *" << x_name << "* must have the length " << l
242  << ".\n"
243  << "The present length of *"<< x_name << "* is " << x.nelem() << ".";
244  throw runtime_error( os.str() );
245  }
246 }
247 
248 
249 
251 
265  const String& x1_name,
266  const String& x2_name,
267  ConstVectorView x1,
268  ConstVectorView x2 )
269 {
270  if ( x1.nelem() != x2.nelem() )
271  {
272  ostringstream os;
273  os << "The vectors *" << x1_name << "* and *" << x2_name
274  << "* must have the same length.\n"
275  << "The length of *"<< x1_name << "* is " << x1.nelem() << ".\n"
276  << "The length of *"<< x2_name << "* is " << x2.nelem() << ".";
277  throw runtime_error( os.str() );
278  }
279 }
280 
281 
282 
284 
298  const String& x_name,
299  ConstVectorView x )
300 {
301  if ( !is_increasing(x) )
302  {
303  ostringstream os;
304  os << "The vector *" << x_name << "* must have strictly\n"
305  << "increasing values, but this is not the case.\n";
306  os << "x = " << x << "\n";
307  throw runtime_error( os.str() );
308  }
309 }
310 
311 
312 
314 
328  const String& x_name,
329  ConstVectorView x )
330 {
331  if ( !is_decreasing(x) )
332  {
333  ostringstream os;
334  os << "The vector *" << x_name << "* must have strictly\ndecreasing "
335  << "values, but this is not the case.\n";
336  throw runtime_error( os.str() );
337  }
338 }
339 
340 
341 
343 
357  const String& x1_name,
358  const String& x2_name,
359  ConstVectorView v1,
360  ConstVectorView v2,
361  Numeric margin
362  )
363 {
364  chk_vector_length(x1_name, x2_name, v1, v2);
365 
366  for (Index i = 0; i<v1.nelem(); i++)
367  {
368  if (abs(v1[i] - v2[i]) > margin)
369  {
370  ostringstream os;
371  os << "Vectors " << x1_name << " and " << x2_name
372  << " differ.\n"
373  << x1_name << "[" << i << "]" << " = " << v1[i] << "\n"
374  << x2_name << "[" << i << "]" << " = " << v2[i] << "\n"
375  << "Difference should not exceed " << margin << "\n";
376  throw runtime_error(os.str());
377  }
378  }
379 }
380 
381 
382 
383 
384 
385 /*===========================================================================
386  === Functions for Matrix
387  ===========================================================================*/
388 
390 
403  const String& x_name,
404  ConstMatrixView x,
405  const Index& l )
406 {
407  if ( x.ncols() != l )
408  {
409  ostringstream os;
410  os << "The matrix *" << x_name << "* must have " << l << " columns,\n"
411  << "but the number of columns is " << x.ncols() << ".";
412  throw runtime_error( os.str() );
413  }
414 }
415 
416 
417 
419 
432  const String& x_name,
433  ConstMatrixView x,
434  const Index& l )
435 {
436  if ( x.nrows() != l )
437  {
438  ostringstream os;
439  os << "The matrix *" << x_name << "* must have " << l << " rows,\n"
440  << "but the number of rows is " << x.nrows() << ".";
441  throw runtime_error( os.str() );
442  }
443 }
444 
445 
446 
447 
448 
449 /*===========================================================================
450  === Functions for Tensors
451  ===========================================================================*/
452 
454 
465 void chk_size( const String& x_name,
466  ConstVectorView x,
467  const Index& c )
468 {
469  if ( !is_size(x,c) )
470  {
471  ostringstream os;
472  os << "The object *" << x_name
473  << "* does not have the right size.\n"
474  << "Dimension should be:"
475  << " " << c
476  << ",\nbut it is: "
477  << " " << x.nelem()
478  << ".";
479  throw runtime_error( os.str() );
480  }
481 }
482 
484 
496 void chk_size( const String& x_name,
497  ConstMatrixView x,
498  const Index& r,
499  const Index& c )
500 {
501  if ( !is_size(x,r,c) )
502  {
503  ostringstream os;
504  os << "The object *" << x_name
505  << "* does not have the right size.\n"
506  << "Dimensions should be:"
507  << " " << r
508  << " " << c
509  << ",\nbut they are: "
510  << " " << x.nrows()
511  << " " << x.ncols()
512  << ".";
513  throw runtime_error( os.str() );
514  }
515 }
516 
518 
531 void chk_size( const String& x_name,
533  const Index& p,
534  const Index& r,
535  const Index& c )
536 {
537  if ( !is_size(x,p,r,c) )
538  {
539  ostringstream os;
540  os << "The object *" << x_name
541  << "* does not have the right size.\n"
542  << "Dimensions should be:"
543  << " " << p
544  << " " << r
545  << " " << c
546  << ",\nbut they are: "
547  << " " << x.npages()
548  << " " << x.nrows()
549  << " " << x.ncols()
550  << ".";
551  throw runtime_error( os.str() );
552  }
553 }
554 
556 
570 void chk_size( const String& x_name,
572  const Index& b,
573  const Index& p,
574  const Index& r,
575  const Index& c )
576 {
577  if ( !is_size(x,b,p,r,c) )
578  {
579  ostringstream os;
580  os << "The object *" << x_name
581  << "* does not have the right size.\n"
582  << "Dimensions should be:"
583  << " " << b
584  << " " << p
585  << " " << r
586  << " " << c
587  << ",\nbut they are: "
588  << " " << x.nbooks()
589  << " " << x.npages()
590  << " " << x.nrows()
591  << " " << x.ncols()
592  << ".";
593  throw runtime_error( os.str() );
594  }
595 }
596 
598 
613 void chk_size( const String& x_name,
615  const Index& s,
616  const Index& b,
617  const Index& p,
618  const Index& r,
619  const Index& c )
620 {
621  if ( !is_size(x,s,b,p,r,c) )
622  {
623  ostringstream os;
624  os << "The object *" << x_name
625  << "* does not have the right size.\n"
626  << "Dimensions should be:"
627  << " " << s
628  << " " << b
629  << " " << p
630  << " " << r
631  << " " << c
632  << ",\nbut they are: "
633  << " " << x.nshelves()
634  << " " << x.nbooks()
635  << " " << x.npages()
636  << " " << x.nrows()
637  << " " << x.ncols()
638  << ".";
639  throw runtime_error( os.str() );
640  }
641 }
642 
644 
660 void chk_size( const String& x_name,
662  const Index& v,
663  const Index& s,
664  const Index& b,
665  const Index& p,
666  const Index& r,
667  const Index& c )
668 {
669  if ( !is_size(x,v,s,b,p,r,c) )
670  {
671  ostringstream os;
672  os << "The object *" << x_name
673  << "* does not have the right size.\n"
674  << "Dimensions should be:"
675  << " " << v
676  << " " << s
677  << " " << b
678  << " " << p
679  << " " << r
680  << " " << c
681  << ",\nbut they are: "
682  << " " << x.nvitrines()
683  << " " << x.nshelves()
684  << " " << x.nbooks()
685  << " " << x.npages()
686  << " " << x.nrows()
687  << " " << x.ncols()
688  << ".";
689  throw runtime_error( os.str() );
690  }
691 }
692 
694 
711 void chk_size( const String& x_name,
713  const Index& l,
714  const Index& v,
715  const Index& s,
716  const Index& b,
717  const Index& p,
718  const Index& r,
719  const Index& c )
720 {
721  if ( !is_size(x,l,v,s,b,p,r,c) )
722  {
723  ostringstream os;
724  os << "The object *" << x_name
725  << "* does not have the right size.\n"
726  << "Dimensions should be:"
727  << " " << l
728  << " " << v
729  << " " << s
730  << " " << b
731  << " " << p
732  << " " << r
733  << " " << c
734  << ",\nbut they are: "
735  << " " << x.nlibraries()
736  << " " << x.nvitrines()
737  << " " << x.nshelves()
738  << " " << x.nbooks()
739  << " " << x.npages()
740  << " " << x.nrows()
741  << " " << x.ncols()
742  << ".";
743  throw runtime_error( os.str() );
744  }
745 }
746 
747 
748 
749 
750 
751 
752 /*===========================================================================
753  === Functions for Agendas
754  ===========================================================================*/
755 
757 
769  const String& x_name,
770  const Agenda& x )
771 {
772  if( x.nelem() == 0 )
773  {
774  ostringstream os;
775  os << "The agenda *" << x_name << "* is empty.\nIt is not allowed \n"
776  << "that an empty agenda that is actually used.\n"
777  << "Empty agendas are only created of methods setting dummy values \n"
778  << "to variables.";
779  throw runtime_error( os.str() );
780  }
781 }
782 
783 
784 
785 
786 
787 
788 
789 /*===========================================================================
790  === Functions for interpolation grids
791  ===========================================================================*/
792 
794 
820  Index& ing_max,
821  const String& which_interpolation,
822  ConstVectorView old_grid,
823  ConstVectorView new_grid,
824  ConstVectorView data,
825  const Index order)
826 {
827  chk_interpolation_grids_loose_no_data_check(ing_min, ing_max, which_interpolation,
828  old_grid, new_grid, order);
829 
830  chk_interpolation_grids_loose_check_data(ing_min, ing_max, which_interpolation,
831  old_grid, new_grid, data);
832 }
833 
834 
836 
860  Index& ing_max,
861  const String& which_interpolation,
862  ConstVectorView old_grid,
863  ConstVectorView new_grid,
864  const Index order)
865 {
866  const Index n_old = old_grid.nelem();
867 
868  if (!new_grid.nelem()) throw runtime_error("The new grid is not allowed to be empty.");
869 
870  ostringstream os;
871  os << "There is a problem with the grids for the\n"
872  << "following interpolation: " << which_interpolation << ".\n";
873 
874  // Old grid must have at least order+1 elements:
875  if (n_old < order+1)
876  {
877  os << "The original grid must have at least " << order+1 << " elements.";
878  throw runtime_error( os.str() );
879  }
880 
881  // Decide whether we have an ascending or descending grid:
882  const bool ascending = ( old_grid[0] <= old_grid[1] );
883 
884  // Minimum and maximum allowed value from old grid. (Will include
885  // extrapolation tolerance.)
886  Numeric og_min, og_max;
887 
888  ing_min = 0;
889  ing_max = new_grid.nelem()-1;
890  if (ascending)
891  {
892  // Old grid must be strictly increasing (no duplicate values.)
893  if ( !is_increasing(old_grid) )
894  {
895  os << "The original grid must be strictly sorted\n"
896  << "(no duplicate values). Yours is:\n"
897  << old_grid << ".";
898  throw runtime_error( os.str() );
899  }
900 
901  // Limits of extrapolation.
902  og_min = old_grid[0];
903  og_max = old_grid[n_old-1];
904  }
905  else
906  {
907  // Old grid must be strictly decreasing (no duplicate values.)
908  if ( !is_decreasing(old_grid) )
909  {
910  os << "The original grid must be strictly sorted\n"
911  << "(no duplicate values). Yours is:\n"
912  << old_grid << ".";
913  throw runtime_error( os.str() );
914  }
915 
916  // The max is now the first point, the min the last point!
917  og_max = old_grid[0];
918  og_min = old_grid[n_old-1];
919  }
920 
921  // Min and max of new grid:
922  const Numeric ng_min = min(new_grid);
923  const Numeric ng_max = max(new_grid);
924 
925  // If new grid is not inside old grid, determine the indexes of the range
926  // that is.
927 
928  const Index iog_min = 0;
929  const Index iog_max = old_grid.nelem()-1;
930 
931  ing_min = 0;
932  ing_max = new_grid.nelem()-1;
933 
934  if (ascending)
935  {
936  if (ng_max > og_max)
937  {
938  while (ing_max > 0 && new_grid[ing_max] > old_grid[iog_max])
939  ing_max--;
940  }
941 
942  if (ng_min < og_min)
943  {
944  while (ing_min < new_grid.nelem()-1 && new_grid[ing_min] < old_grid[iog_min])
945  ing_min++;
946  }
947  }
948  else
949  {
950  if (ng_min < og_min)
951  {
952  while (ing_max > 0 && new_grid[ing_max] < old_grid[iog_max])
953  ing_max--;
954  }
955 
956  if (ng_max > og_max)
957  {
958  while (ing_min < new_grid.nelem()-1 && new_grid[ing_min] > old_grid[iog_min])
959  ing_min++;
960  }
961  }
962 }
963 
964 
966 
990  Index& ing_max,
991  const String& which_interpolation,
992  ConstVectorView old_pgrid,
993  ConstVectorView new_pgrid,
994  const Index order)
995 {
996  // Local variable to store log of the pressure grids
997  Vector logold( old_pgrid.nelem() );
998  Vector lognew( new_pgrid.nelem() );
999 
1000  transform( logold, log, old_pgrid );
1001  transform( lognew, log, new_pgrid );
1002 
1004  which_interpolation,
1005  logold, lognew,
1006  order);
1007 }
1008 
1009 
1011 
1033  Index& ing_max,
1034  const String& which_interpolation,
1035  ConstVectorView old_grid,
1036  ConstVectorView new_grid,
1037  ConstVectorView data)
1038 {
1039  if (!new_grid.nelem()) throw runtime_error("The new grid is not allowed to be empty.");
1040 
1041  ostringstream os;
1042  os << "There is a problem with the grids for the\n"
1043  << "following interpolation: " << which_interpolation << ".\n";
1044 
1045  // Decide whether we have an ascending or descending grid:
1046  const bool ascending = ( old_grid[0] <= old_grid[1] );
1047 
1048  // If new grid is not inside old grid, determine the indexes of the range
1049  // that is.
1050 
1051  const Index iog_min = ascending?old_grid.nelem()-1:0;
1052  const Index iog_max = ascending?0:old_grid.nelem()-1;
1053 
1054  if (ing_min > 0 && data[iog_min] != 0)
1055  {
1056  os << "\nThe new grid is not fully inside the original grid.\n"
1057  << "This is allowed if the corresponding boundary value of raw data is 0.\n"
1058  << "New grid point: " << new_grid[ing_min] << "\n"
1059  << "Old grid point: " << old_grid[iog_min] << "\n"
1060  << "Boundary value: " << data[iog_min];
1061  throw runtime_error(os.str());
1062  }
1063 
1064  if (ing_max < new_grid.nelem()-1 && data[iog_max] != 0)
1065  {
1066  os << "\nThe the new grid is not fully inside the original grid.\n"
1067  << "This is allowed if the corresponding boundary value of raw data is 0.\n"
1068  << "New grid point: " << new_grid[ing_max] << "\n"
1069  << "Old grid point: " << old_grid[iog_max] << "\n"
1070  << "Boundary value: " << data[iog_max];
1071  throw runtime_error(os.str());
1072  }
1073 }
1074 
1075 
1077 
1094 void chk_interpolation_grids(const String& which_interpolation,
1095  ConstVectorView old_grid,
1096  ConstVectorView new_grid,
1097  const Index order,
1098  const Numeric& extpolfac,
1099  const bool islog)
1100 {
1101  const Index n_old = old_grid.nelem();
1102 
1103  if (!new_grid.nelem()) throw runtime_error("The new grid is not allowed to be empty.");
1104 
1105 
1106  // Old grid must have at least order+1 elements:
1107  if (n_old < order+1)
1108  {
1109  ostringstream os;
1110  os << "There is a problem with the grids for the\n"
1111  << "following interpolation: " << which_interpolation << ".\n"
1112  << "The original grid must have at least " << order+1 << " elements.";
1113  throw runtime_error( os.str() );
1114  }
1115 
1116  // Decide whether we have an ascending or descending grid:
1117  const bool ascending = ( old_grid[0] <= old_grid[1] );
1118 
1119  // Minimum and maximum allowed value from old grid. (Will include
1120  // extrapolation tolerance.)
1121  Numeric og_min, og_max;
1122 
1123  if (ascending)
1124  {
1125  // Old grid must be strictly increasing (no duplicate values.)
1126  if ( !is_increasing(old_grid) )
1127  {
1128  ostringstream os;
1129  os << "There is a problem with the grids for the\n"
1130  << "following interpolation: " << which_interpolation << ".\n"
1131  << "The original grid must be strictly sorted\n"
1132  << "(no duplicate values). Yours is:\n"
1133  << old_grid << ".";
1134  throw runtime_error( os.str() );
1135  }
1136 
1137  // Limits of extrapolation.
1138  og_min = old_grid[0] -
1139  extpolfac * ( old_grid[1] - old_grid[0] );
1140  og_max = old_grid[n_old-1] +
1141  extpolfac * ( old_grid[n_old-1] - old_grid[n_old-2] );
1142  }
1143  else
1144  {
1145  // Old grid must be strictly decreasing (no duplicate values.)
1146  if ( !is_decreasing(old_grid) )
1147  {
1148  ostringstream os;
1149  os << "There is a problem with the grids for the\n"
1150  << "following interpolation: " << which_interpolation << ".\n"
1151  << "The original grid must be strictly sorted\n"
1152  << "(no duplicate values). Yours is:\n"
1153  << old_grid << ".";
1154  throw runtime_error( os.str() );
1155  }
1156 
1157  // The max is now the first point, the min the last point!
1158  // I think the sign is right here...
1159  og_max = old_grid[0] -
1160  extpolfac * ( old_grid[1] - old_grid[0] );
1161  og_min = old_grid[n_old-1] +
1162  extpolfac * ( old_grid[n_old-1] - old_grid[n_old-2] );
1163  }
1164 
1165  // Min and max of new grid:
1166  const Numeric ng_min = min(new_grid);
1167  const Numeric ng_max = max(new_grid);
1168 
1169  // New grid must be inside old grid (plus extpolfac).
1170  // (Values right on the edge (ng_min==og_min) are still allowed.)
1171 
1172  if (ng_min < og_min)
1173  {
1174  ostringstream os;
1175  os << "There is a problem with the grids for the\n"
1176  << "following interpolation: " << which_interpolation << ".\n"
1177  << "The minimum of the new grid must be inside\n"
1178  << "the original grid. (We allow a bit of extrapolation,\n"
1179  << "but not so much).\n"
1180  << "Minimum of original grid: " << min(old_grid);
1181  if (islog) os << " (" << exp(min(old_grid)) << ")";
1182  os << "\nMinimum allowed value for new grid: " << og_min;
1183  if (islog) os << " (" << exp(og_min) << ")";
1184  os << "\nActual minimum of new grid: " << ng_min;
1185  if (islog) os << " (" << exp(ng_min) << ")";
1186  throw runtime_error( os.str() );
1187  }
1188 
1189  if (ng_max > og_max)
1190  {
1191  ostringstream os;
1192  os << "There is a problem with the grids for the\n"
1193  << "following interpolation: " << which_interpolation << ".\n"
1194  << "The maximum of the new grid must be inside\n"
1195  << "the original grid. (We allow a bit of extrapolation,\n"
1196  << "but not so much).\n"
1197  << "Maximum of original grid: " << max(old_grid);
1198  if (islog) os << " (" << exp(max(old_grid)) << ")";
1199  os << "\nMaximum allowed value for new grid: " << og_max;
1200  if (islog) os << " (" << exp(og_max) << ")";
1201  os << "\nActual maximum of new grid: " << ng_max;
1202  if (islog) os << " (" << exp(ng_max) << ")";
1203  throw runtime_error( os.str() );
1204  }
1205 
1206  // If we get here, than everything should be fine.
1207 }
1208 
1209 
1211 
1233 void chk_interpolation_grids(const String& which_interpolation,
1234  ConstVectorView old_grid,
1235  const Numeric& new_grid,
1236  const Index order,
1237  const Numeric& extpolfac )
1238 {
1239  const Vector v(1, new_grid);
1240  chk_interpolation_grids(which_interpolation,
1241  old_grid,
1242  v,
1243  order,
1244  extpolfac );
1245 }
1246 
1247 
1249 
1266 void chk_interpolation_pgrids(const String& which_interpolation,
1267  ConstVectorView old_pgrid,
1268  ConstVectorView new_pgrid,
1269  const Index order,
1270  const Numeric& extpolfac )
1271 {
1272  // Local variable to store log of the pressure grids
1273  Vector logold( old_pgrid.nelem() );
1274  Vector lognew( new_pgrid.nelem() );
1275 
1276  transform( logold, log, old_pgrid );
1277  transform( lognew, log, new_pgrid );
1278 
1279  chk_interpolation_grids(which_interpolation, logold, lognew, order, extpolfac, true);
1280 }
1281 
1282 
1283 
1284 
1285 
1286 /*===========================================================================
1287  === Functions related to atmospheric and surface grids and fields.
1288  ===========================================================================*/
1289 
1291 
1306  const Index& dim,
1307  ConstVectorView p_grid,
1308  ConstVectorView lat_grid,
1309  ConstVectorView lon_grid )
1310 {
1311  // p_grid
1312  if( p_grid.nelem() < 2 )
1313  throw runtime_error( "The length of *p_grid* must be >= 2." );
1314  chk_if_decreasing( "p_grid", p_grid );
1315 
1316  // lat_grid
1317  if( dim == 1 )
1318  {
1319  if( lat_grid.nelem() > 0 )
1320  throw runtime_error("For dim=1, the length of *lat_grid* must be 0.");
1321  }
1322  else
1323  {
1324  if( lat_grid.nelem() < 2 )
1325  throw runtime_error(
1326  "For dim>1, the length of *lat_grid* must be >= 2.");
1327  chk_if_increasing( "lat_grid", lat_grid );
1328  }
1329 
1330  // lon_grid
1331  if( dim < 3 )
1332  {
1333  if( lon_grid.nelem() > 0 )
1334  throw runtime_error("For dim<3, the length of *lon_grid* must be 0.");
1335  }
1336  else
1337  {
1338  if( lon_grid.nelem() < 2 )
1339  throw runtime_error(
1340  "For dim=3, the length of *lon_grid* must be >= 2.");
1341  chk_if_increasing( "lon_grid", lon_grid );
1342  }
1343 
1344  // Check that latitude and longitude grids are inside OK ranges for 3D
1345  if( dim == 3 )
1346  {
1347  if( lat_grid[0] < -90 )
1348  throw runtime_error(
1349  "The latitude grid cannot extend below -90 degrees for 3D" );
1350  if( lat_grid[lat_grid.nelem() - 1] > 90 )
1351  throw runtime_error(
1352  "The latitude grid cannot extend above 90 degrees for 3D" );
1353  if( lon_grid[0] < -360 )
1354  throw runtime_error(
1355  "No longitude (in lon_grid) can be below -360 degrees." );
1356  if( lon_grid[lon_grid.nelem() - 1] > 360 )
1357  throw runtime_error(
1358  "No longitude (in lon_grid) can be above 360 degrees." );
1359  if( lon_grid[lon_grid.nelem() - 1]-lon_grid[0] > 360 )
1360  throw runtime_error(
1361  "The longitude grid is not allowed to cover more than 360 degrees." );
1362  }
1363 }
1364 
1365 
1366 
1368 
1386  const String& x_name,
1387  ConstTensor3View x,
1388  const Index& dim,
1389  ConstVectorView p_grid,
1390  ConstVectorView lat_grid,
1391  ConstVectorView lon_grid,
1392  const bool& chk_lat90)
1393 {
1394  // It is assumed that grids OK-ed through chk_atm_grids
1395  Index npages=p_grid.nelem(), nrows=1, ncols=1;
1396  if( dim > 1 )
1397  nrows = lat_grid.nelem();
1398  if( dim > 2 )
1399  ncols = lon_grid.nelem();
1400  if( x.ncols()!=ncols || x.nrows()!=nrows || x.npages()!=npages )
1401  {
1402  ostringstream os;
1403  os << "The atmospheric field *" << x_name << "* has wrong size.\n"
1404  << "Expected size is " << npages << " x " << nrows << " x "
1405  << ncols << ", while actual size is " << x.npages() << " x "
1406  << x.nrows() << " x " << x.ncols() << ".";
1407  throw runtime_error( os.str() );
1408  }
1409 
1410  // NaNs are not allowed
1411  for( Index ip=0; ip<npages; ip++ )
1412  { for( Index ir=0; ir<nrows; ir++ )
1413  { for( Index ic=0; ic<ncols; ic++ )
1414  {
1415  if( isnan( x(ip,ir,ic) ) )
1416  {
1417  ostringstream os;
1418  os << "The variable *" << x_name << "* contains one or "
1419  << "several NaNs. This is not allowed!";
1420  throw runtime_error( os.str() );
1421  }
1422  }
1423  }
1424  }
1425 
1426  // Special 3D checks:
1427  if( dim == 3 )
1428  {
1429  // If all lons are covered, check if cyclic
1430  if( is_lon_cyclic(lon_grid) )
1431  {
1432  const Index ic = ncols-1;
1433  for( Index ip=0; ip<npages; ip++ )
1434  {
1435  for( Index ir=0; ir<nrows; ir++ )
1436  {
1437  if( !is_same_within_epsilon(x(ip,ir,ic),x(ip,ir,0),4*DBL_EPSILON) )
1438  {
1439  ostringstream os;
1440  os << "The variable *" << x_name << "* covers 360 "
1441  << "degrees in the longitude direction, but the field "
1442  << "seems to deviate between first and last longitude "
1443  << "point. The field must be \"cyclic\".\n"
1444  << "Difference: " << setprecision(16) << x(ip,ir,ic)- x(ip,ir,0) << "\n"
1445  << "Epsilon : " << 4*DBL_EPSILON * max(x(ip,ir,ic),x(ip,ir,0));
1446  throw runtime_error( os.str() );
1447  }
1448  }
1449  }
1450  }
1451 
1452  chk_if_bool("chk_lat90", chk_lat90);
1453  if( chk_lat90 )
1454  {
1455  // No variation at the South pole!
1456  if( lat_grid[0] == -90 )
1457  {
1458  for( Index ip=0; ip<npages; ip++ )
1459  {
1460  for( Index ic=1; ic<ncols; ic++ )
1461  {
1462  if( !is_same_within_epsilon(x(ip,0,ic),x(ip,0,ic-1),2*DBL_EPSILON) )
1463  {
1464  ostringstream os;
1465  os << "The variable *" << x_name << "* covers the South\n"
1466  << "pole. The data corresponding to the pole can not\n"
1467  << "vary with longitude, but this appears to be the\n"
1468  << "case.";
1469 /* << "case: at " << ip << ".th pressure it has val\n"
1470  << x(ip,0,ic-1) << ", but " << x(ip,0,ic)
1471  << " (i.e., a diff of " << fabs(x(ip,0,ic)-x(ip,0,ic-1))
1472  << ") at " << ic-1 << "th and " << ic << "th longitudes!\n";
1473 */
1474  throw runtime_error( os.str() );
1475  }
1476  }
1477  }
1478  }
1479  // No variation at the North pole!
1480  if( lat_grid[nrows-1] == 90 )
1481  {
1482  const Index ir = nrows-1;
1483  for( Index ip=0; ip<npages; ip++ )
1484  {
1485  for( Index ic=1; ic<ncols; ic++ )
1486  {
1487  if( !is_same_within_epsilon(x(ip,ir,ic),x(ip,ir,ic-1),2*DBL_EPSILON) )
1488  {
1489  ostringstream os;
1490  os << "The variable *" << x_name << "* covers the North\n"
1491  << "pole. The data corresponding to the pole can not\n"
1492  << "vary with longitude, but this appears to be the "
1493  << "case.";
1494 /* << "case: at " << ip << ".th pressure it has val\n"
1495  << x(ip,ir,ic-1) << ", but " << x(ip,ir,ic)
1496  << " (i.e., a diff of " << fabs(x(ip,ir,ic)-x(ip,ir,ic-1))
1497  << ") at " << ic-1 << "th and " << ic << "th longitudes!\n";
1498 */
1499  throw runtime_error( os.str() );
1500  }
1501  }
1502  }
1503  }
1504  }
1505  }
1506 }
1507 
1508 
1509 
1511 
1530  const String& x_name,
1531  ConstTensor4View x,
1532  const Index& dim,
1533  const Index& nspecies,
1534  ConstVectorView p_grid,
1535  ConstVectorView lat_grid,
1536  ConstVectorView lon_grid )
1537 {
1538  const Index nbooks=nspecies;
1539  //
1540  if( nbooks == 0 )
1541  {
1542  if( x.nbooks() )
1543  {
1544  ostringstream os;
1545  os << "The atmospheric field *" << x_name << "* should be empty.\n";
1546  throw runtime_error( os.str() );
1547  }
1548  else
1549  { return; }
1550  }
1551 
1552  Index npages=p_grid.nelem(), nrows=1, ncols=1;
1553  if( dim > 1 )
1554  nrows = lat_grid.nelem();
1555  if( dim > 2 )
1556  ncols = lon_grid.nelem();
1557 
1558  if( x.ncols()!=ncols || x.nrows()!=nrows || x.npages()!=npages ||
1559  x.nbooks()!=nbooks )
1560  {
1561  ostringstream os;
1562  os << "The atmospheric field *" << x_name << "* has wrong size.\n"
1563  << "Expected size is "
1564  << nbooks << " x " << npages << " x "
1565  << nrows << " x " << ncols << ",\n"
1566  << "while actual size is "
1567  << x.nbooks() << " x " << x.npages() << " x "
1568  << x.nrows() << " x " << x.ncols() << ".";
1569  throw runtime_error( os.str() );
1570  }
1571 
1572  // NaNs are not allowed
1573  for( Index ib=0; ib<nbooks; ib++ )
1574  { for( Index ip=0; ip<npages; ip++ )
1575  { for( Index ir=0; ir<nrows; ir++ )
1576  { for( Index ic=0; ic<ncols; ic++ )
1577  {
1578  if( isnan( x(ib,ip,ir,ic) ) )
1579  {
1580  ostringstream os;
1581  os << "The variable *" << x_name << "* contains one or "
1582  << "several NaNs. This is not allowed!";
1583  throw runtime_error( os.str() );
1584  }
1585  }
1586  }
1587  }
1588  }
1589 
1590  // Special 3D checks:
1591  if( dim == 3 )
1592  {
1593  // If all lons are covered, check if cyclic
1594  if( (lon_grid[ncols-1]-lon_grid[0]) == 360 )
1595  {
1596  const Index ic = ncols-1;
1597  for( Index is=0; is<nspecies; is++ )
1598  {
1599  for( Index ip=0; ip<npages; ip++ )
1600  {
1601  for( Index ir=0; ir<nrows; ir++ )
1602  {
1603  if( !is_same_within_epsilon(x(is,ip,ir,ic),x(is,ip,ir,0),2*DBL_EPSILON) )
1604  {
1605  ostringstream os;
1606  os << "The variable *" << x_name << "* covers 360 "
1607  << "degrees in the longitude direction, but at least "
1608  << "one field seems to deviate between first and last "
1609  << "longitude point. The field must be \"cyclic\". "
1610  << "This was found for field with index "
1611  << is <<" (0-based).";
1612  throw runtime_error( os.str() );
1613  }
1614  }
1615  }
1616  }
1617  }
1618  // No variation at the South pole!
1619  if( lat_grid[0] == -90 )
1620  {
1621  for( Index is=0; is<nspecies; is++ )
1622  {
1623  for( Index ip=0; ip<npages; ip++ )
1624  {
1625  for( Index ic=1; ic<ncols; ic++ )
1626  {
1627  if( !is_same_within_epsilon(x(is,ip,0,ic),x(is,ip,0,ic-1),2*DBL_EPSILON) )
1628  {
1629  ostringstream os;
1630  os << "The variable *" << x_name << "* covers the South "
1631  << "pole. The data corresponding to the pole can not "
1632  << "vary with longitude, but this appears to be the "
1633  << "case. This was found for field with index "
1634  << is <<" (0-based).";
1635  throw runtime_error( os.str() );
1636  }
1637  }
1638  }
1639  }
1640  }
1641  // No variation at the North pole!
1642  if( lat_grid[nrows-1] == 90 )
1643  {
1644  const Index ir = nrows-1;
1645  for( Index is=0; is<nspecies; is++ )
1646  {
1647  for( Index ip=0; ip<npages; ip++ )
1648  {
1649  for( Index ic=1; ic<ncols; ic++ )
1650  {
1651  if( !is_same_within_epsilon(x(is,ip,ir,ic),x(is,ip,ir,ic-1),2*DBL_EPSILON) )
1652  {
1653  ostringstream os;
1654  os << "The variable *" << x_name << "* covers the North "
1655  << "pole. The data corresponding to the pole can not "
1656  << "vary with longitude, but this appears to be the "
1657  << "case. This was found for field with index "
1658  << is <<" (0-based).";
1659  throw runtime_error( os.str() );
1660  }
1661  }
1662  }
1663  }
1664  }
1665  }
1666 }
1667 
1668 
1669 
1671 
1697  const String& x1_name,
1698  ConstTensor3View x1,
1699  const String& x2_name,
1700  ConstTensor3View x2,
1701  const Index& dim,
1702  ConstVectorView lat_grid,
1703  const Numeric& threshold)
1704 {
1705  // It is assumed that grids OK-ed through chk_atm_grids and fields
1706  // individually OK-ed.
1707 
1708  // We only need to check 3D cases. Else there is no variation in longitude
1709  // anyways.
1710  if( dim == 3 )
1711  {
1712  Index npages= x1.npages();
1713  Index nrows = x1.nrows();
1714  Index ncols = x1.ncols();
1715 
1716  // For safety check that both fields have identical dimensions
1717  if( x2.ncols()!=ncols || x2.nrows()!=nrows || x2.npages()!=npages )
1718  {
1719  ostringstream os;
1720  os << "The atmospheric fields *" << x1_name << "* and *"
1721  << x2_name << "* do not match in size.\n"
1722  << "*" << x1_name << "*'s size is " << npages << " x " << nrows
1723  << " x " << ncols << ", while *" << x1_name << "*'s size is "
1724  << x2.npages() << " x " << x2.nrows() << " x " << x2.ncols() << ".";
1725  throw runtime_error( os.str() );
1726  }
1727 
1728  // redefine ratio deviation threshold of vector lengths to ratio of
1729  // squared vector lengths, cause don't want to calc squareroot everytime.
1730  // (val1**2/val2**2 - 1) / (val1/val2 - 1) = val1/val2 + 1
1731  // and with val1~val2 = 2
1732  // i.e., (val1**2/val2**2 - 1) ~ 2 * (val1/val2 - 1)
1733  //
1734  // with val1/1 = sqrt(vec1/2), hence val1/2**2 = vec1/2
1735  // (vec1/vec2 - 1) ~ 2 * (sqrt(vec1)/sqrt(vec2) - 1)
1736  // (sqrt(vec1)/sqrt(vec2) - 1) ~ (vec1/vec2 - 1) / 2
1737  //
1738  // we want to check: sqrt(vec1)/sqrt(vec2) - 1. < threshold
1739  // i.e., with the above,
1740  // (vec1/vec2 - 1) / 2 < threshold
1741  // (vec1/vec2 - 1) < threshold*2
1742  Numeric th = threshold * 2.;
1743 
1744  // No variation at the South pole!
1745  if( lat_grid[0] == -90 )
1746  {
1747  Numeric vec1, vec2;
1748  for( Index ip=0; ip<npages; ip++ )
1749  {
1750  for( Index ic=1; ic<ncols; ic++ )
1751  {
1752  vec1 = x1(ip,0,ic)*x1(ip,0,ic) + x2(ip,0,ic)*x2(ip,0,ic);
1753  vec2 = x1(ip,0,ic-1)*x1(ip,0,ic-1) + x2(ip,0,ic-1)*x2(ip,0,ic-1);
1754  if( fabs( vec1/vec2-1. ) > th )
1755  {
1756  ostringstream os;
1757  os << "The variables *" << x1_name << "* and *" << x2_name
1758  << "* are assumed\n"
1759  << "to be two horizontal components of a vector field.\n"
1760  << "At the pole, the data (here: the total length of\n"
1761  << "the horizontal vector) can NOT vary with longitude,\n"
1762  << "but this appears to be the case on the South pole.\n"
1763  << "The threshold is " << threshold << ", but the actual\n"
1764  << "deviation at pressure level " << ip << " and longitude\n"
1765  << "points " << ic-1 << " and " << ic << " is "
1766  << sqrt(vec1)/sqrt(vec2)-1.;
1767  throw runtime_error( os.str() );
1768  }
1769  }
1770  }
1771  }
1772  // No variation at the North pole!
1773  if( lat_grid[nrows-1] == 90 )
1774  {
1775  Numeric vec1, vec2;
1776  const Index ir = nrows-1;
1777  for( Index ip=0; ip<npages; ip++ )
1778  {
1779  for( Index ic=1; ic<ncols; ic++ )
1780  {
1781  vec1 = x1(ip,ir,ic)*x1(ip,ir,ic) + x2(ip,ir,ic)*x2(ip,ir,ic);
1782  vec2 = x1(ip,ir,ic-1)*x1(ip,ir,ic-1) + x2(ip,ir,ic-1)*x2(ip,ir,ic-1);
1783  if( fabs( vec1/vec2-1. ) > th )
1784  {
1785  ostringstream os;
1786  os << "The variables *" << x1_name << "* and *" << x2_name
1787  << "* are assumed\n"
1788  << "to be two horizontal components of a vector field.\n"
1789  << "At the pole, the data (here: the total length of\n"
1790  << "the horizontal vector) can NOT vary with longitude,\n"
1791  << "but this appears to be the case on the North pole.\n"
1792  << "The threshold is " << threshold << ", but the actual\n"
1793  << "deviation at pressure level " << ip << " and longitude\n"
1794  << "points " << ic-1 << " and " << ic << " is "
1795  << sqrt(vec1)/sqrt(vec2)-1.;
1796  throw runtime_error( os.str() );
1797  }
1798  }
1799  }
1800  }
1801  }
1802 }
1803 
1804 
1805 
1807 
1820  const Index& atmosphere_dim,
1821  ConstVectorView lat_grid,
1822  ConstVectorView lat_true,
1823  ConstVectorView lon_true )
1824 {
1825  if( atmosphere_dim == 1 )
1826  {
1827  if( lat_true.nelem()!=1 || lon_true.nelem()!=1 )
1828  {
1829  throw runtime_error( "For 1D, the method requires that *lat_true* "
1830  "and *lon_true* have length 1." );
1831  }
1832  }
1833  //
1834  else if( atmosphere_dim == 2 )
1835  {
1836  if( lat_true.nelem() != lat_grid.nelem() ||
1837  lon_true.nelem() != lat_grid.nelem() )
1838  {
1839  throw runtime_error( "For 2D, the method requires that *lat_true* "
1840  "and *lon_true* have the same length as *lat_grid*." );
1841  }
1842  }
1843 }
1844 
1845 
1846 
1848 
1863  const String& x_name,
1864  const Matrix& x,
1865  const Index& dim,
1866  ConstVectorView lat_grid,
1867  ConstVectorView lon_grid )
1868 {
1869  Index ncols=1, nrows=1;
1870  if( dim > 1 )
1871  nrows = lat_grid.nelem();
1872  if( dim > 2 )
1873  ncols = lon_grid.nelem();
1874  if( x.ncols()!=ncols || x.nrows()!=nrows )
1875  {
1876  ostringstream os;
1877  os << "The surface variable *" << x_name << "* has wrong size.\n"
1878  << "Expected size is " << nrows << " x " << ncols << ","
1879  << " while actual size is " << x.nrows() << " x " << x.ncols() << ".";
1880  throw runtime_error( os.str() );
1881  }
1882 
1883  // Special 3D checks:
1884  if( dim == 3 )
1885  {
1886  // If all lons are covered, check if cyclic
1887  if( (lon_grid[ncols-1]-lon_grid[0]) == 360 )
1888  {
1889  const Index ic = ncols-1;
1890  for( Index ir=0; ir<nrows; ir++ )
1891  {
1892  if( !is_same_within_epsilon(x(ir,ic),x(ir,0),2*DBL_EPSILON) )
1893  {
1894  ostringstream os;
1895  os << "The variable *" << x_name << "* covers 360 "
1896  << "degrees in the longitude direction, but the field "
1897  << "seems to deviate between first and last longitude "
1898  << "point. The field must be \"cyclic\".";
1899  throw runtime_error( os.str() );
1900  }
1901  }
1902  }
1903 
1904  // No variation at the South pole!
1905  if( lat_grid[0] == -90 )
1906  {
1907  for( Index ic=1; ic<ncols; ic++ )
1908  {
1909  if( !is_same_within_epsilon(x(0,ic),x(0,ic-1),2*DBL_EPSILON) )
1910  {
1911  ostringstream os;
1912  os << "The variable *" << x_name << "* covers the South "
1913  << "pole. The data corresponding to the pole can not "
1914  << "vary with longitude, but this appears to be the "
1915  << "case.";
1916  throw runtime_error( os.str() );
1917  }
1918  }
1919  }
1920  // No variation at the North pole!
1921  if( lat_grid[nrows-1] == 90 )
1922  {
1923  const Index ir = nrows-1;
1924  for( Index ic=1; ic<ncols; ic++ )
1925  {
1926  if( !is_same_within_epsilon(x(ir,ic),x(ir,ic-1),2*DBL_EPSILON) )
1927  {
1928  ostringstream os;
1929  os << "The variable *" << x_name << "* covers the North "
1930  << "pole. The data corresponding to the pole can not "
1931  << "vary with longitude, but this appears to be the "
1932  << "case.";
1933  throw runtime_error( os.str() );
1934  }
1935  }
1936  }
1937  }
1938 }
1939 
1940 
1941 
1942 
1943 
1944 /*===========================================================================
1945  === Functions related to sensor variables.
1946  ===========================================================================*/
1947 
1949 
1962  const Index& atmosphere_dim,
1963  ConstVectorView rte_pos,
1964  const bool& is_rte_pos2 )
1965 
1966 {
1967  String vname = "*rte_pos*";
1968  if( is_rte_pos2 )
1969  { vname = "*rte_pos2*"; }
1970 
1971  if( atmosphere_dim == 1 )
1972  {
1973  if( !is_rte_pos2 )
1974  {
1975  if( rte_pos.nelem() != 1 )
1976  {
1977  ostringstream os;
1978  os << "For 1D, " << vname << " must have length 1.";
1979  throw runtime_error(os.str());
1980  }
1981  }
1982  else
1983  {
1984  if( rte_pos.nelem() != 2 )
1985  {
1986  ostringstream os;
1987  os << "For 1D, " << vname << " must have length 2.";
1988  throw runtime_error(os.str());
1989  }
1990  if( rte_pos[1] < -180 || rte_pos[1] > 180 )
1991  {
1992  ostringstream os;
1993  os << "For 1D, the latitude in " << vname << " must be in the "
1994  << "range [-180,180].";
1995  throw runtime_error(os.str());
1996  }
1997  }
1998  }
1999  else if( atmosphere_dim == 2 )
2000  {
2001  if( rte_pos.nelem() != 2 )
2002  {
2003  ostringstream os;
2004  os << "For 2D, " << vname << " must have length 2.";
2005  throw runtime_error(os.str());
2006  }
2007  }
2008  else
2009  {
2010  if( rte_pos.nelem() != 3 )
2011  {
2012  ostringstream os;
2013  os << "For 3D, " << vname << " must have length 3.";
2014  throw runtime_error(os.str());
2015  }
2016  if( rte_pos[1] < -90 || rte_pos[1] > 90 )
2017  {
2018  ostringstream os;
2019  os << "The (3D) latitude in " << vname << " must be in the "
2020  << "range [-90,90].";
2021  throw runtime_error(os.str());
2022  }
2023  if( rte_pos[2] < -360 || rte_pos[2] > 360 )
2024  {
2025  ostringstream os;
2026  os << "The longitude in " << vname << " must be in the "
2027  << "range [-360,360].";
2028  throw runtime_error(os.str());
2029  }
2030  }
2031 }
2032 
2033 
2034 
2036 
2048  const Index& atmosphere_dim,
2049  ConstVectorView rte_los )
2050 
2051 {
2052  if( atmosphere_dim == 1 )
2053  {
2054  if( rte_los.nelem() != 1 )
2055  { throw runtime_error( "For 1D, *rte_los* must have length 1." ); }
2056  if( rte_los[0] < 0 || rte_los[0] > 180 )
2057  { throw runtime_error( "For 1D, the zenith angle of *rte_los* must "
2058  "be in the range [0,180]." ); }
2059  }
2060  else if( atmosphere_dim == 2 )
2061  {
2062  if( rte_los.nelem() != 1 )
2063  { throw runtime_error( "For 2D, *rte_los* must have length 1." ); }
2064  if( rte_los[0] < -180 || rte_los[0] > 180 )
2065  { throw runtime_error( "For 2D, the zenith angle of *rte_los* must "
2066  "be in the range [-180,180]." ); }
2067  }
2068  else
2069  {
2070  if( rte_los.nelem() != 2 )
2071  { throw runtime_error( "For 3D, *rte_los* must have length 2." ); }
2072  if( rte_los[0] < 0 || rte_los[0] > 180 )
2073  { throw runtime_error( "For 3D, the zenith angle of *rte_los* must "
2074  "be in the range [0,180]." ); }
2075  if( rte_los[1] < -180 || rte_los[1] > 180 )
2076  { throw runtime_error( "For 3D, the azimuth angle of *rte_los* must "
2077  "be in the range [-180,180]." ); }
2078  }
2079 }
2080 
2081 
2082 /*===========================================================================
2083  === Functions related to GriddedFields.
2084  ===========================================================================*/
2085 
2087 
2097  const Index gridindex,
2098  const String& gridname)
2099 {
2100  if (gf.get_dim()-1 < gridindex)
2101  {
2102  ostringstream os;
2103  os << "Grid index " << gridindex << " exceeds dimension of GriddedField";
2104  if (gf.get_name().nelem()) os << " \"" << gf.get_name() << "\"";
2105  throw runtime_error(os.str());
2106  }
2107 
2108  String gfgridnameupper = gf.get_grid_name(gridindex);
2109  gfgridnameupper.toupper();
2110 
2111  String gridnameupper = gridname;
2112  gridnameupper.toupper();
2113 
2114  if (gfgridnameupper != gridnameupper)
2115  {
2116  ostringstream os;
2117  os << "Name of grid " << gridindex << " in GriddedField";
2118  if (gf.get_name().nelem()) os << " \"" << gf.get_name() << "\"";
2119  os << " is \"" << gf.get_grid_name(gridindex) << "\".\n"
2120  << "The expected name is \"" << gridname << "\".";
2121  throw runtime_error(os.str());
2122  }
2123 }
2124 
2125 
2126 
2127 
2128 
2129 /*===========================================================================
2130  === Functions checking agendas
2131  ===========================================================================*/
2132 
2134 
2150  Workspace& ws,
2151  const Agenda& blackbody_radiation_agenda )
2152 {
2153  Vector btest;
2154  blackbody_radiation_agendaExecute( ws, btest, 300, Vector(1,100e9),
2155  blackbody_radiation_agenda );
2156  if( abs( btest[0] - 9.1435e-16) > 1e-19 )
2157  { return false; }
2158  else
2159  { return true; }
2160 }
Index npages() const
Returns the number of pages.
Definition: matpackV.cc:47
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:35
const Index GFIELD3_LAT_GRID
bool is_lon_cyclic(ConstVectorView grid, const Numeric &epsilon)
Check if the given longitude grid is cyclic.
Definition: logic.cc:466
bool chk_if_std_blackbody_agenda(Workspace &ws, const Agenda &blackbody_radiation_agenda)
Checks if blackbody_radiation_agenda returns frequency based radiance.
Index nrows() const
Returns the number of rows.
Definition: matpackV.cc:53
The Agenda class.
Definition: agenda_class.h:44
void chk_if_decreasing(const String &x_name, ConstVectorView x)
chk_if_decreasing
Definition: check_input.cc:327
A constant view of a Tensor7.
Definition: matpackVII.h:162
void chk_atm_surface(const String &x_name, const Matrix &x, const Index &dim, ConstVectorView lat_grid, ConstVectorView lon_grid)
chk_atm_surface
const Index GFIELD3_LON_GRID
void chk_if_increasing(const String &x_name, const ArrayOfIndex &x)
chk_if_increasing
Definition: check_input.cc:132
The Vector class.
Definition: matpackI.h:556
Index nvitrines() const
Returns the number of vitrines.
Definition: matpackVI.cc:32
A constant view of a Tensor6.
Definition: matpackVI.h:159
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
Definition: logic.cc:275
Index nrows() const
Returns the number of rows.
Definition: matpackVII.cc:62
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:69
void chk_not_negative(const String &x_name, const Numeric &x)
chk_not_negative
Definition: check_input.cc:166
void chk_rte_los(const Index &atmosphere_dim, ConstVectorView rte_los)
chk_rte_los
void chk_if_bool(const String &x_name, const Index &x)
chk_if_bool
Definition: check_input.cc:73
Index nbooks() const
Returns the number of books.
Definition: matpackV.cc:41
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.
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:146
Index nrows() const
Returns the number of rows.
Definition: matpackIV.cc:75
void chk_matrix_ncols(const String &x_name, ConstMatrixView x, const Index &l)
chk_matrix_ncols
Definition: check_input.cc:402
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:180
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.
A constant view of a Tensor4.
Definition: matpackIV.h:141
const Index GFIELD3_P_GRID
This file contains the definition of Array.
void chk_not_empty(const String &x_name, const Agenda &x)
chk_not_empty
Definition: check_input.cc:768
const String & get_name() const
Get the name of this gridded field.
Index get_dim() const
Get the dimension of this gridded field.
The implementation for String, the ARTS string class.
Definition: mystring.h:63
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:838
Index nshelves() const
Returns the number of shelves.
Definition: matpackV.cc:35
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:859
bool is_same_within_epsilon(const Numeric &a, const Numeric &b, const Numeric &epsilon)
Check, if two numbers agree within a given epsilon.
Definition: logic.cc:446
void chk_latlon_true(const Index &atmosphere_dim, ConstVectorView lat_grid, ConstVectorView lat_true, ConstVectorView lon_true)
chk_latlon_true
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_rte_pos(const Index &atmosphere_dim, ConstVectorView rte_pos, const bool &is_rte_pos2)
chk_rte_pos
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:149
#define max(a, b)
Definition: continua.cc:20461
void toupper()
Convert to upper case.
Definition: mystring.h:87
void chk_griddedfield_gridname(const GriddedField &gf, const Index gridindex, const String &gridname)
Check name of grid in GriddedField.
Index nrows() const
Returns the number of rows.
Definition: matpackVI.cc:56
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:819
A constant view of a Tensor5.
Definition: matpackV.h:152
#define abs(x)
Definition: continua.cc:20458
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:29
void blackbody_radiation_agendaExecute(Workspace &ws, Vector &blackbody_radiation, const Numeric rtp_temperature, const Vector &f_grid, const Agenda &input_agenda)
Definition: auto_md.cc:13205
The Matrix class.
Definition: matpackI.h:788
Index nlibraries() const
Returns the number of libraries.
Definition: matpackVII.cc:32
Index nelem() const
Number of elements.
Definition: mystring.h:278
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
Index nelem() const
Return the number of agenda elements.
Definition: agenda_class.h:260
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:989
Header file for logic.cc.
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:143
This can be used to make arrays out of anything.
Definition: array.h:40
Index nshelves() const
Returns the number of shelves.
Definition: matpackVI.cc:38
Index ncols() const
Returns the number of columns.
Definition: matpackVI.cc:62
const String & get_grid_name(Index i) const
Get grid name.
void chk_size(const String &x_name, ConstVectorView x, const Index &c)
Runtime check for size of Vector.
Definition: check_input.cc:465
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:101
#define min(a, b)
Definition: continua.cc:20460
A constant view of a Tensor3.
Definition: matpackIII.h:139
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)
A constant view of a Vector.
Definition: matpackI.h:292
Index npages() const
Returns the number of pages.
Definition: matpackVI.cc:50
Index nshelves() const
Returns the number of shelves.
Definition: matpackVII.cc:44
void chk_vector_length(const String &x_name, ConstVectorView x, const Index &l)
chk_vector_length
Definition: check_input.cc:233
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:356
A constant view of a Matrix.
Definition: matpackI.h:596
void chk_matrix_nrows(const String &x_name, ConstMatrixView x, const Index &l)
chk_matrix_nrows
Definition: check_input.cc:431
Index npages() const
Returns the number of pages.
Definition: matpackVII.cc:56
Workspace class.
Definition: workspace_ng.h:47
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:63
void transform(VectorView y, double(&my_func)(double), ConstVectorView x)
A generic transform function for vectors, which can be used to implement mathematical functions opera...
Definition: matpackI.cc:1838
Implementation of gridded fields.
bool is_bool(const Index &x)
Checks if a variable equals 0 or 1.
Definition: logic.cc:54
Index ncols() const
Returns the number of columns.
Definition: matpackV.cc:59
bool is_decreasing(ConstVectorView x)
Checks if a vector is sorted in reversed order and is strictly decreasing.
Definition: logic.cc:324
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
Definition: logic.cc:91
Index nvitrines() const
Returns the number of vitrines.
Definition: matpackVII.cc:38
Index ncols() const
Returns the number of columns.
Definition: matpackVII.cc:68
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:81
void chk_atm_grids(const Index &dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid)
chk_atm_grids
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:832
Index nbooks() const
Returns the number of books.
Definition: matpackVII.cc:50
Index nbooks() const
Returns the number of books.
Definition: matpackVI.cc:44