Skip to content
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
17 changes: 16 additions & 1 deletion src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,23 @@
as_offset = (*ptr2 != '@');
if (!as_offset) ptr2++;

ptr3 = strchr(ptr2, '-');
//skip negative sign of the negative value to check the range
if (ptr3 != nullptr && ptr3 == ptr2) ptr3 = strchr((ptr2+1), '-');

Check failure on line 213 in src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe_q8nloiYJWTWTm&open=AZ-FRe_q8nloiYJWTWTm&pullRequest=3419

// Check for a range of levels
if ((ptr3 = strchr(ptr2, '-')) != nullptr) {
if (ptr3 != nullptr && ptr3 != ptr2) {

Check failure on line 216 in src/libcode/vx_data2d_nc_cf/var_info_nc_cf.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe_r8nloiYJWTWTn&open=AZ-FRe_r8nloiYJWTWTn&pullRequest=3419
*ptr3 = 0;
ptr3++;
if (*ptr3 == '@') {
if (as_offset) {
mlog << Error << "\n" << method_name
<< "Can not mix an offset and a value for NetCDF variable \""
<< MagicStr << "\".\n\n";
exit(1);
}
ptr3++; // to support @vlevel_lower-@vlevel_upper
}

// Check if a range has already been supplied
if (Dimension.has(range_flag)) {
Expand Down
76 changes: 59 additions & 17 deletions src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,33 +121,75 @@ void MetNcWrfDataFile::dump(ostream & out, int depth) const {

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

bool MetNcWrfDataFile::get_real_dimension(const VarInfoNcWrf *vinfo_nc,
const NcVarInfo *info, LongArray &dimension) const {
static const string method_name
= "MetNcWrfDataFile::get_real_dimension() ->";
int dim_count = dimension.n_elements();
for (int k=0; k<dim_count; k++) {
if (dimension[k] == range_flag && vinfo_nc->level().is_offset()) {
dimension[k] = nint(vinfo_nc->level().lower());
continue;
}

if (dimension[k] != vx_data2d_dim_by_value && dimension[k] != range_flag) continue;

string dim_name = GET_NC_NAME(get_nc_dim(info->var, k));
NcVarInfo *var_info = find_var_info_by_dim_name(WrfNc->Var, dim_name,
WrfNc->Nvars);
if (var_info == nullptr) continue;

if (dimension[k] == vx_data2d_dim_by_value) {
long new_offset = get_index_at_nc_data(var_info->var,
vinfo_nc->dim_value(k),
dim_name, (k == info->t_slot));
if (new_offset != bad_data_int) dimension[k] = new_offset;
else {
mlog << Warning << "\n" << method_name
<< "for \"" << vinfo_nc->req_name()
<< "\" variable, the dimension value "
<< vinfo_nc->dim_value(k) << " for " << dim_name
<< " does not exist\n\n";
return false;
}
}
else if (dimension[k] == range_flag) {
double lower = vinfo_nc->level().lower();
double upper = vinfo_nc->level().upper();
long new_offset = get_index_at_nc_data(var_info->var, lower, upper,
dim_name, (k == info->t_slot));
if (new_offset != bad_data_int) dimension[k] = new_offset;
else {
mlog << Warning << "\n" << method_name
<< "for \"" << vinfo_nc->req_name()
<< "\" variable, the dimension value between "
<< lower << " and " << upper << " for " << dim_name
<< " does not exist\n\n";
return false;
}
}
}
return true;
}

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

bool MetNcWrfDataFile::data_plane(VarInfo &vinfo, DataPlane &plane) {
bool status = false;
double pressure;
ConcatString level_str;
VarInfoNcWrf * vinfo_nc = (VarInfoNcWrf *) &vinfo;
NcVarInfo *info = (NcVarInfo *) nullptr;
auto vinfo_nc = (VarInfoNcWrf *) &vinfo;
auto info = (NcVarInfo *) nullptr;

// Initialize the data plane
plane.clear();

// Read the data
WrfNc->get_nc_var_info(vinfo_nc->req_name().c_str(), info);

LongArray dimension = vinfo_nc->dimension();
int dim_count = dimension.n_elements();
for (int k=0; k<dim_count; k++) {
if (dimension[k] == vx_data2d_dim_by_value) {
string dim_name = GET_NC_NAME(get_nc_dim(info->var, k));
NcVarInfo *var_info = find_var_info_by_dim_name(WrfNc->Var, dim_name,
WrfNc->Nvars);
if (var_info) {
long new_offset = get_index_at_nc_data(var_info->var,
vinfo_nc->dim_value(k),
dim_name, (k == info->t_slot));
if (new_offset != bad_data_int) dimension[k] = new_offset;
}
}
}
if (! get_real_dimension(vinfo_nc, info, dimension))
return false;

status = WrfNc->data(vinfo_nc->req_name().c_str(),
dimension, plane, pressure, info);
Expand Down Expand Up @@ -198,7 +240,7 @@ bool MetNcWrfDataFile::data_plane(VarInfo &vinfo, DataPlane &plane) {
////////////////////////////////////////////////////////////////////////

int MetNcWrfDataFile::data_plane_array(VarInfo &vinfo,
DataPlaneArray &plane_array) {
DataPlaneArray &plane_array) {
int i, i_dim, n_level, status, lower, upper;
ConcatString level_str;
double pressure, min_level, max_level;
Expand Down
2 changes: 2 additions & 0 deletions src/libcode/vx_data2d_nc_wrf/data2d_nc_wrf.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class MetNcWrfDataFile : public Met2dDataFile {
private:

void nc_wrf_init_from_scratch();
bool get_real_dimension(const VarInfoNcWrf *vinfo_nc, const NcVarInfo *info,
LongArray &dimension) const;

MetNcWrfDataFile(const MetNcWrfDataFile &);
MetNcWrfDataFile & operator=(const MetNcWrfDataFile &);
Expand Down
20 changes: 18 additions & 2 deletions src/libcode/vx_data2d_nc_wrf/var_info_nc_wrf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,23 @@
as_offset = (*ptr2 != '@');
if (!as_offset) ptr2++;

ptr3 = strchr(ptr2, '-');
//skip negative sign of the negative value to check the range
if (ptr3 != nullptr && ptr3 == ptr2) ptr3 = strchr((ptr2+1), '-');

Check failure on line 214 in src/libcode/vx_data2d_nc_wrf/var_info_nc_wrf.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRfAN8nloiYJWTWTo&open=AZ-FRfAN8nloiYJWTWTo&pullRequest=3419

// Check for a range of levels
if((ptr3 = strchr(ptr2, '-')) != nullptr) {
if (ptr3 != nullptr && ptr3 != ptr2) {

Check failure on line 217 in src/libcode/vx_data2d_nc_wrf/var_info_nc_wrf.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRfAN8nloiYJWTWTp&open=AZ-FRfAN8nloiYJWTWTp&pullRequest=3419
*ptr3 = 0;
ptr3++;
if (*ptr3 == '@') {
if (as_offset) {
mlog << Error << "\n" << method_name
<< "Can not mix an offset and a value for NetCDF variable \""
<< MagicStr << "\".\n\n";
exit(1);
}
ptr3++; // to support @vlevel_lower-@vlevel_upper
}

// Check if a range has already been supplied
if(Dimension.has(range_flag)) {
Expand All @@ -223,10 +238,11 @@
else {
add_dimension(range_flag);
Level.set_lower(atoi(ptr2));
Level.set_upper(atoi(++ptr3));
Level.set_upper(atoi(ptr3));

// Assume pressure level type for a range of levels
Level.set_type(LevelType_Pres);
Level.set_is_offset(as_offset);
}
}
// Single level
Expand Down
83 changes: 82 additions & 1 deletion src/libcode/vx_nc_util/nc_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1888,10 +1888,19 @@
return return_status;
}

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

ConcatString get_value_string(double value, bool is_time) {
ConcatString value_str;
if (is_time && (value > 10000000.)) value_str << unix_to_yyyymmdd_hhmmss(value);
else value_str << value;
return value_str;
}

////////////////////////////////////////////////////////////////////////
// returns matching offset or bad_data_int if not found

int get_index_at_nc_data(NcVar *var, double value, const string dim_name, bool is_time) {
int get_index_at_nc_data(NcVar *var, double value, const string &dim_name, bool is_time) {

Check failure on line 1903 in src/libcode/vx_nc_util/nc_utils.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 37 to the 25 allowed.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe7L8nloiYJWTWTf&open=AZ-FRe7L8nloiYJWTWTf&pullRequest=3419
int offset = bad_data_int;
static const char *method_name = "get_index_at_nc_data() -> ";
if (IS_VALID_NC_P(var)) {
Expand Down Expand Up @@ -1948,6 +1957,78 @@
return offset;
}

////////////////////////////////////////////////////////////////////////
// returns matching offset or bad_data_int if not found

int get_index_at_nc_data(NcVar *var, double value_min, double value_max,

Check failure on line 1963 in src/libcode/vx_nc_util/nc_utils.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 42 to the 25 allowed.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe7L8nloiYJWTWTg&open=AZ-FRe7L8nloiYJWTWTg&pullRequest=3419
const string &dim_name, bool is_time) {
int offset = bad_data_int;
static const char *method_name = "get_index_at_nc_data(min,max) -> ";
if (IS_VALID_NC_P(var)) {
int data_size = get_data_size(var);
vector<double> values(data_size);

if (get_nc_data(var, values.data())) {
unixtime ut;
int sec_per_unit;
bool no_leap_year = get_att_no_leap_year(var);
ut = sec_per_unit = 0;

Check warning on line 1975 in src/libcode/vx_nc_util/nc_utils.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract the assignment to "sec_per_unit" from this expression.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe7L8nloiYJWTWTl&open=AZ-FRe7L8nloiYJWTWTl&pullRequest=3419
if (is_time) {
ConcatString units;
bool has_attr = get_var_units(var, units);
if (has_attr && (!units.empty()))

Check failure on line 1979 in src/libcode/vx_nc_util/nc_utils.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe7L8nloiYJWTWTh&open=AZ-FRe7L8nloiYJWTWTh&pullRequest=3419
parse_cf_time_string(units.c_str(), ut, sec_per_unit);
else {
mlog << Warning << "\n" << method_name
<< "the time variable \"" << GET_NC_NAME_P(var)
<< "\" must contain a \""
<< units_att_name << "\" attribute.\n\n";
}
}
bool found = false;
// Select the first offset between value_min and value_max
for (int idx=0; idx<data_size; idx++) {
if (is_eq(values[idx], value_min)

Check failure on line 1991 in src/libcode/vx_nc_util/nc_utils.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe7L8nloiYJWTWTi&open=AZ-FRe7L8nloiYJWTWTi&pullRequest=3419
|| is_eq(values[idx], value_max)
|| (values[idx] >= value_min && values[idx] <= value_max)) {
found = true;
}
if (!found && is_time) {

Check failure on line 1996 in src/libcode/vx_nc_util/nc_utils.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe7L8nloiYJWTWTj&open=AZ-FRe7L8nloiYJWTWTj&pullRequest=3419
unixtime time_value = add_to_unixtime(ut, sec_per_unit,
values[idx], no_leap_year);
if (is_eq(time_value, value_min)
|| is_eq(time_value, value_max)
|| (time_value >= value_min && time_value <= value_max)) {
found = true;
}
}
if (found) {

Check failure on line 2005 in src/libcode/vx_nc_util/nc_utils.cc

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=dtcenter_MET&issues=AZ-FRe7L8nloiYJWTWTk&open=AZ-FRe7L8nloiYJWTWTk&pullRequest=3419
offset = idx;
break;
}
}
}

ConcatString value_max_str = get_value_string(value_max, is_time);
ConcatString value_min_str = get_value_string(value_min, is_time);
if (offset == bad_data_int)
mlog << Debug(7) << method_name << "Not found value between " << value_min_str
<< " and " << value_max_str << " at " << GET_NC_NAME_P(var)
<< " by dimension name \"" << dim_name << "\"\n";
else {
ConcatString value_str = get_value_string(values[offset], is_time);
mlog << Debug(7) << method_name << "Found value " << value_str
<< " (index=" << offset << ") at " << GET_NC_NAME_P(var)
<< " by dimension name \"" << dim_name << "\"\n";
}
}
else {
mlog << Debug(7) << method_name << "Not found a dimension variable for \""
<< dim_name << "\"\n";
}
return offset;
}

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

bool get_nc_data_to_array(NcVar *var, StringArray *array_buf) {
Expand Down
3 changes: 2 additions & 1 deletion src/libcode/vx_nc_util/nc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ extern bool get_dim_names(const netCDF::NcFile *nc, StringArray *dimNames);
extern netCDF::NcVar get_nc_var_lat(const netCDF::NcFile *nc);
extern netCDF::NcVar get_nc_var_lon(const netCDF::NcFile *nc);
extern netCDF::NcVar get_nc_var_time(const netCDF::NcFile *nc);
extern int get_index_at_nc_data(netCDF::NcVar *var, double value, const std::string dim_name, bool is_time=false);
extern int get_index_at_nc_data(netCDF::NcVar *var, double value, const std::string &dim_name, bool is_time=false);
extern int get_index_at_nc_data(netCDF::NcVar *var, double value_min, double value_max, const std::string &dim_name, bool is_time=false);
extern netCDF::NcFile* open_ncfile(const char * nc_name, bool write = false);

// Moved from nc_cf_file.cc
Expand Down
Loading