diff --git a/met/src/basic/vx_math/nint.cc b/met/src/basic/vx_math/nint.cc index f027903500..d013916ca3 100644 --- a/met/src/basic/vx_math/nint.cc +++ b/met/src/basic/vx_math/nint.cc @@ -46,3 +46,13 @@ return ( a ); //////////////////////////////////////////////////////////////////////// +int positive_modulo(int i, int n) + +{ + +return ( i % n + n ) % n; + +} + + +//////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_math/nint.h b/met/src/basic/vx_math/nint.h index 3c466858d6..712823ecba 100644 --- a/met/src/basic/vx_math/nint.h +++ b/met/src/basic/vx_math/nint.h @@ -11,8 +11,8 @@ //////////////////////////////////////////////////////////////////////// -#ifndef __PS_DITHER_NINT_H__ -#define __PS_DITHER_NINT_H__ +#ifndef __VX_MATH_NINT_H__ +#define __VX_MATH_NINT_H__ //////////////////////////////////////////////////////////////////////// @@ -24,7 +24,13 @@ extern int nint(double); //////////////////////////////////////////////////////////////////////// -#endif // __PS_DITHER_NINT_H__ +extern int positive_modulo(int, int); + + +//////////////////////////////////////////////////////////////////////// + + +#endif // __VX_MATH_NINT_H__ //////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/CircularTemplate.cc b/met/src/basic/vx_util/CircularTemplate.cc index a49f40c62f..2b2bac65d6 100644 --- a/met/src/basic/vx_util/CircularTemplate.cc +++ b/met/src/basic/vx_util/CircularTemplate.cc @@ -1,47 +1,25 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 -// ** University Corporation for Atmospheric Research (UCAR) -// ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -// RCS info: dixon $ -// $Locker: $ -// $Date: 2016/03/03 18:19:27 $ -// $Id: CircularTemplate.cc,v 1.6 2016/03/03 18:19:27 dixon Exp $ -// $Revision: 1.6 $ -// $State: Exp $ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ -/********************************************************************* - * CircularTemplate.cc: class implementing a circular template to be - * applied on gridded data. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - *********************************************************************/ +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** University Corporation for Atmospheric Research (UCAR) +// ** National Center for Atmospheric Research (NCAR) +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: CircularTemplate.cc +// +// Description: +// Class implementing a Circular template to be +// applied on gridded data. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// 001 09-07-21 Halley Gotway Add wrap_lon. +// +/////////////////////////////////////////////////////////////////////////////// #include @@ -56,126 +34,92 @@ using namespace std; +/////////////////////////////////////////////////////////////////////////////// -/********************************************************************** - * Constructor - */ +CircularTemplate::CircularTemplate(const int width, bool wrap_lon) : + GridTemplate(), _width(width) { -CircularTemplate::CircularTemplate(const int width) : - GridTemplate(), - _width(width) -{ + _wrapLon = wrap_lon; - //width of 2 is not supported - if (width == 2){ - mlog << Error << "\nCircularTemplate::CircularTemplate() -> " - << "unsupported width of " << width - << " for circles.\n\n"; + // width of 2 is not supported + if (width == 2) { + mlog << Error << "\nCircularTemplate::CircularTemplate() -> " + << "unsupported width of " << width << " for circles.\n\n"; exit(1); } - - bool evenWidth = ((width % 2) == 0); - // if the width is even, that means we are dealing with a point interpolation - // because grid interpolation has to be odd. - // for an ODD WIDTH the reference point is the same as the center point and is the nearest grid point - - // for an EVEN WIDTH, we move the "reference" point, to the lower left grid point, - // this means offsets are stored relative to the lower left corner of the true center. - // but we find distances based on the the true center location when determining if an - // offset is within the circle. - - double radius = (width-1)/2.0; + bool evenWidth = ((width % 2) == 0); + + // if the width is even, that means we are dealing with a point interpolation + // because grid interpolation has to be odd. + // for an ODD WIDTH the reference point is the same as the center point and is the nearest grid point + // for an EVEN WIDTH, we move the "reference" point, to the lower left grid point, + // this means offsets are stored relative to the lower left corner of the true center. + // but we find distances based on the the true center location when determining if an + // offset is within the circle. + + double radius = (width-1)/2.0; - // Create the offsets list. - - // If the radius is small, then just make the - // template cover the current grid square. - // radius < 1 no longer supported. - /* - if (radius < 1.0) - { - _addOffset(0, 0); - return; - } - */ + // Create the offsets list. - // need to increase the area we look at if the width is even, because - // some valid offset points will actually be farther from the reference point - // than the radius, because the reference point is offset from the true - // center of the circle. - int maxOffset = static_cast(floor(radius)); - if (evenWidth){ - maxOffset++; - } + // Need to increase the area we look at if the width is even, because + // some valid offset points will actually be farther from the reference point + // than the radius, because the reference point is offset from the true + // center of the circle. + + int maxOffset = static_cast(floor(radius)); + if(evenWidth) maxOffset++; - int minOffset = static_cast(floor(-1 * radius)); + int minOffset = static_cast(floor(-1 * radius)); - for (int y = minOffset; y <= maxOffset; y++) - { - for (int x = minOffset; x <= maxOffset; x++) - { - double double_x = (double)x; - double double_y = (double)y; - - if (evenWidth){ - // if width is even, the reference point is actually shifted 1/2 a grid spacing down and to the left, - // from the true center of the circle. - // - // so when we calculate distance, we need to subtract .5 so that the distance reflects the distance from the center - // of the circle, instead of the distance from the reference. - // - // for example - a circle with width == 4. The reference point is the lower left corner of the center square. - // the point directly below that is at (0,-1), but it's actually (-.5, -1.5) from the center of the circle. - // - // another example - same circle. The point directly to the right of the reference point is (1,0), but it's - // actually (.5,-.5) from the center. + for(int y = minOffset; y <= maxOffset; y++) { + for(int x = minOffset; x <= maxOffset; x++) { + double double_x = (double)x; + double double_y = (double)y; + + if(evenWidth) { + // if width is even, the reference point is actually shifted 1/2 a grid spacing down and to the left, + // from the true center of the circle. + // + // so when we calculate distance, we need to subtract .5 so that the distance reflects the distance from the center + // of the circle, instead of the distance from the reference. + // + // for example - a circle with width == 4. The reference point is the lower left corner of the center square. + // the point directly below that is at (0,-1), but it's actually (-.5, -1.5) from the center of the circle. + // + // another example - same circle. The point directly to the right of the reference point is (1,0), but it's + // actually (.5,-.5) from the center. - double_x -= 0.5; - double_y -= 0.5; - } - double distance= sqrt((double_x * double_x) + (double_y * double_y)); - - if (distance <= radius) - { - _addOffset(x, y); - } - - } /* endfor - x */ - - } /* endfor - y */ - - _setEdgeOffsets(); - -} + double_x -= 0.5; + double_y -= 0.5; + } + double distance= sqrt((double_x * double_x) + (double_y * double_y)); + + if(distance <= radius) _addOffset(x, y); + } // end for x + } // end for y -/********************************************************************** - * Destructor - */ + _setEdgeOffsets(); -CircularTemplate::~CircularTemplate(void) -{ - // Do nothing } - -/********************************************************************** - * printOffsetList() - Print the offset list to the given stream. This - * is used for debugging. - */ +/////////////////////////////////////////////////////////////////////////////// -void CircularTemplate::printOffsetList(FILE *stream) -{ - fprintf(stream, "\n\n"); - fprintf(stream, "Circular template with width %d grid spaces:\n", - _width); - - GridTemplate::printOffsetList(stream); +CircularTemplate::~CircularTemplate(void) { + // Do nothing } +/////////////////////////////////////////////////////////////////////////////// + +void CircularTemplate::printOffsetList(FILE *stream) { + fprintf(stream, "\n\n"); + fprintf(stream, "Circular template:"); + fprintf(stream, " width = %d\n", _width); + fprintf(stream, " wrap_lon = %d\n", _wrapLon); + fprintf(stream, " grid points:\n"); + GridTemplate::printOffsetList(stream); +} -/********************************************************************** - * Private Member Functions * - **********************************************************************/ +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/CircularTemplate.h b/met/src/basic/vx_util/CircularTemplate.h index fc92c7db8b..835aa99ed5 100644 --- a/met/src/basic/vx_util/CircularTemplate.h +++ b/met/src/basic/vx_util/CircularTemplate.h @@ -1,53 +1,30 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 -// ** University Corporation for Atmospheric Research (UCAR) -// ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -/* RCS info - * $Author: dixon $ - * $Locker: $ - * $Date: 2016/03/03 19:21:31 $ - * $Id: CircularTemplate.hh,v 1.5 2016/03/03 19:21:31 dixon Exp $ - * $Revision: 1.5 $ - * $State: Exp $ - */ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ - -/************************************************************************ - * CircularTemplate.hh: class implementing a circular template to be - * applied on gridded data. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - ************************************************************************/ - -#ifndef CircularTemplate_HH -#define CircularTemplate_HH +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** University Corporation for Atmospheric Research (UCAR) +// ** National Center for Atmospheric Research (NCAR) +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: CircularTemplate.h +// +// Description: +// Class implementing a Circular template to be +// applied on gridded data. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// 001 09-07-21 Halley Gotway Add wrap_lon. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __CIRCULAR_TEMPLATE_H__ +#define __CIRCULAR_TEMPLATE_H__ + +/////////////////////////////////////////////////////////////////////////////// #include @@ -57,46 +34,39 @@ #include #include +/////////////////////////////////////////////////////////////////////////////// -class CircularTemplate : public GridTemplate -{ - public: +class CircularTemplate : public GridTemplate { - // Constructor + public: - CircularTemplate(int width = 0); - - // Destructor + CircularTemplate(int width, bool wrap_lon); + virtual ~CircularTemplate(void); - virtual ~CircularTemplate(void); + void printOffsetList(FILE *stream); - // Print the offset list to the given stream. This is used for debugging. + // Access methods - void printOffsetList(FILE *stream); - - // Access methods + int getWidth(void) const { + return _width; + } - int getWidth(void) const - { - return _width; - } - - - virtual const char* getClassName(void) const{ - return _className(); - } + virtual const char* getClassName(void) const { + return _className(); + } - private: + private: - int _width; - - // Return the class name for error messages. - static const char* _className(void) - { - return("CircleTemplate"); - } + int _width; + // Return the class name for error messages. + static const char* _className(void) { + return("CircleTemplate"); + } }; +/////////////////////////////////////////////////////////////////////////////// + +#endif // __CIRCULAR_TEMPLATE_H__ -#endif +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/GridOffset.cc b/met/src/basic/vx_util/GridOffset.cc index 4ae65fdf57..f21fd39636 100644 --- a/met/src/basic/vx_util/GridOffset.cc +++ b/met/src/basic/vx_util/GridOffset.cc @@ -1,48 +1,24 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -// RCS info -// $Author: dixon $ -// $Locker: $ -// $Date: 2016/03/03 18:19:27 $ -// $Id: GridOffset.cc,v 1.6 2016/03/03 18:19:27 dixon Exp $ -// $Revision: 1.6 $ -// $State: Exp $ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ -/********************************************************************* - * GridOffset.cc: class implementing grid points as described as offsets - * from an origin. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - *********************************************************************/ +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: GridOffset.cc +// +// Description: +// Class implementing grid index points as described as +// offsets from an origin. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// +/////////////////////////////////////////////////////////////////////////////// #include @@ -53,9 +29,7 @@ using namespace std; -/********************************************************************** - * Constructors - */ +/////////////////////////////////////////////////////////////////////////////// GridOffset::GridOffset(int cur_x_offset, int cur_y_offset) { @@ -63,6 +37,7 @@ GridOffset::GridOffset(int cur_x_offset, int cur_y_offset) this->y_offset = cur_y_offset; } +/////////////////////////////////////////////////////////////////////////////// GridOffset::GridOffset(const GridOffset& rhs) { @@ -70,6 +45,7 @@ GridOffset::GridOffset(const GridOffset& rhs) y_offset = rhs.y_offset; } +/////////////////////////////////////////////////////////////////////////////// GridOffset::GridOffset(const GridOffset* rhs) { @@ -77,16 +53,10 @@ GridOffset::GridOffset(const GridOffset* rhs) y_offset = rhs->y_offset; } - -/********************************************************************** - * Destructor - */ +/////////////////////////////////////////////////////////////////////////////// GridOffset::~GridOffset(void) { } - -/********************************************************************** - * Private Member Functions * - **********************************************************************/ +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/GridOffset.h b/met/src/basic/vx_util/GridOffset.h index 8e4826011b..dd04a36bcc 100644 --- a/met/src/basic/vx_util/GridOffset.h +++ b/met/src/basic/vx_util/GridOffset.h @@ -1,56 +1,34 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 -// ** University Corporation for Atmospheric Research (UCAR) -// ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -/* RCS info - * $Author: dixon $ - * $Locker: $ - * $Date: 2016/03/03 19:21:31 $ - * $Id: GridOffset.hh,v 1.5 2016/03/03 19:21:31 dixon Exp $ - * $Revision: 1.5 $ - * $State: Exp $ - */ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ - -/************************************************************************ - * GridOffset.hh: class implementing grid index points as described as - * offsets from an origin. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - ************************************************************************/ - -#ifndef GridOffset_HH -#define GridOffset_HH +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 +// ** University Corporation for Atmospheric Research (UCAR) +// ** National Center for Atmospheric Research (NCAR) +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: GridOffset.h +// +// Description: +// Class implementing grid index points as described as +// offsets from an origin. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __GRID_OFFSET_H__ +#define __GRID_OFFSET_H__ + +/////////////////////////////////////////////////////////////////////////////// #include +/////////////////////////////////////////////////////////////////////////////// + using namespace std; class GridOffset @@ -74,5 +52,8 @@ class GridOffset }; +/////////////////////////////////////////////////////////////////////////////// + +#endif // __GRID_OFFSET_H__ -#endif +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/GridPoint.cc b/met/src/basic/vx_util/GridPoint.cc index 82581f2aeb..bbba9ee87a 100644 --- a/met/src/basic/vx_util/GridPoint.cc +++ b/met/src/basic/vx_util/GridPoint.cc @@ -1,47 +1,23 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -// RCS info -// $Author: dixon $ -// $Locker: $ -// $Date: 2016/03/03 18:19:27 $ -// $Id: GridPoint.cc,v 1.7 2016/03/03 18:19:27 dixon Exp $ -// $Revision: 1.7 $ -// $State: Exp $ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ -/********************************************************************* - * GridPoint.cc: class implementing grid index points. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - *********************************************************************/ +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: GridPoint.cc +// +// Description: +// Class implementing grid index points. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// +/////////////////////////////////////////////////////////////////////////////// #include @@ -52,42 +28,39 @@ #include using namespace std; -/********************************************************************** - * Constructors - */ +/////////////////////////////////////////////////////////////////////////////// GridPoint::GridPoint(int cur_x, int cur_y) { setPoint(cur_x, cur_y); } +/////////////////////////////////////////////////////////////////////////////// GridPoint::GridPoint(GridPoint *point) { setPoint(point); } +/////////////////////////////////////////////////////////////////////////////// GridPoint::GridPoint(GridPoint *point, GridOffset *offset) { setPoint(point, offset); } - -/********************************************************************** - * Destructor - */ +/////////////////////////////////////////////////////////////////////////////// GridPoint::~GridPoint(void) { } - -/********************************************************************** - * rotate() - Rotate the point about the origin by the given angle. - * The angle value must be given in degrees. - */ - +/////////////////////////////////////////////////////////////////////////////// +// +// Rotate the point about the origin by the given angle. +// The angle value must be given in degrees. +// +/////////////////////////////////////////////////////////////////////////////// void GridPoint::rotate(const double angle) { @@ -103,7 +76,4 @@ void GridPoint::rotate(const double angle) y = (int)(new_y + 0.5); } - -/********************************************************************** - * Private Member Functions * - **********************************************************************/ +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/GridPoint.h b/met/src/basic/vx_util/GridPoint.h index 84876e37fe..9e66aceb0e 100644 --- a/met/src/basic/vx_util/GridPoint.h +++ b/met/src/basic/vx_util/GridPoint.h @@ -1,57 +1,35 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -/* RCS info - * $Author: dixon $ - * $Locker: $ - * $Date: 2016/03/03 19:21:31 $ - * $Id: GridPoint.hh,v 1.10 2016/03/03 19:21:31 dixon Exp $ - * $Revision: 1.10 $ - * $State: Exp $ - */ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ - -/************************************************************************ - * GridPoint.hh: class implementing grid index points. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - ************************************************************************/ - -#ifndef GridPoint_HH -#define GridPoint_HH +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: GridPoint.h +// +// Description: +// Class implementing grid index points. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __GRID_POINT_H__ +#define __GRID_POINT_H__ + +/////////////////////////////////////////////////////////////////////////////// #include #include "GridOffset.h" +/////////////////////////////////////////////////////////////////////////////// + class GridPoint { public: @@ -161,5 +139,8 @@ class GridPoint }; +/////////////////////////////////////////////////////////////////////////////// + +#endif // __GRID_POINT_H__ -#endif +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/GridTemplate.cc b/met/src/basic/vx_util/GridTemplate.cc index f3b83b3252..486ff28b44 100644 --- a/met/src/basic/vx_util/GridTemplate.cc +++ b/met/src/basic/vx_util/GridTemplate.cc @@ -1,48 +1,25 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -// RCS info -// $Author: dixon $ -// $Locker: $ -// $Date: 2016/03/03 18:19:27 $ -// $Id: GridTemplate.cc,v 1.14 2016/03/03 18:19:27 dixon Exp $ -// $Revision: 1.14 $ -// $State: Exp $ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ -/********************************************************************* - * GridTemplate.cc: class implementing a template to be applied to - * gridded data. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - *********************************************************************/ +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: GridTemplate.cc +// +// Description: +// Class implementing a template to be applied to +// gridded data. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// 001 09-07-21 Halley Gotway Add wrap_lon. +// +/////////////////////////////////////////////////////////////////////////////// #include #include @@ -51,6 +28,7 @@ #include #include "vx_log.h" +#include "nint.h" #include "GridTemplate.h" #include "GridOffset.h" @@ -60,18 +38,19 @@ using namespace std; -/********************************************************************** - * Constructors - */ +/////////////////////////////////////////////////////////////////////////////// -GridTemplate::GridTemplate(void) -{ - // Do nothing +GridTemplate::GridTemplate(void) : + _wrapLon(false) { + // Do nothing } -GridTemplate::GridTemplate(const GridTemplate& rhs) -{ - vector< GridOffset* >::const_iterator offset_iter; +/////////////////////////////////////////////////////////////////////////////// + +GridTemplate::GridTemplate(const GridTemplate& rhs) { + _wrapLon = rhs._wrapLon; + + vector::const_iterator offset_iter; for (offset_iter = rhs._offsetList.begin(); offset_iter != rhs._offsetList.end(); ++offset_iter) @@ -83,536 +62,558 @@ GridTemplate::GridTemplate(const GridTemplate& rhs) _pointInGridReturn = rhs._pointInGridReturn; } -/********************************************************************** - * Destructor - */ +/////////////////////////////////////////////////////////////////////////////// -GridTemplate::~GridTemplate(void) -{ - // Reclaim the space for the offset list +GridTemplate::~GridTemplate(void) { - vector< GridOffset* >::iterator list_iter; - for (list_iter = _offsetList.begin(); list_iter != _offsetList.end(); + // Reclaim the space for the offset list + vector::iterator list_iter; + for(list_iter = _offsetList.begin(); list_iter != _offsetList.end(); ++list_iter) - delete *list_iter; - - _offsetList.erase(_offsetList.begin(), _offsetList.end()); + delete *list_iter; + _offsetList.erase(_offsetList.begin(), _offsetList.end()); } -/********************************************************************** - * getFirstInGrid() - Get the first template grid point within the given - * grid. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Get the first template grid point within the given grid. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// GridPoint *GridTemplate::getFirstInGrid( - const int &base_x, const int &base_y, - const int &nx, const int &ny) const -{ - // Set the grid information + const int &base_x, const int &base_y, + const int &nx, const int &ny) const { - setGrid(base_x, base_y, nx, ny); + // Set the grid information, applying the global wrap logic + setGrid((_wrapLon ? base_x % nx : base_x), base_y, nx, ny); - // Send back the first point + // Send back the first point - return getNextInGrid(); + return getNextInGrid(); } -/********************************************************************** - * getNextInGrid() - Get the next template grid point within the grid. - * Returns NULL when there are no more points in the - * grid. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ - -GridPoint *GridTemplate::getNextInGrid(void) const -{ - while (_pointInGridIterator != _offsetList.end()) - { - GridOffset *offset = *_pointInGridIterator; - - _pointInGridIterator++; - - _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; - _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; - - if (_pointInGridReturn.x >= 0 && - _pointInGridReturn.x < _pointInGridNumX && - _pointInGridReturn.y >= 0 && - _pointInGridReturn.y < _pointInGridNumY) - { - return &_pointInGridReturn; - } - - } - - return (GridPoint *)NULL; +/////////////////////////////////////////////////////////////////////////////// +// +// Get the next template grid point within the grid. +// Returns NULL when there are no more points in the grid. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// + +GridPoint *GridTemplate::getNextInGrid(void) const { + + while (_pointInGridIterator != _offsetList.end()) { + GridOffset *offset = *_pointInGridIterator; + + _pointInGridIterator++; + + _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; + _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; + + // Apply global wrap logic + _pointInGridReturn.x = (_wrapLon ? + positive_modulo(_pointInGridReturn.x, _pointInGridNumX) : + _pointInGridReturn.x); + + if(_pointInGridReturn.x >= 0 && + _pointInGridReturn.x < _pointInGridNumX && + _pointInGridReturn.y >= 0 && + _pointInGridReturn.y < _pointInGridNumY) { + return &_pointInGridReturn; + } + } // end while + + return (GridPoint *)NULL; } -/********************************************************************** - * getFirst() - Get the first template grid point without checking - * the grid bounds. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Get the first template grid point without checking the grid +// bounds. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// GridPoint *GridTemplate::getFirst(const int &base_x, const int &base_y, - const int &nx, const int &ny) const -{ - // Set the grid information - setGrid(base_x, base_y, nx, ny); + const int &nx, const int &ny) const { + + // Set the grid information, applying the global wrap logic + setGrid((_wrapLon ? positive_modulo(base_x, nx) : base_x), base_y, nx, ny); - // Send back the first point - return getNext(); + // Send back the first point + return getNext(); } -/********************************************************************** - * getNext() - Get the next template grid point without checking the - * grid bounds. Returns NULL when there are no more points. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Get the next template grid point without checking the grid bounds. +// Returns NULL when there are no more points. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// -GridPoint *GridTemplate::getNext(void) const -{ - GridPoint *next_point = (GridPoint *)NULL; - if (_pointInGridIterator != _offsetList.end()) - { - GridOffset *offset = *_pointInGridIterator; +GridPoint *GridTemplate::getNext(void) const { - _pointInGridIterator++; + GridPoint *next_point = (GridPoint *)NULL; + if(_pointInGridIterator != _offsetList.end()) { + GridOffset *offset = *_pointInGridIterator; - _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; - _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; + _pointInGridIterator++; - next_point = &_pointInGridReturn; + _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; + _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; - } + // Apply global wrap logic + _pointInGridReturn.x = (_wrapLon ? + positive_modulo(_pointInGridReturn.x, _pointInGridNumX) : + _pointInGridReturn.x); + + next_point = &_pointInGridReturn; + } - return next_point; + return next_point; } -/********************************************************************** - * getFirstInLftEdge() - Get the first template grid point in the left - * column. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Get the first template grid point in the left column. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// -GridPoint *GridTemplate::getFirstInLftEdge(void) const -{ - // Reset the iterator and send back the first point +GridPoint *GridTemplate::getFirstInLftEdge(void) const { - _pointInLftEdgeIterator = _offsetLftEdge.begin(); + // Reset the iterator and send back the first point + _pointInLftEdgeIterator = _offsetLftEdge.begin(); - return getNextInLftEdge(); + return getNextInLftEdge(); } -/********************************************************************** - * getNextInLftEdge() - Get the next template grid point in the first - * column. Returns NULL when there are no more - * points in the first column. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ - -GridPoint *GridTemplate::getNextInLftEdge(void) const -{ - while (_pointInLftEdgeIterator != _offsetLftEdge.end()) - { - GridOffset *offset = *_pointInLftEdgeIterator; - - _pointInLftEdgeIterator++; - - _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; - _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; - - if (_pointInGridReturn.x >= 0 && - _pointInGridReturn.x < _pointInGridNumX && - _pointInGridReturn.y >= 0 && - _pointInGridReturn.y < _pointInGridNumY) - { - return &_pointInGridReturn; - } - - } - - return (GridPoint *)NULL; +/////////////////////////////////////////////////////////////////////////////// +// +// Get the next template grid point in the first column. +// Returns NULL when there are no more points in the first column. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// + +GridPoint *GridTemplate::getNextInLftEdge(void) const { + + while(_pointInLftEdgeIterator != _offsetLftEdge.end()) { + + GridOffset *offset = *_pointInLftEdgeIterator; + + _pointInLftEdgeIterator++; + + _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; + _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; + + // Apply global wrap logic + _pointInGridReturn.x = (_wrapLon ? + positive_modulo(_pointInGridReturn.x, _pointInGridNumX) : + _pointInGridReturn.x); + + if(_pointInGridReturn.x >= 0 && + _pointInGridReturn.x < _pointInGridNumX && + _pointInGridReturn.y >= 0 && + _pointInGridReturn.y < _pointInGridNumY) { + return &_pointInGridReturn; + } + } // end while + + return (GridPoint *)NULL; } -/********************************************************************** - * getFirstInTopEdge() - Get the first template grid point in the - * top row. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Get the first template grid point in the top row. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// -GridPoint *GridTemplate::getFirstInTopEdge(void) const -{ - // Reset the iterator and send back the first point +GridPoint *GridTemplate::getFirstInTopEdge(void) const { - _pointInTopEdgeIterator = _offsetTopEdge.begin(); + // Reset the iterator and send back the first point + _pointInTopEdgeIterator = _offsetTopEdge.begin(); - return getNextInTopEdge(); + return getNextInTopEdge(); } -/********************************************************************** - * getNextInTopEdge() - Get the next template grid point in the top - * row. Returns NULL when there are no more - * points in the top row. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ - -GridPoint *GridTemplate::getNextInTopEdge(void) const -{ - while (_pointInTopEdgeIterator != _offsetTopEdge.end()) - { - GridOffset *offset = *_pointInTopEdgeIterator; - - _pointInTopEdgeIterator++; - - _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; - _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; - - if (_pointInGridReturn.x >= 0 && - _pointInGridReturn.x < _pointInGridNumX && - _pointInGridReturn.y >= 0 && - _pointInGridReturn.y < _pointInGridNumY) - { - return &_pointInGridReturn; - } - - } - - return (GridPoint *)NULL; +/////////////////////////////////////////////////////////////////////////////// +// +// Get the next template grid point in the top row. +// Returns NULL when there are no more points in the top row. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// + +GridPoint *GridTemplate::getNextInTopEdge(void) const { + + while(_pointInTopEdgeIterator != _offsetTopEdge.end()) { + GridOffset *offset = *_pointInTopEdgeIterator; + + _pointInTopEdgeIterator++; + + _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; + _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; + + // Apply global wrap logic + _pointInGridReturn.x = (_wrapLon ? + positive_modulo(_pointInGridReturn.x, _pointInGridNumX) : + _pointInGridReturn.x); + + if(_pointInGridReturn.x >= 0 && + _pointInGridReturn.x < _pointInGridNumX && + _pointInGridReturn.y >= 0 && + _pointInGridReturn.y < _pointInGridNumY) { + return &_pointInGridReturn; + } + } // end while + + return (GridPoint *)NULL; } -/********************************************************************** - * getFirstInRgtEdge() - Get the first template grid point in the - * right column. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Get the first template grid point in the right column. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// -GridPoint *GridTemplate::getFirstInRgtEdge(void) const -{ - // Reset the iterator and send back the first point +GridPoint *GridTemplate::getFirstInRgtEdge(void) const { - _pointInRgtEdgeIterator = _offsetRgtEdge.begin(); + // Reset the iterator and send back the first point + _pointInRgtEdgeIterator = _offsetRgtEdge.begin(); - return getNextInRgtEdge(); + return getNextInRgtEdge(); } -/********************************************************************** - * getNextInRgtEdge() - Get the next template grid point in the right - * column. Returns NULL when there are no more - * points in the right column. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ - -GridPoint *GridTemplate::getNextInRgtEdge(void) const -{ - while (_pointInRgtEdgeIterator != _offsetRgtEdge.end()) - { - GridOffset *offset = *_pointInRgtEdgeIterator; - - _pointInRgtEdgeIterator++; - - _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; - _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; - - if (_pointInGridReturn.x >= 0 && - _pointInGridReturn.x < _pointInGridNumX && - _pointInGridReturn.y >= 0 && - _pointInGridReturn.y < _pointInGridNumY) - { - return &_pointInGridReturn; - } - - } - - return (GridPoint *)NULL; +/////////////////////////////////////////////////////////////////////////////// +// +// Get the next template grid point in the right column. +// Returns NULL when there are no more points in the right column. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// + +GridPoint *GridTemplate::getNextInRgtEdge(void) const { + + while(_pointInRgtEdgeIterator != _offsetRgtEdge.end()) { + GridOffset *offset = *_pointInRgtEdgeIterator; + + _pointInRgtEdgeIterator++; + + _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; + _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; + + // Apply global wrap logic + _pointInGridReturn.x = (_wrapLon ? + positive_modulo(_pointInGridReturn.x, _pointInGridNumX) : + _pointInGridReturn.x); + + if(_pointInGridReturn.x >= 0 && + _pointInGridReturn.x < _pointInGridNumX && + _pointInGridReturn.y >= 0 && + _pointInGridReturn.y < _pointInGridNumY) { + return &_pointInGridReturn; + } + } // end while + + return (GridPoint *)NULL; } -/********************************************************************** - * getFirstInBotEdge() - Get the first template grid point in the - * bottom row. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Get the first template grid point in the bottom row. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// -GridPoint *GridTemplate::getFirstInBotEdge(void) const -{ - // Reset the iterator and send back the first point +GridPoint *GridTemplate::getFirstInBotEdge(void) const { - _pointInBotEdgeIterator = _offsetBotEdge.begin(); + // Reset the iterator and send back the first point + _pointInBotEdgeIterator = _offsetBotEdge.begin(); - return getNextInBotEdge(); + return getNextInBotEdge(); } -/********************************************************************** - * getNextInBotEdge() - Get the next template grid point in the bottom - * row. Returns NULL when there are no more points - * in the bottom row. - * - * Returns a pointer to a static object which must NOT be deleted by the - * calling routine. - */ - -GridPoint *GridTemplate::getNextInBotEdge(void) const -{ - while (_pointInBotEdgeIterator != _offsetBotEdge.end()) - { - GridOffset *offset = *_pointInBotEdgeIterator; - - _pointInBotEdgeIterator++; - - _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; - _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; - - if (_pointInGridReturn.x >= 0 && - _pointInGridReturn.x < _pointInGridNumX && - _pointInGridReturn.y >= 0 && - _pointInGridReturn.y < _pointInGridNumY) - { - return &_pointInGridReturn; - } - - } - - return (GridPoint *)NULL; +/////////////////////////////////////////////////////////////////////////////// +// +// Get the next template grid point in the bottom row. +// Returns NULL when there are no more points in the bottom row. +// Initialize the grid dimensions and base location. +// +// Returns a pointer to a static object which must NOT be deleted +// by the calling routine. +// +/////////////////////////////////////////////////////////////////////////////// + +GridPoint *GridTemplate::getNextInBotEdge(void) const { + + while(_pointInBotEdgeIterator != _offsetBotEdge.end()) { + GridOffset *offset = *_pointInBotEdgeIterator; + + _pointInBotEdgeIterator++; + + _pointInGridReturn.x = _pointInGridBase.x + offset->x_offset; + _pointInGridReturn.y = _pointInGridBase.y + offset->y_offset; + + // Apply global wrap logic + _pointInGridReturn.x = (_wrapLon ? + positive_modulo(_pointInGridReturn.x, _pointInGridNumX) : + _pointInGridReturn.x); + + if(_pointInGridReturn.x >= 0 && + _pointInGridReturn.x < _pointInGridNumX && + _pointInGridReturn.y >= 0 && + _pointInGridReturn.y < _pointInGridNumY) { + return &_pointInGridReturn; + } + } // end while + + return (GridPoint *)NULL; } -/********************************************************************** - * setGrid() - Initialize the grid dimensions and base location. - * - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Initialize the grid dimensions and base location. +// +/////////////////////////////////////////////////////////////////////////////// void GridTemplate::setGrid(const int &base_x, const int &base_y, - const int &nx, const int &ny) const -{ - // Set up the iterators and save the grid information + const int &nx, const int &ny) const { - _pointInGridIterator = _offsetList.begin(); + // Set up the iterators and save the grid information + _pointInGridIterator = _offsetList.begin(); - _pointInLftEdgeIterator = _offsetLftEdge.begin(); - _pointInRgtEdgeIterator = _offsetRgtEdge.begin(); - _pointInTopEdgeIterator = _offsetTopEdge.begin(); - _pointInBotEdgeIterator = _offsetBotEdge.begin(); + _pointInLftEdgeIterator = _offsetLftEdge.begin(); + _pointInRgtEdgeIterator = _offsetRgtEdge.begin(); + _pointInTopEdgeIterator = _offsetTopEdge.begin(); + _pointInBotEdgeIterator = _offsetBotEdge.begin(); - _pointInGridBase.x = base_x; - _pointInGridBase.y = base_y; + _pointInGridBase.x = base_x; + _pointInGridBase.y = base_y; - _pointInGridNumX = nx; - _pointInGridNumY = ny; + _pointInGridNumX = nx; + _pointInGridNumY = ny; - return; + return; } -/********************************************************************** - * incBaseX() - Increment the base_x location and reset the offset - * iterators. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Increment the base_x location and reset the offset iterators. +// +/////////////////////////////////////////////////////////////////////////////// + +void GridTemplate::incBaseX(const int &x_inc) const { -void GridTemplate::incBaseX(const int &x_inc) const -{ + _pointInGridBase.x += x_inc; - _pointInGridBase.x += x_inc; + // Apply global wrap logic + _pointInGridBase.x = (_wrapLon ? + positive_modulo(_pointInGridBase.x, _pointInGridNumX) : + _pointInGridBase.x); - if (_pointInGridBase.x < 0 || + if(_pointInGridBase.x < 0 || _pointInGridBase.x >= _pointInGridNumX ) { - mlog << Error << "\nGridTemplate::incBaseX() -> " - << "x (" << _pointInGridBase.x << ") out of range (0, " - << _pointInGridNumX << ").\n\n"; - exit(1); - } + mlog << Error << "\nGridTemplate::incBaseX() -> " + << "x (" << _pointInGridBase.x << ") out of range (0, " + << _pointInGridNumX << ").\n\n"; + exit(1); + } - return; + return; } -/********************************************************************** - * incBaseY() - Increment the base_y location and reset the offset - * iterators. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Increment the base_y location and reset the offset iterators. +// +/////////////////////////////////////////////////////////////////////////////// -void GridTemplate::incBaseY(const int &y_inc) const -{ +void GridTemplate::incBaseY(const int &y_inc) const { - _pointInGridBase.y += y_inc; + _pointInGridBase.y += y_inc; - if (_pointInGridBase.y < 0 || + if(_pointInGridBase.y < 0 || _pointInGridBase.y >= _pointInGridNumY ) { - mlog << Error << "\nGridTemplate::incBaseY() -> " - << "y (" << _pointInGridBase.y << ") out of range (0, " - << _pointInGridNumY << ").\n\n"; - exit(1); - } + mlog << Error << "\nGridTemplate::incBaseY() -> " + << "y (" << _pointInGridBase.y << ") out of range (0, " + << _pointInGridNumY << ").\n\n"; + exit(1); + } - return; + return; } -/********************************************************************** - * printOffsetList() - Print the offset list to the given stream. This - * is used for debugging. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Print the offset list to the given stream. +// This is used for debugging. +// +/////////////////////////////////////////////////////////////////////////////// -void GridTemplate::printOffsetList(FILE *stream) -{ - vector< GridOffset* >::iterator ol_iterator; +void GridTemplate::printOffsetList(FILE *stream) { + vector< GridOffset* >::iterator ol_iterator; - for (ol_iterator = _offsetList.begin(); + for(ol_iterator = _offsetList.begin(); ol_iterator != _offsetList.end(); - ol_iterator++) - { - GridOffset *offset = *ol_iterator; - - double x = (double)offset->x_offset; - double y = (double)offset->y_offset; - - double distance = sqrt((x * x) + (y * y)); + ol_iterator++) { + GridOffset *offset = *ol_iterator; - fprintf(stream, " %4d %4d %f\n", - offset->x_offset, offset->y_offset, distance); + double x = (double)offset->x_offset; + double y = (double)offset->y_offset; - } + double distance = sqrt((x * x) + (y * y)); + fprintf(stream, " %4d %4d %f\n", + offset->x_offset, offset->y_offset, distance); + } } -/********************************************************************** - * Private Member Functions * - **********************************************************************/ - -/********************************************************************** - * _addOffset() - Add the given offset to the offset list. - */ +/////////////////////////////////////////////////////////////////////////////// +// +// Add the given offset to the offset list. +// +/////////////////////////////////////////////////////////////////////////////// -void GridTemplate::_addOffset(int x_offset, int y_offset) -{ - GridOffset *offset = new GridOffset(x_offset, y_offset); +void GridTemplate::_addOffset(int x_offset, int y_offset) { + GridOffset *offset = new GridOffset(x_offset, y_offset); - _offsetList.push_back(offset); + _offsetList.push_back(offset); - return; + return; } -/********************************************************************** - * _setEdgeOffsets() - Process the current offset list and find the - * edges. - */ - -void GridTemplate::_setEdgeOffsets() -{ - vector< GridOffset* >::iterator v_iterator; - map< int, GridOffset* >::iterator m_iterator; - map< int, GridOffset* > min_x_by_y; - map< int, GridOffset* > max_x_by_y; - map< int, GridOffset* > min_y_by_x; - map< int, GridOffset* > max_y_by_x; - int x, y; - - // Loop over the offsets. - // For each row, find the min/max col. - // For each col, find the min/max row. - - for (v_iterator = _offsetList.begin(); +/////////////////////////////////////////////////////////////////////////////// +// +// Process the current offset list and find the edges. +// +/////////////////////////////////////////////////////////////////////////////// + +void GridTemplate::_setEdgeOffsets() { + vector::iterator v_iterator; + map::iterator m_iterator; + map min_x_by_y; + map max_x_by_y; + map min_y_by_x; + map max_y_by_x; + int x, y; + + // Loop over the offsets. + // For each row, find the min/max col. + // For each col, find the min/max row. + + for(v_iterator = _offsetList.begin(); v_iterator != _offsetList.end(); - v_iterator++) - { - GridOffset *offset = *v_iterator; - x = offset->x_offset; - y = offset->y_offset; - - // Min x for each y - if(min_x_by_y.count(y) == 0) { min_x_by_y[y] = offset; } - else if(x < min_x_by_y[y]->x_offset) { min_x_by_y[y] = offset; } - - // Max x for each y - if(max_x_by_y.count(y) == 0) { max_x_by_y[y] = offset; } - else if(x > max_x_by_y[y]->x_offset) { max_x_by_y[y] = offset; } - - // Min y for each x - if(min_y_by_x.count(x) == 0) { min_y_by_x[x] = offset; } - else if(y < min_y_by_x[x]->y_offset) { min_y_by_x[x] = offset; } - - // Max y for each x - if(max_y_by_x.count(x) == 0) { max_y_by_x[x] = offset; } - else if(y > max_y_by_x[x]->y_offset) { max_y_by_x[x] = offset; } - - } + v_iterator++) { + GridOffset *offset = *v_iterator; + x = offset->x_offset; + y = offset->y_offset; + + // Min x for each y + if(min_x_by_y.count(y) == 0) { min_x_by_y[y] = offset; } + else if(x < min_x_by_y[y]->x_offset) { min_x_by_y[y] = offset; } + + // Max x for each y + if(max_x_by_y.count(y) == 0) { max_x_by_y[y] = offset; } + else if(x > max_x_by_y[y]->x_offset) { max_x_by_y[y] = offset; } + + // Min y for each x + if(min_y_by_x.count(x) == 0) { min_y_by_x[x] = offset; } + else if(y < min_y_by_x[x]->y_offset) { min_y_by_x[x] = offset; } + + // Max y for each x + if(max_y_by_x.count(x) == 0) { max_y_by_x[x] = offset; } + else if(y > max_y_by_x[x]->y_offset) { max_y_by_x[x] = offset; } + } - // Store min_x_by_y map as _offsetLftEdge vector - for (m_iterator = min_x_by_y.begin(); + // Store min_x_by_y map as _offsetLftEdge vector + for(m_iterator = min_x_by_y.begin(); m_iterator != min_x_by_y.end(); - m_iterator++) - { - _offsetLftEdge.push_back(m_iterator->second); - } + m_iterator++) { + _offsetLftEdge.push_back(m_iterator->second); + } - // Store max_x_by_y map as _offsetRgtEdge vector - for (m_iterator = max_x_by_y.begin(); + // Store max_x_by_y map as _offsetRgtEdge vector + for(m_iterator = max_x_by_y.begin(); m_iterator != max_x_by_y.end(); - m_iterator++) - { - _offsetRgtEdge.push_back(m_iterator->second); - } + m_iterator++) { + _offsetRgtEdge.push_back(m_iterator->second); + } - // Store max_y_by_x map as _offsetTopEdge vector - for (m_iterator = max_y_by_x.begin(); + // Store max_y_by_x map as _offsetTopEdge vector + for(m_iterator = max_y_by_x.begin(); m_iterator != max_y_by_x.end(); - m_iterator++) - { - _offsetTopEdge.push_back(m_iterator->second); - } + m_iterator++) { + _offsetTopEdge.push_back(m_iterator->second); + } - // Store min_y_by_x map as _offsetBotEdge vector - for (m_iterator = min_y_by_x.begin(); + // Store min_y_by_x map as _offsetBotEdge vector + for(m_iterator = min_y_by_x.begin(); m_iterator != min_y_by_x.end(); - m_iterator++) - { - _offsetBotEdge.push_back(m_iterator->second); - } + m_iterator++) { + _offsetBotEdge.push_back(m_iterator->second); + } - return; + return; } -//////////////////////////////////////////////////////////////// -// GridTemplateFactory -//////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// Code for class GridTemplateFactory. +// +/////////////////////////////////////////////////////////////////////////////// + GridTemplateFactory::GridTemplateFactory() { enum_to_string.resize(GridTemplate_NUM_TEMPLATES); enum_to_string[GridTemplate_None] = ""; enum_to_string[GridTemplate_Square] = "SQUARE"; enum_to_string[GridTemplate_Circle] = "CIRCLE"; - //enum_to_string[GridTemplate_Rectangle] = "RECTANGLE"; } +/////////////////////////////////////////////////////////////////////////////// + GridTemplateFactory::~GridTemplateFactory() { enum_to_string.clear(); } -///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// // log & exit on failure +// +/////////////////////////////////////////////////////////////////////////////// + GridTemplateFactory::GridTemplates GridTemplateFactory::string2Enum(string target) { - for (unsigned int ix = 0; ix < GridTemplate_NUM_TEMPLATES; ix++){ - if (enum_to_string[ix] == target){ + for(unsigned int ix = 0; ix < GridTemplate_NUM_TEMPLATES; ix++) { + if(enum_to_string[ix] == target) { return static_cast(ix); } } @@ -621,13 +622,15 @@ GridTemplateFactory::GridTemplates GridTemplateFactory::string2Enum(string targe exit(1); } - -///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// // log & exit on failure -string GridTemplateFactory::enum2String(GridTemplates target) { +// +/////////////////////////////////////////////////////////////////////////////// - if( static_cast(target) > enum_to_string.size() - 1){ +string GridTemplateFactory::enum2String(GridTemplates target) { + if(static_cast(target) > enum_to_string.size() - 1) { mlog << Error << "\nGridTemplateFactory::enum2String() -> " << "target out of range " << target << " > " << (static_cast(enum_to_string.size()) - 1) @@ -637,26 +640,36 @@ string GridTemplateFactory::enum2String(GridTemplates target) { return enum_to_string[static_cast(target)]; } -///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// // Caller assumes ownership of the returned pointer. -GridTemplate* GridTemplateFactory::buildGT(string gt, int width) { - return buildGT(string2Enum(gt), width); +// +/////////////////////////////////////////////////////////////////////////////// + +GridTemplate* GridTemplateFactory::buildGT(string gt, int width, bool wrap_lon) { + return buildGT(string2Enum(gt), width, wrap_lon); } -///////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// // Caller assumes ownership of the returned pointer. -GridTemplate* GridTemplateFactory::buildGT(GridTemplates gt, int width) { +// +/////////////////////////////////////////////////////////////////////////////// + +GridTemplate* GridTemplateFactory::buildGT(GridTemplates gt, int width, bool wrap_lon) { switch (gt) { case(GridTemplate_Square): - return new RectangularTemplate(width,width); + return new RectangularTemplate(width, width, wrap_lon); case(GridTemplate_Circle): - return new CircularTemplate(width); + return new CircularTemplate(width, wrap_lon); default: mlog << Error << "\nbuildGT() -> " - << "Unexpected gt value of " << gt << ".\n\n"; + << "Unexpected GridTemplates value (" << gt << ").\n\n"; exit(1); } } + +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/GridTemplate.h b/met/src/basic/vx_util/GridTemplate.h index 28cfffec62..fd356c5f36 100644 --- a/met/src/basic/vx_util/GridTemplate.h +++ b/met/src/basic/vx_util/GridTemplate.h @@ -1,53 +1,30 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -/* RCS info - * $Author: dixon $ - * $Locker: $ - * $Date: 2016/03/03 19:21:31 $ - * $Id: GridTemplate.hh,v 1.9 2016/03/03 19:21:31 dixon Exp $ - * $Revision: 1.9 $ - * $State: Exp $ - */ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ - -/************************************************************************ - * GridTemplate.hh: class implementing a template to be applied to - * gridded data. - * - * RAP, NCAR, Boulder CO - * - * January 1999 - * - * Nancy Rehak - * - ************************************************************************/ - -#ifndef GridTemplate_HH -#define GridTemplate_HH +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: GridTemplate.h +// +// Description: +// Class implementing a template to be applied to +// gridded data. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-99 Rehak Initial version. +// 001 09-07-21 Halley Gotway Add wrap_lon. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __GRID_TEMPLATE_H__ +#define __GRID_TEMPLATE_H__ + +/////////////////////////////////////////////////////////////////////////////// #include #include @@ -55,177 +32,154 @@ #include "GridOffset.h" #include "GridPoint.h" -using namespace std; - -class GridTemplate -{ - public: - - // Constructors - - GridTemplate(void); - GridTemplate(const GridTemplate& rhs); - - // Destructor - - virtual ~GridTemplate(void); +/////////////////////////////////////////////////////////////////////////////// - // Methods for iterating through the template within the grid centered - // on the given point. To use these methods, first call getFirstInGrid() - // to get the first point. Then call getNextInGrid() to get all remaining - // points until a (GridPoint *)NULL is returned. Any time getFirstInGrid() - // is called, the iteration will be cleared and will start over again. - // - // base_x and base_y give the coordinates of the point around which the - // template is to be applied. - // - // These routines return a point to a static object which must NOT be - // deleted by the calling routine. +using namespace std; - GridPoint *getFirstInGrid(const int &base_x, const int &base_y, - const int &nx, const int &ny) const; - GridPoint *getNextInGrid(void) const; +class GridTemplate { - GridPoint *getFirst(const int &base_x, const int &base_y, - const int &nx, const int &ny) const; - GridPoint *getNext(void) const; + public: - GridPoint *getFirstInLftEdge(void) const; - GridPoint *getNextInLftEdge(void) const; + GridTemplate(void); + GridTemplate(const GridTemplate& rhs); + virtual ~GridTemplate(void); - GridPoint *getFirstInRgtEdge(void) const; - GridPoint *getNextInRgtEdge(void) const; + // Methods for iterating through the template within the grid centered + // on the given point. To use these methods, first call getFirstInGrid() + // to get the first point. Then call getNextInGrid() to get all remaining + // points until a (GridPoint *)NULL is returned. Any time getFirstInGrid() + // is called, the iteration will be cleared and will start over again. + // + // base_x and base_y give the coordinates of the point around which the + // template is to be applied. + // + // These routines return a point to a static object which must NOT be + // deleted by the calling routine. - GridPoint *getFirstInTopEdge(void) const; - GridPoint *getNextInTopEdge(void) const; + GridPoint *getFirstInGrid(const int &base_x, const int &base_y, + const int &nx, const int &ny) const; + GridPoint *getNextInGrid(void) const; - GridPoint *getFirstInBotEdge(void) const; - GridPoint *getNextInBotEdge(void) const; + GridPoint *getFirst(const int &base_x, const int &base_y, + const int &nx, const int &ny) const; + GridPoint *getNext(void) const; - void setGrid(const int &base_x, const int &base_y, - const int &nx, const int &ny) const; + GridPoint *getFirstInLftEdge(void) const; + GridPoint *getNextInLftEdge(void) const; - void incBaseX(const int &x_inc) const; - void incBaseY(const int &y_inc) const; + GridPoint *getFirstInRgtEdge(void) const; + GridPoint *getNextInRgtEdge(void) const; - // Printing methods + GridPoint *getFirstInTopEdge(void) const; + GridPoint *getNextInTopEdge(void) const; - void printOffsetList(FILE *stream); + GridPoint *getFirstInBotEdge(void) const; + GridPoint *getNextInBotEdge(void) const; - // Access methods + void setGrid(const int &base_x, const int &base_y, + const int &nx, const int &ny) const; - inline void addOffset(const GridOffset &offset) - { - _offsetList.push_back(new GridOffset(offset.x_offset, - offset.y_offset)); - } + void incBaseX(const int &x_inc) const; + void incBaseY(const int &y_inc) const; - inline void addOffset(const int x_offset, const int y_offset) - { - _offsetList.push_back(new GridOffset(x_offset, y_offset)); - } + // Printing methods - int size(void) const - { - return _offsetList.size(); - } + void printOffsetList(FILE *stream); - int getNumPts(void) const - { - return _offsetList.size(); - } + // Access methods - virtual const char* getClassName(void) const = 0; + inline void addOffset(const GridOffset &offset) { + _offsetList.push_back(new GridOffset(offset.x_offset, + offset.y_offset)); + } - virtual int getWidth() const = 0; + inline void addOffset(const int x_offset, const int y_offset) { + _offsetList.push_back(new GridOffset(x_offset, y_offset)); + } - protected: + int size(void) const { + return _offsetList.size(); + } - // The offsets that make up the circle + int getNumPts(void) const { + return _offsetList.size(); + } - vector< GridOffset* > _offsetList; + int getWrapLon(void) const { + return _wrapLon; + } - // The offsets that define the first and last rows and columns + virtual const char* getClassName(void) const = 0; - vector< GridOffset* > _offsetLftEdge; // not allocated - vector< GridOffset* > _offsetRgtEdge; // not allocated - vector< GridOffset* > _offsetTopEdge; // not allocated - vector< GridOffset* > _offsetBotEdge; // not allocated + virtual int getWidth() const = 0; - // Iterator for finding points within a grid + protected: - mutable vector< GridOffset* >::const_iterator _pointInGridIterator; - mutable vector< GridOffset* >::const_iterator _pointInLftEdgeIterator; - mutable vector< GridOffset* >::const_iterator _pointInRgtEdgeIterator; - mutable vector< GridOffset* >::const_iterator _pointInTopEdgeIterator; - mutable vector< GridOffset* >::const_iterator _pointInBotEdgeIterator; + bool _wrapLon; - mutable GridPoint _pointInGridBase; - mutable int _pointInGridNumX; - mutable int _pointInGridNumY; - mutable GridPoint _pointInGridReturn; + // The offsets that make up the circle + vector _offsetList; - // Add the given offset to the offset list + // The offsets that define the first and last rows and columns + vector _offsetLftEdge; // not allocated + vector _offsetRgtEdge; // not allocated + vector _offsetTopEdge; // not allocated + vector _offsetBotEdge; // not allocated - void _addOffset(int x_offset, int y_offset); + // Iterator for finding points within a grid + mutable vector::const_iterator _pointInGridIterator; + mutable vector::const_iterator _pointInLftEdgeIterator; + mutable vector::const_iterator _pointInRgtEdgeIterator; + mutable vector::const_iterator _pointInTopEdgeIterator; + mutable vector::const_iterator _pointInBotEdgeIterator; - // Determine the offsets for the First/Last Row/Column + mutable GridPoint _pointInGridBase; + mutable int _pointInGridNumX; + mutable int _pointInGridNumY; + mutable GridPoint _pointInGridReturn; - void _setEdgeOffsets(); + // Add the given offset to the offset list + void _addOffset(int x_offset, int y_offset); + // Determine the offsets for the First/Last Row/Column + void _setEdgeOffsets(); }; +/////////////////////////////////////////////////////////////////////////////// + // The factory knows about child classes and can create them for you class GridTemplateFactory { - public: - - // constructor - GridTemplateFactory(); + public: - // destructor - ~GridTemplateFactory(); - // do not assign specific values to these enumes. - // other code requires them to start at zero and increase by 1 - // make sure GridTemplate_NUM_TEMPLATES is always last. - // TODO: rename this Shape - enum GridTemplates { - GridTemplate_None, - GridTemplate_Square, - GridTemplate_Circle, - //GridTemplate_Rectangle, - GridTemplate_NUM_TEMPLATES - }; + GridTemplateFactory(); + ~GridTemplateFactory(); - // String corresponding to the enumerated values above - vector enum_to_string; + // do not assign specific values to these enumes. + // other code requires them to start at zero and increase by 1 + // make sure GridTemplate_NUM_TEMPLATES is always last. + enum GridTemplates { + GridTemplate_None, + GridTemplate_Square, + GridTemplate_Circle, + GridTemplate_NUM_TEMPLATES + }; -///////////////////////////////////////////////////////////////// -// exit on failure - GridTemplates string2Enum(string target); + // String corresponding to the enumerated values above + vector enum_to_string; -////////////////////////////////////////////////////////////// -// exit on failure - string enum2String(GridTemplates gt); + GridTemplates string2Enum(string target); + string enum2String(GridTemplates gt); -///////////////////////////////////////////////////////////////// -// Caller assumes ownership of the returned pointer. - GridTemplate* buildGT(string gt, int width); + GridTemplate* buildGT(string gt, int width, bool wrap_lon); + GridTemplate* buildGT(GridTemplates gt, int width, bool wrap_lon); -///////////////////////////////////////////////////////////////// -// Caller assumes ownership of the returned pointer. - GridTemplate* buildGT(GridTemplates gt, int width); - - //FUTURE DEV NOTE: - // If we ever decide to support rectangles or elipses, we are going to - // need to modify these methods to take more than just a single width & shape - // to define the grid template. I suggest building a structure/union that holds - // all the defining characteristics of a grid template (shape, height, width, radius, etc.) - // and passing that around everywhere that we currently pass around a shape & width. +}; +/////////////////////////////////////////////////////////////////////////////// -}; +#endif // __GRID_TEMPLATE_H__ -#endif +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/RectangularTemplate.cc b/met/src/basic/vx_util/RectangularTemplate.cc index 59c06901a0..7368e2125c 100644 --- a/met/src/basic/vx_util/RectangularTemplate.cc +++ b/met/src/basic/vx_util/RectangularTemplate.cc @@ -1,48 +1,25 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -// RCS info -// $Author: dixon $ -// $Locker: $ -// $Date: 2016/03/03 18:19:27 $ -// $Id: RectangularTemplate.cc,v 1.4 2016/03/03 18:19:27 dixon Exp $ -// $Revision: 1.4 $ -// $State: Exp $ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ -/********************************************************************* - * RectangularTemplate.cc: class implementing a Rectangular template - * to be applied on gridded data. - * - * RAP, NCAR, Boulder CO - * - * January 2007 - * - * Dan Megenhardt - * - *********************************************************************/ +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: RectangularTemplate.cc +// +// Description: +// Class implementing a Rectangular template to be +// applied on gridded data. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-07 Megenhardt Initial version. +// 001 09-07-21 Halley Gotway Add wrap_lon. +// +/////////////////////////////////////////////////////////////////////////////// #include @@ -52,82 +29,63 @@ #include #include #include + using namespace std; -/********************************************************************** - * Constructor - */ - -RectangularTemplate::RectangularTemplate(int height, int width) : - GridTemplate(), - _height(height), - _width(width) -{ - - /* - CONVENTION: - If width is even, we push the center to the lower left corner - and have the "extra" in the right & above. - */ - - bool evenWidth = ((width % 2) == 0); - bool evenHeight = ((height % 2) == 0); - - // equivalent of w/2 for even & (w-1)/2 for odd - int halfwidth = width / 2; - int halfheight = height / 2; - - int xmin = halfwidth; - int ymin = halfheight; - - if (evenWidth){ - xmin--; - } - if (evenHeight){ - ymin--; - } - - // Create the offsets list - for (int y = -ymin; y <= halfheight; y++) - { - for (int x = -xmin; x <= halfheight; x++) - { - _addOffset(x, y); - } /* endfor x = 0 */ - } /* endfor y = 0*/ - - _setEdgeOffsets(); -} +/////////////////////////////////////////////////////////////////////////////// +RectangularTemplate::RectangularTemplate(int height, int width, bool wrap_lon) : + GridTemplate(), _height(height), _width(width) { -/********************************************************************** - * Destructor - */ + _wrapLon = wrap_lon; -RectangularTemplate::~RectangularTemplate(void) -{ - // Do nothing -} + // + // CONVENTION: + // If width is even, we push the center to the lower left corner + // and have the "extra" in the right & above. + // + bool evenWidth = ((width % 2) == 0); + bool evenHeight = ((height % 2) == 0); -/********************************************************************** - * printOffsetList() - Print the offset list to the given stream. This - * is used for debugging. - */ + // equivalent of w/2 for even & (w-1)/2 for odd + int halfwidth = width / 2; + int halfheight = height / 2; -void RectangularTemplate::printOffsetList(FILE *stream) -{ - fprintf(stream, "\n\n"); - fprintf(stream, "Rectangular template:"); - fprintf(stream, " height = %d\n", _height); - fprintf(stream, " width = %d\n", _width); + int xmin = halfwidth; + int ymin = halfheight; - fprintf(stream, " grid points:\n"); + if(evenWidth) xmin--; + if(evenHeight) ymin--; + + // Create the offsets list + for(int y = -ymin; y <= halfheight; y++) { + for(int x = -xmin; x <= halfwidth; x++) { + _addOffset(x, y); + } // end for x + } // end for y + + _setEdgeOffsets(); - GridTemplate::printOffsetList(stream); } +/////////////////////////////////////////////////////////////////////////////// + +RectangularTemplate::~RectangularTemplate(void) { + // Do nothing +} + +/////////////////////////////////////////////////////////////////////////////// + +void RectangularTemplate::printOffsetList(FILE *stream) { + fprintf(stream, "\n\n"); + fprintf(stream, "Rectangular template:"); + fprintf(stream, " height = %d\n", _height); + fprintf(stream, " width = %d\n", _width); + fprintf(stream, " wrap_lon = %d\n", _wrapLon); + fprintf(stream, " grid points:\n"); + + GridTemplate::printOffsetList(stream); +} -/********************************************************************** - * Private Member Functions * - **********************************************************************/ +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/RectangularTemplate.h b/met/src/basic/vx_util/RectangularTemplate.h index b45dcb6a77..507286adbc 100644 --- a/met/src/basic/vx_util/RectangularTemplate.h +++ b/met/src/basic/vx_util/RectangularTemplate.h @@ -1,57 +1,30 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2021 +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* +// ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) -// ** Boulder, Colorado, USA -// ** BSD licence applies - redistribution and use in source and binary -// ** forms, with or without modification, are permitted provided that -// ** the following conditions are met: -// ** 1) If the software is modified to produce derivative works, -// ** such modified software should be clearly marked, so as not -// ** to confuse it with the version available from UCAR. -// ** 2) Redistributions of source code must retain the above copyright -// ** notice, this list of conditions and the following disclaimer. -// ** 3) Redistributions in binary form must reproduce the above copyright -// ** notice, this list of conditions and the following disclaimer in the -// ** documentation and/or other materials provided with the distribution. -// ** 4) Neither the name of UCAR nor the names of its contributors, -// ** if any, may be used to endorse or promote products derived from -// ** this software without specific prior written permission. -// ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ - -/* RCS info - * $Author: dixon $ - * $Locker: $ - * $Date: 2016/03/03 19:21:31 $ - * $Id: RectangularTemplate.hh,v 1.3 2016/03/03 19:21:31 dixon Exp $ - * $Revision: 1.3 $ - * $State: Exp $ - */ - -/**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**/ - -/************************************************************************ - * RectangularTemplate.hh: class implementing a Rectangular template to be - * applied on gridded data. - * - * RAP, NCAR, Boulder CO - * - * January 2007 - * - * Dan Megenhardt - * - ************************************************************************/ - -#ifndef RectangularTemplate_HH -#define RectangularTemplate_HH - -/* - **************************** includes ********************************** - */ +// ** Research Applications Lab (RAL) +// ** P.O.Box 3000, Boulder, Colorado, 80307-3000, USA +// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* + +/////////////////////////////////////////////////////////////////////////////// +// +// Filename: RectangularTemplate.h +// +// Description: +// Class implementing a Rectangular template to be +// applied on gridded data. +// +// Mod# Date Name Description +// ---- ---- ---- ----------- +// 000 01-01-07 Megenhardt Initial version. +// 001 09-07-21 Halley Gotway Add wrap_lon. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __RECTANGULAR_TEMPLATE_H__ +#define __RECTANGULAR_TEMPLATE_H__ + +/////////////////////////////////////////////////////////////////////////////// #include @@ -61,71 +34,44 @@ #include #include -/* - ******************************* defines ******************************** - */ +/////////////////////////////////////////////////////////////////////////////// -/* - ******************************* structures ***************************** - */ +class RectangularTemplate : public GridTemplate { -/* - ************************* global variables ***************************** - */ + public: -/* - ***************************** function prototypes ********************** - */ + RectangularTemplate(int height, int width, bool wrap_lon); + virtual ~RectangularTemplate(void); -/* - ************************* class definitions **************************** - */ + void printOffsetList(FILE *stream); -class RectangularTemplate : public GridTemplate -{ - public: + // Access methods - // Constructor - RectangularTemplate(int height, int width); + int getHeight(void) const { + return _height; + } - // Destructor + int getWidth(void) const { + return _width; + } - virtual ~RectangularTemplate(void); + const char* getClassName(void) const { + return RectangularTemplate::_className(); + } - // Print the offset list to the given stream. This is used for debugging. + private: - void printOffsetList(FILE *stream); - - // Access methods - - int getHeight(void) const - { - return _height; - } - - int getWidth(void) const - { - return _width; - } - - const char* getClassName(void) const{ - return RectangularTemplate::_className(); - } - - private: - - // The box dimensions - - int _height; - int _width; - - // Return the class name for error messages. - static const char* _className(void) - { - return("RectangularTemplate"); - } + int _height; + int _width; + // Return the class name for error messages. + static const char* _className(void) { + return("RectangularTemplate"); + } }; +/////////////////////////////////////////////////////////////////////////////// + +#endif // __RECTANGULAR_TEMPLATE_H__ -#endif +/////////////////////////////////////////////////////////////////////////////// diff --git a/met/src/basic/vx_util/data_plane_util.cc b/met/src/basic/vx_util/data_plane_util.cc index 0004abe0f8..38b5469c5a 100644 --- a/met/src/basic/vx_util/data_plane_util.cc +++ b/met/src/basic/vx_util/data_plane_util.cc @@ -95,7 +95,7 @@ void rescale_probability(DataPlane &dp) { void smooth_field(const DataPlane &dp, DataPlane &smooth_dp, InterpMthd mthd, int width, const GridTemplateFactory::GridTemplates shape, - double t, const GaussianInfo &gaussian) { + bool wrap_lon, double t, const GaussianInfo &gaussian) { double v = 0.0; int x, y; @@ -107,10 +107,11 @@ void smooth_field(const DataPlane &dp, DataPlane &smooth_dp, // build the grid template GridTemplateFactory gtf; - GridTemplate* gt = gtf.buildGT(shape, width); + GridTemplate* gt = gtf.buildGT(shape, width, wrap_lon); mlog << Debug(3) - << "Smoothing field using the " << interpmthd_to_string(mthd) + << "Smoothing " << (wrap_lon ? "global" : "non-global") + << " field using the " << interpmthd_to_string(mthd) << "(" << gt->size() << ") " << gt->getClassName() << " interpolation method.\n"; @@ -185,10 +186,10 @@ void smooth_field(const DataPlane &dp, DataPlane &smooth_dp, DataPlane smooth_field(const DataPlane &dp, InterpMthd mthd, int width, const GridTemplateFactory::GridTemplates shape, - double t, const GaussianInfo &gaussian) { + bool wrap_lon, double t, const GaussianInfo &gaussian) { DataPlane smooth_dp; - smooth_field(dp, smooth_dp, mthd, width, shape, t, gaussian); + smooth_field(dp, smooth_dp, mthd, width, shape, wrap_lon, t, gaussian); return(smooth_dp); } @@ -202,7 +203,7 @@ DataPlane smooth_field(const DataPlane &dp, void fractional_coverage(const DataPlane &dp, DataPlane &frac_dp, int width, const GridTemplateFactory::GridTemplates shape, - SingleThresh t, double vld_t) { + bool wrap_lon, SingleThresh t, double vld_t) { GridPoint *gp = NULL; int x, y; int n_vld = 0; @@ -218,7 +219,7 @@ void fractional_coverage(const DataPlane &dp, DataPlane &frac_dp, // Build the grid template GridTemplateFactory gtf; - GridTemplate* gt = gtf.buildGT(shape, width); + GridTemplate* gt = gtf.buildGT(shape, width, wrap_lon); mlog << Debug(3) << "Computing fractional coverage field using the " @@ -291,161 +292,6 @@ void fractional_coverage(const DataPlane &dp, DataPlane &frac_dp, return; } -//////////////////////////////////////////////////////////////////////// -// -// Convert the DataPlane field to the corresponding fractional coverage -// using the threshold critea specified. -// -//////////////////////////////////////////////////////////////////////// - -void fractional_coverage_square(const DataPlane &dp, DataPlane &frac_dp, - int width, SingleThresh t, double vld_t) { - int i, j, k, n, x, y, x_ll, y_ll, y_ur, xx, yy, half_width; - double v; - int count_vld = 0; - int count_thr = 0; - NumArray box_na; - - mlog << Debug(3) - << "Computing fractional coverage field using the " - << t.get_str() << " threshold and the " - << interpmthd_to_string(InterpMthd_Nbrhd) - << "(" << width*width << ") interpolation method.\n"; - - // Check that width is set to 1 or greater - if(width < 1) { - mlog << Error << "\nfractional_coverage_square() -> " - << "width must be set to a value of 1 or greater.\n\n"; - exit(1); - } - - // Initialize the fractional coverage field - frac_dp = dp; - frac_dp.set_constant(bad_data_double); - - // Compute the box half-width - half_width = (width - 1)/2; - - // Initialize the box - for(i=0; i= dp.nx() || - yy < 0 || yy >= dp.ny()) { - k = bad_data_int; - } - // Check v to see if it meets the threshold criteria - else { - v = dp.get(xx, yy); - if(is_bad_data(v)) k = bad_data_int; - else if(t.check(v)) k = 1; - else k = 0; - } - box_na.set(n, k); - - // Increment the counts - if(!is_bad_data(k)) { - count_vld += 1; - count_thr += k; - } - - } // end for j - } // end for i - } // end if - - // Otherwise, update one row of the box - else { - - // Compute the row of the neighborhood box to be updated - j = (y - 1) % width; - - for(i=0; i= dp.nx() || - yy < 0 || yy >= dp.ny()) { - k = bad_data_int; - } - // Check v to see if it meets the threshold criteria - else { - v = dp.get(xx, yy); - if(is_bad_data(v)) k = bad_data_int; - else if(t.check(v)) k = 1; - else k = 0; - } - box_na.set(n, k); - - // Increment the counts - if(!is_bad_data(k)) { - count_vld += 1; - count_thr += k; - } - - } // end for i - } // end else - - // Check whether enough valid grid points were found - if((double) count_vld/(width*width) < vld_t || - count_vld == 0) { - v = bad_data_double; - } - // Compute the fractional coverage - else { - v = (double) count_thr/count_vld; - } - - // Store the fractional coverage value - frac_dp.set(v, x, y); - - } // end for y - } // end for x - - return; - -} - //////////////////////////////////////////////////////////////////////// // // Select points inside the mask and write them to a NumArray. diff --git a/met/src/basic/vx_util/data_plane_util.h b/met/src/basic/vx_util/data_plane_util.h index 401a22c2f7..2531cb80f1 100644 --- a/met/src/basic/vx_util/data_plane_util.h +++ b/met/src/basic/vx_util/data_plane_util.h @@ -43,19 +43,16 @@ extern void rescale_probability(DataPlane &); extern void smooth_field(const DataPlane &dp, DataPlane &smooth_dp, InterpMthd mthd, int width, const GridTemplateFactory::GridTemplates shape, - double t, const GaussianInfo &gaussian); + bool wrap_lon, double t, const GaussianInfo &gaussian); extern DataPlane smooth_field(const DataPlane &dp, InterpMthd mthd, int width, const GridTemplateFactory::GridTemplates shape, - double t, const GaussianInfo &gaussian); + bool wrap_lon, double t, const GaussianInfo &gaussian); extern void fractional_coverage(const DataPlane &dp, DataPlane &frac_dp, int width, const GridTemplateFactory::GridTemplates shape, - SingleThresh t, double vld_t); - -extern void fractional_coverage_square(const DataPlane &dp, DataPlane &frac_dp, - int width, SingleThresh t, double vld_t); + bool wrap_lon, SingleThresh t, double vld_t); extern void apply_mask(const DataPlane &, const MaskPlane &, NumArray &); extern void apply_mask(DataPlane &, const MaskPlane &); diff --git a/met/src/basic/vx_util/interp_util.cc b/met/src/basic/vx_util/interp_util.cc index 1f1de88bea..ac37311a9e 100644 --- a/met/src/basic/vx_util/interp_util.cc +++ b/met/src/basic/vx_util/interp_util.cc @@ -18,7 +18,6 @@ using namespace std; #include #include -//#include "interp_mthd.h" #include "interp_util.h" #include "GridTemplate.h" #include "RectangularTemplate.h" @@ -739,26 +738,30 @@ double interp_nbrhd(const DataPlane &dp, const GridTemplate >, int x, int y, // //////////////////////////////////////////////////////////////////////// -double interp_bilin(const DataPlane &dp, double obs_x, double obs_y, - const MaskPlane *mp) { - int x, y; +double interp_bilin(const DataPlane &dp, bool wrap_lon, + double obs_x, double obs_y, const MaskPlane *mp) { + int x, xp1, y; double bilin_v, dx, dy; double wtsw, wtse, wtnw, wtne; x = nint(floor(obs_x)); y = nint(floor(obs_y)); + // Apply global wrap logic to x and x+1 + x = (wrap_lon ? positive_modulo(x, dp.nx()) : x); + xp1 = (wrap_lon ? positive_modulo(x+1, dp.nx()) : x+1); + // Check the optional mask if(mp) { if(!(*mp)(x, y ) || - !(*mp)(x+1, y ) || + !(*mp)(xp1, y ) || !(*mp)(x, y+1) || - !(*mp)(x+1, y+1)) return(bad_data_double); + !(*mp)(xp1, y+1)) return(bad_data_double); } // Compute dx and dy - dx = obs_x - x; - dy = obs_y - y; + dx = obs_x - nint(floor(obs_x)); + dy = obs_y - nint(floor(obs_y)); // Compute weights for 4 corner points wtsw = (1.0-dx) * (1.0-dy); @@ -767,7 +770,7 @@ double interp_bilin(const DataPlane &dp, double obs_x, double obs_y, wtne = dx * dy; // On the grid boundary, check each corner point - if(x < 0 || x+1 >= dp.nx() || y < 0 || y+1 >= dp.ny()) { + if(x < 0 || xp1 >= dp.nx() || y < 0 || y+1 >= dp.ny()) { // Initialize weighted sum bilin_v = 0.0; @@ -784,12 +787,12 @@ double interp_bilin(const DataPlane &dp, double obs_x, double obs_y, // Southeast Corner if(!is_bad_data(bilin_v) && !is_eq(wtse, 0.0)) { - if(x+1 < 0 || x+1 >= dp.nx() || y < 0 || y >= dp.ny()) + if(xp1 < 0 || xp1 >= dp.nx() || y < 0 || y >= dp.ny()) bilin_v = bad_data_double; - else if(is_bad_data(dp.get(x+1, y))) + else if(is_bad_data(dp.get(xp1, y))) bilin_v = bad_data_double; else - bilin_v += wtse * dp.get(x+1, y); + bilin_v += wtse * dp.get(xp1, y); } // Northwest Corner @@ -804,27 +807,27 @@ double interp_bilin(const DataPlane &dp, double obs_x, double obs_y, // Northeast Corner if(!is_bad_data(bilin_v) && !is_eq(wtne, 0.0)) { - if(x+1 < 0 || x+1 >= dp.nx() || y+1 < 0 || y+1 >= dp.ny()) + if(xp1 < 0 || xp1 >= dp.nx() || y+1 < 0 || y+1 >= dp.ny()) bilin_v = bad_data_double; - else if(is_bad_data(dp.get(x+1, y+1))) + else if(is_bad_data(dp.get(xp1, y+1))) bilin_v = bad_data_double; else - bilin_v += wtne * dp.get(x+1, y+1); + bilin_v += wtne * dp.get(xp1, y+1); } } // On the grid interior, compute weighted average else { if(is_bad_data(dp.get(x, y )) || - is_bad_data(dp.get(x+1, y )) || + is_bad_data(dp.get(xp1, y )) || is_bad_data(dp.get(x, y+1)) || - is_bad_data(dp.get(x+1, y+1))) { + is_bad_data(dp.get(xp1, y+1))) { bilin_v = bad_data_double; } else { bilin_v = wtsw * dp.get(x, y) + - wtse * dp.get(x+1, y) + + wtse * dp.get(xp1, y) + wtnw * dp.get(x, y+1) + - wtne * dp.get(x+1, y+1); + wtne * dp.get(xp1, y+1); } } @@ -837,10 +840,13 @@ double interp_bilin(const DataPlane &dp, double obs_x, double obs_y, // //////////////////////////////////////////////////////////////////////// -double interp_xy(const DataPlane &dp, int x, int y, +double interp_xy(const DataPlane &dp, bool wrap_lon, int x, int y, const MaskPlane *mp) { double v; + // Apply global wrap logic + x = (wrap_lon ? positive_modulo(x, dp.nx()) : x); + // Check the optional mask if(mp) { if(!(*mp)(x, y)) return(bad_data_double); @@ -932,8 +938,8 @@ double compute_sfc_interp(const DataPlane &dp, double obs_elv, double obs_v, const InterpMthd mthd, const int width, const GridTemplateFactory::GridTemplates shape, - double interp_thresh, const SurfaceInfo &sfc_info, - bool is_land_obs) { + bool wrap_lon, double interp_thresh, + const SurfaceInfo &sfc_info, bool is_land_obs) { double v = bad_data_double; int x = nint(obs_x); int y = nint(obs_y); @@ -945,7 +951,7 @@ double compute_sfc_interp(const DataPlane &dp, } GridTemplateFactory gtf; - const GridTemplate* gt = gtf.buildGT(shape,width); + const GridTemplate* gt = gtf.buildGT(shape, width, wrap_lon); MaskPlane sfc_mask = compute_sfc_mask(*gt, x, y, sfc_info, is_land_obs, obs_elv); @@ -979,11 +985,11 @@ double compute_sfc_interp(const DataPlane &dp, break; case(InterpMthd_Bilin): // Bilinear interpolation - v = interp_bilin(dp, obs_x, obs_y, &sfc_mask); + v = interp_bilin(dp, wrap_lon, obs_x, obs_y, &sfc_mask); break; case(InterpMthd_Nearest): // Nearest Neighbor - v = interp_xy(dp, x, y, &sfc_mask); + v = interp_xy(dp, wrap_lon, x, y, &sfc_mask); break; case(InterpMthd_Best): // Best Match @@ -991,19 +997,19 @@ double compute_sfc_interp(const DataPlane &dp, break; case(InterpMthd_Upper_Left): // Upper Left corner of the grid box - v = interp_xy(dp, floor(obs_x), ceil(obs_y), &sfc_mask); + v = interp_xy(dp, wrap_lon, floor(obs_x), ceil(obs_y), &sfc_mask); break; case(InterpMthd_Upper_Right): // Upper Right corner of the grid box - v = interp_xy(dp, ceil(obs_x), ceil(obs_y), &sfc_mask); + v = interp_xy(dp, wrap_lon, ceil(obs_x), ceil(obs_y), &sfc_mask); break; case(InterpMthd_Lower_Right): // Lower Right corner of the grid box - v = interp_xy(dp, ceil(obs_x), floor(obs_y), &sfc_mask); + v = interp_xy(dp, wrap_lon, ceil(obs_x), floor(obs_y), &sfc_mask); break; case(InterpMthd_Lower_Left): // Lower Left corner of the grid box - v = interp_xy(dp, floor(obs_x), floor(obs_y), &sfc_mask); + v = interp_xy(dp, wrap_lon, floor(obs_x), floor(obs_y), &sfc_mask); break; case(InterpMthd_Geog_Match): // Geography Match for surface point verification @@ -1088,9 +1094,11 @@ double compute_horz_interp(const DataPlane &dp, double obs_x, double obs_y, double obs_v, const InterpMthd mthd, const int width, const GridTemplateFactory::GridTemplates shape, - double interp_thresh, const SingleThresh *cat_thresh) { + bool wrap_lon, double interp_thresh, + const SingleThresh *cat_thresh) { return(compute_horz_interp(dp, obs_x, obs_y, obs_v, bad_data_double, - bad_data_double, mthd, width, shape, interp_thresh, cat_thresh)); + bad_data_double, mthd, width, shape, wrap_lon, + interp_thresh, cat_thresh)); } //////////////////////////////////////////////////////////////////////// @@ -1100,19 +1108,20 @@ double compute_horz_interp(const DataPlane &dp, double obs_v, double cmn, double csd, const InterpMthd mthd, const int width, const GridTemplateFactory::GridTemplates shape, - double interp_thresh, const SingleThresh *cat_thresh) { + bool wrap_lon, double interp_thresh, + const SingleThresh *cat_thresh) { double v = bad_data_double; int x = nint(obs_x); int y = nint(obs_y); // if width is even, push center to lower left point instead of nearest - if((width % 2 ) == 0) { + if((width % 2) == 0) { x = static_cast(floor(obs_x)); y = static_cast(floor(obs_y)); } GridTemplateFactory gtf; - const GridTemplate* gt = gtf.buildGT(shape,width); + const GridTemplate* gt = gtf.buildGT(shape, width, wrap_lon); // Compute the interpolated value for the fields above and below switch(mthd) { @@ -1149,11 +1158,11 @@ double compute_horz_interp(const DataPlane &dp, break; case(InterpMthd_Bilin): // Bilinear interpolation - v = interp_bilin(dp, obs_x, obs_y); + v = interp_bilin(dp, wrap_lon, obs_x, obs_y); break; case(InterpMthd_Nearest): // Nearest Neighbor - v = interp_xy(dp, x, y); + v = interp_xy(dp, wrap_lon, x, y); break; case(InterpMthd_Best): // Best Match @@ -1161,19 +1170,19 @@ double compute_horz_interp(const DataPlane &dp, break; case(InterpMthd_Upper_Left): // Upper Left corner of the grid box - v = interp_xy(dp, floor(obs_x), ceil(obs_y)); + v = interp_xy(dp, wrap_lon, floor(obs_x), ceil(obs_y)); break; case(InterpMthd_Upper_Right): // Upper Right corner of the grid box - v = interp_xy(dp, ceil(obs_x), ceil(obs_y)); + v = interp_xy(dp, wrap_lon, ceil(obs_x), ceil(obs_y)); break; case(InterpMthd_Lower_Right): // Lower Right corner of the grid box - v = interp_xy(dp, ceil(obs_x), floor(obs_y)); + v = interp_xy(dp, wrap_lon, ceil(obs_x), floor(obs_y)); break; case(InterpMthd_Lower_Left): // Lower Left corner of the grid box - v = interp_xy(dp, floor(obs_x), floor(obs_y)); + v = interp_xy(dp, wrap_lon, floor(obs_x), floor(obs_y)); break; case(InterpMthd_Geog_Match): // Geography Match for surface point verification diff --git a/met/src/basic/vx_util/interp_util.h b/met/src/basic/vx_util/interp_util.h index 4369557be4..c8e6dc3f21 100644 --- a/met/src/basic/vx_util/interp_util.h +++ b/met/src/basic/vx_util/interp_util.h @@ -17,6 +17,7 @@ // Mod# Date Name Description // ---- ---- ---- ----------- // 000 11-17-08 Halley Gotway +// 001 09-07-21 Halley Gotway Add wrap_lon. // /////////////////////////////////////////////////////////////////////////////// @@ -84,8 +85,8 @@ extern double interp_geog_match(const DataPlane &, const GridTemplate >, dou extern double interp_nbrhd (const DataPlane &, const GridTemplate >, int x, int y, double t, const SingleThresh *, double cmn, double csd, const MaskPlane *mp = 0); -extern double interp_bilin (const DataPlane &, double obs_x, double obs_y, const MaskPlane *mp = 0); -extern double interp_xy (const DataPlane &, int x, int y, const MaskPlane *mp = 0); +extern double interp_bilin (const DataPlane &, bool wrap_lon, double obs_x, double obs_y, const MaskPlane *mp = 0); +extern double interp_xy (const DataPlane &, bool wrap_lon, int x, int y, const MaskPlane *mp = 0); extern double interp_best (const DataPlane &dp, const GridTemplate >, int x, int y, double obs_v, double t, const MaskPlane *mp = 0); @@ -102,8 +103,8 @@ extern double compute_sfc_interp(const DataPlane &dp, double obs_elv, double obs_v, const InterpMthd mthd, const int width, const GridTemplateFactory::GridTemplates shape, - double interp_thresh, const SurfaceInfo &sfc_info, - bool is_land_obs); + bool wrap_lon, double interp_thresh, + const SurfaceInfo &sfc_info, bool is_land_obs); extern MaskPlane compute_sfc_mask(const GridTemplate >, int x, int y, const SurfaceInfo &sfc_info, @@ -113,14 +114,16 @@ extern double compute_horz_interp(const DataPlane &dp, double obs_x, double obs_y, double obs_v, const InterpMthd mthd, const int width, const GridTemplateFactory::GridTemplates shape, - double interp_thresh, const SingleThresh *cat_thresh = 0); + bool wrap_lon, double interp_thresh, + const SingleThresh *cat_thresh = 0); extern double compute_horz_interp(const DataPlane &dp, double obs_x, double obs_y, double obs_v, double cmn, double csd, const InterpMthd mthd, const int width, const GridTemplateFactory::GridTemplates shape, - double interp_thresh, const SingleThresh *cat_thresh = 0); + bool wrap_lon, double interp_thresh, + const SingleThresh *cat_thresh = 0); extern double compute_vert_pinterp(double, double, double, double, double); extern double compute_vert_zinterp(double, double, double, double, double); diff --git a/met/src/libcode/vx_grid/gaussian_grid.cc b/met/src/libcode/vx_grid/gaussian_grid.cc index 6a175077a4..61edbbb7f8 100644 --- a/met/src/libcode/vx_grid/gaussian_grid.cc +++ b/met/src/libcode/vx_grid/gaussian_grid.cc @@ -431,7 +431,7 @@ return ( 0.0 ); //////////////////////////////////////////////////////////////////////// -bool GaussianGrid::is_global() const +bool GaussianGrid::wrap_lon() const { diff --git a/met/src/libcode/vx_grid/gaussian_grid.h b/met/src/libcode/vx_grid/gaussian_grid.h index 404b546097..1825f853e0 100644 --- a/met/src/libcode/vx_grid/gaussian_grid.h +++ b/met/src/libcode/vx_grid/gaussian_grid.h @@ -81,7 +81,7 @@ class GaussianGrid : public GridRep { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); diff --git a/met/src/libcode/vx_grid/goes_grid.cc b/met/src/libcode/vx_grid/goes_grid.cc index f7cc8e96fa..71e6ff61d5 100644 --- a/met/src/libcode/vx_grid/goes_grid.cc +++ b/met/src/libcode/vx_grid/goes_grid.cc @@ -376,7 +376,7 @@ return ( 0.0 ); //////////////////////////////////////////////////////////////////////// -bool GoesImagerGrid::is_global() const +bool GoesImagerGrid::wrap_lon() const { diff --git a/met/src/libcode/vx_grid/goes_grid.h b/met/src/libcode/vx_grid/goes_grid.h index a43869b1f7..291428fa33 100644 --- a/met/src/libcode/vx_grid/goes_grid.h +++ b/met/src/libcode/vx_grid/goes_grid.h @@ -72,7 +72,7 @@ class GoesImagerGrid : public GridRep { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); diff --git a/met/src/libcode/vx_grid/grid_base.cc b/met/src/libcode/vx_grid/grid_base.cc index 7b1fa99790..ece0332ce1 100644 --- a/met/src/libcode/vx_grid/grid_base.cc +++ b/met/src/libcode/vx_grid/grid_base.cc @@ -957,19 +957,19 @@ return ( rep->rot_grid_to_earth(x, y) ); //////////////////////////////////////////////////////////////////////// -bool Grid::is_global() const +bool Grid::wrap_lon() const { if ( !rep ) { - mlog << Error << "\nGrid::is_global() const -> empty grid!\n\n"; + mlog << Error << "\nGrid::wrap_lon() const -> empty grid!\n\n"; exit ( 1 ); } -return ( rep->is_global() ); +return ( rep->wrap_lon() ); } diff --git a/met/src/libcode/vx_grid/grid_base.h b/met/src/libcode/vx_grid/grid_base.h index c2894f0df1..5a225f6275 100644 --- a/met/src/libcode/vx_grid/grid_base.h +++ b/met/src/libcode/vx_grid/grid_base.h @@ -136,7 +136,7 @@ class GridInterface { // pure abstract class for grid public interface virtual double rot_grid_to_earth(int x, int y) const = 0; - virtual bool is_global() const = 0; + virtual bool wrap_lon() const = 0; virtual void shift_right(int) = 0; @@ -168,7 +168,7 @@ class GridRep : public GridInterface { virtual double rot_grid_to_earth(int x, int y) const = 0; - virtual bool is_global() const = 0; + virtual bool wrap_lon() const = 0; virtual void shift_right(int) = 0; @@ -246,7 +246,7 @@ class Grid : public GridInterface { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); diff --git a/met/src/libcode/vx_grid/latlon_grid.cc b/met/src/libcode/vx_grid/latlon_grid.cc index 6176424ed1..11e779cc66 100644 --- a/met/src/libcode/vx_grid/latlon_grid.cc +++ b/met/src/libcode/vx_grid/latlon_grid.cc @@ -1,5 +1,3 @@ - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) @@ -9,8 +7,6 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* - - //////////////////////////////////////////////////////////////////////// @@ -77,6 +73,8 @@ lat_ll = lon_ll = 0.0; delta_lat = delta_lon = 0.0; +wrapLon = false; + memset(&Data, 0, sizeof(Data)); return; @@ -120,7 +118,29 @@ Name = data.name; Data = data; + // + // wrap longitudes when: + // - all 360 degrees are included + // - 360 is divisible by delta_lon + // +bool lon_rng_flag = fabs((Nx + 1)*delta_lon) >= 360.0; +double lon_div = 360.0 / delta_lon; +bool lon_div_flag = is_eq(lon_div, floor(lon_div)); + +wrapLon = (lon_rng_flag && lon_div_flag); + + // + // inform users about unexpected delta longitudes + // + +if ( lon_rng_flag && !lon_div_flag ) { + + mlog << Debug(4) << "Cannot wrap longitudes since 360 is not " + << "evenly divisible by delta_lon = " + << delta_lon << ".\n"; + +} return; @@ -133,6 +153,7 @@ return; void LatLonGrid::latlon_to_xy(double lat, double lon, double &x, double &y) const { + double n; y = (lat - lat_ll)/delta_lat; @@ -249,6 +270,8 @@ out << prefix << "lon_ll = " << lon_ll << "\n"; out << prefix << "delta_lat_ll = " << delta_lat << "\n"; out << prefix << "delta_lon_ll = " << delta_lon << "\n"; +out << prefix << "wrapLon = " << bool_to_string(wrapLon) << "\n"; + // // done // @@ -282,6 +305,8 @@ snprintf(junk, sizeof(junk), " lon_ll: %.3f", lon_ll); a << junk; snprintf(junk, sizeof(junk), " delta_lat: %.3f", delta_lat); a << junk; snprintf(junk, sizeof(junk), " delta_lon: %.3f", delta_lon); a << junk; +snprintf(junk, sizeof(junk), " wrapLon: %s", bool_to_string(wrapLon)); a << junk; + // // done // @@ -328,33 +353,13 @@ return ( 0.0 ); //////////////////////////////////////////////////////////////////////// -bool LatLonGrid::is_global() const - -{ - -const double lon_range = fabs((Nx + 1)*delta_lon); -const double lat_range = fabs((Ny + 1)*delta_lat); - -const bool full_range_lat = (lat_range >= 180.0); -const bool full_range_lon = (lon_range >= 360.0); - -const bool answer = full_range_lat && full_range_lon; - -return ( answer ); - -} - - -//////////////////////////////////////////////////////////////////////// - - void LatLonGrid::shift_right(int N) { if ( N == 0 ) return; -if ( ! is_global() ) { +if ( ! wrapLon ) { mlog << Error << "\n\n LatLonGrid::shift_right(int) -> " @@ -450,5 +455,3 @@ return; //////////////////////////////////////////////////////////////////////// - - diff --git a/met/src/libcode/vx_grid/latlon_grid.h b/met/src/libcode/vx_grid/latlon_grid.h index 4f0f01cb5b..21c86d6e2c 100644 --- a/met/src/libcode/vx_grid/latlon_grid.h +++ b/met/src/libcode/vx_grid/latlon_grid.h @@ -1,5 +1,3 @@ - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) @@ -9,8 +7,6 @@ // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* - - //////////////////////////////////////////////////////////////////////// @@ -46,6 +42,8 @@ class LatLonGrid : public GridRep { int Nx; int Ny; + bool wrapLon; + ConcatString Name; LatLonData Data; @@ -79,7 +77,7 @@ class LatLonGrid : public GridRep { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); @@ -91,7 +89,8 @@ class LatLonGrid : public GridRep { //////////////////////////////////////////////////////////////////////// -inline double LatLonGrid::scale_km() const { return ( -1.0 ); } +inline double LatLonGrid::scale_km() const { return ( -1.0 ); } +inline bool LatLonGrid::wrap_lon() const { return ( wrapLon ); } //////////////////////////////////////////////////////////////////////// @@ -101,6 +100,3 @@ inline double LatLonGrid::scale_km() const { return ( -1.0 ); } //////////////////////////////////////////////////////////////////////// - - - diff --git a/met/src/libcode/vx_grid/lc_grid.cc b/met/src/libcode/vx_grid/lc_grid.cc index aab40b015f..41a2e375e9 100644 --- a/met/src/libcode/vx_grid/lc_grid.cc +++ b/met/src/libcode/vx_grid/lc_grid.cc @@ -638,7 +638,7 @@ return ( angle ); //////////////////////////////////////////////////////////////////////// -bool LambertGrid::is_global() const +bool LambertGrid::wrap_lon() const { diff --git a/met/src/libcode/vx_grid/lc_grid.h b/met/src/libcode/vx_grid/lc_grid.h index 6b67eabb0b..0b3fefdaaa 100644 --- a/met/src/libcode/vx_grid/lc_grid.h +++ b/met/src/libcode/vx_grid/lc_grid.h @@ -118,7 +118,7 @@ class LambertGrid : public GridRep { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); diff --git a/met/src/libcode/vx_grid/merc_grid.cc b/met/src/libcode/vx_grid/merc_grid.cc index c45dee4d6d..d89a7898e4 100644 --- a/met/src/libcode/vx_grid/merc_grid.cc +++ b/met/src/libcode/vx_grid/merc_grid.cc @@ -572,7 +572,7 @@ return ( 0.0 ); //////////////////////////////////////////////////////////////////////// -bool MercatorGrid::is_global() const +bool MercatorGrid::wrap_lon() const { diff --git a/met/src/libcode/vx_grid/merc_grid.h b/met/src/libcode/vx_grid/merc_grid.h index 94dd842bda..f46a9c3bf8 100644 --- a/met/src/libcode/vx_grid/merc_grid.h +++ b/met/src/libcode/vx_grid/merc_grid.h @@ -101,7 +101,7 @@ class MercatorGrid : public GridRep { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); diff --git a/met/src/libcode/vx_grid/rot_latlon_grid.cc b/met/src/libcode/vx_grid/rot_latlon_grid.cc index 2e97cba498..12b6286135 100644 --- a/met/src/libcode/vx_grid/rot_latlon_grid.cc +++ b/met/src/libcode/vx_grid/rot_latlon_grid.cc @@ -1,5 +1,3 @@ - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) @@ -321,6 +319,8 @@ snprintf(junk, sizeof(junk), " rot_lon_ll: %.3f", RData.rot_lon_ll); a << junk snprintf(junk, sizeof(junk), " delta_rot_lat: %.3f", RData.delta_rot_lat); a << junk; snprintf(junk, sizeof(junk), " delta_rot_lon: %.3f", RData.delta_rot_lon); a << junk; +snprintf(junk, sizeof(junk), " wrapLon: %s", bool_to_string(wrapLon)); a << junk; + snprintf(junk, sizeof(junk), " true_lat_south_pole: %.3f", RData.true_lat_south_pole); a << junk; snprintf(junk, sizeof(junk), " true_lon_south_pole: %.3f", RData.true_lon_south_pole); a << junk; @@ -372,26 +372,6 @@ return ( 0.0 ); //////////////////////////////////////////////////////////////////////// -bool RotatedLatLonGrid::is_global() const - -{ - -const double lon_range = fabs((Nx + 1)*delta_lon); -const double lat_range = fabs((Ny + 1)*delta_lat); - -const bool full_range_lat = (lat_range >= 180.0); -const bool full_range_lon = (lon_range >= 360.0); - -const bool answer = full_range_lat && full_range_lon; - -return ( answer ); - -} - - -//////////////////////////////////////////////////////////////////////// - - void RotatedLatLonGrid::shift_right(int N) { @@ -472,5 +452,3 @@ return; //////////////////////////////////////////////////////////////////////// - - diff --git a/met/src/libcode/vx_grid/rot_latlon_grid.h b/met/src/libcode/vx_grid/rot_latlon_grid.h index eea580d285..79a75e1869 100644 --- a/met/src/libcode/vx_grid/rot_latlon_grid.h +++ b/met/src/libcode/vx_grid/rot_latlon_grid.h @@ -1,5 +1,3 @@ - - // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1992 - 2021 // ** University Corporation for Atmospheric Research (UCAR) @@ -72,7 +70,7 @@ class RotatedLatLonGrid : public LatLonGrid { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); @@ -84,7 +82,8 @@ class RotatedLatLonGrid : public LatLonGrid { //////////////////////////////////////////////////////////////////////// -inline double RotatedLatLonGrid::scale_km() const { return ( -1.0 ); } +inline double RotatedLatLonGrid::scale_km() const { return ( -1.0 ); } +inline bool RotatedLatLonGrid::wrap_lon() const { return ( wrapLon ); } //////////////////////////////////////////////////////////////////////// @@ -94,6 +93,3 @@ inline double RotatedLatLonGrid::scale_km() const { return ( -1.0 ); } //////////////////////////////////////////////////////////////////////// - - - diff --git a/met/src/libcode/vx_grid/st_grid.cc b/met/src/libcode/vx_grid/st_grid.cc index 65246ae5fc..3b64e4a14d 100644 --- a/met/src/libcode/vx_grid/st_grid.cc +++ b/met/src/libcode/vx_grid/st_grid.cc @@ -553,7 +553,7 @@ return ( angle ); //////////////////////////////////////////////////////////////////////// -bool StereographicGrid::is_global() const +bool StereographicGrid::wrap_lon() const { diff --git a/met/src/libcode/vx_grid/st_grid.h b/met/src/libcode/vx_grid/st_grid.h index e80f3aadff..9fecdba445 100644 --- a/met/src/libcode/vx_grid/st_grid.h +++ b/met/src/libcode/vx_grid/st_grid.h @@ -99,7 +99,7 @@ class StereographicGrid : public GridRep { double rot_grid_to_earth(int x, int y) const; - bool is_global() const; + bool wrap_lon() const; void shift_right(int); diff --git a/met/src/libcode/vx_regrid/vx_regrid.cc b/met/src/libcode/vx_regrid/vx_regrid.cc index 0a7da68e3e..6be4189fa7 100644 --- a/met/src/libcode/vx_regrid/vx_regrid.cc +++ b/met/src/libcode/vx_regrid/vx_regrid.cc @@ -133,6 +133,7 @@ to_data.set_accum (from_data.accum()); // // copy data // + for (xt=0; xt<(to_grid.nx()); ++xt) { for (yt=0; yt<(to_grid.ny()); ++yt) { @@ -144,14 +145,14 @@ for (xt=0; xt<(to_grid.nx()); ++xt) { xf = nint(x_from); yf = nint(y_from); - if ( (xf < 0) || (xf >= from_grid.nx()) || (yf < 0) || (yf >= from_grid.ny()) ) { - + if ( ( (xf < 0 || xf >= from_grid.nx()) && !from_grid.wrap_lon() ) || + yf < 0 || yf >= from_grid.ny() ) { value = bad_data_float; - - } else { - value = compute_horz_interp(from_data, x_from, y_from, bad_data_double, - info.method, info.width, info.shape, info.vld_thresh); - + } + else { + value = compute_horz_interp(from_data, x_from, y_from, + bad_data_double, info.method, info.width, + info.shape, from_grid.wrap_lon(), info.vld_thresh); } to_data.put(value, xt, yt); @@ -327,6 +328,7 @@ to_data.set_accum (from_data.accum()); // // copy data // + for (xt=0; xt<(to_grid.nx()); ++xt) { for (yt=0; yt<(to_grid.ny()); ++yt) { @@ -338,15 +340,14 @@ for (xt=0; xt<(to_grid.nx()); ++xt) { xf = nint(x_from); yf = nint(y_from); - if ( (xf < 0) || (xf >= from_grid.nx()) || - (yf < 0) || (yf >= from_grid.ny()) ) { - + if ( ( (xf < 0 || xf >= from_grid.nx()) && !from_grid.wrap_lon() ) || + yf < 0 || yf >= from_grid.ny() ) { value = bad_data_float; } else { value = compute_horz_interp(from_data, x_from, y_from, bad_data_double, InterpMthd_Max, info.width, - info.shape, info.vld_thresh); + info.shape, from_grid.wrap_lon(), info.vld_thresh); } to_data.put(value, xt, yt); diff --git a/met/src/libcode/vx_regrid/vx_regrid_budget.cc b/met/src/libcode/vx_regrid/vx_regrid_budget.cc index 881e56ef1c..42157cb729 100644 --- a/met/src/libcode/vx_regrid/vx_regrid_budget.cc +++ b/met/src/libcode/vx_regrid/vx_regrid_budget.cc @@ -77,7 +77,7 @@ for (ixt=0; ixt<(to_grid.nx()); ++ixt) { from_grid.latlon_to_xy(lat, lon, dxf, dyf); - value = interp_bilin(from_data, dxf, dyf); + value = interp_bilin(from_data, from_grid.wrap_lon(), dxf, dyf); if ( value != bad_data_double ) { sum += value; ++count; } diff --git a/met/src/libcode/vx_statistics/apply_mask.cc b/met/src/libcode/vx_statistics/apply_mask.cc index 1aea2fe836..01d88f601e 100644 --- a/met/src/libcode/vx_statistics/apply_mask.cc +++ b/met/src/libcode/vx_statistics/apply_mask.cc @@ -185,7 +185,7 @@ void parse_grid_mask(const ConcatString &mask_grid_str, const Grid &grid, // // Check to make sure that we're not using the full domain // - if( full_domain_str != mask_grid_str) { + if(full_domain_str != mask_grid_str) { // // Search for the grid name in the predefined grids diff --git a/met/src/libcode/vx_statistics/pair_base.cc b/met/src/libcode/vx_statistics/pair_base.cc index d90e3167a6..aaf73755b9 100644 --- a/met/src/libcode/vx_statistics/pair_base.cc +++ b/met/src/libcode/vx_statistics/pair_base.cc @@ -876,6 +876,7 @@ double compute_interp(const DataPlaneArray &dpa, const double obs_v, const double cmn, const double csd, const InterpMthd method, const int width, const GridTemplateFactory::GridTemplates shape, + const bool wrap_lon, const double thresh, const bool spfh_flag, const LevelType lvl_typ, const double to_lvl, const int i_blw, const int i_abv, @@ -886,14 +887,16 @@ double compute_interp(const DataPlaneArray &dpa, if(dpa.n_planes() == 0) return(bad_data_double); v_blw = compute_horz_interp(dpa[i_blw], obs_x, obs_y, obs_v, cmn, csd, - method, width, shape, thresh, cat_thresh); + method, width, shape, wrap_lon, + thresh, cat_thresh); if(i_blw == i_abv) { v = v_blw; } else { v_abv = compute_horz_interp(dpa[i_abv], obs_x, obs_y, obs_v, cmn, csd, - method, width, shape, thresh, cat_thresh); + method, width, shape, wrap_lon, + thresh, cat_thresh); // Check for bad data prior to vertical interpolation if(is_bad_data(v_blw) || is_bad_data(v_abv)) { @@ -932,6 +935,7 @@ void get_interp_points(const DataPlaneArray &dpa, const double obs_x, const double obs_y, const InterpMthd method, const int width, const GridTemplateFactory::GridTemplates shape, + const bool wrap_lon, const double thresh, const bool spfh_flag, const LevelType lvl_typ, const double to_lvl, const int i_blw, const int i_abv, @@ -947,7 +951,7 @@ void get_interp_points(const DataPlaneArray &dpa, int i, n_vld; NumArray pts_blw, pts_abv; GridTemplateFactory gtf; - const GridTemplate* gt = gtf.buildGT(shape, width); + const GridTemplate* gt = gtf.buildGT(shape, width, wrap_lon); // Get interpolation points below the observation pts_blw = interp_points(dpa[i_blw], *gt, obs_x, obs_y); diff --git a/met/src/libcode/vx_statistics/pair_base.h b/met/src/libcode/vx_statistics/pair_base.h index ebe0f845fc..465432f16f 100644 --- a/met/src/libcode/vx_statistics/pair_base.h +++ b/met/src/libcode/vx_statistics/pair_base.h @@ -197,6 +197,7 @@ extern double compute_interp(const DataPlaneArray &dpa, const double obs_v, const double cmn, const double csd, const InterpMthd method, const int width, const GridTemplateFactory::GridTemplates shape, + const bool wrap_lon, const double thresh, const bool spfh_flag, const LevelType lvl_typ, const double to_lvl, const int i_blw, const int i_abv, @@ -206,6 +207,7 @@ extern void get_interp_points(const DataPlaneArray &dpa, const double obs_x, const double obs_y, const InterpMthd method, const int width, const GridTemplateFactory::GridTemplates shape, + const bool wrap_lon, const double thresh, const bool spfh_flag, const LevelType lvl_typ, const double to_lvl, const int i_blw, const int i_abv, diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.cc b/met/src/libcode/vx_statistics/pair_data_ensemble.cc index 0fcf84fc99..683aa499b9 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.cc +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.cc @@ -1408,8 +1408,8 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, y = nint(obs_y); // Check if the observation's lat/lon is on the grid - if(x < 0 || x >= gr.nx() || - y < 0 || y >= gr.ny()) return; + if(((x < 0 || x >= gr.nx()) && !gr.wrap_lon()) || + y < 0 || y >= gr.ny()) return; // For pressure levels, check if the observation pressure level // falls in the requsted range. @@ -1556,7 +1556,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, cmn_v = compute_interp(climo_mn_dpa, obs_x, obs_y, obs_v, bad_data_double, bad_data_double, pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, - pd[0][0][k].interp_shape, + pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, fcst_info->level().type(), to_lvl, cmn_lvl_blw, cmn_lvl_abv); @@ -1583,7 +1583,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, csd_v = compute_interp(climo_sd_dpa, obs_x, obs_y, obs_v, bad_data_double, bad_data_double, pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, - pd[0][0][k].interp_shape, + pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, fcst_info->level().type(), to_lvl, csd_lvl_blw, csd_lvl_abv); @@ -1612,7 +1612,7 @@ void VxPairDataEnsemble::add_point_obs(float *hdr_arr, int *hdr_typ_arr, //////////////////////////////////////////////////////////////////////// -void VxPairDataEnsemble::add_ens(int member, bool mn) { +void VxPairDataEnsemble::add_ens(int member, bool mn, Grid &gr) { int i, j, k, l; int f_lvl_blw, f_lvl_abv; double to_lvl, fcst_v; @@ -1654,6 +1654,7 @@ void VxPairDataEnsemble::add_ens(int member, bool mn) { pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, pd[0][0][k].interp_shape, + gr.wrap_lon(), interp_thresh, spfh_flag, fcst_info->level().type(), to_lvl, f_lvl_blw, f_lvl_abv); diff --git a/met/src/libcode/vx_statistics/pair_data_ensemble.h b/met/src/libcode/vx_statistics/pair_data_ensemble.h index 84aa45796b..7d59896593 100644 --- a/met/src/libcode/vx_statistics/pair_data_ensemble.h +++ b/met/src/libcode/vx_statistics/pair_data_ensemble.h @@ -279,7 +279,7 @@ class VxPairDataEnsemble { unixtime, const char *, float *, Grid &, const char * = 0, const DataPlane * = 0); - void add_ens(int, bool mn); + void add_ens(int, bool mn, Grid &); int get_n_pair() const; diff --git a/met/src/libcode/vx_statistics/pair_data_point.cc b/met/src/libcode/vx_statistics/pair_data_point.cc index a77749abba..7bfda5fa42 100644 --- a/met/src/libcode/vx_statistics/pair_data_point.cc +++ b/met/src/libcode/vx_statistics/pair_data_point.cc @@ -967,8 +967,9 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, y = nint(obs_y); // Check if the observation's lat/lon is on the grid - if(x < 0 || x >= gr.nx() || - y < 0 || y >= gr.ny()) { + if(((x < 0 || x >= gr.nx()) && !gr.wrap_lon()) || + y < 0 || y >= gr.ny()) { + mlog << Debug(4) << "For " << fcst_info->magic_str() << " versus " << obs_info->magic_str() @@ -989,7 +990,8 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, double topo = compute_horz_interp( *sfc_info.topo_ptr, obs_x, obs_y, hdr_elv, InterpMthd_Bilin, 2, - GridTemplateFactory::GridTemplate_Square, 1.0); + GridTemplateFactory::GridTemplate_Square, + gr.wrap_lon(), 1.0); // Skip bad topography values if(is_bad_data(hdr_elv) || is_bad_data(topo)) { @@ -1165,7 +1167,7 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, cmn_v = compute_interp(climo_mn_dpa, obs_x, obs_y, obs_v, bad_data_double, bad_data_double, pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, - pd[0][0][k].interp_shape, + pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, fcst_info->level().type(), to_lvl, cmn_lvl_blw, cmn_lvl_abv); @@ -1192,8 +1194,8 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, // Compute the interpolated climatology standard deviation csd_v = compute_interp(climo_sd_dpa, obs_x, obs_y, obs_v, bad_data_double, bad_data_double, - pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, - pd[0][0][k].interp_shape, + pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, + pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, fcst_info->level().type(), to_lvl, csd_lvl_blw, csd_lvl_abv); @@ -1222,14 +1224,14 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, fcst_v = compute_sfc_interp(fcst_dpa[0], obs_x, obs_y, hdr_elv, obs_v, pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, - pd[0][0][k].interp_shape, interp_thresh, sfc_info, - is_land); + pd[0][0][k].interp_shape, gr.wrap_lon(), + interp_thresh, sfc_info, is_land); } // Otherwise, compute interpolated value else { fcst_v = compute_interp(fcst_dpa, obs_x, obs_y, obs_v, cmn_v, csd_v, pd[0][0][k].interp_mthd, pd[0][0][k].interp_wdth, - pd[0][0][k].interp_shape, + pd[0][0][k].interp_shape, gr.wrap_lon(), interp_thresh, spfh_flag, fcst_info->level().type(), to_lvl, f_lvl_blw, f_lvl_abv); @@ -1239,8 +1241,10 @@ void VxPairDataPoint::add_point_obs(float *hdr_arr, const char *hdr_typ_str, mlog << Debug(4) << "For " << fcst_info->magic_str() << " versus " << obs_info->magic_str() - << ", skipping observation due to bad data in the interpolated " - << "forecast value:\n" + << ", skipping observation due to bad data in the " + << interpmthd_to_string(pd[0][0][k].interp_mthd) << "(" + << pd[0][0][k].interp_wdth * pd[0][0][k].interp_wdth + << ") interpolated forecast value:\n" << point_obs_to_string(hdr_arr, hdr_typ_str, hdr_sid_str, hdr_ut, obs_qty, obs_arr, var_name) << "\n"; diff --git a/met/src/tools/core/ensemble_stat/ensemble_stat.cc b/met/src/tools/core/ensemble_stat/ensemble_stat.cc index d87c377bdf..26a8a5dfb3 100644 --- a/met/src/tools/core/ensemble_stat/ensemble_stat.cc +++ b/met/src/tools/core/ensemble_stat/ensemble_stat.cc @@ -1123,7 +1123,7 @@ int process_point_ens(int i_ens, int &n_miss) { conf_info.vx_opt[i].vx_pd.set_fcst_dpa(fcst_dpa); // Compute forecast values for this ensemble member - conf_info.vx_opt[i].vx_pd.add_ens(i_ens-n_miss, is_ens_mean); + conf_info.vx_opt[i].vx_pd.add_ens(i_ens-n_miss, is_ens_mean, grid); } // end for i @@ -1588,13 +1588,13 @@ void process_grid_vx() { // Smooth the ensemble mean field, if requested if(ens_mean_flag && (field == FieldType_Fcst || field == FieldType_Both)) { - emn_dp = smooth_field(emn_dp, mthd, wdth, shape, + emn_dp = smooth_field(emn_dp, mthd, wdth, shape, grid.wrap_lon(), vld_thresh, gaussian); } // Smooth the observation field, if requested if(field == FieldType_Obs || field == FieldType_Both) { - obs_dp = smooth_field(obs_dp, mthd, wdth, shape, + obs_dp = smooth_field(obs_dp, mthd, wdth, shape, grid.wrap_lon(), vld_thresh, gaussian); } @@ -1617,7 +1617,7 @@ void process_grid_vx() { // Smooth the forecast field, if requested if(field == FieldType_Fcst || field == FieldType_Both) { - fcst_dp[k] = smooth_field(fcst_dp[k], mthd, wdth, shape, + fcst_dp[k] = smooth_field(fcst_dp[k], mthd, wdth, shape, grid.wrap_lon(), vld_thresh, gaussian); } @@ -2060,7 +2060,8 @@ void track_counts(int i_vx, const DataPlane &dp) { fractional_coverage(dp, frac_dp, conf_info.nbrhd_prob.width[j], conf_info.nbrhd_prob.shape, - ThreshBuf[i], conf_info.nbrhd_prob.vld_thresh); + grid.wrap_lon(), ThreshBuf[i], + conf_info.nbrhd_prob.vld_thresh); // Increment counts const double *Frac = frac_dp.data(); @@ -2496,6 +2497,7 @@ void write_ens_nc(int i_ens, DataPlane &dp) { smooth_dp = smooth_field(prob_dp, InterpMthd_UW_Mean, conf_info.nbrhd_prob.width[j], conf_info.nbrhd_prob.shape, + grid.wrap_lon(), conf_info.nbrhd_prob.vld_thresh, info); for(k=0; kshape, interp->width[j]); + GridTemplate* gt = gtf.buildGT(interp->shape, interp->width[j], grid.wrap_lon()); shc.set_interp_mthd(interp_mthd, interp->shape); int interp_pnts = gt->size(); @@ -769,8 +769,8 @@ void process_scores() { if(interp->field == FieldType_Fcst || interp->field == FieldType_Both) { smooth_field(fcst_dp, fcst_dp_smooth, interp_mthd, - interp->width[j], interp->shape, interp->vld_thresh, - interp->gaussian); + interp->width[j], interp->shape, grid.wrap_lon(), + interp->vld_thresh, interp->gaussian); } // Do not smooth the forecast field else { @@ -781,8 +781,8 @@ void process_scores() { if(interp->field == FieldType_Obs || interp->field == FieldType_Both) { smooth_field(obs_dp, obs_dp_smooth, interp_mthd, - interp->width[j], interp->shape, interp->vld_thresh, - interp->gaussian); + interp->width[j], interp->shape, grid.wrap_lon(), + interp->vld_thresh, interp->gaussian); } // Do not smooth the observation field else { @@ -970,8 +970,8 @@ void process_scores() { if(interp->field == FieldType_Fcst || interp->field == FieldType_Both) { smooth_field(fu_dp, fu_dp_smooth, interp_mthd, - interp->width[j], interp->shape, interp->vld_thresh, - interp->gaussian); + interp->width[j], interp->shape, grid.wrap_lon(), + interp->vld_thresh, interp->gaussian); } // Do not smooth the forecast field else { @@ -984,8 +984,8 @@ void process_scores() { interp->field == FieldType_Both) { smooth_field(ou_dp, ou_dp_smooth, interp_mthd, interp->width[j], - interp->shape, interp->vld_thresh, - interp->gaussian); + interp->shape, grid.wrap_lon(), + interp->vld_thresh, interp->gaussian); } // Do not smooth the observation field else { @@ -1392,6 +1392,7 @@ void process_scores() { // Compute fractional coverage fractional_coverage(fcst_dp, fcst_dp_smooth, nbrhd->width[j], nbrhd->shape, + grid.wrap_lon(), conf_info.vx_opt[i].fcat_ta[k], nbrhd->vld_thresh); @@ -1430,6 +1431,7 @@ void process_scores() { // Compute fractional coverage fractional_coverage(obs_dp, obs_dp_smooth, nbrhd->width[j], nbrhd->shape, + grid.wrap_lon(), conf_info.vx_opt[i].ocat_ta[k], nbrhd->vld_thresh); diff --git a/met/src/tools/core/point_stat/point_stat.cc b/met/src/tools/core/point_stat/point_stat.cc index 5f609feeff..549e6fce9f 100644 --- a/met/src/tools/core/point_stat/point_stat.cc +++ b/met/src/tools/core/point_stat/point_stat.cc @@ -1676,7 +1676,8 @@ void do_hira_ens(int i_vx, const PairDataPoint *pd_ptr) { // Determine the number of points in the area GridTemplateFactory gtf; GridTemplate* gt = gtf.buildGT(conf_info.vx_opt[i_vx].hira_info.shape, - conf_info.vx_opt[i_vx].hira_info.width[i]); + conf_info.vx_opt[i_vx].hira_info.width[i], + grid.wrap_lon()); // Initialize hira_pd.clear(); @@ -1696,7 +1697,7 @@ void do_hira_ens(int i_vx, const PairDataPoint *pd_ptr) { get_interp_points(conf_info.vx_opt[i_vx].vx_pd.fcst_dpa, pd_ptr->x_na[j], pd_ptr->y_na[j], InterpMthd_Nbrhd, conf_info.vx_opt[i_vx].hira_info.width[i], - conf_info.vx_opt[i_vx].hira_info.shape, + conf_info.vx_opt[i_vx].hira_info.shape, grid.wrap_lon(), conf_info.vx_opt[i_vx].hira_info.vld_thresh, spfh_flag, conf_info.vx_opt[i_vx].vx_pd.fcst_info->level().type(), pd_ptr->lvl_na[j], lvl_blw, lvl_abv, f_ens); @@ -1873,7 +1874,7 @@ void do_hira_prob(int i_vx, const PairDataPoint *pd_ptr) { pd_ptr->x_na[k], pd_ptr->y_na[k], pd_ptr->o_na[k], pd_ptr->cmn_na[k], pd_ptr->csd_na[k], InterpMthd_Nbrhd, conf_info.vx_opt[i_vx].hira_info.width[j], - conf_info.vx_opt[i_vx].hira_info.shape, + conf_info.vx_opt[i_vx].hira_info.shape, grid.wrap_lon(), conf_info.vx_opt[i_vx].hira_info.vld_thresh, spfh_flag, conf_info.vx_opt[i_vx].vx_pd.fcst_info->level().type(), pd_ptr->lvl_na[k], lvl_blw, lvl_abv, &cat_thresh); @@ -1892,7 +1893,7 @@ void do_hira_prob(int i_vx, const PairDataPoint *pd_ptr) { pd_ptr->x_na[k], pd_ptr->y_na[k], pd_ptr->o_na[k], pd_ptr->cmn_na[k], pd_ptr->csd_na[k], InterpMthd_Nbrhd, conf_info.vx_opt[i_vx].hira_info.width[j], - conf_info.vx_opt[i_vx].hira_info.shape, + conf_info.vx_opt[i_vx].hira_info.shape, grid.wrap_lon(), conf_info.vx_opt[i_vx].hira_info.vld_thresh, spfh_flag, conf_info.vx_opt[i_vx].vx_pd.fcst_info->level().type(), pd_ptr->lvl_na[k], lvl_blw, lvl_abv, &cat_thresh); diff --git a/met/src/tools/core/point_stat/point_stat_conf_info.cc b/met/src/tools/core/point_stat/point_stat_conf_info.cc index 87183cb5d0..6117a0f7fc 100644 --- a/met/src/tools/core/point_stat/point_stat_conf_info.cc +++ b/met/src/tools/core/point_stat/point_stat_conf_info.cc @@ -1051,6 +1051,7 @@ void PointStatVxOpt::set_vx_pd(PointStatConfInfo *conf_info) { for(i=0; i @@ -346,7 +346,7 @@ &DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F036.grib \ G212 \ &OUTPUT_DIR;/regrid/regrid_data_plane_GFS_TO_G212_CONVERT_CENSOR.nc \ - -field 'name="TMP"; level="Z2";' \ + -field 'name="TMP"; level="Z2";' \ -convert 'convert(x) = x - 273.15;' \ -censor lt0 -9999 @@ -355,4 +355,20 @@ + + + + &MET_BIN;/regrid_data_plane + \ + &DATA_DIR_MODEL;/nccf/GloTEC_TEC_2015_03_17.nc \ + "latlon 360 91 -45.0 0 1.0 1.0" \ + &OUTPUT_DIR;/regrid/regrid_data_plane_WRAP_LON.nc \ + -field 'name="TEC"; level="(0,*,*)"; file_type=NETCDF_NCCF;' \ + -method MAX -width 5 -shape CIRCLE + + + &OUTPUT_DIR;/regrid/regrid_data_plane_WRAP_LON.nc + + +