Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature 1918 std climo #2061

Merged
merged 13 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions met/data/config/ConfigConstants
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,10 @@ BETA = 8;
TOP = TRUE;
BOTTOM = FALSE;

// Normalization types
NONE = 1;
CLIMO_ANOM = 2;
CLIMO_STD_ANOM = 3;
FCST_ANOM = 4;
FCST_STD_ANOM = 5;

1 change: 1 addition & 0 deletions met/data/config/GenEnsProdConfig_default
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ regrid = {
//
censor_thresh = [];
censor_val = [];
normalize = NONE;
cat_thresh = [];
nc_var_str = "";

Expand Down
20 changes: 20 additions & 0 deletions met/docs/Users_Guide/gen-ens-prod.rst
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,26 @@ Each value in the array will replace the text **MET_ENS_MEMBER_ID**.
to read a control member. This value is only used when the **-ctrl** command line argument is
used. The value should not be found in the **ens_member_ids** array.

_____________________

.. code-block:: none

normalize = NONE;

The **normalize** option defines if and how the input ensemble member data should be normalized. Options are provided to normalize relative to an external climatology, specified using the **climo_mean** and **climo_stdev** dictionaries, or relative to current ensemble forecast being processed. The anomaly is computed by subtracting the (climatological or ensemble) mean from each ensemble memeber. The standard anomaly is computed by dividing the anomaly by the (climatological or ensemble) standard deviation. Values for the **normalize** option are described below:

• **NONE** (default) to skip the normalization step and process the raw ensemble member data.

• **CLIMO_ANOM** to subtract the climatological mean field.

• **CLIMO_STD_ANOM** to subtract the climatological mean field and divide by the climatological standard deviation.

• **FCST_ANOM** to subtract the current ensemble mean field.

• **FCST_STD_ANOM** to subtract the current ensemble mean field and divide by the current ensemble standard deviation.

Note that the **normalize** option may be specified separately for each entry in the **ens.field** array.

_______________________

.. code-block:: none
Expand Down
6 changes: 6 additions & 0 deletions met/src/basic/vx_config/config_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,12 @@ static const char conf_key_dist_parm[] = "dist_parm";
static const char conf_key_inst_bias_scale[] = "inst_bias_scale";
static const char conf_key_inst_bias_offset[] = "inst_bias_offset";

//
// Gen-Ens-Prod specific parameter key names
//

static const char conf_key_normalize[] = "normalize";

// Distribution options
static const char conf_val_normal[] = "NORMAL";
static const char conf_val_exponential[] = "EXPONENTIAL";
Expand Down
30 changes: 30 additions & 0 deletions met/src/basic/vx_config/config_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2981,3 +2981,33 @@ StringArray parse_conf_ens_member_ids(Dictionary *dict) {
}

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

NormalizeType parse_conf_normalize(Dictionary *dict) {
NormalizeType t = NormalizeType_None;
int v;

if(!dict) {
mlog << Error << "\nparse_conf_normalize() -> "
<< "empty dictionary!\n\n";
exit(1);
}

// Get the integer flag value for the current entry
v = dict->lookup_int(conf_key_normalize);

// Convert integer to enumerated NormalizeType
if(v == conf_const.lookup_int(normalizetype_none_str)) t = NormalizeType_None;
else if(v == conf_const.lookup_int(normalizetype_climo_anom_str)) t = NormalizeType_ClimoAnom;
else if(v == conf_const.lookup_int(normalizetype_climo_std_anom_str)) t = NormalizeType_ClimoStdAnom;
else if(v == conf_const.lookup_int(normalizetype_fcst_anom_str)) t = NormalizeType_FcstAnom;
else if(v == conf_const.lookup_int(normalizetype_fcst_std_anom_str)) t = NormalizeType_FcstStdAnom;
else {
mlog << Error << "\nparse_conf_normalize() -> "
<< "Unexpected value of " << v << ".\n\n";
exit(1);
}

return(t);
}

///////////////////////////////////////////////////////////////////////////////
2 changes: 2 additions & 0 deletions met/src/basic/vx_config/config_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "config_file.h"
#include "data_file_type.h"
#include "config_gaussian.h"
#include "normalize.h"

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

Expand Down Expand Up @@ -78,6 +79,7 @@ extern map<ConcatString,ThreshArray>
extern void parse_conf_range_int(Dictionary *dict, int &beg, int &end);
extern void parse_conf_range_double(Dictionary *dict, double &beg, double &end);
extern StringArray parse_conf_ens_member_ids(Dictionary *dict);
extern NormalizeType parse_conf_normalize(Dictionary *dict);

extern void check_mask_names(const StringArray &);

Expand Down
1 change: 1 addition & 0 deletions met/src/basic/vx_util/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ libvx_util_a_SOURCES = ascii_table.cc ascii_table.h \
thresh_array.cc thresh_array.h \
make_path.cc make_path.h \
memory.cc memory.h \
normalize.cc normalize.h \
ordinal.cc ordinal.h \
roman_numeral.cc roman_numeral.h \
string_fxns.cc string_fxns.h \
Expand Down
62 changes: 55 additions & 7 deletions met/src/basic/vx_util/data_plane.cc
Original file line number Diff line number Diff line change
Expand Up @@ -406,23 +406,71 @@ void DataPlane::censor(const ThreshArray &censor_thresh,

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

void DataPlane::anomaly(const DataPlane &mn) {

// Check dimensions
if(Nxy != mn.Nxy) {
mlog << Error << "\nDataPlane::anomaly() -> "
<< "the data dimensions do not match: ("
<< Nx << ", " << Ny << ") != ("
<< mn.Nx << ", " << mn.Ny << ")!\n\n";
exit(1);
}

void DataPlane::replace_bad_data(const double value)
// Subtract the mean
for(int i=0; i<Nxy; i++) {
if(is_bad_data(Data[i]) || is_bad_data(mn.Data[i])) {
Data[i] = bad_data_double;
}
else {
Data[i] -= mn.Data[i];
}
}

{
return;
}

int j;
///////////////////////////////////////////////////////////////////////////////

for (j=0; j<Nxy; ++j) {
void DataPlane::standard_anomaly(const DataPlane &mn,
const DataPlane &sd) {

// Check dimensions
if(Nxy != mn.Nxy || Nxy != sd.Nxy) {
mlog << Error << "\nDataPlane::standard_anomaly() -> "
<< "the data dimensions do not match: ("
<< Nx << ", " << Ny << ") != ("
<< mn.Nx << ", " << mn.Ny << ") != ("
<< sd.Nx << ", " << sd.Ny << ")!\n\n";
exit(1);
}

if ( is_bad_data(Data[j]) ) Data[j] = value;
// Subtract the mean and divide by the standard deviation
for(int i=0; i<Nxy; i++) {
if(is_bad_data(Data[i]) ||
is_bad_data(mn.Data[i]) ||
is_bad_data(sd.Data[i]) ||
is_eq(sd.Data[i], 0.0)) {
Data[i] = bad_data_double;
}
else {
Data[i] = (Data[i] - mn.Data[i])/sd.Data[i];
}
}

return;
}

return;
///////////////////////////////////////////////////////////////////////////////

}
void DataPlane::replace_bad_data(const double value) {

for(int i=0; i<Nxy; i++) {
if(is_bad_data(Data[i])) Data[i] = value;
}

return;
}

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

Expand Down
11 changes: 8 additions & 3 deletions met/src/basic/vx_util/data_plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class DataPlane {

int Nx;
int Ny;

int Nxy; // Nx*Ny

unixtime InitTime; // Initialization time in unixtime
Expand Down Expand Up @@ -86,6 +85,8 @@ class DataPlane {

int nx() const;
int ny() const;
int nxy() const;

bool is_empty() const;
bool is_all_bad_data() const;
int n_good_data() const;
Expand All @@ -108,6 +109,9 @@ class DataPlane {
void convert (const UserFunc_1Arg &);
void censor (const ThreshArray &, const NumArray &);

void anomaly (const DataPlane &);
void standard_anomaly(const DataPlane &, const DataPlane &);

void replace_bad_data(const double value);

int two_to_one(int x, int y, bool to_north=true) const;
Expand All @@ -131,8 +135,9 @@ class DataPlane {

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

inline int DataPlane::nx() const { return (Nx); }
inline int DataPlane::ny() const { return (Ny); }
inline int DataPlane::nx() const { return (Nx); }
inline int DataPlane::ny() const { return (Ny); }
inline int DataPlane::nxy() const { return (Nxy); }

inline bool DataPlane::is_empty() const { return (Nxy == 0); }

Expand Down
125 changes: 125 additions & 0 deletions met/src/basic/vx_util/normalize.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
// ** Copyright UCAR (c) 1992 - 2022
// ** 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
// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

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

using namespace std;

#include <cstdlib>
#include <iostream>
#include <math.h>
#include <string.h>
#include <unistd.h>

#include "normalize.h"

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

ConcatString normalizetype_to_string(const NormalizeType type) {
ConcatString s;

// Convert enumerated NormalizeType to string
switch(type) {

case NormalizeType_None:
s = normalizetype_none_str;
break;

case NormalizeType_ClimoAnom:
s = normalizetype_climo_anom_str;
break;

case NormalizeType_ClimoStdAnom:
s = normalizetype_climo_std_anom_str;
break;

case NormalizeType_FcstAnom:
s = normalizetype_fcst_anom_str;
break;

case NormalizeType_FcstStdAnom:
s = normalizetype_fcst_std_anom_str;
break;

default:
mlog << Error << "\nnormalizetype_to_string() -> "
<< "Unexpected NormalizeType value of " << type << ".\n\n";
exit(1);
}

return(s);
}

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

void normalize_data(DataPlane &dp, const NormalizeType type,
const DataPlane *cmn_ptr, const DataPlane *csd_ptr,
const DataPlane *fmn_ptr, const DataPlane *fsd_ptr) {

mlog << Debug(3) << "Normalizing input data using "
<< normalizetype_to_string(type) << ".\n";

// Supported types
switch(type) {

case NormalizeType_None:
break;

case NormalizeType_ClimoAnom:
if(!cmn_ptr || dp.nxy() != cmn_ptr->nxy()) {
mlog << Error << "\nnormalize_data() -> "
<< "the climatology mean is required for "
<< normalizetype_to_string(type) << ".\n\n";
exit(1);
}
dp.anomaly(*cmn_ptr);
break;

case NormalizeType_ClimoStdAnom:
if(!cmn_ptr || dp.nxy() != cmn_ptr->nxy() ||
!csd_ptr || dp.nxy() != csd_ptr->nxy()) {
mlog << Error << "\nnormalize_data() -> "
<< "the climatology mean and standard deviation are required for "
<< normalizetype_to_string(type) << ".\n\n";
exit(1);
}
dp.standard_anomaly(*cmn_ptr, *csd_ptr);
break;

case NormalizeType_FcstAnom:
if(!fmn_ptr || dp.nxy() != fmn_ptr->nxy()) {
mlog << Error << "\nnormalize_data() -> "
<< "the forecast mean is required for "
<< normalizetype_to_string(type) << ".\n\n";
exit(1);
}
dp.anomaly(*fmn_ptr);
break;

case NormalizeType_FcstStdAnom:
if(!fmn_ptr || dp.nxy() != fmn_ptr->nxy() ||
!fsd_ptr || dp.nxy() != fsd_ptr->nxy()) {
mlog << Error << "\nnormalize_data() -> "
<< "the forecast mean and standard deviation are required for "
<< normalizetype_to_string(type) << ".\n\n";
exit(1);
}
dp.standard_anomaly(*fmn_ptr, *fsd_ptr);
break;

default:
mlog << Error << "\nnormalize_data() -> "
<< "unexpected NormalizeType value ("
<< type << ")\n\n";
exit(1);
} // end switch

return;
}

///////////////////////////////////////////////////////////////////////////////
Loading