diff --git a/data/bufr/CMakeLists.txt b/data/bufr/CMakeLists.txt index 786cf27b55..ddeee3863b 100644 --- a/data/bufr/CMakeLists.txt +++ b/data/bufr/CMakeLists.txt @@ -13,6 +13,7 @@ string(REGEX REPLACE "\n" ";" bufr_refs_to_download "${bufr_refs_to_download}") # Exceptional case: download bufr files which have to be treated specially list(APPEND bufr_files_to_download "vos308014_v3_26.bufr") # See test ecc-197 +list(APPEND bufr_files_to_download "bad.bufr") # See ECC-1938 if( ENABLE_EXTRA_TESTS ) ecbuild_get_test_multidata( diff --git a/definitions/create_def.pl b/definitions/create_def.pl index 09f46d4753..4320249cd7 100755 --- a/definitions/create_def.pl +++ b/definitions/create_def.pl @@ -23,7 +23,7 @@ #my $tarfilesflag = 0; sub create_cfName { - my $p; my %seen; + my $p; my %seen; my ($key) = "cfName"; my $field = "cf.name"; @@ -33,6 +33,7 @@ sub create_cfName { param,grib_encoding,grib,attribute,centre,units,cf where param.hide_def=0 and param.retired=0 and + grib_encoding.published=1 and grib_encoding.id=grib.encoding_id and param.id=grib_encoding.param_id and attribute.id=grib.attribute_id and @@ -46,7 +47,7 @@ sub create_cfName { my $qh=$dbh->prepare($query); $qh->execute(); - # file containing the list of grib api parameters files we want to tar and + # file containing the list of grib api parameters files we want to tar and # distribute to users for them to download and update their list of parameter # to the latest #open(TAR,$tarfilesflag ? ">>" : ">","tarfiles.txt") or die "Count not open file tarfiles.txt: $!"; @@ -81,7 +82,7 @@ sub create_cfName { } $seen{$attribute}=1; print "($key=$keyval) $edition,$centre,$shortName,$paramId,$name,$attribute,$value\n"; - # we need to allow strings in the attribute_value field + # we need to allow strings in the attribute_value field # for the moment we apply a patch here if ($attribute =~ /stepType/ ) { $value="\"accum\""; @@ -100,7 +101,7 @@ sub create_cfName { } sub create_cfName_legacy { - my $p; my %seen; + my $p; my %seen; my ($key) = "cfName"; my $field = "cf.name"; @@ -123,7 +124,7 @@ sub create_cfName_legacy { my $qh=$dbh->prepare($query); $qh->execute(); - # file containing the list of grib api parameters files we want to tar and + # file containing the list of grib api parameters files we want to tar and # distribute to users for them to download and update their list of parameter # to the latest #open(TAR,$tarfilesflag ? ">>" : ">","tarfiles.txt") or die "Count not open file tarfiles.txt: $!"; @@ -158,7 +159,7 @@ sub create_cfName_legacy { } $seen{$attribute}=1; print "($key=$keyval) $edition,$centre,$shortName,$paramId,$name,$attribute,$value\n"; - # we need to allow strings in the attribute_value field + # we need to allow strings in the attribute_value field # for the moment we apply a patch here if ($attribute =~ /stepType/ ) { $value="\"accum\""; @@ -177,13 +178,13 @@ sub create_cfName_legacy { } sub create_def { - my $p; my %seen; + my $p; my %seen; my ($key) =@_; my $field=$key; - if ($key =~ /paramId/) { $field="param.id"; } - if ($key =~ /name/) { $field="param.name"; } - if ($key =~ /units/) { $field="units.name"; } + if ($key =~ /paramId/) { $field="param.id"; } + if ($key =~ /name/) { $field="param.name"; } + if ($key =~ /units/) { $field="units.name"; } my $query= <<"EOF"; select $field,force128,edition, @@ -191,6 +192,7 @@ sub create_def { from param,grib_encoding,grib,attribute,centre,units where param.hide_def=0 and param.retired=0 and + grib_encoding.published=1 and grib_encoding.id=grib.encoding_id and param.id=grib_encoding.param_id and attribute.id=grib.attribute_id and @@ -203,7 +205,7 @@ sub create_def { my $qh=$dbh->prepare($query); $qh->execute(); - # file containing the list of grib api parameters files we want to tar and + # file containing the list of grib api parameters files we want to tar and # distribute to users for them to download and update their list of parameter # to the latest #open(TAR,$tarfilesflag ? ">>" : ">","tarfiles.txt") or die "Count not open file tarfiles.txt: $!"; @@ -223,9 +225,9 @@ sub create_def { close $out; } $filebase="$basedir/grib$edition$conceptDir"; - mkpath($filebase); + mkpath($filebase); - #copy("$filebase/$key.def","$filebase/$key.def.bkp") + #copy("$filebase/$key.def","$filebase/$key.def.bkp") # or die ("unable to copy $filebase/$key.def"); print TAR "grib$edition$conceptDir/$key.def\n"; @@ -244,7 +246,7 @@ sub create_def { } $seen{$attribute}=1; print "($key=$keyval) $edition,$centre,$shortName,$paramId,$name,$attribute,$value\n"; - # we need to allow strings in the attribute_value field + # we need to allow strings in the attribute_value field # for the moment we apply a patch here if ($attribute =~ /stepType/ ) { $value="\"accum\""; @@ -263,13 +265,13 @@ sub create_def { } sub create_def_legacy { - my $p; my %seen; + my $p; my %seen; my ($key) =@_; my $field=$key; - if ($key =~ /paramId/) { $field="param.id"; } - if ($key =~ /name/) { $field="param.name"; } - if ($key =~ /units/) { $field="units.name"; } + if ($key =~ /paramId/) { $field="param.id"; } + if ($key =~ /name/) { $field="param.name"; } + if ($key =~ /units/) { $field="units.name"; } my $query= <<"EOF"; select $field,force128,edition, @@ -289,7 +291,7 @@ sub create_def_legacy { my $qh=$dbh->prepare($query); $qh->execute(); - # file containing the list of grib api parameters files we want to tar and + # file containing the list of grib api parameters files we want to tar and # distribute to users for them to download and update their list of parameter # to the latest #open(TAR,$tarfilesflag ? ">>" : ">","tarfiles.txt") or die "Count not open file tarfiles.txt: $!"; @@ -309,9 +311,9 @@ sub create_def_legacy { close $out; } $filebase="$basedir/grib$edition$conceptDir"; - mkpath($filebase); + mkpath($filebase); - #copy("$filebase/$key.def","$filebase/$key.def.bkp") + #copy("$filebase/$key.def","$filebase/$key.def.bkp") # or die ("unable to copy $filebase/$key.def"); print TAR "grib$edition$conceptDir/$key.legacy.def\n"; @@ -330,7 +332,7 @@ sub create_def_legacy { } $seen{$attribute}=1; print "($key=$keyval) $edition,$centre,$shortName,$paramId,$name,$attribute,$value\n"; - # we need to allow strings in the attribute_value field + # we need to allow strings in the attribute_value field # for the moment we apply a patch here if ($attribute =~ /stepType/ ) { $value="\"accum\""; @@ -347,14 +349,101 @@ sub create_def_legacy { close(TAR); } - + +sub create_cfVarName { + my $p; my %seen; + my ($key) =@_; + my $field=$key; + + #if ($key =~ /paramId/) { $field="param.id"; } + #if ($key =~ /name/) { $field="param.name"; } + #if ($key =~ /units/) { $field="units.name"; } + if ($key =~ /cfVarName/) { $field="cfVarName"; } + + my $query= <<"EOF"; + select $field,force128,edition, + centre.abbreviation,param_id,attribute.name,attribute_value,param.name,param.shortName + from param,grib_encoding,grib,attribute,centre,units where + param.hide_def=0 and + grib_encoding.id=grib.encoding_id and + param.id=grib_encoding.param_id and + attribute.id=grib.attribute_id and + centre.id=grib_encoding.centre_id and + units.id=param.units_id + and cfVarName IS NOT NULL + order by edition,centre_id,param.o,param.id,grib_encoding.param_version,attribute.o; +EOF + + my $qh=$dbh->prepare($query); + $qh->execute(); + + # file containing the list of grib api parameters files we want to tar and + # distribute to users for them to download and update their list of parameter + # to the latest + #open(TAR,$tarfilesflag ? ">>" : ">","tarfiles.txt") or die "Count not open file tarfiles.txt: $!"; + #$tarfilesflag=1; + + while (my ($keyval,$force128,$edition,$centre,$paramId,$attribute,$value,$name,$shortName)=$qh->fetchrow_array ) + { + if ($centre eq "wmo" ) { $conceptDir=""; } + else { $conceptDir="/localConcepts/$centre"; } + #if ($key =~ /paramId/ && $force128==1 && $keyval >1000) { + # $keyval= $keyval % 1000; + #} + + if ($filebase ne "$basedir/grib$edition$conceptDir") { + if ($filebase) { + print $out "}\n"; + close $out; + } + $filebase="$basedir/grib$edition$conceptDir"; + mkpath($filebase); + + #copy("$filebase/$key.def","$filebase/$key.def.bkp") + # or die ("unable to copy $filebase/$key.def"); + + print TAR "grib$edition$conceptDir/$key.def\n"; + #system("cp -f $filebase/$key.def $filebase/$key.def.orig"); + open($out,"> $filebase/$key.def") + or die "unable to open $filebase/$key.def"; + print $out "# Automatically generated by $0, do not edit\n"; + $p=(); + } + if ($p ne $paramId || exists($seen{$attribute}) ) { + if ($p) { print $out "\t}\n"; } + print $out "#$name\n" ; + print $out "\'".$keyval."\' = {\n" ; + $p=$paramId; + %seen=(); + } + $seen{$attribute}=1; + print "($key=$keyval) $edition,$centre,$shortName,$paramId,$name,$attribute,$value\n"; + # we need to allow strings in the attribute_value field + # for the moment we apply a patch here + if ($attribute =~ /stepType/ ) { + $value="\"accum\""; + } + if ($value eq '') { + $value="missing()"; + } + print $out "\t $attribute = $value ;\n" ; + } + if ($filebase) { + print $out "}\n"; + close $out; + } + + close(TAR); +} + sub create_paramId_def { - my $p; my %seen; + my $p; my %seen; my $query="select edition,centre.abbreviation,param_id,attribute.name,attribute_value,param.name,param.shortName from param,grib_encoding,grib,attribute,centre where param.hide_def=0 and param.retired=0 and + grib_encoding.published=1 and grib_encoding.id=grib.encoding_id and param.id=grib_encoding.param_id and attribute.id=grib.attribute_id and @@ -375,9 +464,9 @@ sub create_paramId_def { close $out; } $filebase="$basedir/grib$edition$conceptDir"; - mkpath($filebase); + mkpath($filebase); - copy("$filebase/paramId.def","$filebase/paramId.def.bkp") + copy("$filebase/paramId.def","$filebase/paramId.def.bkp") or die ("unable to copy $filebase/paramId.def"); open($out,"> $filebase/paramId.def") or die "unable to open $filebase/paramId.def"; @@ -400,7 +489,7 @@ sub create_paramId_def { close $out; } } - + sub create_def_old { my ($key,$query)=@_; @@ -417,9 +506,9 @@ sub create_def_old { close $out; } $filebase="$basedir/grib$edition$conceptDir"; - mkpath($filebase); + mkpath($filebase); - copy("$filebase/$key.def","$filebase/$key.def.bkp") + copy("$filebase/$key.def","$filebase/$key.def.bkp") or die ("unable to copy $filebase/$key.def"); open($out,"> $filebase/$key.def") or die "unable to open $filebase/$key.def"; @@ -440,35 +529,36 @@ sub create_def_old { create_def_legacy("name"); create_def("units"); create_def_legacy("units"); +create_cfVarName("cfVarName"); create_cfName("cfName"); create_cfName_legacy("cfName"); # #create_paramId_def(); # $query="select distinct edition,centre.abbreviation,param_id,param.shortName from param,grib_encoding,centre where -# param.hide_def=0 and -# param.id=grib_encoding.param_id and -# centre.id=grib_encoding.centre_id and +# param.hide_def=0 and +# param.id=grib_encoding.param_id and +# centre.id=grib_encoding.centre_id and # shortName!='~' order by abbreviation,edition,param.o,param.id,shortName"; -# #select distinct edition,centre.abbreviation,param_id,param.shortName -# #from param,grib_encoding,grib,centre where param.hide_def=0 and param.id=grib.param_id and -# #centre.id=grib_encoding.centre_id and shortName!='~' +# #select distinct edition,centre.abbreviation,param_id,param.shortName +# #from param,grib_encoding,grib,centre where param.hide_def=0 and param.id=grib.param_id and +# #centre.id=grib_encoding.centre_id and shortName!='~' # #order by centre,edition,param.o,param_id"; # #create_def("shortName",$query); -# $query="select distinct edition,centre.abbreviation,param_id,param.name -# from param,grib,centre where param.hide_def=0 and param.id=grib.param_id and -# centre.id=grib.centre and shortName!='~' +# $query="select distinct edition,centre.abbreviation,param_id,param.name +# from param,grib,centre where param.hide_def=0 and param.id=grib.param_id and +# centre.id=grib.centre and shortName!='~' # order by centre,edition,param.o,param_id"; # #create_def("name",$query); -# $query="select distinct edition,centre.abbreviation,param_id,units.name +# $query="select distinct edition,centre.abbreviation,param_id,units.name # from param,grib,centre,units where param.hide_def=0 and param.id=grib.param_id and units.id=param.units_id -# and centre.id=grib.centre and shortName!='~' +# and centre.id=grib.centre and shortName!='~' # order by centre,edition,param.o,param_id"; # #create_def("units",$query); diff --git a/definitions/grib1/local.98.16.def b/definitions/grib1/local.98.16.def index f3ff7040a4..8ab7c7aadc 100644 --- a/definitions/grib1/local.98.16.def +++ b/definitions/grib1/local.98.16.def @@ -29,7 +29,7 @@ transient hourOfEndOfOverallTimeInterval=23; transient minuteOfEndOfOverallTimeInterval=59; transient secondOfEndOfOverallTimeInterval=59; -transient indicatorOfUnitForTimeRange=3; +transient indicatorOfUnitForTimeRange=3; # month transient lengthOfTimeRange=1; unsigned[1] averagingPeriod : dump ; diff --git a/definitions/grib1/localConcepts/ecmf/cfVarName.def b/definitions/grib1/localConcepts/ecmf/cfVarName.def index e36c36372c..90347cbff2 100644 --- a/definitions/grib1/localConcepts/ecmf/cfVarName.def +++ b/definitions/grib1/localConcepts/ecmf/cfVarName.def @@ -189,6 +189,11 @@ table2Version = 171 ; indicatorOfParameter = 7 ; } +#100 metre wind speed anomaly +'sia100' = { + table2Version = 171 ; + indicatorOfParameter = 8 ; + } #2 metre specific humidity 'sh2' = { table2Version = 174 ; diff --git a/definitions/grib1/localConcepts/ecmf/name.def b/definitions/grib1/localConcepts/ecmf/name.def index b5a90ffca0..da7d86d1e5 100644 --- a/definitions/grib1/localConcepts/ecmf/name.def +++ b/definitions/grib1/localConcepts/ecmf/name.def @@ -3774,6 +3774,11 @@ table2Version = 171 ; indicatorOfParameter = 7 ; } +#100 metre wind speed anomaly +'100 metre wind speed anomaly' = { + table2Version = 171 ; + indicatorOfParameter = 8 ; + } #Lake mix-layer temperature anomaly 'Lake mix-layer temperature anomaly' = { table2Version = 171 ; diff --git a/definitions/grib1/localConcepts/ecmf/paramId.def b/definitions/grib1/localConcepts/ecmf/paramId.def index 9a4be679c8..69a6d33f79 100644 --- a/definitions/grib1/localConcepts/ecmf/paramId.def +++ b/definitions/grib1/localConcepts/ecmf/paramId.def @@ -3774,6 +3774,11 @@ table2Version = 171 ; indicatorOfParameter = 7 ; } +#100 metre wind speed anomaly +'171008' = { + table2Version = 171 ; + indicatorOfParameter = 8 ; + } #Lake mix-layer temperature anomaly '171024' = { table2Version = 171 ; diff --git a/definitions/grib1/localConcepts/ecmf/shortName.def b/definitions/grib1/localConcepts/ecmf/shortName.def index 307dea7b63..7bded579d6 100644 --- a/definitions/grib1/localConcepts/ecmf/shortName.def +++ b/definitions/grib1/localConcepts/ecmf/shortName.def @@ -3774,6 +3774,11 @@ table2Version = 171 ; indicatorOfParameter = 7 ; } +#100 metre wind speed anomaly +'100sia' = { + table2Version = 171 ; + indicatorOfParameter = 8 ; + } #Lake mix-layer temperature anomaly 'lmlta' = { table2Version = 171 ; diff --git a/definitions/grib1/localConcepts/ecmf/units.def b/definitions/grib1/localConcepts/ecmf/units.def index c84516adaf..0d4dd06c8c 100644 --- a/definitions/grib1/localConcepts/ecmf/units.def +++ b/definitions/grib1/localConcepts/ecmf/units.def @@ -3774,6 +3774,11 @@ table2Version = 171 ; indicatorOfParameter = 7 ; } +#100 metre wind speed anomaly +'m s**-1' = { + table2Version = 171 ; + indicatorOfParameter = 8 ; + } #Lake mix-layer temperature anomaly 'K' = { table2Version = 171 ; diff --git a/definitions/grib2/cfVarName.def b/definitions/grib2/cfVarName.def index 3a0da34226..7d1d589cd1 100644 --- a/definitions/grib2/cfVarName.def +++ b/definitions/grib2/cfVarName.def @@ -119,34 +119,6 @@ scaleFactorOfLowerLimit = 0 ; probabilityType = 3 ; } -#Time-mean 2D wave spectra (single) -'avg_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 0 ; - } -#Time-maximum 2D wave spectra (single) -'max_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 2 ; - } -#Time-minimum 2D wave spectra (single) -'min_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-standard-deviation 2D wave spectra (single) -'std_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 6 ; - } #2 metre specific humidity 'sh2' = { discipline = 0 ; @@ -214,6 +186,26 @@ scaledValueOfFirstFixedSurface = 100 ; scaleFactorOfFirstFixedSurface = 0 ; } +#Time-maximum 2 metre relative humidity +'mx2r' = { + discipline = 0 ; + parameterCategory = 1 ; + parameterNumber = 1 ; + typeOfFirstFixedSurface = 103 ; + scaledValueOfFirstFixedSurface = 2 ; + scaleFactorOfFirstFixedSurface = 0 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-minimum 2 metre relative humidity +'mn2r' = { + discipline = 0 ; + parameterCategory = 1 ; + parameterNumber = 1 ; + typeOfFirstFixedSurface = 103 ; + scaledValueOfFirstFixedSurface = 2 ; + scaleFactorOfFirstFixedSurface = 0 ; + typeOfStatisticalProcessing = 3 ; + } #Time-mean sea ice area fraction 'avg_ci' = { discipline = 10 ; diff --git a/definitions/grib2/local.98.12.def b/definitions/grib2/local.98.12.def index af7a662623..b2a78692be 100644 --- a/definitions/grib2/local.98.12.def +++ b/definitions/grib2/local.98.12.def @@ -17,5 +17,6 @@ alias mars.time = indexingTimeHHMM; # ECC-1425 meta marsForecastMonth g1forecastmonth(dataDate, forecastTime): read_only; +alias forecastMonth = marsForecastMonth; pad padding_loc12_1(50); diff --git a/definitions/grib2/local.98.16.def b/definitions/grib2/local.98.16.def index 2d6b268f39..45d5db6d7c 100644 --- a/definitions/grib2/local.98.16.def +++ b/definitions/grib2/local.98.16.def @@ -8,3 +8,4 @@ alias local.methodNumber=methodNumber; # ECC-1425 meta marsForecastMonth g1forecastmonth(dataDate, forecastTime): read_only; +alias forecastMonth = marsForecastMonth; diff --git a/definitions/grib2/localConcepts/ecmf/cfVarName.def b/definitions/grib2/localConcepts/ecmf/cfVarName.def index 57020b5211..21e27e7849 100644 --- a/definitions/grib2/localConcepts/ecmf/cfVarName.def +++ b/definitions/grib2/localConcepts/ecmf/cfVarName.def @@ -1,4 +1,10 @@ # Automatically generated by ./create_def.pl, do not edit +#Sea ice area fraction +'siconc' = { + discipline = 192 ; + parameterCategory = 128 ; + parameterNumber = 31 ; + } #Maximum temperature at 2 metres in the last 24 hours 'mx2t24' = { discipline = 0 ; @@ -95,6 +101,18 @@ typeOfStatisticalProcessing = 3 ; lengthOfTimeRange = 3 ; } +#Maximum 10 metre wind gust in the last 3 hours +'fg310' = { + discipline = 192 ; + parameterCategory = 228 ; + parameterNumber = 28 ; + } +#100 metre wind speed +'si100' = { + discipline = 192 ; + parameterCategory = 228 ; + parameterNumber = 249 ; + } #10 metre wind gust gradient 'fggrd10' = { discipline = 192 ; @@ -343,6 +361,24 @@ parameterCategory = 140 ; parameterNumber = 250 ; } +#2D wave spectra (single) +'d2fd' = { + discipline = 192 ; + parameterCategory = 140 ; + parameterNumber = 251 ; + } +#Eastward surface sea water velocity +'uoe' = { + discipline = 192 ; + parameterCategory = 151 ; + parameterNumber = 131 ; + } +#Northward surface sea water velocity +'von' = { + discipline = 192 ; + parameterCategory = 151 ; + parameterNumber = 132 ; + } #10 metre wind gust during averaging time 'fgrea10' = { discipline = 192 ; @@ -397,9 +433,33 @@ parameterCategory = 200 ; parameterNumber = 168 ; } +#Time-mean 2 metre temperature +'avg_2t' = { + discipline = 192 ; + parameterCategory = 228 ; + parameterNumber = 4 ; + } +#Time-mean 10 metre wind speed +'avg_10ws' = { + discipline = 192 ; + parameterCategory = 228 ; + parameterNumber = 5 ; + } #2 metre temperature significance 't2s' = { discipline = 192 ; parameterCategory = 234 ; parameterNumber = 167 ; + } +#100 metre U wind component +'u100' = { + discipline = 192 ; + parameterCategory = 228 ; + parameterNumber = 246 ; + } +#100 metre V wind component +'v100' = { + discipline = 192 ; + parameterCategory = 228 ; + parameterNumber = 247 ; } diff --git a/definitions/grib2/localConcepts/era6/name.def b/definitions/grib2/localConcepts/era6/name.def index 8a4b79d14b..5831da6b4c 100644 --- a/definitions/grib2/localConcepts/era6/name.def +++ b/definitions/grib2/localConcepts/era6/name.def @@ -497,4 +497,58 @@ parameterNumber = 25 ; typeOfFirstFixedSurface = 105 ; typeOfStatisticalProcessing = 0 ; + } +#Snow thickness over sea ice +'Snow thickness over sea ice' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Sea ice salinity +'Sea ice salinity' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Time-mean snow thickness over sea ice +'Time-mean snow thickness over sea ice' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean Sea ice salinity +'Time-mean Sea ice salinity' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; } diff --git a/definitions/grib2/localConcepts/era6/paramId.def b/definitions/grib2/localConcepts/era6/paramId.def index afbb3fd2c6..3463b89aa9 100644 --- a/definitions/grib2/localConcepts/era6/paramId.def +++ b/definitions/grib2/localConcepts/era6/paramId.def @@ -497,4 +497,58 @@ parameterNumber = 25 ; typeOfFirstFixedSurface = 105 ; typeOfStatisticalProcessing = 0 ; + } +#Snow thickness over sea ice +'262002' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Sea ice salinity +'262023' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Time-mean snow thickness over sea ice +'263002' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean Sea ice salinity +'263023' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; } diff --git a/definitions/grib2/localConcepts/era6/shortName.def b/definitions/grib2/localConcepts/era6/shortName.def index 2fefe0ab75..b638f864f5 100644 --- a/definitions/grib2/localConcepts/era6/shortName.def +++ b/definitions/grib2/localConcepts/era6/shortName.def @@ -497,4 +497,58 @@ parameterNumber = 25 ; typeOfFirstFixedSurface = 105 ; typeOfStatisticalProcessing = 0 ; + } +#Snow thickness over sea ice +'sisnthick' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Sea ice salinity +'icesalt' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Time-mean snow thickness over sea ice +'avg_sisnthick' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean Sea ice salinity +'avg_icesalt' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; } diff --git a/definitions/grib2/localConcepts/era6/units.def b/definitions/grib2/localConcepts/era6/units.def index 15a30baaa8..551c415f03 100644 --- a/definitions/grib2/localConcepts/era6/units.def +++ b/definitions/grib2/localConcepts/era6/units.def @@ -497,4 +497,58 @@ parameterNumber = 25 ; typeOfFirstFixedSurface = 105 ; typeOfStatisticalProcessing = 0 ; + } +#Snow thickness over sea ice +'m' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Sea ice salinity +'g kg**-1' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + } +#Time-mean snow thickness over sea ice +'m' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 192 ; + typeOfFirstFixedSurface = 173 ; + typeOfSecondFixedSurface = 175 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean Sea ice salinity +'g kg**-1' = { + localTablesVersion = 1 ; + discipline = 10 ; + parameterCategory = 2 ; + parameterNumber = 193 ; + typeOfFirstFixedSurface = 174 ; + typeOfSecondFixedSurface = 176 ; + scaledValueOfFirstFixedSurface = missing() ; + scaleFactorOfFirstFixedSurface = missing() ; + scaledValueOfSecondFixedSurface = missing() ; + scaleFactorOfSecondFixedSurface = missing() ; + typeOfStatisticalProcessing = 0 ; } diff --git a/definitions/grib2/name.def b/definitions/grib2/name.def index d659a415ba..b48d303418 100644 --- a/definitions/grib2/name.def +++ b/definitions/grib2/name.def @@ -1269,6 +1269,78 @@ parameterCategory = 0 ; parameterNumber = 97 ; } +#Peak wave period of wind waves +'Peak wave period of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + } +#Peak wave period of total swell +'Peak wave period of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + } +#Peak wave period of first swell partition +'Peak wave period of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + } +#Peak wave period of second swell partition +'Peak wave period of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + } +#Peak wave period of third swell partition +'Peak wave period of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + } +#Peak wave direction (total) +'Peak wave direction (total)' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + } +#Peak wave direction of wind waves +'Peak wave direction of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + } +#Peak wave direction of total swell +'Peak wave direction of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + } +#Peak wave direction of first swell partition +'Peak wave direction of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + } +#Peak wave direction of second swell partition +'Peak wave direction of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + } +#Peak wave direction of third swell partition +'Peak wave direction of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + } +#Whitecap fraction +'Whitecap fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + } #Wave Spectral Skewness 'Wave Spectral Skewness' = { discipline = 10 ; @@ -1421,88 +1493,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'Time-mean significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'Time-mean significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'Time-mean significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'Time-mean significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'Time-mean significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'Time-mean significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-mean significant wave height of all waves with period larger than 10s -'Time-mean significant wave height of all waves with period larger than 10s' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-mean significant wave height of first swell partition 'Time-mean significant wave height of first swell partition' = { discipline = 10 ; @@ -1594,6 +1584,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 0 ; } +#Time-mean peak wave period of wind waves +'Time-mean peak wave period of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of total swell +'Time-mean peak wave period of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of first swell partition +'Time-mean peak wave period of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of second swell partition +'Time-mean peak wave period of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of third swell partition +'Time-mean peak wave period of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction (total) +'Time-mean peak wave direction (total)' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of wind waves +'Time-mean peak wave direction of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of total swell +'Time-mean peak wave direction of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of first swell partition +'Time-mean peak wave direction of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of second swell partition +'Time-mean peak wave direction of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of third swell partition +'Time-mean peak wave direction of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean whitecap fraction +'Time-mean whitecap fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 0 ; + } #Time-mean wave Spectral Skewness 'Time-mean wave Spectral Skewness' = { discipline = 10 ; @@ -1831,13 +1905,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean 2D wave spectra (single) -'Time-mean 2D wave spectra (single)' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 0 ; - } #Time-mean wave spectral kurtosis 'Time-mean wave spectral kurtosis' = { discipline = 10 ; @@ -1975,88 +2042,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'Time-maximum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'Time-maximum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'Time-maximum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'Time-maximum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'Time-maximum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'Time-maximum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-maximum significant wave height of all waves with period larger than 10s -'Time-maximum significant wave height of all waves with period larger than 10s' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-maximum significant wave height of first swell partition 'Time-maximum significant wave height of first swell partition' = { discipline = 10 ; @@ -2148,6 +2133,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 2 ; } +#Time-maximum peak wave period of wind waves +'Time-maximum peak wave period of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of total swell +'Time-maximum peak wave period of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of first swell partition +'Time-maximum peak wave period of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of second swell partition +'Time-maximum peak wave period of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of third swell partition +'Time-maximum peak wave period of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction (total) +'Time-maximum peak wave direction (total)' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of wind waves +'Time-maximum peak wave direction of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of total swell +'Time-maximum peak wave direction of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of first swell partition +'Time-maximum peak wave direction of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of second swell partition +'Time-maximum peak wave direction of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of third swell partition +'Time-maximum peak wave direction of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum whitecap fraction +'Time-maximum whitecap fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 2 ; + } #Time-maximum wave Spectral Skewness 'Time-maximum wave Spectral Skewness' = { discipline = 10 ; @@ -2385,13 +2454,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum 2D wave spectra (single) -'Time-maximum 2D wave spectra (single)' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 2 ; - } #Time-maximum wave spectral kurtosis 'Time-maximum wave spectral kurtosis' = { discipline = 10 ; @@ -2481,135 +2543,53 @@ typeOfStatisticalProcessing = 3 ; } #Time-minimum wave frequency width of first swell partition -'Time-minimum wave frequency width of first swell partition' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 59 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave directional width of second swell partition -'Time-minimum wave directional width of second swell partition' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 57 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave frequency width of second swell partition -'Time-minimum wave frequency width of second swell partition' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 60 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave directional width of third swell partition -'Time-minimum wave directional width of third swell partition' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 58 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave frequency width of third swell partition -'Time-minimum wave frequency width of third swell partition' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 61 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux magnitude -'Time-minimum wave energy flux magnitude' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 78 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux mean direction -'Time-minimum wave energy flux mean direction' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 79 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'Time-minimum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds' = { +'Time-minimum wave frequency width of first swell partition' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 59 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'Time-minimum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds' = { +#Time-minimum wave directional width of second swell partition +'Time-minimum wave directional width of second swell partition' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 57 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'Time-minimum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds' = { +#Time-minimum wave frequency width of second swell partition +'Time-minimum wave frequency width of second swell partition' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 60 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'Time-minimum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds' = { +#Time-minimum wave directional width of third swell partition +'Time-minimum wave directional width of third swell partition' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 58 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'Time-minimum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds' = { +#Time-minimum wave frequency width of third swell partition +'Time-minimum wave frequency width of third swell partition' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 61 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'Time-minimum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds' = { +#Time-minimum wave energy flux magnitude +'Time-minimum wave energy flux magnitude' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 78 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; } -#Time-minimum significant wave height of all waves with period larger than 10s -'Time-minimum significant wave height of all waves with period larger than 10s' = { +#Time-minimum wave energy flux mean direction +'Time-minimum wave energy flux mean direction' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 79 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; } #Time-minimum significant wave height of first swell partition 'Time-minimum significant wave height of first swell partition' = { @@ -2702,6 +2682,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 3 ; } +#Time-minimum peak wave period of wind waves +'Time-minimum peak wave period of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of total swell +'Time-minimum peak wave period of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of first swell partition +'Time-minimum peak wave period of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of second swell partition +'Time-minimum peak wave period of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of third swell partition +'Time-minimum peak wave period of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction (total) +'Time-minimum peak wave direction (total)' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of wind waves +'Time-minimum peak wave direction of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of total swell +'Time-minimum peak wave direction of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of first swell partition +'Time-minimum peak wave direction of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of second swell partition +'Time-minimum peak wave direction of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of third swell partition +'Time-minimum peak wave direction of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum whitecap fraction +'Time-minimum whitecap fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 3 ; + } #Time-minimum wave Spectral Skewness 'Time-minimum wave Spectral Skewness' = { discipline = 10 ; @@ -2939,13 +3003,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 3 ; } -#Time-minimum 2D wave spectra (single) -'Time-minimum 2D wave spectra (single)' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 3 ; - } #Time-minimum wave spectral kurtosis 'Time-minimum wave spectral kurtosis' = { discipline = 10 ; @@ -3083,88 +3140,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-standard-deviation significant wave height of all waves with period larger than 10s -'Time-standard-deviation significant wave height of all waves with period larger than 10s' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-standard-deviation significant wave height of first swell partition 'Time-standard-deviation significant wave height of first swell partition' = { discipline = 10 ; @@ -3256,6 +3231,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 6 ; } +#Time-standard-deviation peak wave period of wind waves +'Time-standard-deviation peak wave period of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of total swell +'Time-standard-deviation peak wave period of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of first swell partition +'Time-standard-deviation peak wave period of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of second swell partition +'Time-standard-deviation peak wave period of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of third swell partition +'Time-standard-deviation peak wave period of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction (total) +'Time-standard-deviation peak wave direction (total)' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of wind waves +'Time-standard-deviation peak wave direction of wind waves' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of total swell +'Time-standard-deviation peak wave direction of total swell' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of first swell partition +'Time-standard-deviation peak wave direction of first swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of second swell partition +'Time-standard-deviation peak wave direction of second swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of third swell partition +'Time-standard-deviation peak wave direction of third swell partition' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation whitecap fraction +'Time-standard-deviation whitecap fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 6 ; + } #Time-standard-deviation wave Spectral Skewness 'Time-standard-deviation wave Spectral Skewness' = { discipline = 10 ; @@ -3493,13 +3552,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation 2D wave spectra (single) -'Time-standard-deviation 2D wave spectra (single)' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 6 ; - } #Time-standard-deviation wave spectral kurtosis 'Time-standard-deviation wave spectral kurtosis' = { discipline = 10 ; @@ -16501,6 +16553,12 @@ parameterCategory = 0 ; parameterNumber = 32 ; } +#Wet-bulb temperature +'Wet-bulb temperature' = { + discipline = 0 ; + parameterCategory = 0 ; + parameterNumber = 27 ; + } #Sea ice thickness 'Sea ice thickness' = { discipline = 10 ; diff --git a/definitions/grib2/paramId.def b/definitions/grib2/paramId.def index 6e431f71e8..a912c14e64 100644 --- a/definitions/grib2/paramId.def +++ b/definitions/grib2/paramId.def @@ -1269,6 +1269,78 @@ parameterCategory = 0 ; parameterNumber = 97 ; } +#Peak wave period of wind waves +'140135' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + } +#Peak wave period of total swell +'140136' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + } +#Peak wave period of first swell partition +'140137' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + } +#Peak wave period of second swell partition +'140138' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + } +#Peak wave period of third swell partition +'140139' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + } +#Peak wave direction (total) +'140140' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + } +#Peak wave direction of wind waves +'140141' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + } +#Peak wave direction of total swell +'140142' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + } +#Peak wave direction of first swell partition +'140143' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + } +#Peak wave direction of second swell partition +'140144' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + } +#Peak wave direction of third swell partition +'140145' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + } +#Whitecap fraction +'140146' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + } #Wave Spectral Skewness '140207' = { discipline = 10 ; @@ -1421,88 +1493,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'141114' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'141115' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'141116' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'141117' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'141118' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'141119' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-mean significant wave height of all waves with period larger than 10s -'141120' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-mean significant wave height of first swell partition '141121' = { discipline = 10 ; @@ -1594,6 +1584,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 0 ; } +#Time-mean peak wave period of wind waves +'141135' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of total swell +'141136' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of first swell partition +'141137' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of second swell partition +'141138' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of third swell partition +'141139' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction (total) +'141140' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of wind waves +'141141' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of total swell +'141142' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of first swell partition +'141143' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of second swell partition +'141144' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of third swell partition +'141145' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean whitecap fraction +'141146' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 0 ; + } #Time-mean wave Spectral Skewness '141207' = { discipline = 10 ; @@ -1831,13 +1905,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean 2D wave spectra (single) -'141251' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 0 ; - } #Time-mean wave spectral kurtosis '141252' = { discipline = 10 ; @@ -1975,88 +2042,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'143114' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'143115' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'143116' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'143117' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'143118' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'143119' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-maximum significant wave height of all waves with period larger than 10s -'143120' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-maximum significant wave height of first swell partition '143121' = { discipline = 10 ; @@ -2148,6 +2133,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 2 ; } +#Time-maximum peak wave period of wind waves +'143135' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of total swell +'143136' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of first swell partition +'143137' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of second swell partition +'143138' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of third swell partition +'143139' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction (total) +'143140' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of wind waves +'143141' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of total swell +'143142' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of first swell partition +'143143' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of second swell partition +'143144' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of third swell partition +'143145' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum whitecap fraction +'143146' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 2 ; + } #Time-maximum wave Spectral Skewness '143207' = { discipline = 10 ; @@ -2385,13 +2454,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum 2D wave spectra (single) -'143251' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 2 ; - } #Time-maximum wave spectral kurtosis '143252' = { discipline = 10 ; @@ -2481,135 +2543,53 @@ typeOfStatisticalProcessing = 3 ; } #Time-minimum wave frequency width of first swell partition -'144107' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 59 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave directional width of second swell partition -'144108' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 57 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave frequency width of second swell partition -'144109' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 60 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave directional width of third swell partition -'144110' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 58 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave frequency width of third swell partition -'144111' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 61 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux magnitude -'144112' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 78 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux mean direction -'144113' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 79 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'144114' = { +'144107' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 59 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'144115' = { +#Time-minimum wave directional width of second swell partition +'144108' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 57 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'144116' = { +#Time-minimum wave frequency width of second swell partition +'144109' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 60 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'144117' = { +#Time-minimum wave directional width of third swell partition +'144110' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 58 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'144118' = { +#Time-minimum wave frequency width of third swell partition +'144111' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 61 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'144119' = { +#Time-minimum wave energy flux magnitude +'144112' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 78 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; } -#Time-minimum significant wave height of all waves with period larger than 10s -'144120' = { +#Time-minimum wave energy flux mean direction +'144113' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 79 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; } #Time-minimum significant wave height of first swell partition '144121' = { @@ -2702,6 +2682,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 3 ; } +#Time-minimum peak wave period of wind waves +'144135' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of total swell +'144136' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of first swell partition +'144137' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of second swell partition +'144138' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of third swell partition +'144139' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction (total) +'144140' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of wind waves +'144141' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of total swell +'144142' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of first swell partition +'144143' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of second swell partition +'144144' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of third swell partition +'144145' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum whitecap fraction +'144146' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 3 ; + } #Time-minimum wave Spectral Skewness '144207' = { discipline = 10 ; @@ -2939,13 +3003,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 3 ; } -#Time-minimum 2D wave spectra (single) -'144251' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 3 ; - } #Time-minimum wave spectral kurtosis '144252' = { discipline = 10 ; @@ -3083,88 +3140,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'145114' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'145115' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'145116' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'145117' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'145118' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'145119' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-standard-deviation significant wave height of all waves with period larger than 10s -'145120' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-standard-deviation significant wave height of first swell partition '145121' = { discipline = 10 ; @@ -3256,6 +3231,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 6 ; } +#Time-standard-deviation peak wave period of wind waves +'145135' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of total swell +'145136' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of first swell partition +'145137' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of second swell partition +'145138' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of third swell partition +'145139' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction (total) +'145140' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of wind waves +'145141' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of total swell +'145142' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of first swell partition +'145143' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of second swell partition +'145144' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of third swell partition +'145145' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation whitecap fraction +'145146' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 6 ; + } #Time-standard-deviation wave Spectral Skewness '145207' = { discipline = 10 ; @@ -3493,13 +3552,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation 2D wave spectra (single) -'145251' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 6 ; - } #Time-standard-deviation wave spectral kurtosis '145252' = { discipline = 10 ; @@ -16501,6 +16553,12 @@ parameterCategory = 0 ; parameterNumber = 32 ; } +#Wet-bulb temperature +'261023' = { + discipline = 0 ; + parameterCategory = 0 ; + parameterNumber = 27 ; + } #Sea ice thickness '262000' = { discipline = 10 ; diff --git a/definitions/grib2/shortName.def b/definitions/grib2/shortName.def index 254199b0ea..5931bb1062 100644 --- a/definitions/grib2/shortName.def +++ b/definitions/grib2/shortName.def @@ -1269,6 +1269,78 @@ parameterCategory = 0 ; parameterNumber = 97 ; } +#Peak wave period of wind waves +'pp1dw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + } +#Peak wave period of total swell +'pp1ds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + } +#Peak wave period of first swell partition +'pp1d1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + } +#Peak wave period of second swell partition +'pp1d2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + } +#Peak wave period of third swell partition +'pp1d3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + } +#Peak wave direction (total) +'pwd' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + } +#Peak wave direction of wind waves +'pwdw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + } +#Peak wave direction of total swell +'pwds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + } +#Peak wave direction of first swell partition +'pwd1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + } +#Peak wave direction of second swell partition +'pwd2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + } +#Peak wave direction of third swell partition +'pwd3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + } +#Whitecap fraction +'wcfr' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + } #Wave Spectral Skewness 'wss' = { discipline = 10 ; @@ -1421,88 +1493,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'avg_h1012' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'avg_h1214' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'avg_h1417' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'avg_h1721' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'avg_h2125' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'avg_h2530' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-mean significant wave height of all waves with period larger than 10s -'avg_sh10' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-mean significant wave height of first swell partition 'avg_swh1' = { discipline = 10 ; @@ -1594,6 +1584,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 0 ; } +#Time-mean peak wave period of wind waves +'avg_pp1dw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of total swell +'avg_pp1ds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of first swell partition +'avg_pp1d1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of second swell partition +'avg_pp1d2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of third swell partition +'avg_pp1d3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction (total) +'avg_pwd' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of wind waves +'avg_pwdw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of total swell +'avg_pwds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of first swell partition +'avg_pwd1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of second swell partition +'avg_pwd2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of third swell partition +'avg_pwd3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean whitecap fraction +'avg_wcfr' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 0 ; + } #Time-mean wave Spectral Skewness 'avg_wss' = { discipline = 10 ; @@ -1831,13 +1905,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean 2D wave spectra (single) -'avg_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 0 ; - } #Time-mean wave spectral kurtosis 'avg_wsk' = { discipline = 10 ; @@ -1975,88 +2042,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'max_h1012' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'max_h1214' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'max_h1417' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'max_h1721' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'max_h2125' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'max_h2530' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-maximum significant wave height of all waves with period larger than 10s -'max_sh10' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-maximum significant wave height of first swell partition 'max_swh1' = { discipline = 10 ; @@ -2148,6 +2133,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 2 ; } +#Time-maximum peak wave period of wind waves +'max_pp1dw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of total swell +'max_pp1ds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of first swell partition +'max_pp1d1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of second swell partition +'max_pp1d2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of third swell partition +'max_pp1d3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction (total) +'max_pwd' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of wind waves +'max_pwdw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of total swell +'max_pwds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of first swell partition +'max_pwd1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of second swell partition +'max_pwd2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of third swell partition +'max_pwd3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum whitecap fraction +'max_wcfr' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 2 ; + } #Time-maximum wave Spectral Skewness 'max_wss' = { discipline = 10 ; @@ -2385,13 +2454,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum 2D wave spectra (single) -'max_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 2 ; - } #Time-maximum wave spectral kurtosis 'max_wsk' = { discipline = 10 ; @@ -2481,135 +2543,53 @@ typeOfStatisticalProcessing = 3 ; } #Time-minimum wave frequency width of first swell partition -'min_wfw1' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 59 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave directional width of second swell partition -'min_wdw2' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 57 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave frequency width of second swell partition -'min_wfw2' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 60 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave directional width of third swell partition -'min_wdw3' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 58 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave frequency width of third swell partition -'min_wfw3' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 61 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux magnitude -'min_wefxm' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 78 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux mean direction -'min_wefxd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 79 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'min_h1012' = { +'min_wfw1' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 59 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'min_h1214' = { +#Time-minimum wave directional width of second swell partition +'min_wdw2' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 57 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'min_h1417' = { +#Time-minimum wave frequency width of second swell partition +'min_wfw2' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 60 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'min_h1721' = { +#Time-minimum wave directional width of third swell partition +'min_wdw3' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 58 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'min_h2125' = { +#Time-minimum wave frequency width of third swell partition +'min_wfw3' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 61 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'min_h2530' = { +#Time-minimum wave energy flux magnitude +'min_wefxm' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 78 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; } -#Time-minimum significant wave height of all waves with period larger than 10s -'min_sh10' = { +#Time-minimum wave energy flux mean direction +'min_wefxd' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 79 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; } #Time-minimum significant wave height of first swell partition 'min_swh1' = { @@ -2702,6 +2682,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 3 ; } +#Time-minimum peak wave period of wind waves +'min_pp1dw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of total swell +'min_pp1ds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of first swell partition +'min_pp1d1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of second swell partition +'min_pp1d2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of third swell partition +'min_pp1d3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction (total) +'min_pwd' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of wind waves +'min_pwdw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of total swell +'min_pwds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of first swell partition +'min_pwd1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of second swell partition +'min_pwd2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of third swell partition +'min_pwd3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum whitecap fraction +'min_wcfr' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 3 ; + } #Time-minimum wave Spectral Skewness 'min_wss' = { discipline = 10 ; @@ -2939,13 +3003,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 3 ; } -#Time-minimum 2D wave spectra (single) -'min_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 3 ; - } #Time-minimum wave spectral kurtosis 'min_wsk' = { discipline = 10 ; @@ -3083,88 +3140,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'std_h1012' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'std_h1214' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'std_h1417' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'std_h1721' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'std_h2125' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'std_h2530' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-standard-deviation significant wave height of all waves with period larger than 10s -'std_sh10' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-standard-deviation significant wave height of first swell partition 'std_swh1' = { discipline = 10 ; @@ -3256,6 +3231,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 6 ; } +#Time-standard-deviation peak wave period of wind waves +'std_pp1dw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of total swell +'std_pp1ds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of first swell partition +'std_pp1d1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of second swell partition +'std_pp1d2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of third swell partition +'std_pp1d3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction (total) +'std_pwd' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of wind waves +'std_pwdw' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of total swell +'std_pwds' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of first swell partition +'std_pwd1' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of second swell partition +'std_pwd2' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of third swell partition +'std_pwd3' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation whitecap fraction +'std_wcfr' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 6 ; + } #Time-standard-deviation wave Spectral Skewness 'std_wss' = { discipline = 10 ; @@ -3493,13 +3552,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation 2D wave spectra (single) -'std_2dfd' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 6 ; - } #Time-standard-deviation wave spectral kurtosis 'std_wsk' = { discipline = 10 ; @@ -16501,6 +16553,12 @@ parameterCategory = 0 ; parameterNumber = 32 ; } +#Wet-bulb temperature +'wbt' = { + discipline = 0 ; + parameterCategory = 0 ; + parameterNumber = 27 ; + } #Sea ice thickness 'sithick' = { discipline = 10 ; diff --git a/definitions/grib2/templates/template.3.101.def b/definitions/grib2/templates/template.3.101.def index fb8cb71f19..7908cf4218 100644 --- a/definitions/grib2/templates/template.3.101.def +++ b/definitions/grib2/templates/template.3.101.def @@ -14,3 +14,5 @@ unsigned[1] numberOfGridInReference : dump; byte[16] uuidOfHGrid : dump; template_nofail unstructuredGrid "grib2/localConcepts/[centre:s]/unstructuredGrid.def"; + +# iterator unstructured(numberOfPoints, missingValue, values, uuidOfHGrid); diff --git a/definitions/grib2/units.def b/definitions/grib2/units.def index 8692146818..ed0706bbdf 100644 --- a/definitions/grib2/units.def +++ b/definitions/grib2/units.def @@ -1269,6 +1269,78 @@ parameterCategory = 0 ; parameterNumber = 97 ; } +#Peak wave period of wind waves +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + } +#Peak wave period of total swell +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + } +#Peak wave period of first swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + } +#Peak wave period of second swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + } +#Peak wave period of third swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + } +#Peak wave direction (total) +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + } +#Peak wave direction of wind waves +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + } +#Peak wave direction of total swell +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + } +#Peak wave direction of first swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + } +#Peak wave direction of second swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + } +#Peak wave direction of third swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + } +#Whitecap fraction +'Fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + } #Wave Spectral Skewness 'Numeric' = { discipline = 10 ; @@ -1421,88 +1493,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-mean significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-mean significant wave height of all waves with period larger than 10s -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 0 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-mean significant wave height of first swell partition 'm' = { discipline = 10 ; @@ -1594,6 +1584,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 0 ; } +#Time-mean peak wave period of wind waves +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of total swell +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of first swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of second swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave period of third swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction (total) +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of wind waves +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of total swell +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of first swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of second swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean peak wave direction of third swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 0 ; + } +#Time-mean whitecap fraction +'Fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 0 ; + } #Time-mean wave Spectral Skewness 'Numeric' = { discipline = 10 ; @@ -1831,13 +1905,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 0 ; } -#Time-mean 2D wave spectra (single) -'m**2 s radian**-1' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 0 ; - } #Time-mean wave spectral kurtosis 'dimensionless' = { discipline = 10 ; @@ -1975,88 +2042,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-maximum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-maximum significant wave height of all waves with period larger than 10s -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 2 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-maximum significant wave height of first swell partition 'm' = { discipline = 10 ; @@ -2148,6 +2133,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 2 ; } +#Time-maximum peak wave period of wind waves +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of total swell +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of first swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of second swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave period of third swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction (total) +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of wind waves +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of total swell +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of first swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of second swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum peak wave direction of third swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 2 ; + } +#Time-maximum whitecap fraction +'Fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 2 ; + } #Time-maximum wave Spectral Skewness 'Numeric' = { discipline = 10 ; @@ -2385,13 +2454,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 2 ; } -#Time-maximum 2D wave spectra (single) -'m**2 s radian**-1' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 2 ; - } #Time-maximum wave spectral kurtosis 'dimensionless' = { discipline = 10 ; @@ -2509,107 +2571,25 @@ typeOfStatisticalProcessing = 3 ; } #Time-minimum wave frequency width of third swell partition -'dimensionless' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 61 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux magnitude -'W m**-1' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 78 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum wave energy flux mean direction -'Degree true' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 79 ; - typeOfStatisticalProcessing = 3 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'m' = { +'dimensionless' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 61 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; } -#Time-minimum significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'m' = { +#Time-minimum wave energy flux magnitude +'W m**-1' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 78 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; } -#Time-minimum significant wave height of all waves with period larger than 10s -'m' = { +#Time-minimum wave energy flux mean direction +'Degree true' = { discipline = 10 ; parameterCategory = 0 ; - parameterNumber = 3 ; + parameterNumber = 79 ; typeOfStatisticalProcessing = 3 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; } #Time-minimum significant wave height of first swell partition 'm' = { @@ -2702,6 +2682,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 3 ; } +#Time-minimum peak wave period of wind waves +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of total swell +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of first swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of second swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave period of third swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction (total) +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of wind waves +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of total swell +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of first swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of second swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum peak wave direction of third swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 3 ; + } +#Time-minimum whitecap fraction +'Fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 3 ; + } #Time-minimum wave Spectral Skewness 'Numeric' = { discipline = 10 ; @@ -2939,13 +3003,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 3 ; } -#Time-minimum 2D wave spectra (single) -'m**2 s radian**-1' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 3 ; - } #Time-minimum wave spectral kurtosis 'dimensionless' = { discipline = 10 ; @@ -3083,88 +3140,6 @@ parameterNumber = 79 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 10 to 12 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 12 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 12 to 14 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 12 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 14 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 14 to 17 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 14 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 17 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 17 to 21 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 17 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 21 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 21 to 25 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 21 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 25 ; - } -#Time-standard-deviation significant wave height of all waves with periods within the inclusive range from 25 to 30 seconds -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 7 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 25 ; - scaleFactorOfUpperWavePeriodLimit = 0 ; - scaledValueOfUpperWavePeriodLimit = 30 ; - } -#Time-standard-deviation significant wave height of all waves with period larger than 10s -'m' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 3 ; - typeOfStatisticalProcessing = 6 ; - typeOfWavePeriodInterval = 3 ; - scaleFactorOfLowerWavePeriodLimit = 0 ; - scaledValueOfLowerWavePeriodLimit = 10 ; - } #Time-standard-deviation significant wave height of first swell partition 'm' = { discipline = 10 ; @@ -3256,6 +3231,90 @@ parameterNumber = 97 ; typeOfStatisticalProcessing = 6 ; } +#Time-standard-deviation peak wave period of wind waves +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 35 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of total swell +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 36 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of first swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 65 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of second swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 66 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave period of third swell partition +'s' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 67 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction (total) +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 46 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of wind waves +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 71 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of total swell +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 72 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of first swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 68 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of second swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 69 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation peak wave direction of third swell partition +'Degree true' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 70 ; + typeOfStatisticalProcessing = 6 ; + } +#Time-standard-deviation whitecap fraction +'Fraction' = { + discipline = 10 ; + parameterCategory = 0 ; + parameterNumber = 73 ; + typeOfStatisticalProcessing = 6 ; + } #Time-standard-deviation wave Spectral Skewness 'Numeric' = { discipline = 10 ; @@ -3493,13 +3552,6 @@ scaleFactorOfFirstFixedSurface = 0 ; typeOfStatisticalProcessing = 6 ; } -#Time-standard-deviation 2D wave spectra (single) -'m**2 s radian**-1' = { - discipline = 10 ; - parameterCategory = 0 ; - parameterNumber = 86 ; - typeOfStatisticalProcessing = 6 ; - } #Time-standard-deviation wave spectral kurtosis 'dimensionless' = { discipline = 10 ; @@ -16501,6 +16553,12 @@ parameterCategory = 0 ; parameterNumber = 32 ; } +#Wet-bulb temperature +'K' = { + discipline = 0 ; + parameterCategory = 0 ; + parameterNumber = 27 ; + } #Sea ice thickness 'm' = { discipline = 10 ; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa38b6ad3b..01d497bb1b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/accessor" "${CMAKE_CURRENT_SOURCE_DIR}/geo_iterator" + "${CMAKE_CURRENT_SOURCE_DIR}/geo_nearest" ) list( APPEND eccodes_src_files @@ -325,32 +326,31 @@ list( APPEND eccodes_src_files grib_expression_class_double.cc grib_expression_class_string.cc grib_expression_class_sub_string.cc - grib_nearest.cc - grib_nearest_class.cc - grib_nearest_class_gen.cc - grib_nearest_class_healpix.cc - grib_nearest_class_regular.cc - grib_nearest_class_reduced.cc - grib_nearest_class_latlon_reduced.cc - grib_nearest_class_lambert_conformal.cc - grib_nearest_class_lambert_azimuthal_equal_area.cc - grib_nearest_class_mercator.cc - grib_nearest_class_polar_stereographic.cc - grib_nearest_class_space_view.cc - geo_iterator/grib_iterator_class_polar_stereographic.cc - geo_iterator/grib_iterator_class_lambert_azimuthal_equal_area.cc - geo_iterator/grib_iterator_class_lambert_conformal.cc - geo_iterator/grib_iterator_class_mercator.cc + geo_nearest/grib_nearest.cc + geo_nearest/grib_nearest_class_gen.cc + geo_nearest/grib_nearest_class_healpix.cc + geo_nearest/grib_nearest_class_lambert_azimuthal_equal_area.cc + geo_nearest/grib_nearest_class_lambert_conformal.cc + geo_nearest/grib_nearest_class_latlon_reduced.cc + geo_nearest/grib_nearest_class_mercator.cc + geo_nearest/grib_nearest_class_polar_stereographic.cc + geo_nearest/grib_nearest_class_reduced.cc + geo_nearest/grib_nearest_class_regular.cc + geo_nearest/grib_nearest_class_space_view.cc geo_iterator/grib_iterator.cc - grib_iterator_class.cc geo_iterator/grib_iterator_class_gaussian.cc geo_iterator/grib_iterator_class_gaussian_reduced.cc - geo_iterator/grib_iterator_class_latlon_reduced.cc geo_iterator/grib_iterator_class_gen.cc + geo_iterator/grib_iterator_class_healpix.cc + geo_iterator/grib_iterator_class_lambert_azimuthal_equal_area.cc + geo_iterator/grib_iterator_class_lambert_conformal.cc geo_iterator/grib_iterator_class_latlon.cc + geo_iterator/grib_iterator_class_latlon_reduced.cc + geo_iterator/grib_iterator_class_mercator.cc + geo_iterator/grib_iterator_class_polar_stereographic.cc geo_iterator/grib_iterator_class_regular.cc geo_iterator/grib_iterator_class_space_view.cc - geo_iterator/grib_iterator_class_healpix.cc + geo_iterator/grib_iterator_class_unstructured.cc grib_expression.cc codes_util.cc grib_util.cc @@ -363,10 +363,8 @@ list( APPEND eccodes_src_files eccodes_prototypes.h grib_dumper_class.h grib_dumper_factory.h - grib_iterator_class.h - grib_iterator_factory.h - grib_nearest_class.h - grib_nearest_factory.h + grib_iterator_factory.cc + grib_nearest_factory.cc grib_yacc.h md5.h md5.cc diff --git a/src/accessor/grib_accessor_class_ascii.cc b/src/accessor/grib_accessor_class_ascii.cc index e6d9a34363..6fa3f4cbc6 100644 --- a/src/accessor/grib_accessor_class_ascii.cc +++ b/src/accessor/grib_accessor_class_ascii.cc @@ -66,21 +66,41 @@ int grib_accessor_ascii_t::pack_string(const char* val, size_t* len) { grib_handle* hand = grib_handle_of_accessor(this); const size_t alen = length_; - if (len[0] > (alen + 1)) { + if (*len > (alen + 1)) { grib_context_log(context_, GRIB_LOG_ERROR, - "pack_string: Wrong size (%zu) for %s, it contains %ld values", - len[0], name_, length_ + 1); - len[0] = 0; + "%s: Buffer too small for %s. It is %zu bytes long (input string len=%zu)", + class_name_, name_, alen, *len); + *len = alen; return GRIB_BUFFER_TOO_SMALL; } for (size_t i = 0; i < alen; i++) { - if (i < len[0]) + if (i < *len) hand->buffer->data[offset_ + i] = val[i]; else hand->buffer->data[offset_ + i] = 0; } + // TODO(masn): Make this an error. + // But we have to allow this case unfortunately as returning an error breaks + // clients e.g. grib1 local def 40 has marsDomain of 2 bytes but local def 21 + // has the same key with 1 byte! Legacy stuff that cannot be changed easily. + // So at least issue a warning + if (*len > alen) { + // Decode the string and compare with the incoming value + size_t size = 0; + if (grib_get_string_length_acc(this, &size) == GRIB_SUCCESS) { + char* value = (char*)grib_context_malloc_clear(context_, size); + if (value) { + if (this->unpack_string(value, &size) == GRIB_SUCCESS && !STR_EQUAL(val, value)) { + fprintf(stderr, "ECCODES WARNING : String input '%s' truncated to '%s'. Key %s is %zu byte(s)\n", + val, value, name_, alen); + } + grib_context_free(context_, value); + } + } + } + return GRIB_SUCCESS; } diff --git a/src/accessor/grib_accessor_class_concept.cc b/src/accessor/grib_accessor_class_concept.cc index 249dde8887..9dd0b71a5e 100644 --- a/src/accessor/grib_accessor_class_concept.cc +++ b/src/accessor/grib_accessor_class_concept.cc @@ -389,12 +389,21 @@ static int grib_concept_apply(grib_accessor* a, const char* name) grib_set_values(h, &values[i], 1); } } - // else if (STR_EQUAL(values[i].name, "sourceSinkChemicalPhysicalProcess")) { - // if (grib_set_long(h, "is_chemical_srcsink", 1) == GRIB_SUCCESS) { - // resubmit = true; - // grib_set_values(h, &values[i], 1); - // } - // } + else if (STR_EQUAL(values[i].name, "typeOfWavePeriodInterval")) { + grib_context_log(h->context, GRIB_LOG_DEBUG, "%s: Switch to waves selected by period range", __func__); + // TODO(masn): Add a new key e.g. is_wave_period_range + if (grib_set_long(h, "productDefinitionTemplateNumber", 103) == GRIB_SUCCESS) { + resubmit = true; + grib_set_values(h, &values[i], 1); + } + } + else if (STR_EQUAL(values[i].name, "sourceSinkChemicalPhysicalProcess")) { + grib_context_log(h->context, GRIB_LOG_DEBUG, "%s: Switch to chemical src/sink", __func__); + if (grib_set_long(h, "is_chemical_srcsink", 1) == GRIB_SUCCESS) { + resubmit = true; + grib_set_values(h, &values[i], 1); + } + } } } diff --git a/src/accessor/grib_accessor_class_expanded_descriptors.cc b/src/accessor/grib_accessor_class_expanded_descriptors.cc index 6acb4e878a..1e37332561 100644 --- a/src/accessor/grib_accessor_class_expanded_descriptors.cc +++ b/src/accessor/grib_accessor_class_expanded_descriptors.cc @@ -58,7 +58,7 @@ void grib_accessor_expanded_descriptors_t::init(const long len, grib_arguments* #if MYDEBUG static int global_depth = -1; -static char* descriptor_type_name(int dtype) +static const char* descriptor_type_name(int dtype) { switch (dtype) { case BUFR_DESCRIPTOR_TYPE_STRING: diff --git a/src/accessor/grib_accessor_class_g2_chemical.cc b/src/accessor/grib_accessor_class_g2_chemical.cc index 6244636996..c86240aa98 100644 --- a/src/accessor/grib_accessor_class_g2_chemical.cc +++ b/src/accessor/grib_accessor_class_g2_chemical.cc @@ -13,6 +13,15 @@ grib_accessor_g2_chemical_t _grib_accessor_g2_chemical{}; grib_accessor* grib_accessor_g2_chemical = &_grib_accessor_g2_chemical; +// Meaning of data member chemical_type_: +// 0 = atmospheric chemical constituents +// 1 = atmospheric chemical constituents based on a distribution function +// 2 = atmospheric chemical constituents with source or sink +// +#define CHEM_PLAIN 0 +#define CHEM_DISTRIB 1 +#define CHEM_SRCSINK 2 + void grib_accessor_g2_chemical_t::init(const long l, grib_arguments* c) { grib_accessor_unsigned_t::init(l, c); @@ -29,15 +38,10 @@ int grib_accessor_g2_chemical_t::unpack_long(long* val, size_t* len) long productDefinitionTemplateNumber = 0; grib_get_long(grib_handle_of_accessor(this), productDefinitionTemplateNumber_, &productDefinitionTemplateNumber); - // Meaning of self->chemical_type: - // 0 = atmospheric chemical constituents - // 1 = atmospheric chemical constituents based on a distribution function - // 2 = atmospheric chemical constituents with source or sink - // - Assert(chemical_type_ == 0 || chemical_type_ == 1 || chemical_type_ == 2); - if (chemical_type_ == 1) + Assert(chemical_type_ == CHEM_PLAIN || chemical_type_ == CHEM_DISTRIB || chemical_type_ == CHEM_SRCSINK); + if (chemical_type_ == CHEM_DISTRIB) *val = grib2_is_PDTN_ChemicalDistFunc(productDefinitionTemplateNumber); - else if (chemical_type_ == 2) + else if (chemical_type_ == CHEM_SRCSINK) *val = grib2_is_PDTN_ChemicalSourceSink(productDefinitionTemplateNumber); else *val = grib2_is_PDTN_Chemical(productDefinitionTemplateNumber); @@ -74,47 +78,42 @@ int grib_accessor_g2_chemical_t::pack_long(const long* val, size_t* len) if (!strcmp(stepType, "instant")) isInstant = 1; - // Meaning of self->chemical_type: - // 0 = atmospheric chemical constituents - // 1 = atmospheric chemical constituents based on a distribution function - // 2 = atmospheric chemical constituents with source or sink - // - Assert(chemical_type_ == 0 || chemical_type_ == 1 || chemical_type_ == 2); + Assert(chemical_type_ == CHEM_PLAIN || chemical_type_ == CHEM_DISTRIB || chemical_type_ == CHEM_SRCSINK); if (eps == 1) { if (isInstant) { - if (chemical_type_ == 0) + if (chemical_type_ == CHEM_PLAIN) productDefinitionTemplateNumberNew = 41; - else if (chemical_type_ == 1) + else if (chemical_type_ == CHEM_DISTRIB) productDefinitionTemplateNumberNew = 58; - else if (chemical_type_ == 2) + else if (chemical_type_ == CHEM_SRCSINK) productDefinitionTemplateNumberNew = 77; } else { - if (chemical_type_ == 0) + if (chemical_type_ == CHEM_PLAIN) productDefinitionTemplateNumberNew = 43; - else if (chemical_type_ == 1) + else if (chemical_type_ == CHEM_DISTRIB) productDefinitionTemplateNumberNew = 68; - else if (chemical_type_ == 2) + else if (chemical_type_ == CHEM_SRCSINK) productDefinitionTemplateNumberNew = 79; } } else { // deterministic if (isInstant) { - if (chemical_type_ == 0) + if (chemical_type_ == CHEM_PLAIN) productDefinitionTemplateNumberNew = 40; - else if (chemical_type_ == 1) + else if (chemical_type_ == CHEM_DISTRIB) productDefinitionTemplateNumberNew = 57; - else if (chemical_type_ == 2) + else if (chemical_type_ == CHEM_SRCSINK) productDefinitionTemplateNumberNew = 76; } else { - if (chemical_type_ == 0) + if (chemical_type_ == CHEM_PLAIN) productDefinitionTemplateNumberNew = 42; - else if (chemical_type_ == 1) + else if (chemical_type_ == CHEM_DISTRIB) productDefinitionTemplateNumberNew = 67; - else if (chemical_type_ == 2) + else if (chemical_type_ == CHEM_SRCSINK) productDefinitionTemplateNumberNew = 78; } } diff --git a/src/accessor/grib_accessor_class_iterator.h b/src/accessor/grib_accessor_class_iterator.h index da0a8d9641..aa3a4017fb 100644 --- a/src/accessor/grib_accessor_class_iterator.h +++ b/src/accessor/grib_accessor_class_iterator.h @@ -11,6 +11,7 @@ #pragma once #include "grib_accessor_class_gen.h" +#include "geo_iterator/grib_iterator.h" class grib_accessor_iterator_t : public grib_accessor_gen_t { diff --git a/src/accessor/grib_accessor_class_nearest.cc b/src/accessor/grib_accessor_class_nearest.cc index f8d97d00ae..31617c0098 100644 --- a/src/accessor/grib_accessor_class_nearest.cc +++ b/src/accessor/grib_accessor_class_nearest.cc @@ -25,34 +25,3 @@ void grib_accessor_nearest_t::dump(grib_dumper* dumper) grib_dump_label(dumper, this, NULL); } -#if defined(HAVE_GEOGRAPHY) -grib_nearest* grib_nearest_new(const grib_handle* ch, int* error) -{ - grib_handle* h = (grib_handle*)ch; - grib_accessor* a = NULL; - grib_accessor_nearest_t* na = NULL; - grib_nearest* n = NULL; - *error = GRIB_NOT_IMPLEMENTED; - a = grib_find_accessor(h, "NEAREST"); - na = (grib_accessor_nearest_t*)a; - - if (!a) - return NULL; - - n = grib_nearest_factory(h, na->args_, error); - - if (n) - *error = GRIB_SUCCESS; - - return n; -} -#else -grib_nearest* grib_nearest_new(const grib_handle* ch, int* error) -{ - *error = GRIB_FUNCTIONALITY_NOT_ENABLED; - grib_context_log(ch->context, GRIB_LOG_ERROR, - "Nearest neighbour functionality not enabled. Please rebuild with -DENABLE_GEOGRAPHY=ON"); - - return NULL; -} -#endif diff --git a/src/accessor/grib_accessor_class_nearest.h b/src/accessor/grib_accessor_class_nearest.h index 9a012c3491..15ed88e73a 100644 --- a/src/accessor/grib_accessor_class_nearest.h +++ b/src/accessor/grib_accessor_class_nearest.h @@ -11,6 +11,7 @@ #pragma once #include "grib_accessor_class_gen.h" +#include "geo_nearest/grib_nearest.h" class grib_accessor_nearest_t : public grib_accessor_gen_t { @@ -23,8 +24,5 @@ class grib_accessor_nearest_t : public grib_accessor_gen_t private: grib_arguments* args_ = nullptr; - - friend grib_nearest* grib_nearest_new(const grib_handle* ch, int* error); + friend eccodes::geo_nearest::Nearest* eccodes::geo_nearest::gribNearestNew(const grib_handle* ch, int* error); }; - -// grib_nearest* grib_nearest_new(const grib_handle* ch, int* error); diff --git a/src/eccodes_prototypes.h b/src/eccodes_prototypes.h index a32aa87493..fcc74f3f23 100644 --- a/src/eccodes_prototypes.h +++ b/src/eccodes_prototypes.h @@ -793,23 +793,23 @@ grib_expression* new_string_expression(grib_context* c, const char* value); grib_expression* new_sub_string_expression(grib_context* c, const char* value, size_t start, size_t length); /* grib_nearest.cc */ -int grib_nearest_find(grib_nearest* nearest, const grib_handle* h, double inlat, double inlon, unsigned long flags, double* outlats, double* outlons, double* values, double* distances, int* indexes, size_t* len); -int grib_nearest_init(grib_nearest* i, grib_handle* h, grib_arguments* args); -int grib_nearest_delete(grib_nearest* i); -int grib_nearest_get_radius(grib_handle* h, double* radiusInKm); -void grib_binary_search(const double xx[], const size_t n, double x, size_t* ju, size_t* jl); -int grib_nearest_find_multiple(const grib_handle* h, int is_lsm, const double* inlats, const double* inlons, long npoints, double* outlats, double* outlons, double* values, double* distances, int* indexes); -int grib_nearest_find_generic(grib_nearest* nearest, grib_handle* h, double inlat, double inlon, unsigned long flags, - const char* values_keyname, - double** out_lats, - int* out_lats_count, - double** out_lons, - int* out_lons_count, - double** out_distances, - double* outlats, double* outlons, double* values, double* distances, int* indexes, size_t* len); +//int grib_nearest_find(grib_nearest* nearest, const grib_handle* h, double inlat, double inlon, unsigned long flags, double* outlats, double* outlons, double* values, double* distances, int* indexes, size_t* len); +//int grib_nearest_init(grib_nearest* i, grib_handle* h, grib_arguments* args); +//int grib_nearest_delete(grib_nearest* i); +//int grib_nearest_get_radius(grib_handle* h, double* radiusInKm); +//void grib_binary_search(const double xx[], const size_t n, double x, size_t* ju, size_t* jl); +//int grib_nearest_find_multiple(const grib_handle* h, int is_lsm, const double* inlats, const double* inlons, long npoints, double* outlats, double* outlons, double* values, double* distances, int* indexes); +//int grib_nearest_find_generic(grib_nearest* nearest, grib_handle* h, double inlat, double inlon, unsigned long flags, +// const char* values_keyname, +// double** out_lats, +// int* out_lats_count, +// double** out_lons, +// int* out_lons_count, +// double** out_distances, +// double* outlats, double* outlons, double* values, double* distances, int* indexes, size_t* len); /* grib_nearest_class.cc */ -grib_nearest* grib_nearest_factory(grib_handle* h, grib_arguments* args, int* error); +//eccodes::geo_nearest::Nearest* grib_nearest_factory(grib_handle* h, grib_arguments* args, int* error); /* grib_iterator.cc */ int grib_get_data(const grib_handle* h, double* lats, double* lons, double* values); diff --git a/src/geo_iterator/grib_iterator.cc b/src/geo_iterator/grib_iterator.cc index 5e40269436..56e34c2517 100644 --- a/src/geo_iterator/grib_iterator.cc +++ b/src/geo_iterator/grib_iterator.cc @@ -11,7 +11,9 @@ /*************************************************************************** * Jean Baptiste Filippi - 01.11.2005 * ***************************************************************************/ + #include "grib_iterator.h" +#include "grib_iterator_factory.h" #include "accessor/grib_accessor_class_iterator.h" namespace eccodes::geo_iterator { @@ -55,7 +57,6 @@ int gribIteratorDelete(eccodes::geo_iterator::Iterator* i) return GRIB_SUCCESS; } - } // namespace eccodes::geo_iterator diff --git a/src/geo_iterator/grib_iterator_class_unstructured.cc b/src/geo_iterator/grib_iterator_class_unstructured.cc new file mode 100644 index 0000000000..dab834c12a --- /dev/null +++ b/src/geo_iterator/grib_iterator_class_unstructured.cc @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_iterator_class_unstructured.h" + +eccodes::geo_iterator::Unstructured _grib_iterator_unstructured{}; +eccodes::geo_iterator::Iterator* grib_iterator_unstructured = &_grib_iterator_unstructured; + +namespace eccodes::geo_iterator { + +#define ITER "Unstructured grid Geoiterator" + +int Unstructured::next(double* lat, double* lon, double* val) const +{ + if ((long)e_ >= (long)(nv_ - 1)) + return 0; + e_++; + + *lat = lats_[e_]; + *lon = lons_[e_]; + if (val && data_) { + *val = data_[e_]; + } + return 1; +} + +int Unstructured::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args)) != GRIB_SUCCESS) + return ret; + + const char* s_uuidOfHGrid = grib_arguments_get_name(h, args, carg_++); + char uuidOfHGrid[32] = {0,}; + auto slen = sizeof(uuidOfHGrid); + if ((ret = grib_get_string_internal(h, s_uuidOfHGrid, uuidOfHGrid, &slen)) != GRIB_SUCCESS) { + return ret; + } + + lats_ = (double*)grib_context_malloc(h->context, nv_ * sizeof(double)); + if (!lats_) { + grib_context_log(h->context, GRIB_LOG_ERROR, "%s: Error allocating %zu bytes", ITER, nv_ * sizeof(double)); + return GRIB_OUT_OF_MEMORY; + } + lons_ = (double*)grib_context_malloc(h->context, nv_ * sizeof(double)); + if (!lons_) { + grib_context_log(h->context, GRIB_LOG_ERROR, "%s: Error allocating %zu bytes", ITER, nv_ * sizeof(double)); + return GRIB_OUT_OF_MEMORY; + } + + e_ = -1; + + return ret; +} + +int Unstructured::destroy() +{ + DEBUG_ASSERT(h_); + const grib_context* c = h_->context; + grib_context_free(c, lats_); + grib_context_free(c, lons_); + + return Gen::destroy(); +} + +} // namespace eccodes::geo_iterator diff --git a/src/geo_iterator/grib_iterator_class_unstructured.h b/src/geo_iterator/grib_iterator_class_unstructured.h new file mode 100644 index 0000000000..3e99e01665 --- /dev/null +++ b/src/geo_iterator/grib_iterator_class_unstructured.h @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_iterator_class_gen.h" + +namespace eccodes::geo_iterator { + +class Unstructured : public Gen +{ +public: + Unstructured() : + Gen() { class_name_ = "unstructured"; } + Iterator* create() const override { return new Unstructured(); } + + int init(grib_handle*, grib_arguments*) override; + int next(double*, double*, double*) const override; + int destroy() override; +}; + +} // namespace eccodes::geo_iterator diff --git a/src/grib_nearest.cc b/src/geo_nearest/grib_nearest.cc similarity index 81% rename from src/grib_nearest.cc rename to src/geo_nearest/grib_nearest.cc index d020fb2694..81feae303e 100644 --- a/src/grib_nearest.cc +++ b/src/geo_nearest/grib_nearest.cc @@ -8,249 +8,25 @@ * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ -/** -* Author: Enrico Fucile -* date: 31/10/2007 -* -*/ +#include "grib_nearest.h" +#include "grib_nearest_factory.h" +#include "accessor/grib_accessor_class_nearest.h" -#include "grib_api_internal.h" - -/* Note: The 'values' argument can be NULL in which case the data section will not be decoded - * See ECC-499 - */ -int grib_nearest_find( - grib_nearest* nearest, const grib_handle* ch, - double inlat, double inlon, - unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_handle* h = (grib_handle*)ch; - grib_nearest_class* c = NULL; - if (!nearest) - return GRIB_INVALID_ARGUMENT; - c = nearest->cclass; - Assert(flags <= (GRIB_NEAREST_SAME_GRID | GRIB_NEAREST_SAME_DATA | GRIB_NEAREST_SAME_POINT)); - - while (c) { - grib_nearest_class* s = c->super ? *(c->super) : NULL; - if (c->find) { - int ret = c->find(nearest, h, inlat, inlon, flags, outlats, outlons, values, distances, indexes, len); - if (ret != GRIB_SUCCESS) { - if (inlon > 0) - inlon -= 360; - else - inlon += 360; - ret = c->find(nearest, h, inlat, inlon, flags, outlats, outlons, values, distances, indexes, len); - } - return ret; - } - c = s; - } - Assert(0); - return 0; -} - -/* For this one, ALL init are called */ -static int init_nearest(grib_nearest_class* c, grib_nearest* i, grib_handle* h, grib_arguments* args) -{ - if (c) { - int ret = GRIB_SUCCESS; - grib_nearest_class* s = c->super ? *(c->super) : NULL; - if (!c->inited) { - if (c->init_class) - c->init_class(c); - c->inited = 1; - } - if (s) - ret = init_nearest(s, i, h, args); - - if (ret != GRIB_SUCCESS) - return ret; - - if (c->init) - return c->init(i, h, args); - } - return GRIB_INTERNAL_ERROR; -} - -int grib_nearest_init(grib_nearest* i, grib_handle* h, grib_arguments* args) -{ - return init_nearest(i->cclass, i, h, args); -} - -/* For this one, ALL destroy are called */ - -int grib_nearest_delete(grib_nearest* i) -{ - grib_nearest_class* c = NULL; - if (!i) - return GRIB_INVALID_ARGUMENT; - c = i->cclass; - while (c) { - grib_nearest_class* s = c->super ? *(c->super) : NULL; - if (c->destroy) - c->destroy(i); - c = s; - } - return 0; -} - -/* Get the radius in kilometres for nearest neighbour distance calculations */ -/* For an ellipsoid, approximate the radius using the average of the semimajor and semiminor axes */ -int grib_nearest_get_radius(grib_handle* h, double* radiusInKm) +struct PointStore { - int err = 0; - long lRadiusInMetres; - double result = 0; - const char* s_radius = "radius"; - const char* s_minor = "earthMinorAxisInMetres"; - const char* s_major = "earthMajorAxisInMetres"; - - if ((err = grib_get_long(h, s_radius, &lRadiusInMetres)) == GRIB_SUCCESS) { - if (grib_is_missing(h, s_radius, &err) || lRadiusInMetres == GRIB_MISSING_LONG) { - grib_context_log(h->context, GRIB_LOG_DEBUG, "Key 'radius' is missing"); - return GRIB_GEOCALCULUS_PROBLEM; - } - result = ((double)lRadiusInMetres) / 1000.0; - } - else { - double minor = 0, major = 0; - if ((err = grib_get_double_internal(h, s_minor, &minor)) != GRIB_SUCCESS) return err; - if ((err = grib_get_double_internal(h, s_major, &major)) != GRIB_SUCCESS) return err; - if (grib_is_missing(h, s_minor, &err)) return GRIB_GEOCALCULUS_PROBLEM; - if (grib_is_missing(h, s_major, &err)) return GRIB_GEOCALCULUS_PROBLEM; - result = (major + minor) / 2.0; - result = result / 1000.0; - } - *radiusInKm = result; - return GRIB_SUCCESS; -} - -/* Note: the argument 'n' is NOT the size of the 'xx' array but its LAST index i.e. size of xx - 1 */ -void grib_binary_search(const double xx[], const size_t n, double x, size_t* ju, size_t* jl) -{ - size_t jm = 0; - int ascending = 0; - *jl = 0; - *ju = n; - ascending = (xx[n] >= xx[0]); - while (*ju - *jl > 1) { - jm = (*ju + *jl) >> 1; - if ((x >= xx[jm]) == ascending) - *jl = jm; - else - *ju = jm; - } -} - -int grib_nearest_find_multiple( - const grib_handle* h, int is_lsm, - const double* inlats, const double* inlons, long npoints, - double* outlats, double* outlons, - double* values, double* distances, int* indexes) -{ - grib_nearest* nearest = 0; - double* pdistances = distances; - double* poutlats = outlats; - double* poutlons = outlons; - double* pvalues = values; - int* pindexes = indexes; - int idx = 0, ii = 0; - double max, min; - double qdistances[4] = {0,}; - double qoutlats[4] = {0,}; - double qoutlons[4] = {0,}; - double qvalues[4] = {0,}; - double* rvalues = NULL; - int qindexes[4] = {0,}; - int ret = 0; - long i = 0; - size_t len = 4; - const unsigned long flags = GRIB_NEAREST_SAME_GRID | GRIB_NEAREST_SAME_DATA; - - if (values) - rvalues = qvalues; - - nearest = grib_nearest_new(h, &ret); - if (ret != GRIB_SUCCESS) - return ret; - - if (is_lsm) { - int noland = 1; - /* ECC-499: In land-sea mask mode, 'values' cannot be NULL because we need to query whether >= 0.5 */ - Assert(values); - for (i = 0; i < npoints; i++) { - ret = grib_nearest_find(nearest, h, inlats[i], inlons[i], flags, qoutlats, qoutlons, - qvalues, qdistances, qindexes, &len); - max = qdistances[0]; - for (ii = 0; ii < 4; ii++) { - if (max < qdistances[ii]) { - max = qdistances[ii]; - idx = ii; - } - if (qvalues[ii] >= 0.5) - noland = 0; - } - min = max; - for (ii = 0; ii < 4; ii++) { - if ((min >= qdistances[ii]) && (noland || (qvalues[ii] >= 0.5))) { - min = qdistances[ii]; - idx = ii; - } - } - *poutlats = qoutlats[idx]; - poutlats++; - *poutlons = qoutlons[idx]; - poutlons++; - *pvalues = qvalues[idx]; - pvalues++; - *pdistances = qdistances[idx]; - pdistances++; - *pindexes = qindexes[idx]; - pindexes++; - } - } - else { - /* ECC-499: 'values' can be NULL */ - for (i = 0; i < npoints; i++) { - ret = grib_nearest_find(nearest, h, inlats[i], inlons[i], flags, qoutlats, qoutlons, - rvalues, qdistances, qindexes, &len); - min = qdistances[0]; - for (ii = 0; ii < 4; ii++) { - if ((min >= qdistances[ii])) { - min = qdistances[ii]; - idx = ii; - } - } - *poutlats = qoutlats[idx]; - poutlats++; - *poutlons = qoutlons[idx]; - poutlons++; - if (values) { - *pvalues = qvalues[idx]; - pvalues++; - } - *pdistances = qdistances[idx]; - pdistances++; - *pindexes = qindexes[idx]; - pindexes++; - } - } - - grib_nearest_delete(nearest); - - return ret; -} - + double m_lat; + double m_lon; + double m_dist; + double m_value; + int m_index; +}; /* Generic implementation of nearest for Lambert, Polar stereo, Mercator etc */ static int compare_doubles(const void* a, const void* b, int ascending) { /* ascending is a boolean: 0 or 1 */ - double* arg1 = (double*)a; - double* arg2 = (double*)b; + const double* arg1 = (const double*)a; + const double* arg2 = (const double*)b; if (ascending) { if (*arg1 < *arg2) return -1; /*Smaller values come before larger ones*/ @@ -270,28 +46,34 @@ static int compare_doubles_ascending(const void* a, const void* b) return compare_doubles(a, b, 1); } -typedef struct PointStore -{ - double m_lat; - double m_lon; - double m_dist; - double m_value; - int m_index; -} PointStore; - /* Comparison function to sort points by distance */ static int compare_points(const void* a, const void* b) { - PointStore* pA = (PointStore*)a; - PointStore* pB = (PointStore*)b; + const PointStore* pA = (const PointStore*)a; + const PointStore* pB = (const PointStore*)b; if (pA->m_dist < pB->m_dist) return -1; if (pA->m_dist > pB->m_dist) return 1; return 0; } -int grib_nearest_find_generic( - grib_nearest* nearest, grib_handle* h, +namespace eccodes::geo_nearest { + +int Nearest::init(grib_handle* h, grib_arguments* args) +{ + //h_ = h; + return GRIB_SUCCESS; +} + +/* For this one, ALL destroy are called */ +int Nearest::destroy() +{ + delete this; + return GRIB_SUCCESS; +} + +int Nearest::grib_nearest_find_generic( + grib_handle* h, double inlat, double inlon, unsigned long flags, const char* values_keyname, @@ -317,7 +99,7 @@ int grib_nearest_find_generic( if ((ret = grib_get_size(h, values_keyname, &nvalues)) != GRIB_SUCCESS) return ret; - nearest->values_count = nvalues; + values_count_ = nvalues; if ((ret = grib_nearest_get_radius(h, &radiusInKm)) != GRIB_SUCCESS) return ret; @@ -407,7 +189,7 @@ int grib_nearest_find_generic( grib_iterator_delete(iter); } - nearest->h = h; + h_ = h; /* Sanity check for sorting */ #ifdef DEBUG @@ -439,3 +221,250 @@ int grib_nearest_find_generic( free(neighbours); return GRIB_SUCCESS; } + +eccodes::geo_nearest::Nearest* gribNearestNew(const grib_handle* ch, int* error) +{ + *error = GRIB_NOT_IMPLEMENTED; + + grib_handle* h = (grib_handle*)ch; + grib_accessor* a = grib_find_accessor(h, "NEAREST"); + grib_accessor_nearest_t* n = (grib_accessor_nearest_t*)a; + + if (!a) + return NULL; + + eccodes::geo_nearest::Nearest* nearest = grib_nearest_factory(h, n->args_, error); + + if (nearest) + *error = GRIB_SUCCESS; + + return nearest; +} + +int gribNearestDelete(eccodes::geo_nearest::Nearest* i) +{ + if (i) + i->destroy(); + return GRIB_SUCCESS; +} + + +} // namespace eccodes::geo_nearest + + +/* Get the radius in kilometres for nearest neighbour distance calculations */ +/* For an ellipsoid, approximate the radius using the average of the semimajor and semiminor axes */ +int grib_nearest_get_radius(grib_handle* h, double* radiusInKm) +{ + int err = 0; + long lRadiusInMetres; + double result = 0; + const char* s_radius = "radius"; + + if ((err = grib_get_long(h, s_radius, &lRadiusInMetres)) == GRIB_SUCCESS) { + if (grib_is_missing(h, s_radius, &err) || lRadiusInMetres == GRIB_MISSING_LONG) { + grib_context_log(h->context, GRIB_LOG_DEBUG, "Key 'radius' is missing"); + return GRIB_GEOCALCULUS_PROBLEM; + } + result = ((double)lRadiusInMetres) / 1000.0; + } + else { + double minor = 0, major = 0; + const char* s_minor = "earthMinorAxisInMetres"; + const char* s_major = "earthMajorAxisInMetres"; + if ((err = grib_get_double_internal(h, s_minor, &minor)) != GRIB_SUCCESS) return err; + if ((err = grib_get_double_internal(h, s_major, &major)) != GRIB_SUCCESS) return err; + if (grib_is_missing(h, s_minor, &err)) return GRIB_GEOCALCULUS_PROBLEM; + if (grib_is_missing(h, s_major, &err)) return GRIB_GEOCALCULUS_PROBLEM; + result = (major + minor) / 2.0; + result = result / 1000.0; + } + *radiusInKm = result; + return GRIB_SUCCESS; +} + +/* Note: the argument 'n' is NOT the size of the 'xx' array but its LAST index i.e. size of xx - 1 */ +void grib_binary_search(const double xx[], const size_t n, double x, size_t* ju, size_t* jl) +{ + size_t jm = 0; + int ascending = 0; + *jl = 0; + *ju = n; + ascending = (xx[n] >= xx[0]); + while (*ju - *jl > 1) { + jm = (*ju + *jl) >> 1; + if ((x >= xx[jm]) == ascending) + *jl = jm; + else + *ju = jm; + } +} + + +/* + * C API Implementation + * codes_iterator_* wrappers are in eccodes.h and eccodes.cc + * grib_iterator_* declarations are in grib_api.h + */ + +int grib_nearest_find_multiple( + const grib_handle* h, int is_lsm, + const double* inlats, const double* inlons, long npoints, + double* outlats, double* outlons, + double* values, double* distances, int* indexes) +{ + grib_nearest* nearest = 0; + double* pdistances = distances; + double* poutlats = outlats; + double* poutlons = outlons; + double* pvalues = values; + int* pindexes = indexes; + int idx = 0, ii = 0; + double max, min; + double qdistances[4] = {0,}; + double qoutlats[4] = {0,}; + double qoutlons[4] = {0,}; + double qvalues[4] = {0,}; + double* rvalues = NULL; + int qindexes[4] = {0,}; + int ret = 0; + long i = 0; + size_t len = 4; + const unsigned long flags = GRIB_NEAREST_SAME_GRID | GRIB_NEAREST_SAME_DATA; + + if (values) + rvalues = qvalues; + + nearest = grib_nearest_new(h, &ret); + if (ret != GRIB_SUCCESS) + return ret; + + if (is_lsm) { + int noland = 1; + /* ECC-499: In land-sea mask mode, 'values' cannot be NULL because we need to query whether >= 0.5 */ + Assert(values); + for (i = 0; i < npoints; i++) { + ret = grib_nearest_find(nearest, h, inlats[i], inlons[i], flags, qoutlats, qoutlons, + qvalues, qdistances, qindexes, &len); + max = qdistances[0]; + for (ii = 0; ii < 4; ii++) { + if (max < qdistances[ii]) { + max = qdistances[ii]; + idx = ii; + } + if (qvalues[ii] >= 0.5) + noland = 0; + } + min = max; + for (ii = 0; ii < 4; ii++) { + if ((min >= qdistances[ii]) && (noland || (qvalues[ii] >= 0.5))) { + min = qdistances[ii]; + idx = ii; + } + } + *poutlats = qoutlats[idx]; + poutlats++; + *poutlons = qoutlons[idx]; + poutlons++; + *pvalues = qvalues[idx]; + pvalues++; + *pdistances = qdistances[idx]; + pdistances++; + *pindexes = qindexes[idx]; + pindexes++; + } + } + else { + /* ECC-499: 'values' can be NULL */ + for (i = 0; i < npoints; i++) { + ret = grib_nearest_find(nearest, h, inlats[i], inlons[i], flags, qoutlats, qoutlons, + rvalues, qdistances, qindexes, &len); + min = qdistances[0]; + for (ii = 0; ii < 4; ii++) { + if ((min >= qdistances[ii])) { + min = qdistances[ii]; + idx = ii; + } + } + *poutlats = qoutlats[idx]; + poutlats++; + *poutlons = qoutlons[idx]; + poutlons++; + if (values) { + *pvalues = qvalues[idx]; + pvalues++; + } + *pdistances = qdistances[idx]; + pdistances++; + *pindexes = qindexes[idx]; + pindexes++; + } + } + + grib_nearest_delete(nearest); + + return ret; +} + +/* Note: The 'values' argument can be NULL in which case the data section will not be decoded + * See ECC-499 + */ +int grib_nearest_find( + grib_nearest* nearest, const grib_handle* ch, + double inlat, double inlon, + unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + grib_handle* h = (grib_handle*)ch; + if (!nearest) + return GRIB_INVALID_ARGUMENT; + Assert(flags <= (GRIB_NEAREST_SAME_GRID | GRIB_NEAREST_SAME_DATA | GRIB_NEAREST_SAME_POINT)); + + int ret = nearest->nearest->find(h, inlat, inlon, flags, outlats, outlons, values, distances, indexes, len); + if (ret != GRIB_SUCCESS) { + if (inlon > 0) + inlon -= 360; + else + inlon += 360; + ret = nearest->nearest->find(h, inlat, inlon, flags, outlats, outlons, values, distances, indexes, len); + } + return ret; +} + +int grib_nearest_init(grib_nearest* i, grib_handle* h, grib_arguments* args) +{ + return i->nearest->init(h, args); +} + +int grib_nearest_delete(grib_nearest* i) +{ + if (i) { + grib_context* c = grib_context_get_default(); + gribNearestDelete(i->nearest); + grib_context_free(c, i); + } + return GRIB_SUCCESS; +} + +#if defined(HAVE_GEOGRAPHY) +grib_nearest* grib_nearest_new(const grib_handle* ch, int* error) +{ + grib_nearest* i = (grib_nearest*)grib_context_malloc_clear(ch->context, sizeof(grib_nearest)); + i->nearest = eccodes::geo_nearest::gribNearestNew(ch, error); + if (!i->nearest) { + grib_context_free(ch->context, i); + return NULL; + } + return i; +} +#else +grib_nearest* grib_nearest_new(const grib_handle* ch, int* error) +{ + *error = GRIB_FUNCTIONALITY_NOT_ENABLED; + grib_context_log(ch->context, GRIB_LOG_ERROR, + "Nearest neighbour functionality not enabled. Please rebuild with -DENABLE_GEOGRAPHY=ON"); + + return NULL; +} +#endif diff --git a/src/geo_nearest/grib_nearest.h b/src/geo_nearest/grib_nearest.h new file mode 100644 index 0000000000..74cf9a0ff4 --- /dev/null +++ b/src/geo_nearest/grib_nearest.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_api_internal.h" + +namespace eccodes::geo_nearest { + +class Nearest { +public: + virtual ~Nearest() {} + virtual int init(grib_handle*, grib_arguments*) = 0; + virtual int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) = 0; + virtual int destroy() = 0; + virtual Nearest* create() = 0; + +protected: + int grib_nearest_find_generic(grib_handle*, double, double, unsigned long, + const char*, + double**, + int*, + double**, + int*, + double**, + double*, double*, double*, double*, int*, size_t*); + + grib_handle* h_ = nullptr; + double* values_ = nullptr; + size_t values_count_ = 0; + unsigned long flags_ = 0; + const char* class_name_ = nullptr; +}; + +Nearest* gribNearestNew(const grib_handle*, int*); +int gribNearestDelete(Nearest*); + +} // namespace eccodes::geo_nearest + +int grib_nearest_get_radius(grib_handle* h, double* radiusInKm); +void grib_binary_search(const double xx[], const size_t n, double x, size_t* ju, size_t* jl); diff --git a/src/geo_nearest/grib_nearest_class_gen.cc b/src/geo_nearest/grib_nearest_class_gen.cc new file mode 100644 index 0000000000..68a257367a --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_gen.cc @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +int Gen::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Nearest::init(h, args) != GRIB_SUCCESS)) + return ret; + + cargs_ = 1; + + values_key_ = grib_arguments_get_name(h, args, cargs_++); + radius_ = grib_arguments_get_name(h, args, cargs_++); + values_ = NULL; + + return ret; +} + +int Gen::destroy() +{ + grib_context* c = grib_context_get_default(); + + if (lats_) grib_context_free(c, lats_); + if (lons_) grib_context_free(c, lons_); + if (i_) grib_context_free(c, i_); + if (j_) grib_context_free(c, j_); + if (k_) grib_context_free(c, k_); + if (distances_) grib_context_free(c, distances_); + if (values_) grib_context_free(c, values_); + + return Nearest::destroy(); +} + +int Gen::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, double* values, + double* distances, int* indexes, size_t* len) +{ + return GRIB_NOT_IMPLEMENTED; +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_gen.h b/src/geo_nearest/grib_nearest_class_gen.h new file mode 100644 index 0000000000..0e35c62e5c --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_gen.h @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest.h" + +namespace eccodes::geo_nearest { + +class Gen : public Nearest { +public: + Gen() { class_name_ = "gen"; } + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; + int destroy() override; + +protected: + int cargs_ = 0; + const char* values_key_ = nullptr; + + double* lats_ = nullptr; + int lats_count_ = 0; + double* lons_ = nullptr; + int lons_count_ = 0; + + double* distances_ = nullptr; + size_t* k_ = nullptr; + size_t* i_ = nullptr; + size_t* j_ = nullptr; + const char* Ni_ = nullptr; + const char* Nj_ = nullptr; + +private: + const char* radius_ = nullptr; +}; + +int grib_nearest_find_generic( + Nearest* nearest, grib_handle* h, + double inlat, double inlon, unsigned long flags, + + const char* values_keyname, + double** out_lats, + int* out_lats_count, + double** out_lons, + int* out_lons_count, + double** out_distances, + + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len); + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_healpix.cc b/src/geo_nearest/grib_nearest_class_healpix.cc new file mode 100644 index 0000000000..ed49a96443 --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_healpix.cc @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_healpix.h" + +eccodes::geo_nearest::Healpix _grib_nearest_healpix{}; +eccodes::geo_nearest::Nearest* grib_nearest_healpix = &_grib_nearest_healpix; + +namespace eccodes::geo_nearest { + +int Healpix::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Ni_ = grib_arguments_get_name(h, args, cargs_++); + Nj_ = grib_arguments_get_name(h, args, cargs_++); + i_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + + return ret; +} + +int Healpix::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + return grib_nearest_find_generic( + h, inlat, inlon, flags, /* inputs */ + + values_key_, /* outputs to set the 'self' object */ + &(lats_), + &(lats_count_), + &(lons_), + &(lons_count_), + &(distances_), + + outlats, outlons, /* outputs of the find function */ + values, distances, indexes, len); +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_healpix.h b/src/geo_nearest/grib_nearest_class_healpix.h new file mode 100644 index 0000000000..37e6e5f834 --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_healpix.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class Healpix : public Gen { +public: + Healpix() { + class_name_ = "healpix"; + } + Nearest* create() override { return new Healpix(); }; + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; +}; + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_lambert_azimuthal_equal_area.cc b/src/geo_nearest/grib_nearest_class_lambert_azimuthal_equal_area.cc new file mode 100644 index 0000000000..eb701ee759 --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_lambert_azimuthal_equal_area.cc @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_lambert_azimuthal_equal_area.h" + +eccodes::geo_nearest::LambertAzimuthalEqualArea _grib_nearest_lambert_azimuthal_equal_area{}; +eccodes::geo_nearest::Nearest* grib_nearest_lambert_azimuthal_equal_area = &_grib_nearest_lambert_azimuthal_equal_area; + +namespace eccodes::geo_nearest { + +int LambertAzimuthalEqualArea::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Ni_ = grib_arguments_get_name(h, args, cargs_++); + Nj_ = grib_arguments_get_name(h, args, cargs_++); + i_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + + return ret; +} + +int LambertAzimuthalEqualArea::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + return grib_nearest_find_generic( + h, inlat, inlon, flags, /* inputs */ + + values_key_, /* outputs to set the 'self' object */ + &(lats_), + &(lats_count_), + &(lons_), + &(lons_count_), + &(distances_), + + outlats, outlons, /* outputs of the find function */ + values, distances, indexes, len); +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_lambert_azimuthal_equal_area.h b/src/geo_nearest/grib_nearest_class_lambert_azimuthal_equal_area.h new file mode 100644 index 0000000000..38ec127bad --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_lambert_azimuthal_equal_area.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class LambertAzimuthalEqualArea : public Gen { +public: + LambertAzimuthalEqualArea() { + class_name_ = "lambert_azimuthal_equal_area"; + } + Nearest* create() override { return new LambertAzimuthalEqualArea(); } + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; +}; + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_lambert_conformal.cc b/src/geo_nearest/grib_nearest_class_lambert_conformal.cc new file mode 100644 index 0000000000..a61756e54d --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_lambert_conformal.cc @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_lambert_conformal.h" + +eccodes::geo_nearest::LambertConformal _grib_nearest_lambert_conformal{}; +eccodes::geo_nearest::Nearest* grib_nearest_lambert_conformal = &_grib_nearest_lambert_conformal; + +namespace eccodes::geo_nearest { + +int LambertConformal::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Ni_ = grib_arguments_get_name(h, args, cargs_++); + Nj_ = grib_arguments_get_name(h, args, cargs_++); + i_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + + return ret; +} + +int LambertConformal::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + return grib_nearest_find_generic( + h, inlat, inlon, flags, /* inputs */ + + values_key_, /* outputs to set the 'self' object */ + &(lats_), + &(lats_count_), + &(lons_), + &(lons_count_), + &(distances_), + + outlats, outlons, /* outputs of the find function */ + values, distances, indexes, len); +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_lambert_conformal.h b/src/geo_nearest/grib_nearest_class_lambert_conformal.h new file mode 100644 index 0000000000..bcb3d27e21 --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_lambert_conformal.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class LambertConformal : public Gen { +public: + LambertConformal() { + class_name_ = "lambert_conformal"; + } + Nearest* create() override { return new LambertConformal(); }; + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; +}; + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_latlon_reduced.cc b/src/geo_nearest/grib_nearest_class_latlon_reduced.cc new file mode 100644 index 0000000000..d7e54da11a --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_latlon_reduced.cc @@ -0,0 +1,344 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_latlon_reduced.h" + +eccodes::geo_nearest::LatlonReduced _grib_nearest_latlon_reduced{}; +eccodes::geo_nearest::Nearest* grib_nearest_latlon_reduced = &_grib_nearest_latlon_reduced; + +namespace eccodes::geo_nearest { + +int LatlonReduced::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Nj_ = grib_arguments_get_name(h, args, cargs_++); + pl_ = grib_arguments_get_name(h, args, cargs_++); + lonFirst_ = grib_arguments_get_name(h, args, cargs_++); + lonLast_ = grib_arguments_get_name(h, args, cargs_++); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + if (!j_) + return GRIB_OUT_OF_MEMORY; + k_ = (size_t*)grib_context_malloc(h->context, 4 * sizeof(size_t)); + if (!k_) + return GRIB_OUT_OF_MEMORY; + + return ret; +} + +int LatlonReduced::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, double* values, + double* distances, int* indexes, size_t* len) +{ + int err = 0; + double lat1, lat2, lon1, lon2; + int is_global = 1; + + if (grib_get_double(h, "longitudeFirstInDegrees", &lon1) == GRIB_SUCCESS && + grib_get_double(h, "longitudeLastInDegrees", &lon2) == GRIB_SUCCESS && + grib_get_double(h, "latitudeFirstInDegrees", &lat1) == GRIB_SUCCESS && + grib_get_double(h, "latitudeLastInDegrees", &lat2) == GRIB_SUCCESS) + { + const double difflat = fabs(lat1-lat2); + if (difflat < 180 || lon1 != 0 || lon2 < 359) { + is_global = 0; /* subarea */ + } + } + + if (is_global) { + err = find_global(h, inlat, inlon, flags, + outlats, outlons, values, + distances, indexes, len); + } + else + { + int lons_count = 0; /*dummy*/ + err = grib_nearest_find_generic( + h, inlat, inlon, flags, + values_key_, + &(lats_), + &(lats_count_), + &(lons_), + &(lons_count), + &(distances_), + outlats, outlons, + values, distances, indexes, len); + } + return err; +} + +int LatlonReduced::find_global(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, double* values, + double* distances, int* indexes, size_t* len) +{ + int ret = 0, kk = 0, ii = 0, jj = 0; + int j = 0; + long* pla = NULL; + long* pl = NULL; + size_t nvalues = 0; + grib_iterator* iter = NULL; + double lat = 0, lon = 0; + double radiusInKm; + int ilat = 0, ilon = 0; + + if ((ret = grib_get_size(h, values_key_, &nvalues)) != GRIB_SUCCESS) + return ret; + values_count_ = nvalues; + + if ((ret = grib_nearest_get_radius(h, &radiusInKm)) != GRIB_SUCCESS) + return ret; + + /* Compute lat/lon info, create iterator etc if it's the 1st time or different grid. + * This is for performance: if the grid has not changed, we only do this once + * and reuse for other messages */ + if (!h_ || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + double olat = 1.e10; + long n = 0; + + ilat = 0; + ilon = 0; + if (grib_is_missing(h, Nj_, &ret)) { + grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", Nj_); + return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; + } + + if ((ret = grib_get_long(h, Nj_, &n)) != GRIB_SUCCESS) + return ret; + lats_count_ = n; + + if (lats_) + grib_context_free(h->context, lats_); + lats_ = (double*)grib_context_malloc(h->context, + lats_count_ * sizeof(double)); + if (!lats_) + return GRIB_OUT_OF_MEMORY; + + if (lons_) + grib_context_free(h->context, lons_); + lons_ = (double*)grib_context_malloc(h->context, + values_count_ * sizeof(double)); + if (!lons_) + return GRIB_OUT_OF_MEMORY; + + iter = grib_iterator_new(h, GRIB_GEOITERATOR_NO_VALUES, &ret); + if (ret) { + grib_context_log(h->context, GRIB_LOG_ERROR, "Unable to create iterator"); + return ret; + } + while (grib_iterator_next(iter, &lat, &lon, NULL)) { + if (ilat < lats_count_ && olat != lat) { + lats_[ilat++] = lat; + olat = lat; + } + lons_[ilon++] = lon; + } + lats_count_ = ilat; + grib_iterator_delete(iter); + } + h_ = h; + + /* Compute distances if it's the 1st time or different point or different grid. + * This is for performance: if the grid and the input point have not changed + * we only do this once and reuse for other messages */ + if (!distances_ || (flags & GRIB_NEAREST_SAME_POINT) == 0 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + double* lons = NULL; + int nlon = 0; + size_t plsize = 0; + long nplm1 = 0; + int nearest_lons_found = 0; + double lon_first, lon_last; + int islocal = 0; + long plmax; + double dimin; + + if ((ret = grib_get_double(h, lonFirst_, &lon_first)) != GRIB_SUCCESS) { + grib_context_log(h->context, GRIB_LOG_ERROR, + "grib_nearest_latlon_reduced.find(): unable to get %s %s\n", lonFirst_, + grib_get_error_message(ret)); + return ret; + } + if ((ret = grib_get_double(h, lonLast_, &lon_last)) != GRIB_SUCCESS) { + grib_context_log(h->context, GRIB_LOG_ERROR, + "grib_nearest_latlon_reduced.find(): unable to get %s %s\n", lonLast_, + grib_get_error_message(ret)); + return ret; + } + + plsize = lats_count_; + if ((ret = grib_get_size(h, pl_, &plsize)) != GRIB_SUCCESS) + return ret; + pla = (long*)grib_context_malloc(h->context, plsize * sizeof(long)); + if (!pla) + return GRIB_OUT_OF_MEMORY; + if ((ret = grib_get_long_array(h, pl_, pla, &plsize)) != GRIB_SUCCESS) + return ret; + + pl = pla; + while ((*pl) == 0) { + pl++; + } + + plmax = pla[0]; + for (j = 0; j < plsize; j++) + if (plmax < pla[j]) + plmax = pla[j]; + dimin = 360.0 / plmax; + + if (360 - fabs(lon_last - lon_first) < 2 * dimin) { + islocal = 0; + } + else { + islocal = 1; + } + + if (islocal) + for (j = 0; j < plsize; j++) + pla[j]--; + + /* printf("XXXX islocal=%d\n",islocal); */ + while (inlon < 0) + inlon += 360; + while (inlon > 360) + inlon -= 360; + + ilat = lats_count_; + if (lats_[ilat - 1] > lats_[0]) { + if (inlat < lats_[0] || inlat > lats_[ilat - 1]) + return GRIB_OUT_OF_AREA; + } + else { + if (inlat > lats_[0] || inlat < lats_[ilat - 1]) + return GRIB_OUT_OF_AREA; + } + + if (!distances_) + distances_ = (double*)grib_context_malloc(h->context, 4 * sizeof(double)); + if (!distances_) + return GRIB_OUT_OF_MEMORY; + + //void grib_binary_search(const double xx[], const size_t n, double x, size_t* ju, size_t* jl) + grib_binary_search(lats_, ilat - 1, inlat, + &(j_[0]), &(j_[1])); + + nlon = 0; + for (jj = 0; jj < j_[0]; jj++) + nlon += pl[jj]; + nplm1 = pl[j_[0]] - 1; + + lons = lons_ + nlon; + + nearest_lons_found = 0; + if (lons[nplm1] > lons[0]) { + if (inlon < lons[0] || inlon > lons[nplm1]) { + if (lons[nplm1] - lons[0] - 360 <= + lons[nplm1] - lons[nplm1 - 1]) { + k_[0] = 0; + k_[1] = nplm1; + nearest_lons_found = 1; + } + else + return GRIB_OUT_OF_AREA; + } + } + else { + if (inlon > lons[0] || inlon < lons[nplm1]) { + if (lons[0] - lons[nplm1] - 360 <= + lons[0] - lons[1]) { + k_[0] = 0; + k_[1] = nplm1; + nearest_lons_found = 1; + } + else + return GRIB_OUT_OF_AREA; + } + } + + if (!nearest_lons_found) { + grib_binary_search(lons, pl[j_[0]] - 1, inlon, + &(k_[0]), &(k_[1])); + } + k_[0] += nlon; + k_[1] += nlon; + + nlon = 0; + for (jj = 0; jj < j_[1]; jj++) + nlon += pl[jj]; + nplm1 = pl[j_[1]] - 1; + + lons = lons_ + nlon; + + nearest_lons_found = 0; + if (lons[nplm1] > lons[0]) { + if (inlon < lons[0] || inlon > lons[nplm1]) { + if (lons[nplm1] - lons[0] - 360 <= + lons[nplm1] - lons[nplm1 - 1]) { + k_[2] = 0; + k_[3] = nplm1; + nearest_lons_found = 1; + } + else + return GRIB_OUT_OF_AREA; + } + } + else { + if (inlon > lons[0] || inlon < lons[nplm1]) { + if (lons[0] - lons[nplm1] - 360 <= + lons[0] - lons[1]) { + k_[2] = 0; + k_[3] = nplm1; + nearest_lons_found = 1; + } + else + return GRIB_OUT_OF_AREA; + } + } + + if (!nearest_lons_found) { + grib_binary_search(lons, pl[j_[1]] - 1, inlon, + &(k_[2]), &(k_[3])); + } + + k_[2] += nlon; + k_[3] += nlon; + + kk = 0; + for (jj = 0; jj < 2; jj++) { + for (ii = 0; ii < 2; ii++) { + distances_[kk] = geographic_distance_spherical(radiusInKm, inlon, inlat, + lons_[k_[kk]], lats_[j_[jj]]); + kk++; + } + } + + grib_context_free(h->context, pla); + } + + kk = 0; + for (jj = 0; jj < 2; jj++) { + for (ii = 0; ii < 2; ii++) { + distances[kk] = distances_[kk]; + outlats[kk] = lats_[j_[jj]]; + outlons[kk] = lons_[k_[kk]]; + if (values) { /* ECC-499 */ + grib_get_double_element_internal(h, values_key_, k_[kk], &(values[kk])); + } + indexes[kk] = (int)k_[kk]; + kk++; + } + } + + return GRIB_SUCCESS; +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_latlon_reduced.h b/src/geo_nearest/grib_nearest_class_latlon_reduced.h new file mode 100644 index 0000000000..99ebb930bf --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_latlon_reduced.h @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class LatlonReduced : public Gen { +public: + LatlonReduced() { + class_name_ = "latlon_reduced"; + } + Nearest* create() override { return new LatlonReduced(); } + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; + +private: + const char* pl_ = nullptr; + const char* lonFirst_ = nullptr; + const char* lonLast_ = nullptr; + + int find_global(grib_handle*, + double, double, unsigned long, + double*, double*, double*, + double*, int*, size_t*); +}; + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_mercator.cc b/src/geo_nearest/grib_nearest_class_mercator.cc new file mode 100644 index 0000000000..e8d1935f7c --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_mercator.cc @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_mercator.h" + +eccodes::geo_nearest::Mercator _grib_nearest_mercator{}; +eccodes::geo_nearest::Nearest* grib_nearest_mercator = &_grib_nearest_mercator; + +namespace eccodes::geo_nearest { + +int Mercator::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Ni_ = grib_arguments_get_name(h, args, cargs_++); + Nj_ = grib_arguments_get_name(h, args, cargs_++); + i_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + + return ret; +} + +int Mercator::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + return grib_nearest_find_generic( + h, inlat, inlon, flags, /* inputs */ + + values_key_, /* outputs to set the 'self' object */ + &(lats_), + &(lats_count_), + &(lons_), + &(lons_count_), + &(distances_), + + outlats, outlons, /* outputs of the find function */ + values, distances, indexes, len); +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_mercator.h b/src/geo_nearest/grib_nearest_class_mercator.h new file mode 100644 index 0000000000..9d79cee4c2 --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_mercator.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class Mercator : public Gen { +public: + Mercator() { + class_name_ = "mercator"; + } + Nearest* create() override { return new Mercator(); }; + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; +}; + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_polar_stereographic.cc b/src/geo_nearest/grib_nearest_class_polar_stereographic.cc new file mode 100644 index 0000000000..ed223f285f --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_polar_stereographic.cc @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_polar_stereographic.h" + +eccodes::geo_nearest::PolarStereographic _grib_nearest_polar_stereographic{}; +eccodes::geo_nearest::Nearest* grib_nearest_polar_stereographic = &_grib_nearest_polar_stereographic; + +namespace eccodes::geo_nearest { + +int PolarStereographic::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Ni_ = grib_arguments_get_name(h, args, cargs_++); + Nj_ = grib_arguments_get_name(h, args, cargs_++); + i_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + + return ret; +} + +int PolarStereographic::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + return grib_nearest_find_generic( + h, inlat, inlon, flags, /* inputs */ + + values_key_, /* outputs to set the 'self' object */ + &(lats_), + &(lats_count_), + &(lons_), + &(lons_count_), + &(distances_), + + outlats, outlons, /* outputs of the find function */ + values, distances, indexes, len); +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_polar_stereographic.h b/src/geo_nearest/grib_nearest_class_polar_stereographic.h new file mode 100644 index 0000000000..8580dffd84 --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_polar_stereographic.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class PolarStereographic : public Gen { +public: + PolarStereographic() { + class_name_ = "polar_stereographic"; + } + Nearest* create() override { return new PolarStereographic(); } + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; +}; + +} // namespace eccodes::geo_nearest diff --git a/src/grib_nearest_class_reduced.cc b/src/geo_nearest/grib_nearest_class_reduced.cc similarity index 51% rename from src/grib_nearest_class_reduced.cc rename to src/geo_nearest/grib_nearest_class_reduced.cc index ffc8eaad81..60a40fb151 100644 --- a/src/grib_nearest_class_reduced.cc +++ b/src/geo_nearest/grib_nearest_class_reduced.cc @@ -8,119 +8,43 @@ * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ -#include "grib_api_internal.h" +#include "grib_nearest_class_reduced.h" -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init;destroy;find - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = double* distances - MEMBERS = size_t* k - MEMBERS = size_t* j - MEMBERS = const char* Nj - MEMBERS = const char* pl - MEMBERS = long global - MEMBERS = double lon_first - MEMBERS = double lon_last - MEMBERS = int legacy - MEMBERS = int rotated - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ +eccodes::geo_nearest::Reduced _grib_nearest_reduced{}; +eccodes::geo_nearest::Nearest* grib_nearest_reduced = &_grib_nearest_reduced; -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_reduced{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in reduced */ - double* lats; - int lats_count; - double* lons; - double* distances; - size_t* k; - size_t* j; - const char* Nj; - const char* pl; - long global; - double lon_first; - double lon_last; - int legacy; - int rotated; -} grib_nearest_reduced; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_reduced = { - &grib_nearest_class_gen, /* super */ - "reduced", /* name */ - sizeof(grib_nearest_reduced), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_reduced = &_grib_nearest_class_reduced; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ +namespace eccodes::geo_nearest { #define NUM_NEIGHBOURS 4 -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) +int Reduced::init(grib_handle* h, grib_arguments* args) { - grib_nearest_reduced* self = (grib_nearest_reduced*)nearest; - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->pl = grib_arguments_get_name(h, args, self->cargs++); - self->j = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); - self->legacy = -1; - self->rotated = -1; - if (!self->j) + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Nj_ = grib_arguments_get_name(h, args, cargs_++); + pl_ = grib_arguments_get_name(h, args, cargs_++); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + legacy_ = -1; + rotated_ = -1; + if (!j_) return GRIB_OUT_OF_MEMORY; - self->k = (size_t*)grib_context_malloc(h->context, NUM_NEIGHBOURS * sizeof(size_t)); - if (!self->k) + k_ = (size_t*)grib_context_malloc(h->context, NUM_NEIGHBOURS * sizeof(size_t)); + if (!k_) return GRIB_OUT_OF_MEMORY; - grib_get_long(h, "global", &self->global); - if (!self->global) { + grib_get_long(h, "global", &global_); + if (!global_) { int err; /*TODO longitudeOfFirstGridPointInDegrees from the def file*/ - if ((err = grib_get_double(h, "longitudeOfFirstGridPointInDegrees", &self->lon_first)) != GRIB_SUCCESS) { + if ((err = grib_get_double(h, "longitudeOfFirstGridPointInDegrees", &lon_first_)) != GRIB_SUCCESS) { grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_reduced: Unable to get longitudeOfFirstGridPointInDegrees %s\n", grib_get_error_message(err)); return err; } /*TODO longitudeOfLastGridPointInDegrees from the def file*/ - if ((err = grib_get_double(h, "longitudeOfLastGridPointInDegrees", &self->lon_last)) != GRIB_SUCCESS) { + if ((err = grib_get_double(h, "longitudeOfLastGridPointInDegrees", &lon_last_)) != GRIB_SUCCESS) { grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_reduced: Unable to get longitudeOfLastGridPointInDegrees %s\n", grib_get_error_message(err)); @@ -128,16 +52,11 @@ static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) } } - return 0; + return ret; } typedef void (*get_reduced_row_proc)(long pl, double lon_first, double lon_last, long* npoints, long* ilon_first, long* ilon_last); -static int find_global(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, double* values, - double* distances, int* indexes, size_t* len); - static int is_legacy(grib_handle* h, int* legacy) { int err = 0; @@ -159,21 +78,20 @@ static int is_rotated(grib_handle* h, int* rotated) return GRIB_SUCCESS; } -static int find(grib_nearest* nearest, grib_handle* h, +int Reduced::find(grib_handle* h, double inlat, double inlon, unsigned long flags, double* outlats, double* outlons, double* values, double* distances, int* indexes, size_t* len) { int err = 0; - grib_nearest_reduced* self = (grib_nearest_reduced*)nearest; - if (self->rotated == -1 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { - err = is_rotated(h, &(self->rotated)); + if (rotated_ == -1 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + err = is_rotated(h, &(rotated_)); if (err) return err; } - if (self->global && self->rotated == 0) { - err = find_global(nearest, h, + if (global_ && rotated_ == 0) { + err = find_global( h, inlat, inlon, flags, outlats, outlons, values, distances, indexes, len); @@ -186,13 +104,13 @@ static int find(grib_nearest* nearest, grib_handle* h, int lons_count = 0; /*dummy*/ err = grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, - self->values_key, - &(self->lats), - &(self->lats_count), - &(self->lons), + h, inlat, inlon, flags, + values_key_, + &(lats_), + &(lats_count_), + &(lons_), &(lons_count), - &(self->distances), + &(distances_), outlats, outlons, values, distances, indexes, len); } @@ -200,12 +118,11 @@ static int find(grib_nearest* nearest, grib_handle* h, } /* Old implementation in src/deprecated/grib_nearest_class_reduced.old */ -static int find_global(grib_nearest* nearest, grib_handle* h, +int Reduced::find_global(grib_handle* h, double inlat, double inlon, unsigned long flags, double* outlats, double* outlons, double* values, double* distances, int* indexes, size_t* len) { - grib_nearest_reduced* self = (grib_nearest_reduced*)nearest; int err = 0, kk = 0, ii = 0; size_t jj = 0; long* pla = NULL; @@ -217,17 +134,17 @@ static int find_global(grib_nearest* nearest, grib_handle* h, int ilat = 0, ilon = 0; get_reduced_row_proc get_reduced_row_func = &grib_get_reduced_row; - if (self->legacy == -1 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { - err = is_legacy(h, &(self->legacy)); + if (legacy_ == -1 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + err = is_legacy(h, &(legacy_)); if (err) return err; } - if (self->legacy == 1) { + if (legacy_ == 1) { get_reduced_row_func = &grib_get_reduced_row_legacy; } - if ((err = grib_get_size(h, self->values_key, &nvalues)) != GRIB_SUCCESS) + if ((err = grib_get_size(h, values_key_, &nvalues)) != GRIB_SUCCESS) return err; - nearest->values_count = nvalues; + values_count_ = nvalues; if ((err = grib_nearest_get_radius(h, &radiusInKm)) != GRIB_SUCCESS) return err; @@ -235,31 +152,31 @@ static int find_global(grib_nearest* nearest, grib_handle* h, /* Compute lat/lon info, create iterator etc if it's the 1st time or different grid. * This is for performance: if the grid has not changed, we only do this once * and reuse for other messages */ - if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + if (!h_ || (flags & GRIB_NEAREST_SAME_GRID) == 0) { double olat = 1.e10; long n = 0; ilat = 0; ilon = 0; - if (grib_is_missing(h, self->Nj, &err)) { - grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", self->Nj); + if (grib_is_missing(h, Nj_, &err)) { + grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", Nj_); return err ? err : GRIB_GEOCALCULUS_PROBLEM; } - if ((err = grib_get_long(h, self->Nj, &n)) != GRIB_SUCCESS) + if ((err = grib_get_long(h, Nj_, &n)) != GRIB_SUCCESS) return err; - self->lats_count = n; + lats_count_ = n; - if (self->lats) - grib_context_free(h->context, self->lats); - self->lats = (double*)grib_context_malloc(h->context, self->lats_count * sizeof(double)); - if (!self->lats) + if (lats_) + grib_context_free(h->context, lats_); + lats_ = (double*)grib_context_malloc(h->context, lats_count_ * sizeof(double)); + if (!lats_) return GRIB_OUT_OF_MEMORY; - if (self->lons) - grib_context_free(h->context, self->lons); - self->lons = (double*)grib_context_malloc(h->context, nearest->values_count * sizeof(double)); - if (!self->lons) + if (lons_) + grib_context_free(h->context, lons_); + lons_ = (double*)grib_context_malloc(h->context, values_count_ * sizeof(double)); + if (!lons_) return GRIB_OUT_OF_MEMORY; iter = grib_iterator_new(h, GRIB_GEOITERATOR_NO_VALUES, &err); @@ -268,29 +185,29 @@ static int find_global(grib_nearest* nearest, grib_handle* h, return err; } while (grib_iterator_next(iter, &lat, &lon, NULL)) { - if (ilat < self->lats_count && olat != lat) { - self->lats[ilat++] = lat; + if (ilat < lats_count_ && olat != lat) { + lats_[ilat++] = lat; olat = lat; } while (lon > 360) lon -= 360; - if (!self->global) { /* ECC-756 */ - if (self->legacy == 0) /*TODO*/ + if (!global_) { /* ECC-756 */ + if (legacy_ == 0) /*TODO*/ if (lon > 180 && lon < 360) lon -= 360; } - DEBUG_ASSERT_ACCESS(self->lons, (long)ilon, (long)nearest->values_count); - self->lons[ilon++] = lon; + DEBUG_ASSERT_ACCESS(lons_, (long)ilon, (long)values_count_); + lons_[ilon++] = lon; } - self->lats_count = ilat; + lats_count_ = ilat; grib_iterator_delete(iter); } - nearest->h = h; + h_ = h; /* Compute distances if it's the 1st time or different point or different grid. * This is for performance: if the grid and the input point have not changed * we only do this once and reuse for other messages */ - if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT) == 0 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + if (!distances_ || (flags & GRIB_NEAREST_SAME_POINT) == 0 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { double* lons = NULL; int nlon = 0; size_t plsize = 0; @@ -298,40 +215,40 @@ static int find_global(grib_nearest* nearest, grib_handle* h, int nearest_lons_found = 0; long row_count, ilon_first, ilon_last; - if (self->global) { + if (global_) { inlon = normalise_longitude_in_degrees(inlon); } else { /* TODO: Experimental */ - if (self->legacy == 0) + if (legacy_ == 0) if (inlon > 180 && inlon < 360) inlon -= 360; } - ilat = self->lats_count; - if (self->lats[ilat - 1] > self->lats[0]) { - if (inlat < self->lats[0] || inlat > self->lats[ilat - 1]) + ilat = lats_count_; + if (lats_[ilat - 1] > lats_[0]) { + if (inlat < lats_[0] || inlat > lats_[ilat - 1]) return GRIB_OUT_OF_AREA; } else { - if (inlat > self->lats[0] || inlat < self->lats[ilat - 1]) + if (inlat > lats_[0] || inlat < lats_[ilat - 1]) return GRIB_OUT_OF_AREA; } - if (!self->distances) - self->distances = (double*)grib_context_malloc(h->context, NUM_NEIGHBOURS * sizeof(double)); - if (!self->distances) + if (!distances_) + distances_ = (double*)grib_context_malloc(h->context, NUM_NEIGHBOURS * sizeof(double)); + if (!distances_) return GRIB_OUT_OF_MEMORY; - grib_binary_search(self->lats, ilat - 1, inlat, &(self->j[0]), &(self->j[1])); + grib_binary_search(lats_, ilat - 1, inlat, &(j_[0]), &(j_[1])); - plsize = self->lats_count; - if ((err = grib_get_size(h, self->pl, &plsize)) != GRIB_SUCCESS) + plsize = lats_count_; + if ((err = grib_get_size(h, pl_, &plsize)) != GRIB_SUCCESS) return err; pla = (long*)grib_context_malloc(h->context, plsize * sizeof(long)); if (!pla) return GRIB_OUT_OF_MEMORY; - if ((err = grib_get_long_array(h, self->pl, pla, &plsize)) != GRIB_SUCCESS) + if ((err = grib_get_long_array(h, pl_, pla, &plsize)) != GRIB_SUCCESS) return err; pl = pla; @@ -340,27 +257,27 @@ static int find_global(grib_nearest* nearest, grib_handle* h, } nlon = 0; - if (self->global) { - for (jj = 0; jj < self->j[0]; jj++) + if (global_) { + for (jj = 0; jj < j_[0]; jj++) nlon += pl[jj]; - nplm1 = pl[self->j[0]] - 1; + nplm1 = pl[j_[0]] - 1; } else { nlon = 0; - for (jj = 0; jj < self->j[0]; jj++) { + for (jj = 0; jj < j_[0]; jj++) { row_count = 0; ilon_first = 0; ilon_last = 0; - get_reduced_row_func(pl[jj], self->lon_first, self->lon_last, &row_count, &ilon_first, &ilon_last); + get_reduced_row_func(pl[jj], lon_first_, lon_last_, &row_count, &ilon_first, &ilon_last); nlon += row_count; } row_count = 0; ilon_first = 0; ilon_last = 0; - get_reduced_row_func(pl[self->j[0]], self->lon_first, self->lon_last, &row_count, &ilon_first, &ilon_last); + get_reduced_row_func(pl[j_[0]], lon_first_, lon_last_, &row_count, &ilon_first, &ilon_last); nplm1 = row_count - 1; } - lons = self->lons + nlon; + lons = lons_ + nlon; nearest_lons_found = 0; /* ECC-756: The comparisons of longitudes here depends on the longitude values @@ -371,8 +288,8 @@ static int find_global(grib_nearest* nearest, grib_handle* h, if (lons[nplm1] > lons[0]) { if (inlon < lons[0] || inlon > lons[nplm1]) { if (lons[nplm1] - lons[0] - 360 <= lons[nplm1] - lons[nplm1 - 1]) { - self->k[0] = 0; - self->k[1] = nplm1; + k_[0] = 0; + k_[1] = nplm1; nearest_lons_found = 1; } else @@ -382,8 +299,8 @@ static int find_global(grib_nearest* nearest, grib_handle* h, else { if (inlon > lons[0] || inlon < lons[nplm1]) { if (lons[0] - lons[nplm1] - 360 <= lons[0] - lons[1]) { - self->k[0] = 0; - self->k[1] = nplm1; + k_[0] = 0; + k_[1] = nplm1; nearest_lons_found = 1; } else @@ -392,51 +309,51 @@ static int find_global(grib_nearest* nearest, grib_handle* h, } if (!nearest_lons_found) { - if (!self->global) { + if (!global_) { row_count = 0; ilon_first = 0; ilon_last = 0; - get_reduced_row_func(pl[self->j[0]], self->lon_first, self->lon_last, &row_count, &ilon_first, &ilon_last); + get_reduced_row_func(pl[j_[0]], lon_first_, lon_last_, &row_count, &ilon_first, &ilon_last); } else { - row_count = pl[self->j[0]]; + row_count = pl[j_[0]]; } grib_binary_search(lons, row_count - 1, inlon, - &(self->k[0]), &(self->k[1])); + &(k_[0]), &(k_[1])); } - self->k[0] += nlon; - self->k[1] += nlon; + k_[0] += nlon; + k_[1] += nlon; nlon = 0; - if (self->global) { - for (jj = 0; jj < self->j[1]; jj++) + if (global_) { + for (jj = 0; jj < j_[1]; jj++) nlon += pl[jj]; - nplm1 = pl[self->j[1]] - 1; + nplm1 = pl[j_[1]] - 1; } else { - for (jj = 0; jj < self->j[1]; jj++) { + for (jj = 0; jj < j_[1]; jj++) { row_count = 0; ilon_first = 0; ilon_last = 0; - get_reduced_row_func(pl[jj], self->lon_first, self->lon_last, &row_count, &ilon_first, &ilon_last); + get_reduced_row_func(pl[jj], lon_first_, lon_last_, &row_count, &ilon_first, &ilon_last); nlon += row_count; } row_count = 0; ilon_first = 0; ilon_last = 0; - get_reduced_row_func(pl[self->j[1]], self->lon_first, self->lon_last, &nplm1, &ilon_first, &ilon_last); + get_reduced_row_func(pl[j_[1]], lon_first_, lon_last_, &nplm1, &ilon_first, &ilon_last); nplm1--; } - lons = self->lons + nlon; + lons = lons_ + nlon; nearest_lons_found = 0; if (lons[nplm1] > lons[0]) { if (inlon < lons[0] || inlon > lons[nplm1]) { if (lons[nplm1] - lons[0] - 360 <= lons[nplm1] - lons[nplm1 - 1]) { - self->k[2] = 0; - self->k[3] = nplm1; + k_[2] = 0; + k_[3] = nplm1; nearest_lons_found = 1; } else @@ -447,8 +364,8 @@ static int find_global(grib_nearest* nearest, grib_handle* h, if (inlon > lons[0] || inlon < lons[nplm1]) { if (lons[0] - lons[nplm1] - 360 <= lons[0] - lons[1]) { - self->k[2] = 0; - self->k[3] = nplm1; + k_[2] = 0; + k_[3] = nplm1; nearest_lons_found = 1; } else @@ -457,28 +374,28 @@ static int find_global(grib_nearest* nearest, grib_handle* h, } if (!nearest_lons_found) { - if (!self->global) { + if (!global_) { row_count = 0; ilon_first = 0; ilon_last = 0; - get_reduced_row_func(pl[self->j[1]], self->lon_first, self->lon_last, &row_count, &ilon_first, &ilon_last); + get_reduced_row_func(pl[j_[1]], lon_first_, lon_last_, &row_count, &ilon_first, &ilon_last); } else { - row_count = pl[self->j[1]]; + row_count = pl[j_[1]]; } grib_binary_search(lons, row_count - 1, inlon, - &(self->k[2]), &(self->k[3])); + &(k_[2]), &(k_[3])); } - self->k[2] += nlon; - self->k[3] += nlon; + k_[2] += nlon; + k_[3] += nlon; kk = 0; for (jj = 0; jj < 2; jj++) { for (ii = 0; ii < 2; ii++) { - self->distances[kk] = geographic_distance_spherical(radiusInKm, inlon, inlat, - self->lons[self->k[kk]], self->lats[self->j[jj]]); + distances_[kk] = geographic_distance_spherical(radiusInKm, inlon, inlat, + lons_[k_[kk]], lats_[j_[jj]]); kk++; } } @@ -490,24 +407,24 @@ static int find_global(grib_nearest* nearest, grib_handle* h, if (values) { /* See ECC-1403 and ECC-499 */ /* Performance: Decode the field once and get all 4 values */ - err = grib_get_double_element_set(h, self->values_key, self->k, NUM_NEIGHBOURS, values); + err = grib_get_double_element_set(h, values_key_, k_, NUM_NEIGHBOURS, values); if (err != GRIB_SUCCESS) return err; } for (jj = 0; jj < 2; jj++) { for (ii = 0; ii < 2; ii++) { - distances[kk] = self->distances[kk]; - outlats[kk] = self->lats[self->j[jj]]; - outlons[kk] = self->lons[self->k[kk]]; + distances[kk] = distances_[kk]; + outlats[kk] = lats_[j_[jj]]; + outlons[kk] = lons_[k_[kk]]; /*if (values) { - * grib_get_double_element_internal(h, self->values_key, self->k[kk], &(values[kk])); + * grib_get_double_element_internal(h, values_key_, k_[kk], &(values[kk])); *} */ - if (self->k[kk] >= INT_MAX) { + if (k_[kk] >= INT_MAX) { /* Current interface uses an 'int' for 'indexes' which is 32bits! We should change this to a 64bit type */ grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_reduced: Unable to compute index. Value too large"); return GRIB_OUT_OF_RANGE; } else { - indexes[kk] = (int)self->k[kk]; + indexes[kk] = (int)k_[kk]; } kk++; } @@ -516,16 +433,4 @@ static int find_global(grib_nearest* nearest, grib_handle* h, return GRIB_SUCCESS; } -static int destroy(grib_nearest* nearest) -{ - grib_nearest_reduced* self = (grib_nearest_reduced*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - - return GRIB_SUCCESS; -} +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_reduced.h b/src/geo_nearest/grib_nearest_class_reduced.h new file mode 100644 index 0000000000..6132c26b9d --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_reduced.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class Reduced : public Gen { +public: + Reduced() { + class_name_ = "reduced"; + } + Nearest* create() override { return new Reduced(); } + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; + +private: + const char* pl_ = nullptr; + long global_ = 0.0; + double lon_first_ = 0.0; + double lon_last_ = 0.0; + int legacy_ = 0; + int rotated_ = 0; + + int find_global(grib_handle*, + double, double, unsigned long, + double*, double*, double*, + double*, int*, size_t*); +}; + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_regular.cc b/src/geo_nearest/grib_nearest_class_regular.cc new file mode 100644 index 0000000000..9dac4b0cc9 --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_regular.cc @@ -0,0 +1,288 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_regular.h" + +eccodes::geo_nearest::Regular _grib_nearest_regular{}; +eccodes::geo_nearest::Nearest* grib_nearest_regular = &_grib_nearest_regular; + +namespace eccodes::geo_nearest { + +#define NUM_NEIGHBOURS 4 + +int Regular::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Ni_ = grib_arguments_get_name(h, args, cargs_++); + Nj_ = grib_arguments_get_name(h, args, cargs_++); + i_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + return ret; +} + +static bool is_rotated_grid(grib_handle* h) +{ + long is_rotated = 0; + int err = grib_get_long(h, "isRotatedGrid", &is_rotated); + if (!err && is_rotated) + return true; + return false; +} + +// Old implementation in +// src/deprecated/grib_nearest_class_regular.cc +// +int Regular::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + int ret = 0, kk = 0, ii = 0, jj = 0; + size_t nvalues = 0; + double radiusInKm; + + grib_iterator* iter = NULL; + double lat = 0, lon = 0; + const bool is_rotated = is_rotated_grid(h); + double angleOfRotation = 0, southPoleLat = 0, southPoleLon = 0; + grib_context* c = h->context; + + while (inlon < 0) + inlon += 360; + while (inlon > 360) + inlon -= 360; + + if ((ret = grib_get_size(h, values_key_, &nvalues)) != GRIB_SUCCESS) + return ret; + values_count_ = nvalues; + + if ((ret = grib_nearest_get_radius(h, &radiusInKm)) != GRIB_SUCCESS) + return ret; + + /* Compute lat/lon info, create iterator etc if it's the 1st time or different grid. + * This is for performance: if the grid has not changed, we only do this once + * and reuse for other messages */ + if (!h_ || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + double olat = 1.e10, olon = 1.e10; + int ilat = 0, ilon = 0; + long n = 0; + + if (grib_is_missing(h, Ni_, &ret)) { + grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", Ni_); + return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; + } + + if (grib_is_missing(h, Nj_, &ret)) { + grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", Nj_); + return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; + } + + /* ECC-600: Support for rotated grids + * First: rotate the input point + * Then: run the lat/lon iterator over the rotated grid (disableUnrotate) + * Finally: unrotate the resulting point + */ + if (is_rotated) { + double new_lat = 0, new_lon = 0; + ret = grib_get_double_internal(h, "angleOfRotation", &angleOfRotation); + if (ret) + return ret; + ret = grib_get_double_internal(h, "latitudeOfSouthernPoleInDegrees", &southPoleLat); + if (ret) + return ret; + ret = grib_get_double_internal(h, "longitudeOfSouthernPoleInDegrees", &southPoleLon); + if (ret) + return ret; + ret = grib_set_long(h, "iteratorDisableUnrotate", 1); + if (ret) + return ret; + /* Rotate the inlat, inlon */ + rotate(inlat, inlon, angleOfRotation, southPoleLat, southPoleLon, &new_lat, &new_lon); + inlat = new_lat; + inlon = new_lon; + /*if(h->context->debug) printf("nearest find: rotated grid: new point=(%g,%g)\n",new_lat,new_lon);*/ + } + + if ((ret = grib_get_long(h, Ni_, &n)) != GRIB_SUCCESS) + return ret; + lons_count_ = n; + + if ((ret = grib_get_long(h, Nj_, &n)) != GRIB_SUCCESS) + return ret; + lats_count_ = n; + + if (lats_) + grib_context_free(c, lats_); + lats_ = (double*)grib_context_malloc(c, lats_count_ * sizeof(double)); + if (!lats_) + return GRIB_OUT_OF_MEMORY; + + if (lons_) + grib_context_free(c, lons_); + lons_ = (double*)grib_context_malloc(c, lons_count_ * sizeof(double)); + if (!lons_) + return GRIB_OUT_OF_MEMORY; + + iter = grib_iterator_new(h, GRIB_GEOITERATOR_NO_VALUES, &ret); + if (ret != GRIB_SUCCESS) { + grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_regular: Unable to create lat/lon iterator"); + return ret; + } + while (grib_iterator_next(iter, &lat, &lon, NULL)) { + if (ilat < lats_count_ && olat != lat) { + lats_[ilat++] = lat; + olat = lat; + } + if (ilon < lons_count_ && olon != lon) { + lons_[ilon++] = lon; + olon = lon; + } + } + grib_iterator_delete(iter); + } + h_ = h; + + /* Compute distances if it's the 1st time or different point or different grid. + * This is for performance: if the grid and the input point have not changed + * we only do this once and reuse for other messages */ + if (!distances_ || (flags & GRIB_NEAREST_SAME_POINT) == 0 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { + int nearest_lons_found = 0; + + if (lats_[lats_count_ - 1] > lats_[0]) { + if (inlat < lats_[0] || inlat > lats_[lats_count_ - 1]) + return GRIB_OUT_OF_AREA; + } + else { + if (inlat > lats_[0] || inlat < lats_[lats_count_ - 1]) + return GRIB_OUT_OF_AREA; + } + + if (lons_[lons_count_ - 1] > lons_[0]) { + if (inlon < lons_[0] || inlon > lons_[lons_count_ - 1]) { + /* try to scale*/ + if (inlon > 0) + inlon -= 360; + else + inlon += 360; + + if (inlon < lons_[0] || inlon > lons_[lons_count_ - 1]) { + if (lons_[0] + 360 - lons_[lons_count_ - 1] <= + lons_[1] - lons_[0]) { + /*it's a global field in longitude*/ + i_[0] = 0; + i_[1] = lons_count_ - 1; + nearest_lons_found = 1; + } + else + return GRIB_OUT_OF_AREA; + } + } + } + else { + if (inlon > lons_[0] || inlon < lons_[lons_count_ - 1]) { + /* try to scale*/ + if (inlon > 0) + inlon -= 360; + else + inlon += 360; + if (lons_[0] - lons_[lons_count_ - 1] - 360 <= + lons_[0] - lons_[1]) { + /*it's a global field in longitude*/ + i_[0] = 0; + i_[1] = lons_count_ - 1; + nearest_lons_found = 1; + } + else if (inlon > lons_[0] || inlon < lons_[lons_count_ - 1]) + return GRIB_OUT_OF_AREA; + } + } + + grib_binary_search(lats_, lats_count_ - 1, inlat, + &(j_[0]), &(j_[1])); + + if (!nearest_lons_found) + grib_binary_search(lons_, lons_count_ - 1, inlon, + &(i_[0]), &(i_[1])); + + if (!distances_) + distances_ = (double*)grib_context_malloc(c, NUM_NEIGHBOURS * sizeof(double)); + if (!k_) + k_ = (size_t*)grib_context_malloc(c, NUM_NEIGHBOURS * sizeof(size_t)); + kk = 0; + for (jj = 0; jj < 2; jj++) { + for (ii = 0; ii < 2; ii++) { + k_[kk] = i_[ii] + lons_count_ * j_[jj]; + distances_[kk] = geographic_distance_spherical(radiusInKm, inlon, inlat, + lons_[i_[ii]], lats_[j_[jj]]); + kk++; + } + } + } + + kk = 0; + + /* + * Brute force algorithm: + * First unpack all the values into an array. Then when we need the 4 points + * we just index into this array so no need to call grib_get_double_element_internal + * + * if (nearest->values) grib_context_free(c,nearest->values); + * nearest->values = grib_context_malloc(h->context,nvalues*sizeof(double)); + * if (!nearest->values) return GRIB_OUT_OF_MEMORY; + * ret = grib_get_double_array(h, values_key_, nearest->values ,&nvalues); + * if (ret) return ret; + */ + + if (values) { + /* See ECC-1403 and ECC-499 */ + /* Performance: Decode the field once and get all 4 values */ + if ((ret = grib_get_double_element_set(h, values_key_, k_, NUM_NEIGHBOURS, values)) != GRIB_SUCCESS) + return ret; + } + + for (jj = 0; jj < 2; jj++) { + for (ii = 0; ii < 2; ii++) { + distances[kk] = distances_[kk]; + outlats[kk] = lats_[j_[jj]]; + outlons[kk] = lons_[i_[ii]]; + if (is_rotated) { + /* Unrotate resulting lat/lon */ + double new_lat = 0, new_lon = 0; + unrotate(outlats[kk], outlons[kk], angleOfRotation, southPoleLat, southPoleLon, &new_lat, &new_lon); + outlats[kk] = new_lat; + outlons[kk] = new_lon; + } + /* See ECC-1403 and ECC-499 + * if (values) { + * grib_get_double_element_internal(h, values_key_, k_[kk], &(values[kk])); + *} + */ + /* Using the brute force approach described above */ + /* Assert(k_[kk] < nvalues); */ + /* values[kk]=nearest->values[k_[kk]]; */ + + if (k_[kk] >= INT_MAX) { + /* Current interface uses an 'int' for 'indexes' which is 32bits! We should change this to a 64bit type */ + grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_regular: Unable to compute index. Value too large"); + return GRIB_OUT_OF_RANGE; + } else { + indexes[kk] = (int)k_[kk]; + } + kk++; + } + } + + return GRIB_SUCCESS; +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_regular.h b/src/geo_nearest/grib_nearest_class_regular.h new file mode 100644 index 0000000000..481b6a1c8b --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_regular.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class Regular : public Gen { +public: + Regular() { + class_name_ = "regular"; + } + Nearest* create() override { return new Regular(); } + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; +}; + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_space_view.cc b/src/geo_nearest/grib_nearest_class_space_view.cc new file mode 100644 index 0000000000..fdad5fba6e --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_space_view.cc @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_nearest_class_space_view.h" + +eccodes::geo_nearest::SpaceView _grib_nearest_space_view{}; +eccodes::geo_nearest::Nearest* grib_nearest_space_view = &_grib_nearest_space_view; + +namespace eccodes::geo_nearest { + +int SpaceView::init(grib_handle* h, grib_arguments* args) +{ + int ret = GRIB_SUCCESS; + if ((ret = Gen::init(h, args) != GRIB_SUCCESS)) + return ret; + + Ni_ = grib_arguments_get_name(h, args, cargs_++); + Nj_ = grib_arguments_get_name(h, args, cargs_++); + i_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + j_ = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); + + return ret; +} + +int SpaceView::find(grib_handle* h, + double inlat, double inlon, unsigned long flags, + double* outlats, double* outlons, + double* values, double* distances, int* indexes, size_t* len) +{ + return grib_nearest_find_generic( + h, inlat, inlon, flags, /* inputs */ + + values_key_, /* outputs to set the 'self' object */ + &(lats_), + &(lats_count_), + &(lons_), + &(lons_count_), + &(distances_), + + outlats, outlons, /* outputs of the find function */ + values, distances, indexes, len); +} + +} // namespace eccodes::geo_nearest diff --git a/src/geo_nearest/grib_nearest_class_space_view.h b/src/geo_nearest/grib_nearest_class_space_view.h new file mode 100644 index 0000000000..4f6447ed0f --- /dev/null +++ b/src/geo_nearest/grib_nearest_class_space_view.h @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_nearest_class_gen.h" + +namespace eccodes::geo_nearest { + +class SpaceView : public Gen { +public: + SpaceView() { + class_name_ = "space_view"; + } + Nearest* create() override { return new SpaceView(); } + int init(grib_handle*, grib_arguments*) override; + int find(grib_handle*, double, double, unsigned long, double*, double*, double*, double*, int*, size_t*) override; +}; + +} // namespace eccodes::geo_nearest diff --git a/src/grib_api_internal.h b/src/grib_api_internal.h index b093c2e6cf..5a1f05f03c 100644 --- a/src/grib_api_internal.h +++ b/src/grib_api_internal.h @@ -256,7 +256,6 @@ typedef struct grib_iterator { eccodes::geo_iterator::Iterator* iterator; } grib_iterator; -typedef struct grib_nearest_class grib_nearest_class; typedef struct grib_dumper grib_dumper; typedef struct grib_dumper_class grib_dumper_class; typedef struct grib_dependency grib_dependency; @@ -264,16 +263,6 @@ typedef struct grib_dependency grib_dependency; typedef struct codes_condition codes_condition; /* typedef void (*dynamic_key_proc) (const char*, void*) */ -typedef void (*nearest_init_class_proc)(grib_nearest_class*); -typedef int (*nearest_init_proc)(grib_nearest* i, grib_handle*, grib_arguments*); - -typedef int (*nearest_find_proc)(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, - unsigned long flags, double* outlats, - double* outlons, double* values, - double* distances, int* indexes, size_t* len); -typedef int (*nearest_destroy_proc)(grib_nearest* nearest); - typedef int (*grib_pack_proc)(grib_handle* h, const double* in, size_t inlen, void* out, size_t* outlen); typedef int (*grib_unpack_proc)(grib_handle* h, const void* in, size_t inlen, double* out, size_t* outlen); @@ -458,17 +447,13 @@ struct grib_section size_t padding; }; -struct grib_nearest_class -{ - grib_nearest_class** super; - const char* name; - size_t size; - int inited; - nearest_init_class_proc init_class; - nearest_init_proc init; - nearest_destroy_proc destroy; - nearest_find_proc find; -}; +namespace eccodes::geo_nearest { +class Nearest; +} + +typedef struct grib_nearest { + eccodes::geo_nearest::Nearest* nearest; +} grib_nearest; /* --------------- */ typedef int (*dumper_init_proc)(grib_dumper*); @@ -513,15 +498,6 @@ struct grib_dumper_class dumper_footer_proc footer; }; -struct grib_nearest -{ - grib_handle* h; - double* values; - size_t values_count; - grib_nearest_class* cclass; - unsigned long flags; -}; - struct grib_dependency { grib_dependency* next; @@ -1243,13 +1219,14 @@ typedef struct j2k_encode_helper } j2k_encode_helper; -#include "eccodes_prototypes.h" +#include "eccodes_prototypes.h" #ifdef __cplusplus } #include "accessor/grib_accessor.h" #include "accessor/grib_accessors_list.h" #include "geo_iterator/grib_iterator.h" +#include "geo_nearest/grib_nearest.h" #endif #endif diff --git a/src/grib_io.cc b/src/grib_io.cc index 43e559b3fc..4de9e45994 100644 --- a/src/grib_io.cc +++ b/src/grib_io.cc @@ -822,6 +822,9 @@ static int read_BUFR(reader* r, int no_alloc) if (sec3len < 5) { return GRIB_INVALID_MESSAGE; // ECC-1778 } + if (sec3len > 10'000'000) { + return GRIB_INVALID_MESSAGE; // ECC-1938 + } if ((r->read(r->read_data, tmp + i, sec3len - 3, &err) != sec3len - 3) || err) return err; i += sec3len - 3; diff --git a/src/grib_iterator_class.h b/src/grib_iterator_class.h deleted file mode 100644 index 31aabe9850..0000000000 --- a/src/grib_iterator_class.h +++ /dev/null @@ -1,13 +0,0 @@ -/* This file is automatically generated by ./make_class.pl, do not edit */ -extern eccodes::geo_iterator::Iterator* grib_iterator_gaussian; -extern eccodes::geo_iterator::Iterator* grib_iterator_gaussian_reduced; -//extern eccodes::geo_iterator::Iterator* grib_iterator_gen; -extern eccodes::geo_iterator::Iterator* grib_iterator_healpix; -extern eccodes::geo_iterator::Iterator* grib_iterator_lambert_azimuthal_equal_area; -extern eccodes::geo_iterator::Iterator* grib_iterator_lambert_conformal; -extern eccodes::geo_iterator::Iterator* grib_iterator_latlon; -extern eccodes::geo_iterator::Iterator* grib_iterator_latlon_reduced; -extern eccodes::geo_iterator::Iterator* grib_iterator_mercator; -extern eccodes::geo_iterator::Iterator* grib_iterator_polar_stereographic; -extern eccodes::geo_iterator::Iterator* grib_iterator_regular; -extern eccodes::geo_iterator::Iterator* grib_iterator_space_view; diff --git a/src/grib_iterator_class.cc b/src/grib_iterator_factory.cc similarity index 90% rename from src/grib_iterator_class.cc rename to src/grib_iterator_factory.cc index fbf208818c..9ea143b3d5 100644 --- a/src/grib_iterator_class.cc +++ b/src/grib_iterator_factory.cc @@ -8,18 +8,9 @@ * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ -/*************************************************************************** - * Jean Baptiste Filippi - 01.11.2005 * - * Enrico Fucile * - ***************************************************************************/ - -#include "grib_api_internal.h" -#include "geo_iterator/grib_iterator.h" +#include "grib_iterator_factory.h" #include "accessor/grib_accessor_class_iterator.h" -/* This file is generated by ./make_class.pl */ -#include "grib_iterator_class.h" - #if GRIB_PTHREADS static pthread_once_t once = PTHREAD_ONCE_INIT; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -55,11 +46,20 @@ struct table_entry }; static const struct table_entry table[] = { - /* This file is generated by ./make_class.pl */ - #include "grib_iterator_factory.h" + { "gaussian", &grib_iterator_gaussian, }, + { "gaussian_reduced", &grib_iterator_gaussian_reduced, }, + { "healpix", &grib_iterator_healpix, }, + { "lambert_azimuthal_equal_area", &grib_iterator_lambert_azimuthal_equal_area, }, + { "lambert_conformal", &grib_iterator_lambert_conformal, }, + { "latlon", &grib_iterator_latlon, }, + { "latlon_reduced", &grib_iterator_latlon_reduced, }, + { "mercator", &grib_iterator_mercator, }, + { "polar_stereographic", &grib_iterator_polar_stereographic, }, + { "regular", &grib_iterator_regular, }, + { "space_view", &grib_iterator_space_view, }, + { "unstructured", &grib_iterator_unstructured, }, }; - eccodes::geo_iterator::Iterator* grib_iterator_factory(grib_handle* h, grib_arguments* args, unsigned long flags, int* error) { size_t i = 0, num_table_entries = 0; diff --git a/src/grib_iterator_factory.h b/src/grib_iterator_factory.h index ed247bebde..b45f6cfe00 100644 --- a/src/grib_iterator_factory.h +++ b/src/grib_iterator_factory.h @@ -1,13 +1,30 @@ -/* This file is automatically generated by ./make.pl, do not edit */ -{ "gaussian", &grib_iterator_gaussian, }, -{ "gaussian_reduced", &grib_iterator_gaussian_reduced, }, -//{ "gen", &grib_iterator_gen, }, -{ "healpix", &grib_iterator_healpix, }, -{ "lambert_azimuthal_equal_area", &grib_iterator_lambert_azimuthal_equal_area, }, -{ "lambert_conformal", &grib_iterator_lambert_conformal, }, -{ "latlon", &grib_iterator_latlon, }, -{ "latlon_reduced", &grib_iterator_latlon_reduced, }, -{ "mercator", &grib_iterator_mercator, }, -{ "polar_stereographic", &grib_iterator_polar_stereographic, }, -{ "regular", &grib_iterator_regular, }, -{ "space_view", &grib_iterator_space_view, }, +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_api_internal.h" +#include "geo_iterator/grib_iterator.h" + +extern eccodes::geo_iterator::Iterator* grib_iterator_gaussian; +extern eccodes::geo_iterator::Iterator* grib_iterator_gaussian_reduced; +extern eccodes::geo_iterator::Iterator* grib_iterator_healpix; +extern eccodes::geo_iterator::Iterator* grib_iterator_lambert_azimuthal_equal_area; +extern eccodes::geo_iterator::Iterator* grib_iterator_lambert_conformal; +extern eccodes::geo_iterator::Iterator* grib_iterator_latlon; +extern eccodes::geo_iterator::Iterator* grib_iterator_latlon_reduced; +extern eccodes::geo_iterator::Iterator* grib_iterator_mercator; +extern eccodes::geo_iterator::Iterator* grib_iterator_polar_stereographic; +extern eccodes::geo_iterator::Iterator* grib_iterator_regular; +extern eccodes::geo_iterator::Iterator* grib_iterator_space_view; +extern eccodes::geo_iterator::Iterator* grib_iterator_unstructured; + + +eccodes::geo_iterator::Iterator* grib_iterator_factory(grib_handle* h, grib_arguments* args, unsigned long flags, int* error); diff --git a/src/grib_nearest_class.h b/src/grib_nearest_class.h deleted file mode 100644 index a1341806a8..0000000000 --- a/src/grib_nearest_class.h +++ /dev/null @@ -1,11 +0,0 @@ -/* This file is automatically generated by ./make_class.pl, do not edit */ -extern grib_nearest_class* grib_nearest_class_gen; -extern grib_nearest_class* grib_nearest_class_healpix; -extern grib_nearest_class* grib_nearest_class_lambert_azimuthal_equal_area; -extern grib_nearest_class* grib_nearest_class_lambert_conformal; -extern grib_nearest_class* grib_nearest_class_latlon_reduced; -extern grib_nearest_class* grib_nearest_class_mercator; -extern grib_nearest_class* grib_nearest_class_polar_stereographic; -extern grib_nearest_class* grib_nearest_class_reduced; -extern grib_nearest_class* grib_nearest_class_regular; -extern grib_nearest_class* grib_nearest_class_space_view; diff --git a/src/grib_nearest_class_gen.cc b/src/grib_nearest_class_gen.cc deleted file mode 100644 index c97e6b8b9f..0000000000 --- a/src/grib_nearest_class_gen.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - IMPLEMENTS = destroy - IMPLEMENTS = find - IMPLEMENTS = init - MEMBERS = const char* values_key - MEMBERS = const char* radius - MEMBERS = int cargs - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_gen{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; -} grib_nearest_gen; - - -static grib_nearest_class _grib_nearest_class_gen = { - 0, /* super */ - "gen", /* name */ - sizeof(grib_nearest_gen), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_gen = &_grib_nearest_class_gen; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_gen* self = (grib_nearest_gen*)nearest; - int ret = GRIB_SUCCESS; - - self->cargs = 1; - - self->values_key = grib_arguments_get_name(h, args, self->cargs++); - self->radius = grib_arguments_get_name(h, args, self->cargs++); - nearest->values = NULL; - - return ret; -} - -static int destroy(grib_nearest* nearest) -{ - grib_context* c = grib_context_get_default(); - if (nearest->values) - grib_context_free(c, nearest->values); - grib_context_free(c, nearest); - return GRIB_SUCCESS; -} - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, double* values, - double* distances, int* indexes, size_t* len) -{ - return GRIB_NOT_IMPLEMENTED; -} diff --git a/src/grib_nearest_class_healpix.cc b/src/grib_nearest_class_healpix.cc deleted file mode 100644 index d8618ba34b..0000000000 --- a/src/grib_nearest_class_healpix.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init - IMPLEMENTS = find;destroy - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = int lons_count - MEMBERS = double* distances - MEMBERS = int* k - MEMBERS = int* i - MEMBERS = int* j - MEMBERS = const char* Ni - MEMBERS = const char* Nj - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_healpix{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in healpix */ - double* lats; - int lats_count; - double* lons; - int lons_count; - double* distances; - int* k; - int* i; - int* j; - const char* Ni; - const char* Nj; -} grib_nearest_healpix; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_healpix = { - &grib_nearest_class_gen, /* super */ - "healpix", /* name */ - sizeof(grib_nearest_healpix), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_healpix = &_grib_nearest_class_healpix; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_healpix* self = (grib_nearest_healpix*)nearest; - self->Ni = grib_arguments_get_name(h, args, self->cargs++); - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->lats = self->lons = self->distances = NULL; - self->lats_count = self->lons_count = 0; - self->i = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - self->j = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - return GRIB_SUCCESS; -} - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_nearest_healpix* self = (grib_nearest_healpix*)nearest; - return grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, /* inputs */ - - self->values_key, /* outputs to set the 'self' object */ - &(self->lats), - &(self->lats_count), - &(self->lons), - &(self->lons_count), - &(self->distances), - - outlats, outlons, /* outputs of the find function */ - values, distances, indexes, len); -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_healpix* self = (grib_nearest_healpix*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->i) grib_context_free(c, self->i); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class_lambert_azimuthal_equal_area.cc b/src/grib_nearest_class_lambert_azimuthal_equal_area.cc deleted file mode 100644 index 951f3e571e..0000000000 --- a/src/grib_nearest_class_lambert_azimuthal_equal_area.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init - IMPLEMENTS = find;destroy - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = int lons_count - MEMBERS = double* distances - MEMBERS = int* k - MEMBERS = int* i - MEMBERS = int* j - MEMBERS = const char* Ni - MEMBERS = const char* Nj - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_lambert_azimuthal_equal_area{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in lambert_azimuthal_equal_area */ - double* lats; - int lats_count; - double* lons; - int lons_count; - double* distances; - int* k; - int* i; - int* j; - const char* Ni; - const char* Nj; -} grib_nearest_lambert_azimuthal_equal_area; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_lambert_azimuthal_equal_area = { - &grib_nearest_class_gen, /* super */ - "lambert_azimuthal_equal_area", /* name */ - sizeof(grib_nearest_lambert_azimuthal_equal_area), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_lambert_azimuthal_equal_area = &_grib_nearest_class_lambert_azimuthal_equal_area; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_lambert_azimuthal_equal_area* self = (grib_nearest_lambert_azimuthal_equal_area*)nearest; - self->Ni = grib_arguments_get_name(h, args, self->cargs++); - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->i = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - self->j = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - return 0; -} - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_nearest_lambert_azimuthal_equal_area* self = (grib_nearest_lambert_azimuthal_equal_area*)nearest; - return grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, /* inputs */ - - self->values_key, /* outputs to set the 'self' object */ - &(self->lats), - &(self->lats_count), - &(self->lons), - &(self->lons_count), - &(self->distances), - - outlats, outlons, /* outputs of the find function */ - values, distances, indexes, len); -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_lambert_azimuthal_equal_area* self = (grib_nearest_lambert_azimuthal_equal_area*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->i) grib_context_free(c, self->i); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class_lambert_conformal.cc b/src/grib_nearest_class_lambert_conformal.cc deleted file mode 100644 index 9f96c64894..0000000000 --- a/src/grib_nearest_class_lambert_conformal.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init - IMPLEMENTS = find;destroy - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = int lons_count - MEMBERS = double* distances - MEMBERS = int* k - MEMBERS = int* i - MEMBERS = int* j - MEMBERS = const char* Ni - MEMBERS = const char* Nj - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_lambert_conformal{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in lambert_conformal */ - double* lats; - int lats_count; - double* lons; - int lons_count; - double* distances; - int* k; - int* i; - int* j; - const char* Ni; - const char* Nj; -} grib_nearest_lambert_conformal; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_lambert_conformal = { - &grib_nearest_class_gen, /* super */ - "lambert_conformal", /* name */ - sizeof(grib_nearest_lambert_conformal), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_lambert_conformal = &_grib_nearest_class_lambert_conformal; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_lambert_conformal* self = (grib_nearest_lambert_conformal*)nearest; - self->Ni = grib_arguments_get_name(h, args, self->cargs++); - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->i = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - self->j = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - return 0; -} - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_nearest_lambert_conformal* self = (grib_nearest_lambert_conformal*)nearest; - return grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, /* inputs */ - - self->values_key, /* outputs to set the 'self' object */ - &(self->lats), - &(self->lats_count), - &(self->lons), - &(self->lons_count), - &(self->distances), - - outlats, outlons, /* outputs of the find function */ - values, distances, indexes, len); -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_lambert_conformal* self = (grib_nearest_lambert_conformal*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->i) grib_context_free(c, self->i); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class_latlon_reduced.cc b/src/grib_nearest_class_latlon_reduced.cc deleted file mode 100644 index ad07f3816e..0000000000 --- a/src/grib_nearest_class_latlon_reduced.cc +++ /dev/null @@ -1,436 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init;destroy;find - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = double* distances - MEMBERS = size_t* k - MEMBERS = size_t* j - MEMBERS = const char* Nj - MEMBERS = const char* pl - MEMBERS = const char* lonFirst - MEMBERS = const char* lonLast - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_latlon_reduced{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in latlon_reduced */ - double* lats; - int lats_count; - double* lons; - double* distances; - size_t* k; - size_t* j; - const char* Nj; - const char* pl; - const char* lonFirst; - const char* lonLast; -} grib_nearest_latlon_reduced; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_latlon_reduced = { - &grib_nearest_class_gen, /* super */ - "latlon_reduced", /* name */ - sizeof(grib_nearest_latlon_reduced), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_latlon_reduced = &_grib_nearest_class_latlon_reduced; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_latlon_reduced* self = (grib_nearest_latlon_reduced*)nearest; - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->pl = grib_arguments_get_name(h, args, self->cargs++); - self->lonFirst = grib_arguments_get_name(h, args, self->cargs++); - self->lonLast = grib_arguments_get_name(h, args, self->cargs++); - self->j = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); - if (!self->j) - return GRIB_OUT_OF_MEMORY; - self->k = (size_t*)grib_context_malloc(h->context, 4 * sizeof(size_t)); - if (!self->k) - return GRIB_OUT_OF_MEMORY; - - return 0; -} - -static int find_global(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, double* values, - double* distances, int* indexes, size_t* len); - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, double* values, - double* distances, int* indexes, size_t* len) -{ - int err = 0; - grib_nearest_latlon_reduced* self = (grib_nearest_latlon_reduced*)nearest; - double lat1, lat2, lon1, lon2; - int is_global = 1; - - if (grib_get_double(h, "longitudeFirstInDegrees", &lon1) == GRIB_SUCCESS && - grib_get_double(h, "longitudeLastInDegrees", &lon2) == GRIB_SUCCESS && - grib_get_double(h, "latitudeFirstInDegrees", &lat1) == GRIB_SUCCESS && - grib_get_double(h, "latitudeLastInDegrees", &lat2) == GRIB_SUCCESS) - { - const double difflat = fabs(lat1-lat2); - if (difflat < 180 || lon1 != 0 || lon2 < 359) { - is_global = 0; /* subarea */ - } - } - - if (is_global) { - err = find_global(nearest, h, inlat, inlon, flags, - outlats, outlons, values, - distances, indexes, len); - } - else - { - int lons_count = 0; /*dummy*/ - err = grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, - self->values_key, - &(self->lats), - &(self->lats_count), - &(self->lons), - &(lons_count), - &(self->distances), - outlats, outlons, - values, distances, indexes, len); - } - return err; -} - -static int find_global(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, double* values, - double* distances, int* indexes, size_t* len) -{ - grib_nearest_latlon_reduced* self = (grib_nearest_latlon_reduced*)nearest; - int ret = 0, kk = 0, ii = 0, jj = 0; - int j = 0; - long* pla = NULL; - long* pl = NULL; - size_t nvalues = 0; - grib_iterator* iter = NULL; - double lat = 0, lon = 0; - double radiusInKm; - int ilat = 0, ilon = 0; - - if ((ret = grib_get_size(h, self->values_key, &nvalues)) != GRIB_SUCCESS) - return ret; - nearest->values_count = nvalues; - - if ((ret = grib_nearest_get_radius(h, &radiusInKm)) != GRIB_SUCCESS) - return ret; - - /* Compute lat/lon info, create iterator etc if it's the 1st time or different grid. - * This is for performance: if the grid has not changed, we only do this once - * and reuse for other messages */ - if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID) == 0) { - double olat = 1.e10; - long n = 0; - - ilat = 0; - ilon = 0; - if (grib_is_missing(h, self->Nj, &ret)) { - grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", self->Nj); - return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; - } - - if ((ret = grib_get_long(h, self->Nj, &n)) != GRIB_SUCCESS) - return ret; - self->lats_count = n; - - if (self->lats) - grib_context_free(h->context, self->lats); - self->lats = (double*)grib_context_malloc(h->context, - self->lats_count * sizeof(double)); - if (!self->lats) - return GRIB_OUT_OF_MEMORY; - - if (self->lons) - grib_context_free(h->context, self->lons); - self->lons = (double*)grib_context_malloc(h->context, - nearest->values_count * sizeof(double)); - if (!self->lons) - return GRIB_OUT_OF_MEMORY; - - iter = grib_iterator_new(h, GRIB_GEOITERATOR_NO_VALUES, &ret); - if (ret) { - grib_context_log(h->context, GRIB_LOG_ERROR, "Unable to create iterator"); - return ret; - } - while (grib_iterator_next(iter, &lat, &lon, NULL)) { - if (ilat < self->lats_count && olat != lat) { - self->lats[ilat++] = lat; - olat = lat; - } - self->lons[ilon++] = lon; - } - self->lats_count = ilat; - grib_iterator_delete(iter); - } - nearest->h = h; - - /* Compute distances if it's the 1st time or different point or different grid. - * This is for performance: if the grid and the input point have not changed - * we only do this once and reuse for other messages */ - if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT) == 0 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { - double* lons = NULL; - int nlon = 0; - size_t plsize = 0; - long nplm1 = 0; - int nearest_lons_found = 0; - double lon_first, lon_last; - int islocal = 0; - long plmax; - double dimin; - - if ((ret = grib_get_double(h, self->lonFirst, &lon_first)) != GRIB_SUCCESS) { - grib_context_log(h->context, GRIB_LOG_ERROR, - "grib_nearest_latlon_reduced.find(): unable to get %s %s\n", self->lonFirst, - grib_get_error_message(ret)); - return ret; - } - if ((ret = grib_get_double(h, self->lonLast, &lon_last)) != GRIB_SUCCESS) { - grib_context_log(h->context, GRIB_LOG_ERROR, - "grib_nearest_latlon_reduced.find(): unable to get %s %s\n", self->lonLast, - grib_get_error_message(ret)); - return ret; - } - - plsize = self->lats_count; - if ((ret = grib_get_size(h, self->pl, &plsize)) != GRIB_SUCCESS) - return ret; - pla = (long*)grib_context_malloc(h->context, plsize * sizeof(long)); - if (!pla) - return GRIB_OUT_OF_MEMORY; - if ((ret = grib_get_long_array(h, self->pl, pla, &plsize)) != GRIB_SUCCESS) - return ret; - - pl = pla; - while ((*pl) == 0) { - pl++; - } - - plmax = pla[0]; - for (j = 0; j < plsize; j++) - if (plmax < pla[j]) - plmax = pla[j]; - dimin = 360.0 / plmax; - - if (360 - fabs(lon_last - lon_first) < 2 * dimin) { - islocal = 0; - } - else { - islocal = 1; - } - - if (islocal) - for (j = 0; j < plsize; j++) - pla[j]--; - - /* printf("XXXX islocal=%d\n",islocal); */ - while (inlon < 0) - inlon += 360; - while (inlon > 360) - inlon -= 360; - - ilat = self->lats_count; - if (self->lats[ilat - 1] > self->lats[0]) { - if (inlat < self->lats[0] || inlat > self->lats[ilat - 1]) - return GRIB_OUT_OF_AREA; - } - else { - if (inlat > self->lats[0] || inlat < self->lats[ilat - 1]) - return GRIB_OUT_OF_AREA; - } - - if (!self->distances) - self->distances = (double*)grib_context_malloc(h->context, 4 * sizeof(double)); - if (!self->distances) - return GRIB_OUT_OF_MEMORY; - - grib_binary_search(self->lats, ilat - 1, inlat, - &(self->j[0]), &(self->j[1])); - - nlon = 0; - for (jj = 0; jj < self->j[0]; jj++) - nlon += pl[jj]; - nplm1 = pl[self->j[0]] - 1; - - lons = self->lons + nlon; - - nearest_lons_found = 0; - if (lons[nplm1] > lons[0]) { - if (inlon < lons[0] || inlon > lons[nplm1]) { - if (lons[nplm1] - lons[0] - 360 <= - lons[nplm1] - lons[nplm1 - 1]) { - self->k[0] = 0; - self->k[1] = nplm1; - nearest_lons_found = 1; - } - else - return GRIB_OUT_OF_AREA; - } - } - else { - if (inlon > lons[0] || inlon < lons[nplm1]) { - if (lons[0] - lons[nplm1] - 360 <= - lons[0] - lons[1]) { - self->k[0] = 0; - self->k[1] = nplm1; - nearest_lons_found = 1; - } - else - return GRIB_OUT_OF_AREA; - } - } - - if (!nearest_lons_found) { - grib_binary_search(lons, pl[self->j[0]] - 1, inlon, - &(self->k[0]), &(self->k[1])); - } - self->k[0] += nlon; - self->k[1] += nlon; - - nlon = 0; - for (jj = 0; jj < self->j[1]; jj++) - nlon += pl[jj]; - nplm1 = pl[self->j[1]] - 1; - - lons = self->lons + nlon; - - nearest_lons_found = 0; - if (lons[nplm1] > lons[0]) { - if (inlon < lons[0] || inlon > lons[nplm1]) { - if (lons[nplm1] - lons[0] - 360 <= - lons[nplm1] - lons[nplm1 - 1]) { - self->k[2] = 0; - self->k[3] = nplm1; - nearest_lons_found = 1; - } - else - return GRIB_OUT_OF_AREA; - } - } - else { - if (inlon > lons[0] || inlon < lons[nplm1]) { - if (lons[0] - lons[nplm1] - 360 <= - lons[0] - lons[1]) { - self->k[2] = 0; - self->k[3] = nplm1; - nearest_lons_found = 1; - } - else - return GRIB_OUT_OF_AREA; - } - } - - if (!nearest_lons_found) { - grib_binary_search(lons, pl[self->j[1]] - 1, inlon, - &(self->k[2]), &(self->k[3])); - } - - self->k[2] += nlon; - self->k[3] += nlon; - - kk = 0; - for (jj = 0; jj < 2; jj++) { - for (ii = 0; ii < 2; ii++) { - self->distances[kk] = geographic_distance_spherical(radiusInKm, inlon, inlat, - self->lons[self->k[kk]], self->lats[self->j[jj]]); - kk++; - } - } - - grib_context_free(h->context, pla); - } - - kk = 0; - for (jj = 0; jj < 2; jj++) { - for (ii = 0; ii < 2; ii++) { - distances[kk] = self->distances[kk]; - outlats[kk] = self->lats[self->j[jj]]; - outlons[kk] = self->lons[self->k[kk]]; - if (values) { /* ECC-499 */ - grib_get_double_element_internal(h, self->values_key, self->k[kk], &(values[kk])); - } - indexes[kk] = (int)self->k[kk]; - kk++; - } - } - - return GRIB_SUCCESS; -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_latlon_reduced* self = (grib_nearest_latlon_reduced*)nearest; - grib_context* c = grib_context_get_default(); - if (self->lats) - grib_context_free(c, self->lats); - if (self->lons) - grib_context_free(c, self->lons); - if (self->j) - grib_context_free(c, self->j); - if (self->k) - grib_context_free(c, self->k); - if (self->distances) - grib_context_free(c, self->distances); - - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class_mercator.cc b/src/grib_nearest_class_mercator.cc deleted file mode 100644 index a160d9dfb5..0000000000 --- a/src/grib_nearest_class_mercator.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init - IMPLEMENTS = find;destroy - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = int lons_count - MEMBERS = double* distances - MEMBERS = int* k - MEMBERS = int* i - MEMBERS = int* j - MEMBERS = const char* Ni - MEMBERS = const char* Nj - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_mercator{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in mercator */ - double* lats; - int lats_count; - double* lons; - int lons_count; - double* distances; - int* k; - int* i; - int* j; - const char* Ni; - const char* Nj; -} grib_nearest_mercator; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_mercator = { - &grib_nearest_class_gen, /* super */ - "mercator", /* name */ - sizeof(grib_nearest_mercator), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_mercator = &_grib_nearest_class_mercator; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_mercator* self = (grib_nearest_mercator*)nearest; - self->Ni = grib_arguments_get_name(h, args, self->cargs++); - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->lats = self->lons = self->distances = NULL; - self->lats_count = self->lons_count = 0; - self->i = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - self->j = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - return GRIB_SUCCESS; -} - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_nearest_mercator* self = (grib_nearest_mercator*)nearest; - return grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, /* inputs */ - - self->values_key, /* outputs to set the 'self' object */ - &(self->lats), - &(self->lats_count), - &(self->lons), - &(self->lons_count), - &(self->distances), - - outlats, outlons, /* outputs of the find function */ - values, distances, indexes, len); -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_mercator* self = (grib_nearest_mercator*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->i) grib_context_free(c, self->i); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class_polar_stereographic.cc b/src/grib_nearest_class_polar_stereographic.cc deleted file mode 100644 index 7f04e4ef84..0000000000 --- a/src/grib_nearest_class_polar_stereographic.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init - IMPLEMENTS = find;destroy - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = int lons_count - MEMBERS = double* distances - MEMBERS = int* k - MEMBERS = int* i - MEMBERS = int* j - MEMBERS = const char* Ni - MEMBERS = const char* Nj - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_polar_stereographic{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in polar_stereographic */ - double* lats; - int lats_count; - double* lons; - int lons_count; - double* distances; - int* k; - int* i; - int* j; - const char* Ni; - const char* Nj; -} grib_nearest_polar_stereographic; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_polar_stereographic = { - &grib_nearest_class_gen, /* super */ - "polar_stereographic", /* name */ - sizeof(grib_nearest_polar_stereographic), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_polar_stereographic = &_grib_nearest_class_polar_stereographic; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_polar_stereographic* self = (grib_nearest_polar_stereographic*)nearest; - self->Ni = grib_arguments_get_name(h, args, self->cargs++); - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->i = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - self->j = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - return GRIB_SUCCESS; -} - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_nearest_polar_stereographic* self = (grib_nearest_polar_stereographic*)nearest; - return grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, /* inputs */ - - self->values_key, /* outputs to set the 'self' object */ - &(self->lats), - &(self->lats_count), - &(self->lons), - &(self->lons_count), - &(self->distances), - - outlats, outlons, /* outputs of the find function */ - values, distances, indexes, len); -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_polar_stereographic* self = (grib_nearest_polar_stereographic*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->i) grib_context_free(c, self->i); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class_regular.cc b/src/grib_nearest_class_regular.cc deleted file mode 100644 index 5d591a6e3f..0000000000 --- a/src/grib_nearest_class_regular.cc +++ /dev/null @@ -1,373 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init - IMPLEMENTS = find;destroy - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = int lons_count - MEMBERS = double* distances - MEMBERS = size_t* k - MEMBERS = size_t* i - MEMBERS = size_t* j - MEMBERS = const char* Ni - MEMBERS = const char* Nj - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_regular{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in regular */ - double* lats; - int lats_count; - double* lons; - int lons_count; - double* distances; - size_t* k; - size_t* i; - size_t* j; - const char* Ni; - const char* Nj; -} grib_nearest_regular; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_regular = { - &grib_nearest_class_gen, /* super */ - "regular", /* name */ - sizeof(grib_nearest_regular), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_regular = &_grib_nearest_class_regular; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - - -#define NUM_NEIGHBOURS 4 - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_regular* self = (grib_nearest_regular*)nearest; - self->Ni = grib_arguments_get_name(h, args, self->cargs++); - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->i = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); - self->j = (size_t*)grib_context_malloc(h->context, 2 * sizeof(size_t)); - return 0; -} - -static bool is_rotated_grid(grib_handle* h) -{ - long is_rotated = 0; - int err = grib_get_long(h, "isRotatedGrid", &is_rotated); - if (!err && is_rotated) - return true; - return false; -} - -// Old implementation in -// src/deprecated/grib_nearest_class_regular.cc -// -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_nearest_regular* self = (grib_nearest_regular*)nearest; - int ret = 0, kk = 0, ii = 0, jj = 0; - size_t nvalues = 0; - double radiusInKm; - - grib_iterator* iter = NULL; - double lat = 0, lon = 0; - const bool is_rotated = is_rotated_grid(h); - double angleOfRotation = 0, southPoleLat = 0, southPoleLon = 0; - grib_context* c = h->context; - - while (inlon < 0) - inlon += 360; - while (inlon > 360) - inlon -= 360; - - if ((ret = grib_get_size(h, self->values_key, &nvalues)) != GRIB_SUCCESS) - return ret; - nearest->values_count = nvalues; - - if ((ret = grib_nearest_get_radius(h, &radiusInKm)) != GRIB_SUCCESS) - return ret; - - /* Compute lat/lon info, create iterator etc if it's the 1st time or different grid. - * This is for performance: if the grid has not changed, we only do this once - * and reuse for other messages */ - if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID) == 0) { - double olat = 1.e10, olon = 1.e10; - int ilat = 0, ilon = 0; - long n = 0; - - if (grib_is_missing(h, self->Ni, &ret)) { - grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", self->Ni); - return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; - } - - if (grib_is_missing(h, self->Nj, &ret)) { - grib_context_log(h->context, GRIB_LOG_DEBUG, "Key '%s' is missing", self->Nj); - return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; - } - - /* ECC-600: Support for rotated grids - * First: rotate the input point - * Then: run the lat/lon iterator over the rotated grid (disableUnrotate) - * Finally: unrotate the resulting point - */ - if (is_rotated) { - double new_lat = 0, new_lon = 0; - ret = grib_get_double_internal(h, "angleOfRotation", &angleOfRotation); - if (ret) - return ret; - ret = grib_get_double_internal(h, "latitudeOfSouthernPoleInDegrees", &southPoleLat); - if (ret) - return ret; - ret = grib_get_double_internal(h, "longitudeOfSouthernPoleInDegrees", &southPoleLon); - if (ret) - return ret; - ret = grib_set_long(h, "iteratorDisableUnrotate", 1); - if (ret) - return ret; - /* Rotate the inlat, inlon */ - rotate(inlat, inlon, angleOfRotation, southPoleLat, southPoleLon, &new_lat, &new_lon); - inlat = new_lat; - inlon = new_lon; - /*if(h->context->debug) printf("nearest find: rotated grid: new point=(%g,%g)\n",new_lat,new_lon);*/ - } - - if ((ret = grib_get_long(h, self->Ni, &n)) != GRIB_SUCCESS) - return ret; - self->lons_count = n; - - if ((ret = grib_get_long(h, self->Nj, &n)) != GRIB_SUCCESS) - return ret; - self->lats_count = n; - - if (self->lats) - grib_context_free(c, self->lats); - self->lats = (double*)grib_context_malloc(c, self->lats_count * sizeof(double)); - if (!self->lats) - return GRIB_OUT_OF_MEMORY; - - if (self->lons) - grib_context_free(c, self->lons); - self->lons = (double*)grib_context_malloc(c, self->lons_count * sizeof(double)); - if (!self->lons) - return GRIB_OUT_OF_MEMORY; - - iter = grib_iterator_new(h, GRIB_GEOITERATOR_NO_VALUES, &ret); - if (ret != GRIB_SUCCESS) { - grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_regular: Unable to create lat/lon iterator"); - return ret; - } - while (grib_iterator_next(iter, &lat, &lon, NULL)) { - if (ilat < self->lats_count && olat != lat) { - self->lats[ilat++] = lat; - olat = lat; - } - if (ilon < self->lons_count && olon != lon) { - self->lons[ilon++] = lon; - olon = lon; - } - } - grib_iterator_delete(iter); - } - nearest->h = h; - - /* Compute distances if it's the 1st time or different point or different grid. - * This is for performance: if the grid and the input point have not changed - * we only do this once and reuse for other messages */ - if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT) == 0 || (flags & GRIB_NEAREST_SAME_GRID) == 0) { - int nearest_lons_found = 0; - - if (self->lats[self->lats_count - 1] > self->lats[0]) { - if (inlat < self->lats[0] || inlat > self->lats[self->lats_count - 1]) - return GRIB_OUT_OF_AREA; - } - else { - if (inlat > self->lats[0] || inlat < self->lats[self->lats_count - 1]) - return GRIB_OUT_OF_AREA; - } - - if (self->lons[self->lons_count - 1] > self->lons[0]) { - if (inlon < self->lons[0] || inlon > self->lons[self->lons_count - 1]) { - /* try to scale*/ - if (inlon > 0) - inlon -= 360; - else - inlon += 360; - - if (inlon < self->lons[0] || inlon > self->lons[self->lons_count - 1]) { - if (self->lons[0] + 360 - self->lons[self->lons_count - 1] <= - self->lons[1] - self->lons[0]) { - /*it's a global field in longitude*/ - self->i[0] = 0; - self->i[1] = self->lons_count - 1; - nearest_lons_found = 1; - } - else - return GRIB_OUT_OF_AREA; - } - } - } - else { - if (inlon > self->lons[0] || inlon < self->lons[self->lons_count - 1]) { - /* try to scale*/ - if (inlon > 0) - inlon -= 360; - else - inlon += 360; - if (self->lons[0] - self->lons[self->lons_count - 1] - 360 <= - self->lons[0] - self->lons[1]) { - /*it's a global field in longitude*/ - self->i[0] = 0; - self->i[1] = self->lons_count - 1; - nearest_lons_found = 1; - } - else if (inlon > self->lons[0] || inlon < self->lons[self->lons_count - 1]) - return GRIB_OUT_OF_AREA; - } - } - - grib_binary_search(self->lats, self->lats_count - 1, inlat, - &(self->j[0]), &(self->j[1])); - - if (!nearest_lons_found) - grib_binary_search(self->lons, self->lons_count - 1, inlon, - &(self->i[0]), &(self->i[1])); - - if (!self->distances) - self->distances = (double*)grib_context_malloc(c, NUM_NEIGHBOURS * sizeof(double)); - if (!self->k) - self->k = (size_t*)grib_context_malloc(c, NUM_NEIGHBOURS * sizeof(size_t)); - kk = 0; - for (jj = 0; jj < 2; jj++) { - for (ii = 0; ii < 2; ii++) { - self->k[kk] = self->i[ii] + self->lons_count * self->j[jj]; - self->distances[kk] = geographic_distance_spherical(radiusInKm, inlon, inlat, - self->lons[self->i[ii]], self->lats[self->j[jj]]); - kk++; - } - } - } - - kk = 0; - - /* - * Brute force algorithm: - * First unpack all the values into an array. Then when we need the 4 points - * we just index into this array so no need to call grib_get_double_element_internal - * - * if (nearest->values) grib_context_free(c,nearest->values); - * nearest->values = grib_context_malloc(h->context,nvalues*sizeof(double)); - * if (!nearest->values) return GRIB_OUT_OF_MEMORY; - * ret = grib_get_double_array(h, self->values_key, nearest->values ,&nvalues); - * if (ret) return ret; - */ - - if (values) { - /* See ECC-1403 and ECC-499 */ - /* Performance: Decode the field once and get all 4 values */ - if ((ret = grib_get_double_element_set(h, self->values_key, self->k, NUM_NEIGHBOURS, values)) != GRIB_SUCCESS) - return ret; - } - - for (jj = 0; jj < 2; jj++) { - for (ii = 0; ii < 2; ii++) { - distances[kk] = self->distances[kk]; - outlats[kk] = self->lats[self->j[jj]]; - outlons[kk] = self->lons[self->i[ii]]; - if (is_rotated) { - /* Unrotate resulting lat/lon */ - double new_lat = 0, new_lon = 0; - unrotate(outlats[kk], outlons[kk], angleOfRotation, southPoleLat, southPoleLon, &new_lat, &new_lon); - outlats[kk] = new_lat; - outlons[kk] = new_lon; - } - /* See ECC-1403 and ECC-499 - * if (values) { - * grib_get_double_element_internal(h, self->values_key, self->k[kk], &(values[kk])); - *} - */ - /* Using the brute force approach described above */ - /* Assert(self->k[kk] < nvalues); */ - /* values[kk]=nearest->values[self->k[kk]]; */ - - if (self->k[kk] >= INT_MAX) { - /* Current interface uses an 'int' for 'indexes' which is 32bits! We should change this to a 64bit type */ - grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_regular: Unable to compute index. Value too large"); - return GRIB_OUT_OF_RANGE; - } else { - indexes[kk] = (int)self->k[kk]; - } - kk++; - } - } - - return GRIB_SUCCESS; -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_regular* self = (grib_nearest_regular*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->i) grib_context_free(c, self->i); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class_space_view.cc b/src/grib_nearest_class_space_view.cc deleted file mode 100644 index ccba897b98..0000000000 --- a/src/grib_nearest_class_space_view.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * (C) Copyright 2005- ECMWF. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - * - * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by - * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. - */ - -#include "grib_api_internal.h" - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = nearest - SUPER = grib_nearest_class_gen - IMPLEMENTS = init - IMPLEMENTS = find;destroy - MEMBERS = double* lats - MEMBERS = int lats_count - MEMBERS = double* lons - MEMBERS = int lons_count - MEMBERS = double* distances - MEMBERS = int* k - MEMBERS = int* i - MEMBERS = int* j - MEMBERS = const char* Ni - MEMBERS = const char* Nj - END_CLASS_DEF - - */ - -/* START_CLASS_IMP */ - -/* - -Don't edit anything between START_CLASS_IMP and END_CLASS_IMP -Instead edit values between START_CLASS_DEF and END_CLASS_DEF -or edit "nearest.class" and rerun ./make_class.pl - -*/ - - -static void init_class (grib_nearest_class*); - -static int init (grib_nearest* nearest,grib_handle* h,grib_arguments* args); -static int find(grib_nearest* nearest, grib_handle* h,double inlat, double inlon, unsigned long flags, double* outlats,double* outlons, double *values,double *distances, int *indexes,size_t *len); -static int destroy (grib_nearest* nearest); - -typedef struct grib_nearest_space_view{ - grib_nearest nearest; - /* Members defined in gen */ - const char* values_key; - const char* radius; - int cargs; - /* Members defined in space_view */ - double* lats; - int lats_count; - double* lons; - int lons_count; - double* distances; - int* k; - int* i; - int* j; - const char* Ni; - const char* Nj; -} grib_nearest_space_view; - -extern grib_nearest_class* grib_nearest_class_gen; - -static grib_nearest_class _grib_nearest_class_space_view = { - &grib_nearest_class_gen, /* super */ - "space_view", /* name */ - sizeof(grib_nearest_space_view), /* size of instance */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* constructor */ - &destroy, /* destructor */ - &find, /* find nearest */ -}; - -grib_nearest_class* grib_nearest_class_space_view = &_grib_nearest_class_space_view; - - -static void init_class(grib_nearest_class* c) -{ -} -/* END_CLASS_IMP */ - -static int init(grib_nearest* nearest, grib_handle* h, grib_arguments* args) -{ - grib_nearest_space_view* self = (grib_nearest_space_view*)nearest; - self->Ni = grib_arguments_get_name(h, args, self->cargs++); - self->Nj = grib_arguments_get_name(h, args, self->cargs++); - self->i = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - self->j = (int*)grib_context_malloc(h->context, 2 * sizeof(int)); - return 0; -} - -static int find(grib_nearest* nearest, grib_handle* h, - double inlat, double inlon, unsigned long flags, - double* outlats, double* outlons, - double* values, double* distances, int* indexes, size_t* len) -{ - grib_nearest_space_view* self = (grib_nearest_space_view*)nearest; - return grib_nearest_find_generic( - nearest, h, inlat, inlon, flags, /* inputs */ - - self->values_key, /* outputs to set the 'self' object */ - &(self->lats), - &(self->lats_count), - &(self->lons), - &(self->lons_count), - &(self->distances), - - outlats, outlons, /* outputs of the find function */ - values, distances, indexes, len); -} - -static int destroy(grib_nearest* nearest) -{ - grib_nearest_space_view* self = (grib_nearest_space_view*)nearest; - grib_context* c = grib_context_get_default(); - - if (self->lats) grib_context_free(c, self->lats); - if (self->lons) grib_context_free(c, self->lons); - if (self->i) grib_context_free(c, self->i); - if (self->j) grib_context_free(c, self->j); - if (self->k) grib_context_free(c, self->k); - if (self->distances) grib_context_free(c, self->distances); - return GRIB_SUCCESS; -} diff --git a/src/grib_nearest_class.cc b/src/grib_nearest_factory.cc similarity index 57% rename from src/grib_nearest_class.cc rename to src/grib_nearest_factory.cc index 8128e844e2..6babc985c1 100644 --- a/src/grib_nearest_class.cc +++ b/src/grib_nearest_factory.cc @@ -8,23 +8,28 @@ * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ -#include "grib_api_internal.h" - -/* This file is generated by ./make_class.pl */ -#include "grib_nearest_class.h" +#include "grib_nearest_factory.h" +#include "accessor/grib_accessor_class_nearest.h" struct table_entry { const char* type; - grib_nearest_class** cclass; + eccodes::geo_nearest::Nearest** nearest; }; static const struct table_entry table[] = { -/* This file is generated by ./make_class.pl */ -#include "grib_nearest_factory.h" + { "healpix", &grib_nearest_healpix, }, + { "lambert_azimuthal_equal_area", &grib_nearest_lambert_azimuthal_equal_area, }, + { "lambert_conformal", &grib_nearest_lambert_conformal, }, + { "latlon_reduced", &grib_nearest_latlon_reduced, }, + { "mercator", &grib_nearest_mercator, }, + { "polar_stereographic", &grib_nearest_polar_stereographic, }, + { "reduced", &grib_nearest_reduced, }, + { "regular", &grib_nearest_regular, }, + { "space_view", &grib_nearest_space_view, }, }; -grib_nearest* grib_nearest_factory(grib_handle* h, grib_arguments* args, int* error) +eccodes::geo_nearest::Nearest* grib_nearest_factory(grib_handle* h, grib_arguments* args, int* error) { size_t i = 0, num_table_entries = 0; *error = GRIB_NOT_IMPLEMENTED; @@ -33,15 +38,16 @@ grib_nearest* grib_nearest_factory(grib_handle* h, grib_arguments* args, int* er num_table_entries = sizeof(table) / sizeof(table[0]); for (i = 0; i < num_table_entries; i++) { if (strcmp(type, table[i].type) == 0) { - grib_nearest_class* c = *(table[i].cclass); - grib_nearest* it = (grib_nearest*)grib_context_malloc_clear(h->context, c->size); - it->cclass = c; - *error = grib_nearest_init(it, h, args); + eccodes::geo_nearest::Nearest* creator = *(table[i].nearest); + eccodes::geo_nearest::Nearest* it = creator->create(); + + *error = it->init(h, args); + if (*error == GRIB_SUCCESS) return it; grib_context_log(h->context, GRIB_LOG_ERROR, "grib_nearest_factory: Error instantiating nearest %s (%s)", table[i].type, grib_get_error_message(*error)); - grib_nearest_delete(it); + gribNearestDelete(it); return NULL; } } diff --git a/src/grib_nearest_factory.h b/src/grib_nearest_factory.h index 8375249146..658abff30a 100644 --- a/src/grib_nearest_factory.h +++ b/src/grib_nearest_factory.h @@ -1,11 +1,26 @@ -/* This file is automatically generated by ./make_class.pl, do not edit */ -{ "gen", &grib_nearest_class_gen, }, -{ "healpix", &grib_nearest_class_healpix, }, -{ "lambert_azimuthal_equal_area", &grib_nearest_class_lambert_azimuthal_equal_area, }, -{ "lambert_conformal", &grib_nearest_class_lambert_conformal, }, -{ "latlon_reduced", &grib_nearest_class_latlon_reduced, }, -{ "mercator", &grib_nearest_class_mercator, }, -{ "polar_stereographic", &grib_nearest_class_polar_stereographic, }, -{ "reduced", &grib_nearest_class_reduced, }, -{ "regular", &grib_nearest_class_regular, }, -{ "space_view", &grib_nearest_class_space_view, }, +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#pragma once + +#include "grib_api_internal.h" +#include "geo_nearest/grib_nearest.h" + +extern eccodes::geo_nearest::Nearest* grib_nearest_healpix; +extern eccodes::geo_nearest::Nearest* grib_nearest_lambert_azimuthal_equal_area; +extern eccodes::geo_nearest::Nearest* grib_nearest_lambert_conformal; +extern eccodes::geo_nearest::Nearest* grib_nearest_latlon_reduced; +extern eccodes::geo_nearest::Nearest* grib_nearest_mercator; +extern eccodes::geo_nearest::Nearest* grib_nearest_polar_stereographic; +extern eccodes::geo_nearest::Nearest* grib_nearest_reduced; +extern eccodes::geo_nearest::Nearest* grib_nearest_regular; +extern eccodes::geo_nearest::Nearest* grib_nearest_space_view; + +eccodes::geo_nearest::Nearest* grib_nearest_factory(grib_handle* h, grib_arguments* args, int* error); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fa685fd447..87fa0c8d45 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -258,6 +258,7 @@ if( HAVE_BUILD_TOOLS ) bufr_ecc-1476 bufr_ecc-1623 bufr_ecc-1785 + bufr_ecc-1938 grib_ecc-490 grib_ecc-756 grib_ecc-806 diff --git a/tests/bufr_ecc-1938.sh b/tests/bufr_ecc-1938.sh new file mode 100755 index 0000000000..29eba16e07 --- /dev/null +++ b/tests/bufr_ecc-1938.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# (C) Copyright 2005- ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# +# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by +# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. +# + +. ./include.ctest.sh + +label="bufr_ecc-1938_test" + +tempBufr=temp.$label.bufr +tempLog=temp.$label.log +tempOut=temp.$label.txt + +# This has 2 unreadable messages +infile=${data_dir}/bufr/bad.bufr +if [ -f "$infile" ]; then + count=$( ${tools_dir}/bufr_count -f $infile ) + [ $count -eq 24 ] + set +e + ${tools_dir}/bufr_copy $infile $tempBufr + status=$? + set -e + [ $status -ne 0 ] + count=$( ${tools_dir}/bufr_count $tempBufr ) + [ $count -eq 24 ] +fi + +# Clean up +rm -f $tempBufr $tempLog $tempOut diff --git a/tests/grib2_product_templates.sh b/tests/grib2_product_templates.sh index 579592462d..60836df316 100755 --- a/tests/grib2_product_templates.sh +++ b/tests/grib2_product_templates.sh @@ -74,14 +74,13 @@ grib_check_key_equals $tempGribA productDefinitionTemplateNumber 8 grib_check_key_equals $tempGribA typeOfStatisticalProcessing,stepType '2 max' grib_check_key_equals $tempGribA shortName,name 'max_visp Time-maximum visibility through precipitation' -# Test an expected failure. paramId=140114 contains wave keys +# Test an expected failure, e.g., paramId=239375 has constituentType set +e -$tools_dir/grib_set -s paramId=140114 $sample_g2 $tempGribA 2>$tempText +$tools_dir/grib_set -s paramId=239375 $sample_g2 $tempGribA 2>$tempText status=$? set -e [ $status -ne 0 ] -grep -q "typeOfWavePeriodInterval .* failed: Key/value not found" $tempText -grep -q "scaleFactorOfLowerWavePeriodLimit .* failed: Key/value not found" $tempText +grep -q "constituentType .* failed: Key/value not found" $tempText # Clean up diff --git a/tests/grib_check_param_concepts.sh b/tests/grib_check_param_concepts.sh index fd112b4d3b..77f5ecc228 100755 --- a/tests/grib_check_param_concepts.sh +++ b/tests/grib_check_param_concepts.sh @@ -53,6 +53,18 @@ for paramIdFile in $paramIdFiles; do fi done + +# ----------------------------------- +echo "Check for bad shortNames" +# ----------------------------------- +shortNameFile="$ECCODES_DEFINITION_PATH/grib2/shortName.def" +grep "^'.*=" $shortNameFile | sed -e 's/ = {//' > $tempText +set +e +grep ' ' $tempText # This grep should fail. No spaces must be found +status=$? +set -e +[ $status -ne 0 ] + # First check the GRIB2 paramId.def and shortName.def # ---------------------------------------------------- $EXEC ${test_dir}/grib_check_param_concepts paramId $ECCODES_DEFINITION_PATH/grib2/paramId.def diff --git a/tests/grib_keys_iter.cc b/tests/grib_keys_iter.cc index d68977b13b..4becf79c7c 100644 --- a/tests/grib_keys_iter.cc +++ b/tests/grib_keys_iter.cc @@ -17,12 +17,11 @@ int main(int argc, char* argv[]) { - FILE* f = NULL; grib_handle* h = NULL; - int err = 0; + int err = 0; Assert(argc == 2); - f = fopen(argv[1], "rb"); + FILE* f = fopen(argv[1], "rb"); Assert(f); while ((h = grib_handle_new_from_file(0, f, &err)) != NULL) { @@ -39,6 +38,8 @@ int main(int argc, char* argv[]) int type = 0; GRIB_CHECK(grib_get_native_type(h, name, &type), 0); Assert( type > 0 && type < 7 ); + int ktype = grib_keys_iterator_get_native_type(kiter); + Assert(type == ktype); const char* type_name = grib_get_type_name(type); Assert( !STR_EQUAL(type_name, "unknown") ); printf("%s = %s (%d)\n", name, type_name, type); @@ -48,6 +49,16 @@ int main(int argc, char* argv[]) size_t vlen = MAX_VAL_LEN; GRIB_CHECK(grib_get_string(h, name, value, &vlen), name); Assert( strlen(value) > 0 ); + int e = grib_keys_iterator_get_string(kiter, value, &vlen); + Assert(!e); + Assert( STR_EQUAL(name, value) ); + } + if (STR_EQUAL(name, "editionNumber")) { + long lVal = 0; + size_t llen = 1; + int e = grib_keys_iterator_get_long(kiter, &lVal, &llen); + Assert(!e); + Assert(lVal == 1 || lVal == 2); } }