Skip to content

Commit

Permalink
Feature 1055 read rot latlon (#2041)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnHalleyGotway committed Feb 8, 2022
1 parent 4a31d4f commit 872e2e4
Show file tree
Hide file tree
Showing 22 changed files with 318 additions and 95 deletions.
8 changes: 4 additions & 4 deletions met/docs/Users_Guide/mode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -967,16 +967,16 @@ The dimensions and variables included in the mode NetCDF files are described in
- Number of Forecast Simple Boundary Points
* - fcst_simp_bdy :raw-html:`<br />` \_lat
- fcst_simp_bdy
- Forecast Simple Boundary PoLatitude
- Forecast Simple Boundary Latitude
* - fcst_simp_bdy :raw-html:`<br />` \_lon
- fcst_simp_bdy
- Forecast Simple Boundary PoLongitude
- Forecast Simple Boundary Longitude
* - fcst_simp_bdy_x
- fcst_simp_bdy
- Forecast Simple Boundary PoX-Coordinate
- Forecast Simple Boundary X-Coordinate
* - fcst_simp_bdy_y
- fcst_simp_bdy
- Forecast Simple Boundary PoY-Coordinate
- Forecast Simple Boundary Y-Coordinate
* - fcst_simp_hull :raw-html:`<br />` \_start
- fcst_simp
- Forecast Simple Convex Hull Starting Index
Expand Down
2 changes: 1 addition & 1 deletion met/docs/Users_Guide/tc-gen.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Required arguments for tc_gen

3. The **-shape source** argument is the path to one or more NHC genesis warning area shapefiles, an ASCII file list containing them, or a top-level directory with files matching the regular expression "gtwo_areas.*.shp". The genesis warning areas and corresponding 2, 5, and 7 day probability values area verified against the **-track** data.

Note: The **-genesis**, **-edeck**, or **-shape** options must be used at least once.
Note: At least one of the **-genesis**, **-edeck**, or **-shape** command line options are required.

4. The **-track source** argument is one or more ATCF reference track files or an ASCII file list or top-level directory containing them, with files ending in ".dat". This tool processes either Best track data from bdeck files, or operational track data (e.g. CARQ) from adeck files, or both. Providing both bdeck and adeck files will result in a richer dataset to match with the **-genesis** files. Both adeck and bdeck data should be provided using the **-track** option. The **-track** option must be used at least once.

Expand Down
18 changes: 11 additions & 7 deletions met/src/libcode/vx_data2d/data_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -361,21 +361,25 @@ if ( vinfo->grid_attr().nxy() > 0 ) {
}

//
// Print a data summary
// Print the grid information and data summary
//

if ( mlog.verbosity_level() >= 4 ) {

mlog << Debug(4) << "\n"
<< "Grid information:\n "
<< Dest_Grid->serialize("\n ") << "\n";

double min_v, max_v;
dp.data_range(min_v, max_v);
mlog << Debug(4) << "\n"
<< "Data plane information:\n"
<< " plane min: " << min_v << "\n"
<< " plane max: " << max_v << "\n"
<< " valid time: " << unix_to_yyyymmdd_hhmmss(dp.valid()) << "\n"
<< " lead time: " << sec_to_hhmmss(dp.lead()) << "\n"
<< " init time: " << unix_to_yyyymmdd_hhmmss(dp.init()) << "\n"
<< " accum time: " << sec_to_hhmmss(dp.accum()) << "\n\n";
<< " plane min: " << min_v << "\n"
<< " plane max: " << max_v << "\n"
<< " valid time: " << unix_to_yyyymmdd_hhmmss(dp.valid()) << "\n"
<< " lead time: " << sec_to_hhmmss(dp.lead()) << "\n"
<< " init time: " << unix_to_yyyymmdd_hhmmss(dp.init()) << "\n"
<< " accum time: " << sec_to_hhmmss(dp.accum()) << "\n\n";

}

Expand Down
221 changes: 210 additions & 11 deletions met/src/libcode/vx_data2d_nccf/nccf_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ bool NcCfFile::open(const char * filepath)
// calling program. In the case of this example, we just exit with
// an NC_ERR error code.

//FIXME: Commented out with NetcDf4 enabling
//NcError err(NcError::silent_nonfatal);
// FIXME: Commented out with NetCDF4 enabling
// NcError err(NcError::silent_nonfatal);

// Open the file

Expand Down Expand Up @@ -2266,16 +2266,191 @@ void NcCfFile::get_grid_mapping_polar_stereographic(const NcVar *grid_mapping_va
}


////////////////////////////////////////////////////////////////////////
//
// Reference:
// https://cfconventions.org/Data/cf-conventions/cf-conventions-1.9/cf-conventions.html#_rotated_pole
//
////////////////////////////////////////////////////////////////////////


void NcCfFile::get_grid_mapping_rotated_latitude_longitude(const NcVar *grid_mapping_var)
{
static const string method_name = "NcCfFile::get_grid_mapping_rotated_latitude_longitude()";

mlog << Error << "\n" << method_name << " -> "
<< "Rotated latitude longitude grid not handled in MET.\n\n";
exit(1);
// grid_north_pole_latitude

NcVarAtt *grid_np_lat_att = get_nc_att(
grid_mapping_var, (string)"grid_north_pole_latitude");
if (IS_INVALID_NC_P(grid_np_lat_att))
{
mlog << Error << "\n" << method_name << " -> "
<< "Cannot get grid_north_pole_latitude attribute from "
<< GET_NC_NAME_P(grid_mapping_var) << " variable.\n\n";
exit(1);
}

// grid_north_pole_longitude

NcVarAtt *grid_np_lon_att = get_nc_att(
grid_mapping_var, (string)"grid_north_pole_longitude");
if (IS_INVALID_NC_P(grid_np_lon_att))
{
mlog << Error << "\n" << method_name << " -> "
<< "Cannot get grid_north_pole_longitude attribute from "
<< GET_NC_NAME_P(grid_mapping_var) << " variable.\n\n";
exit(1);
}

// Look for the grid_latitude and grid_longitude dimensions

for (int dim_num = 0; dim_num < _numDims; ++dim_num)
{
// These dimensions are identified by the standard_name attribute

const NcVar coord_var = get_var(_ncFile, _dims[dim_num]->getName().c_str());
if (IS_INVALID_NC(coord_var))
continue;

const NcVarAtt *std_name_att = get_nc_att(&coord_var, (string)"standard_name");
if (IS_INVALID_NC_P(std_name_att)) {
if (std_name_att) delete std_name_att;
continue;
}

ConcatString dim_standard_name;
if (!get_att_value_chars(std_name_att, dim_standard_name)) {
if (std_name_att) delete std_name_att;
continue;
}

if (std_name_att) delete std_name_att;

// See if this is a grid_latitude or grid_longitude dimension

if (dim_standard_name == "grid_latitude")
{
if (_yDim == 0)
{
_yDim = _dims[dim_num];

y_dim_var_name = GET_NC_NAME_P(_yDim).c_str();

for (int var_num = 0; var_num < Nvars; ++var_num)
{
if ( Var[var_num].name == GET_NC_NAME_P(_yDim))
{
_yCoordVar = Var[var_num].var;
break;
}
}
}
else
{
mlog << Warning << "\n" << method_name << " -> "
<< "Found multiple variables for grid_latitude, using \""
<< GET_NC_NAME_P(_yCoordVar) << "\".\n\n";
}
}

if (dim_standard_name == "grid_longitude")
{
if (_xDim == 0)
{
_xDim = _dims[dim_num];

x_dim_var_name = GET_NC_NAME_P(_xDim).c_str();
for (int var_num = 0; var_num < Nvars; ++var_num)
{
if ( Var[var_num].name == GET_NC_NAME_P(_xDim))
{
_xCoordVar = Var[var_num].var;
break;
}
}
}
else
{
mlog << Warning << "\n" << method_name << " -> "
<< "Found multiple variables for grid_longitude, using \""
<< GET_NC_NAME_P(_xCoordVar) << "\".\n\n";
}
}

}

if (_xDim == 0)
{
mlog << Error << "\n" << method_name << " -> "
<< "Didn't find X dimension (degrees_east) in netCDF file.\n\n";
exit(1);
}

if (_yDim == 0)
{
mlog << Error << "\n" << method_name << " -> "
<< "Didn't find Y dimension (degrees_north) in netCDF file.\n\n";
exit(1);
}

if (_xCoordVar == 0)
{
mlog << Error << "\n" << method_name << " -> "
<< "Didn't find X coord variable (" << GET_NC_NAME_P(_xDim)
<< ") in netCDF file.\n\n";
exit(1);
}

if (_yCoordVar == 0)
{
mlog << Error << "\n" << method_name << " -> "
<< "Didn't find Y coord variable (" << GET_NC_NAME_P(_yDim)
<< ") in netCDF file.\n\n";
exit(1);
}

long lon_counts = _xDim->getSize();
long lat_counts = _yDim->getSize();
if (get_data_size(_xCoordVar) != lon_counts ||
get_data_size(_yCoordVar) != lat_counts)
{
mlog << Error << "\n" << method_name << " -> "
<< "Coordinate variables don't match dimension sizes in netCDF file.\n\n";
exit(1);
}

// Store spacing in LatLon data structure
bool swap_to_north;
LatLonData ll_data = get_data_from_lat_lon_vars(_yCoordVar, _xCoordVar,
lat_counts, lon_counts,
swap_to_north);

// Fill in the Rotated LatLon data structure
RotatedLatLonData data;

data.name = rotated_latlon_proj_type;

// Derive south pole location from the north pole
data.true_lat_south_pole = -1.0 * get_att_value_double(grid_np_lat_att);
double np_lon = rescale_lon(get_att_value_double(grid_np_lon_att));
data.true_lon_south_pole = rescale_lon(-1.0 * (180.0 - fabs(np_lon)));

// Copied from the LatLon data structure
data.rot_lat_ll = ll_data.lat_ll;
data.rot_lon_ll = ll_data.lon_ll;
data.delta_rot_lat = ll_data.delta_lat;
data.delta_rot_lon = ll_data.delta_lon;

// Grid dimension
data.Nlon = _xDim->getSize();
data.Nlat = _yDim->getSize();

data.aux_rotation = 0;

grid.set(data);

if(grid_np_lat_att) delete grid_np_lat_att;
if(grid_np_lon_att) delete grid_np_lon_att;
}


Expand Down Expand Up @@ -2865,17 +3040,36 @@ bool NcCfFile::get_grid_from_dimensions()

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


void NcCfFile::get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var,
const long lat_counts, const long lon_counts) {
static const string method_name = "NcCfFile::get_grid_from_lat_lon_vars()";

bool swap_to_north;
LatLonData data = get_data_from_lat_lon_vars(lat_var, lon_var,
lat_counts, lon_counts,
swap_to_north);

grid.set(data); // resets swap_to_north to false
if (swap_to_north) grid.set_swap_to_north(true);
}


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


