Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #2565 nccf_laea #2616

Merged
merged 13 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/jobs/build_docker_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ if [ $? != 0 ]; then
cat ${GITHUB_WORKSPACE}/docker_build.log
exit 1
fi

# Copy the log directory from the image
id=$(docker create ${DOCKERHUB_TAG})
time_command docker cp $id:/met/logs met_logs
mv met_logs/*.log ${GITHUB_WORKSPACE}/.
docker rm -v $id
4 changes: 2 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ jobs:
MET_BASE_REPO: ${{ needs.job_control.outputs.met_base_repo }}
MET_BASE_TAG: ${{ needs.job_control.outputs.met_base_tag }}

- name: Copy Docker build log into logs directory
- name: Copy all build log files into logs directory
if: always()
run: cp ${GITHUB_WORKSPACE}/docker_build.log ${RUNNER_WORKSPACE}/logs/
run: cp ${GITHUB_WORKSPACE}/*.log ${RUNNER_WORKSPACE}/logs/

- name: Push Docker Image
run: .github/jobs/push_docker_image.sh
Expand Down
4 changes: 4 additions & 0 deletions docs/Users_Guide/appendixB.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The following map projections are currently supported in MET:

* Lambert Conformal Projection

* Lambert Azimuthal Equal Area Projection

* Polar Stereographic Projection (Northern)

* Polar Stereographic Projection (Southern)
Expand Down Expand Up @@ -46,6 +48,8 @@ As an example of specifying a Lambert grid, suppose you have a northern hemisphe

To grid = "lambert 614 428 12.190 -133.459 -95.0 12.19058 6367.47 25.0 N";

For a Lambert Azimuthal Equal Area grid, grid specification strings are not supported.

For a Polar Stereographic grid, the syntax is

.. code-block:: none
Expand Down
4 changes: 0 additions & 4 deletions internal/test_unit/xml/unit_plot_data_plane.xml
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,6 @@
</output>
</test>

<!-- MET #1693 removed support for CF-Compliant LAEA grids.
MET #2565 should restore this supoprt prior to the MET-11.1.0 release.

<test name="plot_data_plane_LAEA_NCCF">
<exec>&MET_BIN;/plot_data_plane</exec>
<param> \
Expand All @@ -538,7 +535,6 @@
<ps>&OUTPUT_DIR;/plot_data_plane/air_temperature_laea_nccf.ps</ps>
</output>
</test>
-->

<test name="plot_data_plane_NCCF_POLAR_STEREO">
<exec>&MET_BIN;/plot_data_plane</exec>
Expand Down
56 changes: 28 additions & 28 deletions src/basic/vx_config/celltype_to_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
////////////////////////////////////////////////////////////////////////


#include <string.h>
using namespace std;

#include "celltype_to_string.h"

#include <string.h>

using namespace std;
#include "celltype_to_string.h"


////////////////////////////////////////////////////////////////////////
Expand All @@ -39,7 +39,7 @@ ConcatString celltype_to_string(const CellType t)

{

const char * s = (const char *) nullptr;
const char * s = (const char *) 0;

switch ( t ) {

Expand Down Expand Up @@ -73,7 +73,7 @@ switch ( t ) {
} // switch


return ConcatString (s);
return ( ConcatString (s) );

}

Expand All @@ -85,33 +85,33 @@ bool string_to_celltype(const char * text, CellType & t)

{

if ( strcmp(text, "integer" ) == 0 ) { t = integer; return true; }
else if ( strcmp(text, "floating_point" ) == 0 ) { t = floating_point; return true; }
else if ( strcmp(text, "boolean" ) == 0 ) { t = boolean; return true; }
else if ( strcmp(text, "cell_mark" ) == 0 ) { t = cell_mark; return true; }
else if ( strcmp(text, "op_add" ) == 0 ) { t = op_add; return true; }

else if ( strcmp(text, "op_multiply" ) == 0 ) { t = op_multiply; return true; }
else if ( strcmp(text, "op_divide" ) == 0 ) { t = op_divide; return true; }
else if ( strcmp(text, "op_subtract" ) == 0 ) { t = op_subtract; return true; }
else if ( strcmp(text, "op_power" ) == 0 ) { t = op_power; return true; }
else if ( strcmp(text, "op_square" ) == 0 ) { t = op_square; return true; }

else if ( strcmp(text, "op_negate" ) == 0 ) { t = op_negate; return true; }
else if ( strcmp(text, "op_store" ) == 0 ) { t = op_store; return true; }
else if ( strcmp(text, "op_recall" ) == 0 ) { t = op_recall; return true; }
else if ( strcmp(text, "identifier" ) == 0 ) { t = identifier; return true; }
else if ( strcmp(text, "user_func" ) == 0 ) { t = user_func; return true; }

else if ( strcmp(text, "builtin_func" ) == 0 ) { t = builtin_func; return true; }
else if ( strcmp(text, "local_var" ) == 0 ) { t = local_var; return true; }
else if ( strcmp(text, "character_string") == 0 ) { t = character_string; return true; }
else if ( strcmp(text, "no_cell_type" ) == 0 ) { t = no_cell_type; return true; }
if ( strcmp(text, "integer" ) == 0 ) { t = integer; return ( true ); }
else if ( strcmp(text, "floating_point" ) == 0 ) { t = floating_point; return ( true ); }
else if ( strcmp(text, "boolean" ) == 0 ) { t = boolean; return ( true ); }
else if ( strcmp(text, "cell_mark" ) == 0 ) { t = cell_mark; return ( true ); }
else if ( strcmp(text, "op_add" ) == 0 ) { t = op_add; return ( true ); }

else if ( strcmp(text, "op_multiply" ) == 0 ) { t = op_multiply; return ( true ); }
else if ( strcmp(text, "op_divide" ) == 0 ) { t = op_divide; return ( true ); }
else if ( strcmp(text, "op_subtract" ) == 0 ) { t = op_subtract; return ( true ); }
else if ( strcmp(text, "op_power" ) == 0 ) { t = op_power; return ( true ); }
else if ( strcmp(text, "op_square" ) == 0 ) { t = op_square; return ( true ); }

else if ( strcmp(text, "op_negate" ) == 0 ) { t = op_negate; return ( true ); }
else if ( strcmp(text, "op_store" ) == 0 ) { t = op_store; return ( true ); }
else if ( strcmp(text, "op_recall" ) == 0 ) { t = op_recall; return ( true ); }
else if ( strcmp(text, "identifier" ) == 0 ) { t = identifier; return ( true ); }
else if ( strcmp(text, "user_func" ) == 0 ) { t = user_func; return ( true ); }

else if ( strcmp(text, "builtin_func" ) == 0 ) { t = builtin_func; return ( true ); }
else if ( strcmp(text, "local_var" ) == 0 ) { t = local_var; return ( true ); }
else if ( strcmp(text, "character_string") == 0 ) { t = character_string; return ( true ); }
else if ( strcmp(text, "no_cell_type" ) == 0 ) { t = no_cell_type; return ( true ); }
//
// nope
//

return false;
return ( false );

}

Expand Down
149 changes: 115 additions & 34 deletions src/libcode/vx_data2d_grib2/data2d_grib2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ using namespace std;
////////////////////////////////////////////////////////////////////////

double scaled2dbl(int scale_factor, int scale_value);
int parse_int4(g2int);

////////////////////////////////////////////////////////////////////////
//
Expand Down Expand Up @@ -1294,45 +1295,101 @@ void MetGrib2DataFile::read_grib2_grid( gribfield *gfld) {
// Lambert Azimuthal Equal Area
else if ( gfld->igdtnum == 140 ) {

const g2int * p = gfld->igdtmpl;

ScanMode = p[16];
ScanMode = gfld->igdtmpl[16];

// build an LaeaGrib2Data struct with the projection information
LaeaGrib2Data laea;
// build an LaeaData struct with the projection information
LaeaData laea;
laea.name = laea_proj_type;
laea.spheroid_name = "Grib template";
int earth_shape_int = p[0];
if(earth_shape_int == 4) {
laea.radius_km = 0;
laea.equatorial_radius_km = 0.5*6378.1370;
laea.polar_radius_km = 0.5*6356.752314;
laea.is_sphere = false;
}
else {
mlog << Error << "\nMetGrib2DataFile::read_grib2_grid() -> "
<< "unsupported earth shape value of " << earth_shape_int << "!\n\n";
exit(1);

// earth shape
// Reference: https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml
int earth_shape_int = gfld->igdtmpl[0];
switch(earth_shape_int){
case 0:
laea.radius_km = 6367.47;
laea.equatorial_radius_km = 0;
laea.polar_radius_km = 0;
laea.is_sphere = true;
break;

case 1:
laea.radius_km = scaled2dbl(gfld->igdtmpl[1], gfld->igdtmpl[2]) / 1000.0;
laea.equatorial_radius_km = 0;
laea.polar_radius_km = 0;
laea.is_sphere = true;
break;

case 2:
laea.radius_km = 0;
laea.equatorial_radius_km = 6378.1600;
laea.polar_radius_km = 6356.7750;
laea.is_sphere = false;
break;

case 3:
laea.radius_km = 0;
laea.equatorial_radius_km = scaled2dbl(gfld->igdtmpl[3], gfld->igdtmpl[4]);
laea.polar_radius_km = scaled2dbl(gfld->igdtmpl[5], gfld->igdtmpl[6]);
laea.is_sphere = false;
break;

case 4:
laea.radius_km = 0;
laea.equatorial_radius_km = 6378.1370;
laea.polar_radius_km = 6356.752314;
laea.is_sphere = false;
break;

case 6:
laea.radius_km = 6371.2290;
laea.equatorial_radius_km = 0;
laea.polar_radius_km = 0;
laea.is_sphere = true;
break;

case 7:
laea.radius_km = 0;
laea.equatorial_radius_km = scaled2dbl(gfld->igdtmpl[3], gfld->igdtmpl[4]) / 1000.0;
laea.polar_radius_km = scaled2dbl(gfld->igdtmpl[5], gfld->igdtmpl[6]) / 1000.0;
laea.is_sphere = false;
break;

default:
mlog << Error << "\nMetGrib2DataFile::read_grib2_grid() -> "
<< "unsupported earth shape value of " << earth_shape_int << "!\n\n";
exit(1);
}
laea.nx = p[7];
laea.ny = p[8];
laea.lat_first = (double)p[9] / 1000000.0;
// TODO: Suspect a bug in g2clib
// laea.lon_first = -1.0*rescale_lon( (double)p[10] / 1000000.0 );

//
// MET#2565:
// Fix a bug when parsing laea.lon_first and laea.central_lon
// in gfld->igdtmpl[10] and gfld->igdtmpl[12] for GRIB2 UKV data.
// These longitudes are negative which the GRIB2C library does not
// parse properly. The parse_int4() function is a workaround to
// reprocesses the data as unsigned chars and check for negative
// values, mimicing logic from the int4() function in wgrib2.
//
// grib_dump: longitudeOfFirstGridPointInDegrees = -17.1171;
// wgrib2: Lon1 2164.600777
// 3-43=129,5,47,201
// g2clib-1.6.0 grid_templates.h
// 3.140: Lambert Azimuthal Equal Area Projection
// BAD? {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,4,4,1,4,4,1} },
// FIX? {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,-4,4,1,4,4,1} },
cout << "TODO LAEA p[10] should be 17.1171 = "<< (double)p[10] / 1000000.0 << "\n";
laea.lon_first = 17.1171;
laea.standard_lat = (double)p[11] / 1000000.0;
laea.central_lon = -1.0*rescale_lon( (double)p[12] / 1000000.0 );
laea.dx_km = (double)p[14] / 1000000.0;
laea.dy_km = (double)p[15] / 1000000.0;
// The grib_dump utility already handles negative longitudes well.
// The wgrib2 utility does NOT when populating gfld->igdtmpl.
// However, the wgrib2 -get_byte and -get_int options do work,
// as shown below:
// wgrib2 ukv_agl_temperature_1.5_12.grib2 \
// -get_byte 3 43 4 -get_int 3 43 1 \
// -get_byte 3 51 4 -get_int 3 51 1
//
// The longitudes are correctly parsed as -17.117129 and -2.5, respectively.
// 1:0:3-43=129,5,47,201:3-43=-17117129:3-51=128,38,37,160:3-51=-2500000
//

laea.nx = gfld->igdtmpl[7];
laea.ny = gfld->igdtmpl[8];
laea.lat_first = (double)gfld->igdtmpl[9] / 1000000.0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it's worth it, particularly with the time crunch, but I was wondering if we should consider creating a variable for the 1000000.0 value, which is reused?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point Julie. Thanks for mentioning that. I'd like to not make a change at this time because it would apply to about 40 lines of code in this file. I'd rather limit the changes to what's explicitly necessary for this issue during the official release testing time period to limit the lines of code I touch. But this would be good to consider as part of the changes to the vx_grid library's use of the proj library in the future.

laea.lon_first = -1.0*rescale_lon( (double)parse_int4(gfld->igdtmpl[10]) / 1000000.0);
laea.standard_lat = (double)gfld->igdtmpl[11] / 1000000.0;
laea.central_lon = -1.0*rescale_lon( (double)parse_int4(gfld->igdtmpl[12]) / 1000000.0);
laea.dx_km = (double)gfld->igdtmpl[14] / 1000000.0;
laea.dy_km = (double)gfld->igdtmpl[15] / 1000000.0;

// store the grid information

Expand Down Expand Up @@ -1567,3 +1624,27 @@ double scaled2dbl(int scale_factor, int scale_value) {
}

////////////////////////////////////////////////////////////////////////

int parse_int4(g2int i) {
unsigned char c[4];
unsigned long n = i;

c[0] = (n >> 24) & 0xFF;
c[1] = (n >> 16) & 0xFF;
c[2] = (n >> 8) & 0xFF;
c[3] = n & 0xFF;

// convert unsigned char to signed integer
int i_val;
if(c[0] & 0x80) {
i_val = -(((c[0] & 0x7f) << 24) + (c[1] << 16) + (c[2] << 8) + c[3]);
}
else {
i_val = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
}

return(i_val);
}

////////////////////////////////////////////////////////////////////////

Loading