00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00036
00037
00038
00039
00040 #include <stdexcept>
00041 #include "check_input.h"
00042 #include "array.h"
00043 #include "logic.h"
00044
00045
00046
00047
00048
00049
00050
00052
00063 void chk_if_bool(
00064 const String& x_name,
00065 const Index& x )
00066 {
00067 if ( !is_bool(x) )
00068 {
00069 ostringstream os;
00070 os << "The variable *" << x_name << "* must be a boolean (0 or 1).\n"
00071 << "The present value of *"<< x_name << "* is " << x << ".";
00072 throw runtime_error( os.str() );
00073 }
00074 }
00075
00077
00091 void chk_if_in_range(
00092 const String& x_name,
00093 const Index& x,
00094 const Index& x_low,
00095 const Index& x_high )
00096 {
00097 if ( (x<x_low) || (x>x_high) )
00098 {
00099 ostringstream os;
00100 os << "The variable *" << x_name << "* must fulfill:\n"
00101 << " " << x_low << " <= " << x_name << " <= " << x_high << "\n"
00102 << "The present value of *"<< x_name << "* is " << x << ".";
00103 throw runtime_error( os.str() );
00104 }
00105 }
00106
00108
00122 void chk_if_increasing(
00123 const String& x_name,
00124 const ArrayOfIndex& x )
00125 {
00126 if ( !is_increasing(x) )
00127 {
00128 ostringstream os;
00129 os << "The ArrayOfIndex *" << x_name << "* must have strictly\n"
00130 << "increasing values, but this is not the case.\n";
00131 os << "x = " << x << "\n";
00132 throw runtime_error( os.str() );
00133 }
00134 }
00135
00136
00137
00138
00139
00140
00142
00154 void chk_if_over_0(
00155 const String& x_name,
00156 const Numeric& x )
00157 {
00158 if ( x <= 0 )
00159 {
00160 ostringstream os;
00161 os << "The variable *" << x_name << "* must exceed 0.\n"
00162 << "The present value of *"<< x_name << "* is " << x << ".";
00163 throw runtime_error( os.str() );
00164 }
00165 }
00166
00167
00168
00170
00184 void chk_if_in_range(
00185 const String& x_name,
00186 const Numeric& x,
00187 const Numeric& x_low,
00188 const Numeric& x_high )
00189 {
00190 if ( (x<x_low) || (x>x_high) )
00191 {
00192 ostringstream os;
00193 os << "The variable *" << x_name << "* must fulfill:\n"
00194 << " " << x_low << " <= " << x_name << " <= " << x_high << "\n"
00195 << "The present value of *"<< x_name << "* is " << x << ".";
00196 throw runtime_error( os.str() );
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00207
00219 void chk_vector_length(
00220 const String& x_name,
00221 ConstVectorView x,
00222 const Index& l )
00223 {
00224 if ( x.nelem() != l )
00225 {
00226 ostringstream os;
00227 os << "The vector *" << x_name << "* must have the length " << l
00228 << ".\n"
00229 << "The present length of *"<< x_name << "* is " << x.nelem() << ".";
00230 throw runtime_error( os.str() );
00231 }
00232 }
00233
00234
00235
00237
00250 void chk_vector_length(
00251 const String& x1_name,
00252 const String& x2_name,
00253 ConstVectorView x1,
00254 ConstVectorView x2 )
00255 {
00256 if ( x1.nelem() != x2.nelem() )
00257 {
00258 ostringstream os;
00259 os << "The vectors *" << x1_name << "* and *" << x1_name
00260 << "* must have the same length.\n"
00261 << "The length of *"<< x1_name << "* is " << x1.nelem() << ".\n"
00262 << "The length of *"<< x2_name << "* is " << x2.nelem() << ".";
00263 throw runtime_error( os.str() );
00264 }
00265 }
00266
00267
00268
00270
00283 void chk_if_increasing(
00284 const String& x_name,
00285 ConstVectorView x )
00286 {
00287 if ( !is_increasing(x) )
00288 {
00289 ostringstream os;
00290 os << "The vector *" << x_name << "* must have strictly\n"
00291 << "increasing values, but this is not the case.\n";
00292 os << "x = " << x << "\n";
00293 throw runtime_error( os.str() );
00294 }
00295 }
00296
00297
00298
00300
00313 void chk_if_decreasing(
00314 const String& x_name,
00315 ConstVectorView x )
00316 {
00317 if ( !is_decreasing(x) )
00318 {
00319 ostringstream os;
00320 os << "The vector *" << x_name << "* must have strictly\ndecreasing "
00321 << "values, but this is not the case.\n";
00322 throw runtime_error( os.str() );
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331
00333
00349 void chk_interpolation_grids(const String& which_interpolation,
00350 ConstVectorView old_grid,
00351 ConstVectorView new_grid,
00352 const Numeric& extpolfac )
00353 {
00354 const Index n_old = old_grid.nelem();
00355
00356 ostringstream os;
00357 os << "There is a problem with the grids for the\n"
00358 << "following interpolation: " << which_interpolation << ".\n";
00359
00360
00361 if (n_old < 2)
00362 {
00363 os << "The original grid must have at least 2 elements.";
00364 throw runtime_error( os.str() );
00365 }
00366
00367
00368 bool ascending = ( old_grid[0] <= old_grid[1] );
00369
00370
00371
00372 Numeric og_min, og_max;
00373
00374 if (ascending)
00375 {
00376
00377 if ( !is_increasing(old_grid) )
00378 {
00379 os << "The original grid must be strictly sorted\n"
00380 << "(no duplicate values). Yours is:\n"
00381 << old_grid << ".";
00382 throw runtime_error( os.str() );
00383 }
00384
00385
00386 og_min = old_grid[0] -
00387 extpolfac * ( old_grid[1] - old_grid[0] );
00388 og_max = old_grid[n_old-1] +
00389 extpolfac * ( old_grid[n_old-1] - old_grid[n_old-2] );
00390 }
00391 else
00392 {
00393
00394 if ( !is_decreasing(old_grid) )
00395 {
00396 os << "The original grid must be strictly sorted\n"
00397 << "(no duplicate values). Yours is:\n"
00398 << old_grid << ".";
00399 throw runtime_error( os.str() );
00400 }
00401
00402
00403
00404 og_max = old_grid[0] -
00405 extpolfac * ( old_grid[1] - old_grid[0] );
00406 og_min = old_grid[n_old-1] +
00407 extpolfac * ( old_grid[n_old-1] - old_grid[n_old-2] );
00408 }
00409
00410
00411 const Numeric ng_min = min(new_grid);
00412 const Numeric ng_max = max(new_grid);
00413
00414
00415
00416
00417 if (ng_min < og_min)
00418 {
00419 os << "The minimum of the new grid must be inside\n"
00420 << "the original grid. (We allow a bit of extrapolation,\n"
00421 << "but not so much).\n"
00422 << "Minimum of original grid: " << min(old_grid) << "\n"
00423 << "Minimum allowed value for new grid: " << og_min << "\n"
00424 << "Actual minimum of new grid: " << ng_min;
00425 throw runtime_error( os.str() );
00426 }
00427
00428 if (ng_max > og_max)
00429 {
00430 os << "The maximum of the new grid must be inside\n"
00431 << "the original grid. (We allow a bit of extrapolation,\n"
00432 << "but not so much).\n"
00433 << "Maximum of original grid: " << max(old_grid) << "\n"
00434 << "Maximum allowed value for new grid: " << og_max << "\n"
00435 << "Actual maximum of new grid: " << ng_max;
00436 throw runtime_error( os.str() );
00437 }
00438
00439
00440 }
00441
00442
00444
00465 void chk_interpolation_grids(const String& which_interpolation,
00466 ConstVectorView old_grid,
00467 const Numeric& new_grid,
00468 const Numeric& extpolfac )
00469 {
00470 Vector v(1, new_grid);
00471 chk_interpolation_grids(which_interpolation,
00472 old_grid,
00473 v,
00474 extpolfac );
00475 }
00476
00477
00478
00479
00480
00482
00494 void chk_matrix_ncols(
00495 const String& x_name,
00496 ConstMatrixView x,
00497 const Index& l )
00498 {
00499 if ( x.ncols() != l )
00500 {
00501 ostringstream os;
00502 os << "The matrix *" << x_name << "* must have " << l << " columns,\n"
00503 << "but the number of columns is " << x.ncols() << ".";
00504 throw runtime_error( os.str() );
00505 }
00506 }
00507
00508
00509
00511
00523 void chk_matrix_nrows(
00524 const String& x_name,
00525 ConstMatrixView x,
00526 const Index& l )
00527 {
00528 if ( x.nrows() != l )
00529 {
00530 ostringstream os;
00531 os << "The matrix *" << x_name << "* must have " << l << " rows,\n"
00532 << "but the number of rows is " << x.nrows() << ".";
00533 throw runtime_error( os.str() );
00534 }
00535 }
00536
00537
00538
00539
00540
00541
00542
00544
00558 void chk_atm_grids(
00559 const Index& dim,
00560 ConstVectorView p_grid,
00561 ConstVectorView lat_grid,
00562 ConstVectorView lon_grid )
00563 {
00564
00565 if( p_grid.nelem() < 2 )
00566 throw runtime_error( "The length of *p_grid* must be >= 2." );
00567 chk_if_decreasing( "p_grid", p_grid );
00568
00569
00570 if( dim == 1 )
00571 {
00572 if( lat_grid.nelem() != 0 )
00573 throw runtime_error(
00574 "For dim=1, the length of *lat_grid* must be 0." );
00575 }
00576 else
00577 {
00578 if( lat_grid.nelem() < 2 )
00579 throw runtime_error(
00580 "For dim>1, the length of *lat_grid* must be >= 2.");
00581 chk_if_increasing( "lat_grid", lat_grid );
00582 }
00583
00584
00585 if( dim < 3 )
00586 {
00587 if( lon_grid.nelem() != 0 )
00588 throw runtime_error(
00589 "For dim<3, the length of *lon_grid* must be 0." );
00590 }
00591 else
00592 {
00593 if( lon_grid.nelem() < 2 )
00594 throw runtime_error(
00595 "For dim=3, the length of *lon_grid* must be >= 2.");
00596 chk_if_increasing( "lon_grid", lon_grid );
00597 }
00598
00599
00600 if( dim == 3 )
00601 {
00602 if( lat_grid[0] < -90 )
00603 throw runtime_error(
00604 "The latitude grid cannot extend below -90 degrees for 3D" );
00605 if( lat_grid[lat_grid.nelem() - 1] > 90 )
00606 throw runtime_error(
00607 "The latitude grid cannot extend above 90 degrees for 3D" );
00608 if( lon_grid[0] < -360 )
00609 throw runtime_error(
00610 "The longitude grid cannot extend below -360 degrees for 3D" );
00611 if( lon_grid[lon_grid.nelem() - 1] > 360 )
00612 throw runtime_error(
00613 "The longitude grid cannot extend above 360 degrees for 3D" );
00614 }
00615 }
00616
00617
00618
00620
00635 void chk_atm_field(
00636 const String& x_name,
00637 ConstTensor3View x,
00638 const Index& dim,
00639 ConstVectorView p_grid,
00640 ConstVectorView lat_grid,
00641 ConstVectorView lon_grid )
00642 {
00643 Index npages=p_grid.nelem(), nrows=1, ncols=1;
00644 if( dim > 1 )
00645 nrows = lat_grid.nelem();
00646 if( dim > 2 )
00647 ncols = lon_grid.nelem();
00648 if( x.ncols()!=ncols || x.nrows()!=nrows || x.npages()!=npages )
00649 {
00650 ostringstream os;
00651 os << "The atmospheric field *" << x_name << "* has wrong size.\n"
00652 << "Expected size is " << npages << " x " << nrows << " x "
00653 << ncols << ", while actual size is " << x.npages() << " x "
00654 << x.nrows() << " x " << x.ncols() << ".";
00655 throw runtime_error( os.str() );
00656 }
00657 }
00658
00660
00678 void chk_atm_field(
00679 const String& x_name,
00680 ConstTensor4View x,
00681 const Index& dim,
00682 const Index& nspecies,
00683 ConstVectorView p_grid,
00684 ConstVectorView lat_grid,
00685 ConstVectorView lon_grid )
00686 {
00687 Index npages=p_grid.nelem(), nrows=1, ncols=1;
00688 if( dim > 1 )
00689 nrows = lat_grid.nelem();
00690 if( dim > 2 )
00691 ncols = lon_grid.nelem();
00692
00693 const Index nbooks=nspecies;
00694
00695 if( x.ncols()!=ncols || x.nrows()!=nrows || x.npages()!=npages ||
00696 x.nbooks()!=nbooks )
00697 {
00698 ostringstream os;
00699 os << "The atmospheric field *" << x_name << "* has wrong size.\n"
00700 << "Expected size is "
00701 << nbooks << " x " << npages << " x "
00702 << nrows << " x " << ncols << ",\n"
00703 << "while actual size is "
00704 << x.nbooks() << " x " << x.npages() << " x "
00705 << x.nrows() << " x " << x.ncols() << ".";
00706 throw runtime_error( os.str() );
00707 }
00708 }
00709
00710
00712
00728 void chk_atm_surface(
00729 const String& x_name,
00730 const Matrix& x,
00731 const Index& dim,
00732 ConstVectorView lat_grid,
00733 ConstVectorView lon_grid )
00734 {
00735 Index ncols=1, nrows=1;
00736 if( dim > 1 )
00737 nrows = lat_grid.nelem();
00738 if( dim > 2 )
00739 ncols = lon_grid.nelem();
00740 if( x.ncols()!=ncols || x.nrows()!=nrows )
00741 {
00742 ostringstream os;
00743 os << "The atmospheric surface *" << x_name << "* has wrong size.\n"
00744 << "Expected size is " << nrows << " x " << ncols << ","
00745 << " while actual size is " << x.nrows() << " x " << x.ncols() << ".";
00746 throw runtime_error( os.str() );
00747 }
00748 }
00749
00750
00751
00752
00753
00754
00755
00757
00774 void chk_cloudbox(
00775 const Index& dim,
00776 ConstVectorView p_grid,
00777 ConstVectorView lat_grid,
00778 ConstVectorView lon_grid,
00779 const Index& cloudbox_on,
00780 const ArrayOfIndex& cloudbox_limits )
00781 {
00782 chk_if_bool( "cloudbox_on", cloudbox_on );
00783
00784 if( cloudbox_on )
00785 {
00786 if( cloudbox_limits.nelem() != dim*2 )
00787 {
00788 ostringstream os;
00789 os << "The array *cloudbox_limits* has incorrect length.\n"
00790 << "For dim = " << dim << " the length shall be " << dim*2
00791 << " but it is " << cloudbox_limits.nelem() << ".";
00792 throw runtime_error( os.str() );
00793 }
00794 if( cloudbox_limits[1]<=cloudbox_limits[0] || cloudbox_limits[0]<0 ||
00795 cloudbox_limits[1]>=p_grid.nelem() )
00796 {
00797 ostringstream os;
00798 os << "Incorrect value(s) for cloud box pressure limit(s) found."
00799 << "\nValues are either out of range or upper limit is not "
00800 << "greater than lower limit.\nWith present length of "
00801 << "*p_grid*, OK values are 0 - " << p_grid.nelem()-1
00802 << ".\nThe pressure index limits are set to "
00803 << cloudbox_limits[0] << " - " << cloudbox_limits[1] << ".";
00804 throw runtime_error( os.str() );
00805 }
00806 if( dim >= 2 )
00807 {
00808 if( cloudbox_limits[3]<=cloudbox_limits[2] || cloudbox_limits[2]<1 ||
00809 cloudbox_limits[3]>=lat_grid.nelem()-1 )
00810 {
00811 ostringstream os;
00812 os << "Incorrect value(s) for cloud box latitude limit(s) found."
00813 << "\nValues are either out of range or upper limit is not "
00814 << "greater than lower limit.\nWith present length of "
00815 << "*lat_grid*, OK values are 1 - " << lat_grid.nelem()-2
00816 << ".\nThe latitude index limits are set to "
00817 << cloudbox_limits[2] << " - " << cloudbox_limits[3] << ".";
00818 throw runtime_error( os.str() );
00819 }
00820 }
00821 if( dim >= 3 )
00822 {
00823 if( cloudbox_limits[5]<=cloudbox_limits[4] || cloudbox_limits[4]<1 ||
00824 cloudbox_limits[5]>=lon_grid.nelem()-1 )
00825 {
00826 ostringstream os;
00827 os << "Incorrect value(s) for cloud box longitude limit(s) found"
00828 << ".\nValues are either out of range or upper limit is not "
00829 << "greater than lower limit.\nWith present length of "
00830 << "*lon_grid*, OK values are 1 - " << lon_grid.nelem()-2
00831 << ".\nThe longitude limits are set to "
00832 << cloudbox_limits[4] << " - " << cloudbox_limits[5] << ".";
00833 throw runtime_error( os.str() );
00834 }
00835 }
00836 }
00837 }
00838
00839
00840
00841
00842
00843
00844
00846
00857 void chk_not_empty(
00858 const String& x_name,
00859 const Agenda& x )
00860 {
00861 if( x.nelem() == 0 )
00862 {
00863 ostringstream os;
00864 os << "The agenda *" << x_name << "* is empty.\nIt is not allowed \n"
00865 << "that an agenda that is actually used to be empty.\n"
00866 << "Empty agendas are only created of methods setting dummy values \n"
00867 << "to variables.";
00868 throw runtime_error( os.str() );
00869 }
00870 }
00871
00872
00873
00874
00875
00877
00888 void chk_size( const String& x_name,
00889 ConstVectorView x,
00890 const Index& c )
00891 {
00892 if ( !is_size(x,c) )
00893 {
00894 ostringstream os;
00895 os << "The object *" << x_name
00896 << "* does not have the right size.\n"
00897 << "Dimensions should be:"
00898 << " " << c
00899 << ",\nbut they are: "
00900 << " " << x.nelem()
00901 << ".";
00902 throw runtime_error( os.str() );
00903 }
00904 }
00905
00907
00919 void chk_size( const String& x_name,
00920 ConstMatrixView x,
00921 const Index& r,
00922 const Index& c )
00923 {
00924 if ( !is_size(x,r,c) )
00925 {
00926 ostringstream os;
00927 os << "The object *" << x_name
00928 << "* does not have the right size.\n"
00929 << "Dimensions should be:"
00930 << " " << r
00931 << " " << c
00932 << ",\nbut they are: "
00933 << " " << x.nrows()
00934 << " " << x.ncols()
00935 << ".";
00936 throw runtime_error( os.str() );
00937 }
00938 }
00939
00941
00954 void chk_size( const String& x_name,
00955 ConstTensor3View x,
00956 const Index& p,
00957 const Index& r,
00958 const Index& c )
00959 {
00960 if ( !is_size(x,p,r,c) )
00961 {
00962 ostringstream os;
00963 os << "The object *" << x_name
00964 << "* does not have the right size.\n"
00965 << "Dimensions should be:"
00966 << " " << p
00967 << " " << r
00968 << " " << c
00969 << ",\nbut they are: "
00970 << " " << x.npages()
00971 << " " << x.nrows()
00972 << " " << x.ncols()
00973 << ".";
00974 throw runtime_error( os.str() );
00975 }
00976 }
00977
00979
00993 void chk_size( const String& x_name,
00994 ConstTensor4View x,
00995 const Index& b,
00996 const Index& p,
00997 const Index& r,
00998 const Index& c )
00999 {
01000 if ( !is_size(x,b,p,r,c) )
01001 {
01002 ostringstream os;
01003 os << "The object *" << x_name
01004 << "* does not have the right size.\n"
01005 << "Dimensions should be:"
01006 << " " << b
01007 << " " << p
01008 << " " << r
01009 << " " << c
01010 << ",\nbut they are: "
01011 << " " << x.nbooks()
01012 << " " << x.npages()
01013 << " " << x.nrows()
01014 << " " << x.ncols()
01015 << ".";
01016 throw runtime_error( os.str() );
01017 }
01018 }
01019
01021
01036 void chk_size( const String& x_name,
01037 ConstTensor5View x,
01038 const Index& s,
01039 const Index& b,
01040 const Index& p,
01041 const Index& r,
01042 const Index& c )
01043 {
01044 if ( !is_size(x,s,b,p,r,c) )
01045 {
01046 ostringstream os;
01047 os << "The object *" << x_name
01048 << "* does not have the right size.\n"
01049 << "Dimensions should be:"
01050 << " " << s
01051 << " " << b
01052 << " " << p
01053 << " " << r
01054 << " " << c
01055 << ",\nbut they are: "
01056 << " " << x.nshelves()
01057 << " " << x.nbooks()
01058 << " " << x.npages()
01059 << " " << x.nrows()
01060 << " " << x.ncols()
01061 << ".";
01062 throw runtime_error( os.str() );
01063 }
01064 }
01065
01067
01083 void chk_size( const String& x_name,
01084 ConstTensor6View x,
01085 const Index& v,
01086 const Index& s,
01087 const Index& b,
01088 const Index& p,
01089 const Index& r,
01090 const Index& c )
01091 {
01092 if ( !is_size(x,v,s,b,p,r,c) )
01093 {
01094 ostringstream os;
01095 os << "The object *" << x_name
01096 << "* does not have the right size.\n"
01097 << "Dimensions should be:"
01098 << " " << v
01099 << " " << s
01100 << " " << b
01101 << " " << p
01102 << " " << r
01103 << " " << c
01104 << ",\nbut they are: "
01105 << " " << x.nvitrines()
01106 << " " << x.nshelves()
01107 << " " << x.nbooks()
01108 << " " << x.npages()
01109 << " " << x.nrows()
01110 << " " << x.ncols()
01111 << ".";
01112 throw runtime_error( os.str() );
01113 }
01114 }
01115
01117
01134 void chk_size( const String& x_name,
01135 ConstTensor7View x,
01136 const Index& l,
01137 const Index& v,
01138 const Index& s,
01139 const Index& b,
01140 const Index& p,
01141 const Index& r,
01142 const Index& c )
01143 {
01144 if ( !is_size(x,l,v,s,b,p,r,c) )
01145 {
01146 ostringstream os;
01147 os << "The object *" << x_name
01148 << "* does not have the right size.\n"
01149 << "Dimensions should be:"
01150 << " " << l
01151 << " " << v
01152 << " " << s
01153 << " " << b
01154 << " " << p
01155 << " " << r
01156 << " " << c
01157 << ",\nbut they are: "
01158 << " " << x.nlibraries()
01159 << " " << x.nvitrines()
01160 << " " << x.nshelves()
01161 << " " << x.nbooks()
01162 << " " << x.npages()
01163 << " " << x.nrows()
01164 << " " << x.ncols()
01165 << ".";
01166 throw runtime_error( os.str() );
01167 }
01168 }
01169
01170