LatLonData NcCfFile::get_data_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var,
const long lat_counts, const long lon_counts,
bool &swap_to_north) {
static const string method_name = "get_data_from_lat_lon_vars()";

// Figure out the dlat/dlon values from the dimension variables

long x_size = get_data_size(lon_var);
long y_size = get_data_size(lat_var);
long latlon_counts = lon_counts*lat_counts;
bool two_dim_corrd = (x_size == latlon_counts) && (y_size == latlon_counts );
if( !two_dim_corrd && (x_size != lon_counts || y_size != lat_counts))
bool two_dim_coord = (x_size == latlon_counts) && (y_size == latlon_counts );
if( !two_dim_coord && (x_size != lon_counts || y_size != lat_counts))
{
mlog << Error << "\n" << method_name << " -> "
<< "Coordinate variables don't match dimension sizes in netCDF file.\n\n";
Expand All @@ -2885,7 +3079,7 @@ void NcCfFile::get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var,
double lat_values[lat_counts];
double lon_values[lon_counts];
bool lat_first = false;
if (two_dim_corrd) {
if (two_dim_coord) {
lat_first = (lat_counts == get_dim_size(lat_var, 0));
long cur[2], length[2];
cur[0] = cur[1] = 0;
Expand Down Expand Up @@ -2992,19 +3186,24 @@ void NcCfFile::get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var,

data.name = latlon_proj_type;
data.lat_ll = lat_values[0];
data.lon_ll = -lon_values[0];
data.lon_ll = rescale_lon(-lon_values[0]);
data.delta_lat = dlat;
data.delta_lon = dlon;
data.Nlat = lat_counts;
data.Nlon = lon_counts;

if (dlat < 0) {
swap_to_north = true;
data.delta_lat = -dlat;
data.lat_ll = lat_values[lat_counts-1];
}
else {
swap_to_north = false;
}

grid.set(data); // resets swap_to_north to false
if (dlat < 0) grid.set_swap_to_north(true);
return(data);

}


////////////////////////////////////////////////////////////////////////
4 changes: 4 additions & 0 deletions met/src/libcode/vx_data2d_nccf/nccf_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ class NcCfFile {
bool get_grid_from_dimensions();
void get_grid_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var,
const long lat_counts, const long lon_counts);

LatLonData get_data_from_lat_lon_vars(NcVar *lat_var, NcVar *lon_var,
const long lat_counts, const long lon_counts,
bool &swap_to_north);
};


Expand Down
8 changes: 4 additions & 4 deletions met/src/libcode/vx_grid/gaussian_grid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -370,19 +370,19 @@ return;
////////////////////////////////////////////////////////////////////////


ConcatString GaussianGrid::serialize() const
ConcatString GaussianGrid::serialize(const char *sep) const

{

ConcatString a;
char junk[256];

a << "Projection: Gaussian";
a << "Projection: Gaussian" << sep;

snprintf(junk, sizeof(junk), " Lon_Zero: %.4f", Lon_Zero); a << junk;

a << " Nx: " << Nx;
a << " Ny: " << Ny;
a << "Nx: " << Nx << sep;
a << "Ny: " << Ny;

//
// done
Expand Down
2 changes: 1 addition & 1 deletion met/src/libcode/vx_grid/gaussian_grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class GaussianGrid : public GridRep {

void dump(ostream &, int = 0) const;

ConcatString serialize() const;
ConcatString serialize(const char *sep=" ") const;

GridInfo info() const;

Expand Down
Loading

0 comments on commit 872e2e4

Please sign in to comment.