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

Bugfix 1715 pb2nc seg fault with pbl #1719

Merged
merged 6 commits into from
Mar 18, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
74 changes: 54 additions & 20 deletions met/src/tools/other/pb2nc/pb2nc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2920,39 +2920,65 @@ int combine_tqz_and_uv(map<float, float*> pqtzuv_map_tq,
float *pqtzuv_tq, *pqtzuv_uv;
float *pqtzuv_merged = (float *) 0;
float *next_pqtzuv, *prev_pqtzuv;
float tq_pres_max, tq_pres_min, uv_pres_max, uv_pres_min;
std::map<float,float*>::iterator it, it_tq, it_uv;

// Gets pressure levels for TQZ records
for (it=pqtzuv_map_tq.begin(); it!=pqtzuv_map_tq.end(); ++it) {
tq_levels.add(int(it->first));
it = pqtzuv_map_tq.begin();
tq_pres_min = tq_pres_max = it->first;
for (; it!=pqtzuv_map_tq.end(); ++it) {
float pres_v = it->first;
if (tq_pres_min > pres_v) tq_pres_min = pres_v;
if (tq_pres_max < pres_v) tq_pres_max = pres_v;
tq_levels.add(nint(pres_v));
}
// Gets pressure levels for common records
for (it=pqtzuv_map_uv.begin(); it!=pqtzuv_map_uv.end(); ++it) {
if (tq_levels.has(int(it->first))) {
common_levels.add(int(it->first));
it = pqtzuv_map_uv.begin();
uv_pres_min = uv_pres_max = it->first;
for (; it!=pqtzuv_map_uv.end(); ++it) {
float pres_v = it->first;
if (uv_pres_min > pres_v) uv_pres_min = pres_v;
if (uv_pres_max < pres_v) uv_pres_max = pres_v;
if (tq_levels.has(nint(pres_v))) {
common_levels.add(nint(pres_v));
}
}

if(mlog.verbosity_level() >= PBL_DEBUG_LEVEL) {
log_tqz_and_uv(pqtzuv_map_tq, pqtzuv_map_uv, method_name);
}

bool no_overlap = (tq_pres_max < uv_pres_min) || (tq_pres_min > uv_pres_max);
mlog << Debug(6) << method_name << "TQZ pressures: " << tq_pres_max
<< " to " << tq_pres_min << " UV pressures: " << uv_pres_max
<< " to " << uv_pres_min << (no_overlap ? " no overlap!" : " overlapping") << "\n";
if( no_overlap ) {
mlog << Warning << method_name
JohnHalleyGotway marked this conversation as resolved.
Show resolved Hide resolved
<< "Can not combine TQ and UV records because of no overlapping.\n";
JohnHalleyGotway marked this conversation as resolved.
Show resolved Hide resolved
mlog << Warning << " TQZ record count: " << tq_count
JohnHalleyGotway marked this conversation as resolved.
Show resolved Hide resolved
<< ", UV record count: " << uv_count
<< " common_levels: " << common_levels.n() << "\n";
JohnHalleyGotway marked this conversation as resolved.
Show resolved Hide resolved
return pqtzuv_map_merged.size();
}

// Select first record by 1) merging two records with the same pressure
// level or 2) interpolate
int tq_pres, uv_pres;
next_pqtzuv = (float *)0;
it_tq = pqtzuv_map_tq.begin();
it_uv = pqtzuv_map_uv.begin();
pqtzuv_tq = (float *)it_tq->second;
pqtzuv_uv = (float *)it_uv->second;;
pqtzuv_merged = new float[mxr8vt];
if (common_levels.has(int(it_tq->first))
|| common_levels.has(int(it_uv->first))) {
tq_pres = nint(it_tq->first);
uv_pres = nint(it_uv->first);
if (common_levels.has(tq_pres) || common_levels.has(uv_pres)) {
// Found the records with the same precsure level
if (it_tq->first != it_uv->first) {
if (common_levels.has(int(it_uv->first))) {
if (tq_pres != uv_pres) {
if (common_levels.has(uv_pres)) {
pqtzuv_uv = pqtzuv_map_uv[it_uv->first];
}
else if (common_levels.has(int(it_tq->first))) {
else if (common_levels.has(tq_pres)) {
pqtzuv_tq = pqtzuv_map_tq[it_tq->first];
}
}
Expand All @@ -2968,7 +2994,7 @@ int combine_tqz_and_uv(map<float, float*> pqtzuv_map_tq,
prev_pqtzuv = (float *)it_uv->second;
++it_uv;
}
next_pqtzuv = it_uv->second;
next_pqtzuv = (float *)it_uv->second;
}
else {
//Interpolate TQZ into UV
Expand All @@ -2978,7 +3004,7 @@ int combine_tqz_and_uv(map<float, float*> pqtzuv_map_tq,
prev_pqtzuv = (float *)it_tq->second;
++it_tq;
}
next_pqtzuv = it_tq->second;
next_pqtzuv = (float *)it_tq->second;
}
interpolate_pqtzuv(prev_pqtzuv, pqtzuv_merged, next_pqtzuv);
}
Expand All @@ -2996,6 +3022,7 @@ int combine_tqz_and_uv(map<float, float*> pqtzuv_map_tq,
if(mlog.verbosity_level() >= PBL_DEBUG_LEVEL) {
log_merged_tqz_uv(pqtzuv_map_tq, pqtzuv_map_uv, pqtzuv_map_merged, method_name);
}
delete [] pqtzuv_merged;
}

return pqtzuv_map_merged.size();
Expand Down Expand Up @@ -3048,7 +3075,7 @@ float compute_pbl(map<float, float*> pqtzuv_map_tq,
pbl_data_vgrd[index] = pqtzuv[5];
if (!is_eq(pbl_data_spfh[index], bad_data_float)) spfh_cnt++;
if (!is_eq(pbl_data_hgt[index], bad_data_float)) hgt_cnt++;
selected_levels.add(int(it->first));
selected_levels.add(nint(it->first));
}

index--;
Expand All @@ -3070,7 +3097,7 @@ float compute_pbl(map<float, float*> pqtzuv_map_tq,
if (!is_eq(highest_pressure, bad_data_float)) {
index = MAX_PBL_LEVEL - 1;
for (; it!=pqtzuv_map_tq.end(); ++it) {
int pres_level = int(it->first);
int pres_level = nint(it->first);
if (selected_levels.has(pres_level)) break;

float *pqtzuv = pqtzuv_map_merged[it->first];
Expand Down Expand Up @@ -3192,9 +3219,14 @@ int interpolate_by_pressure(int length, float *pres_data, float *var_data) {
<< var_data[idx_start] << " and " << var_data[idx_end] << "\n";
float data_diff = var_data[idx_end] - var_data[idx_start];
for (idx2 = idx_start+1; idx2<idx_end; idx2++) {
float pres_ratio = (pres_data[idx2] - pres_data[idx_start])
/ (pres_data[idx_end] - pres_data[idx_start]);
var_data[idx2] = var_data[idx_start] + (data_diff * pres_ratio);
if (!is_eq(pres_data[idx_end], pres_data[idx_start])) {
float pres_ratio = (pres_data[idx2] - pres_data[idx_start])
/ (pres_data[idx_end] - pres_data[idx_start]);
var_data[idx2] = var_data[idx_start] + (data_diff * pres_ratio);
}
else {
var_data[idx2] = var_data[idx_start];
}
mlog << Debug(7) << method_name << " interpolated value["
<< idx2 << "] = " << var_data[idx2] << "\n";
count_interpolated++;
Expand All @@ -3219,7 +3251,9 @@ int interpolate_by_pressure(int length, float *pres_data, float *var_data) {
void interpolate_pqtzuv(float *prev_pqtzuv, float *cur_pqtzuv, float *next_pqtzuv) {
static const char *method_name = "interpolate_pqtzuv() ";

if ((prev_pqtzuv[0] == cur_pqtzuv[0]) || (next_pqtzuv[0] == cur_pqtzuv[0])) {
if ((nint(prev_pqtzuv[0]) == nint(cur_pqtzuv[0]))
|| (nint(next_pqtzuv[0]) == nint(cur_pqtzuv[0]))
|| (nint(prev_pqtzuv[0]) == nint(next_pqtzuv[0]))) {
mlog << Error << method_name
<< " Can't interpolate because of same pressure levels. prev: "
<< prev_pqtzuv[0] << ", cur: " << cur_pqtzuv[0]
Expand Down Expand Up @@ -3272,8 +3306,8 @@ void merge_records(float *first_pqtzuv, map<float, float*> pqtzuv_map_pivot,
if (first_pres < it_pivot->first) break;
}
mlog << Debug(8) << method_name << "pivot->first: " << it_pivot->first
<< " aux->first " << it_aux->first << " first_pres: " << first_pres
<< " prev_pqtzuv[0]" << prev_pqtzuv[0] << "\n";
<< " aux->first: " << it_aux->first << " first_pres: " << first_pres
<< " prev_pqtzuv[0]: " << prev_pqtzuv[0] << "\n";
// Find next UV level
for (; it_aux!=pqtzuv_map_aux.end(); ++it_aux) {
// Skip the records below the first mathcing/interpolated level
Expand Down
163 changes: 163 additions & 0 deletions test/config/PB2NCConfig_pbl
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
////////////////////////////////////////////////////////////////////////////////
//
// PB2NC configuration file.
//
// For additional information, see the MET_BASE/config/README file.
//
////////////////////////////////////////////////////////////////////////////////

//
// PrepBufr message type
//
message_type = ["ONLYSF", "ADPUPA"];

//
// Mapping of message type group name to comma-separated list of values
// Derive PRMSL only for SURFACE message types
//
message_type_group_map = [
{ key = "SURFACE"; val = "ADPSFC,SFCSHP,MSONET"; },
{ key = "ANYAIR"; val = "AIRCAR,AIRCFT"; },
{ key = "ANYSFC"; val = "ADPSFC,SFCSHP,ADPUPA,PROFLR,MSONET"; },
{ key = "ONLYSF"; val = "ADPSFC,SFCSHP"; }
];

//
// Mapping of input PrepBufr message types to output message types
//
message_type_map = [];

//
// PrepBufr station ID
//
station_id = [];

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

//
// Observation time window
//
obs_window = {
beg = -2700;
end = 2700;
}

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

//
// Observation retention regions
//
mask = {
grid = "";
poly = "";
}

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

//
// Observing location elevation
//
elevation_range = {
beg = -1000;
end = 100000;
}

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

//
// Observation types
//
pb_report_type = [ 120, 220, 221, 122, 222, 223, 224, 131, 133, 233, 153, 156, 157, 180, 280, 181, 182, 281, 282, 183, 284, 187, 287 ];
JohnHalleyGotway marked this conversation as resolved.
Show resolved Hide resolved

in_report_type = [];

instrument_type = [];

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

//
// Vertical levels to retain
//
level_range = {
beg = 1;
end = 511;
}

level_category = [0, 1, 4, 5, 6];

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

//
// BUFR variable names to retain or derive.
// Use obs_bufr_map to rename variables in the output.
// If empty, process all available variables.
//
obs_bufr_var = ["TOB", "UOB", "VOB", "TOCC", "D_RH", "TDO", "PMO", "HOVI", "CEILING", "MXGS", "D_CAPE", "D_PBL"];
JohnHalleyGotway marked this conversation as resolved.
Show resolved Hide resolved
//obs_bufr_var = ["TOB", "UOB", "VOB", "TOCC", "D_RH", "TDO", "PMO", "HOVI", "CEILING", "MXGS", "D_CAPE"];
JohnHalleyGotway marked this conversation as resolved.
Show resolved Hide resolved
////////////////////////////////////////////////////////////////////////////////

//
// Mapping of input BUFR variable names to output variables names.
// The default PREPBUFR map, obs_prepbufr_map, is appended to this map.
//
obs_bufr_map = [];

//
// Default mapping for PREPBUFR. Replace input BUFR variable names with GRIB
// abbreviations in the output. This default map is appended to obs_bufr_map.
// This should not typically be overridden.
//
obs_prefbufr_map = [
{ key = "POB"; val = "PRES"; },
{ key = "QOB"; val = "SPFH"; },
{ key = "TOB"; val = "TMP"; },
{ key = "UOB"; val = "UGRD"; },
{ key = "VOB"; val = "VGRD"; },
{ key = "D_DPT"; val = "DPT"; },
{ key = "D_WDIR"; val = "WDIR"; },
{ key = "D_WIND"; val = "WIND"; },
{ key = "D_RH"; val = "RH"; },
{ key = "D_MIXR"; val = "MIXR"; },
{ key = "D_PBL"; val = "HPBL"; },
{ key = "D_PRMSL"; val = "PRMSL"; },
{ key = "D_CAPE"; val = "CAPE"; },
{ key = "TDO"; val = "DPT"; },
{ key = "PMO"; val = "PRMSL"; },
{ key = "TOCC"; val = "TCDC"; },
{ key = "HOVI"; val = "VIS"; },
{ key = "CEILING"; val = "HGT"; },
{ key = "MXGS"; val = "GUST"; }
];

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

quality_mark_thresh = 9;
event_stack_flag = TOP;

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

//
// Time periods for the summarization
// obs_var (string array) is added and works like grib_code (int array)
// when use_var_id is enabled and variable names are saved.
//
time_summary = {
flag = FALSE;
raw_data = FALSE;
beg = "000000";
end = "235959";
step = 300;
width = 600;
grib_code = [];
obs_var = [ "TMP", "WDIR", "RH" ];
type = [ "min", "max", "range", "mean", "stdev", "median", "p80" ];
vld_freq = 0;
vld_thresh = 0.0;
}

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

tmp_dir = "/tmp";
version = "V10.0";

////////////////////////////////////////////////////////////////////////////////
19 changes: 19 additions & 0 deletions test/xml/unit_pb2nc.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,25 @@
</output>
</test>

<test name="pb2nc_compute_pbl_cape">
<exec>&MET_BIN;/pb2nc</exec>
<env>
<pair><name>STATION_ID</name> <value></value></pair>
<pair><name>MASK_GRID</name> <value></value></pair>
<pair><name>MASK_POLY</name> <value></value></pair>
<pair><name>QUALITY_MARK_THRESH</name> <value>2</value></pair>
</env>
<param> \
&DATA_DIR_OBS;/prepbufr/nam.20210311.t00z.prepbufr.tm00 \
&OUTPUT_DIR;/pb2nc/nam.20210311.t00z.prepbufr.tm00.pbl.nc \
&CONFIG_DIR;/PB2NCConfig_pbl \
-v 1
</param>
<output>
<point_nc>&OUTPUT_DIR;/pb2nc/nam.20210311.t00z.prepbufr.tm00.pbl.nc</point_nc>
</output>
</test>

<test name="pb2nc_NDAS_var_all">
<exec>&MET_BIN;/pb2nc</exec>
<env>
Expand Down