From 5d8da0dd12898452130194a0f7812c5d8f2471d4 Mon Sep 17 00:00:00 2001 From: mike-dixon Date: Sat, 18 Nov 2023 17:25:50 -0700 Subject: [PATCH] apps/ingest/src/Era5Nc2Mdv - testing --- codebase/apps/ingest/src/CMakeLists.txt | 1 + codebase/apps/ingest/src/Era5Nc2Mdv/CIDD.era5 | 20 +- .../apps/ingest/src/Era5Nc2Mdv/CMakeLists.txt | 7 +- .../apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.cc | 71 +++ .../apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.hh | 4 +- .../ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.test | 239 +++----- codebase/apps/ingest/src/Era5Nc2Mdv/Params.cc | 243 +++----- codebase/apps/ingest/src/Era5Nc2Mdv/Params.hh | 42 +- .../apps/ingest/src/Era5Nc2Mdv/PresInterp.cc | 251 --------- .../apps/ingest/src/Era5Nc2Mdv/PresInterp.hh | 138 ----- .../ingest/src/Era5Nc2Mdv/__makefile.template | 19 +- .../ingest/src/Era5Nc2Mdv/orig/OutputFile.cc | 450 --------------- .../ingest/src/Era5Nc2Mdv/orig/OutputFile.hh | 97 ---- .../apps/ingest/src/Era5Nc2Mdv/orig/main.cc | 84 --- .../ingest/src/Era5Nc2Mdv/orig/paramdef.orig | 520 ------------------ .../ingest/src/Era5Nc2Mdv/paramdef.Era5Nc2Mdv | 194 ++----- codebase/apps/ingest/src/Makefile | 1 + codebase/apps/ingest/src/__makefile.template | 1 + 18 files changed, 325 insertions(+), 2057 deletions(-) delete mode 100644 codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.cc delete mode 100644 codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.hh delete mode 100644 codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.cc delete mode 100644 codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.hh delete mode 100644 codebase/apps/ingest/src/Era5Nc2Mdv/orig/main.cc delete mode 100644 codebase/apps/ingest/src/Era5Nc2Mdv/orig/paramdef.orig diff --git a/codebase/apps/ingest/src/CMakeLists.txt b/codebase/apps/ingest/src/CMakeLists.txt index 7de8bae5d5..2ff8c6a064 100644 --- a/codebase/apps/ingest/src/CMakeLists.txt +++ b/codebase/apps/ingest/src/CMakeLists.txt @@ -28,6 +28,7 @@ add_subdirectory (CwbObs2Spdb) add_subdirectory (CwbSfc2Mdv) add_subdirectory (EolMobileKml2Spdb) add_subdirectory (EraGrib2Mdv) +add_subdirectory (Era5Nc2Mdv) add_subdirectory (GemVolXml2Dsr) add_subdirectory (Gini2Mdv) add_subdirectory (GoesRGLM2Spdb) diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/CIDD.era5 b/codebase/apps/ingest/src/Era5Nc2Mdv/CIDD.era5 index 2d19fcaecb..c27c5848fa 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/CIDD.era5 +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/CIDD.era5 @@ -97,16 +97,16 @@ field_list = { # ERA5 # -Div Div mdvp:://localhost::$(HOME)/data/ERA5/mdv&D div.colors 1/s -5 80 5 dcont 1 0 -Q Q mdvp:://localhost::$(HOME)/data/ERA5/mdv&Q mixr_kgpkg.colors kg/kg -5 80 5 dcont 1 0 -RH RH mdvp:://localhost::$(HOME)/data/ERA5/mdv&R rh.colors % -5 80 5 dcont 1 0 -T T mdvp:://localhost::$(HOME)/data/ERA5/mdv&T tempK.colors K -5 80 5 dcont 1 0 -U U mdvp:://localhost::$(HOME)/data/ERA5/mdv&U vel_45.colors m/s -5 80 5 dcont 1 0 -V V mdvp:://localhost::$(HOME)/data/ERA5/mdv&V vel_45.colors m/s -5 80 5 dcont 1 0 -W W mdvp:://localhost::$(HOME)/data/ERA5/mdv&W vert_wspd.colors Pa/s -5 80 5 dcont 1 0 -Z Z mdvp:://localhost::$(HOME)/data/ERA5/mdv&Z geoht_m.colors m2/s2 -5 80 5 dcont 1 0 -ht ht mdvp:://localhost::$(HOME)/data/ERA5/mdv&height heightkm.colors m -5 80 5 dcont 1 0 -pres pres mdvp:://localhost::$(HOME)/data/ERA5/mdv&pressure pressure_mb.colors hPa -5 80 5 dcont 1 0 +Div Div mdvp:://localhost::$(HOME)/data/ERA5/mdv&div div.colors 1/s -5 80 5 dcont 1 0 +Q Q mdvp:://localhost::$(HOME)/data/ERA5/mdv&spec_hum mixr_kgpkg.colors kg/kg -5 80 5 dcont 1 0 +RH RH mdvp:://localhost::$(HOME)/data/ERA5/mdv&RH rh.colors % -5 80 5 dcont 1 0 +T T mdvp:://localhost::$(HOME)/data/ERA5/mdv&temp tempK.colors K -5 80 5 dcont 1 0 +U U mdvp:://localhost::$(HOME)/data/ERA5/mdv&u vel_45.colors m/s -5 80 5 dcont 1 0 +V V mdvp:://localhost::$(HOME)/data/ERA5/mdv&v vel_45.colors m/s -5 80 5 dcont 1 0 +W W mdvp:://localhost::$(HOME)/data/ERA5/mdv&w vert_wspd.colors Pa/s -5 80 5 dcont 1 0 +Z Z mdvp:://localhost::$(HOME)/data/ERA5/mdv&Z geoht_m.colors m2/s2 -5 80 5 dcont 1 0 +ht ht mdvp:://localhost::$(HOME)/data/ERA5/mdv&height heightkm.colors m -5 80 5 dcont 1 0 +pres pres mdvp:://localhost::$(HOME)/data/ERA5/mdv&pressure pressure_mb.colors hPa -5 80 5 dcont 1 0 diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/CMakeLists.txt b/codebase/apps/ingest/src/Era5Nc2Mdv/CMakeLists.txt index b25c78ae74..088983d308 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/CMakeLists.txt +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/CMakeLists.txt @@ -16,11 +16,10 @@ project (Era5Nc2Mdv) set (SRCS Params.cc Args.cc - ReadFile.cc - HtInterp.cc - OutputFile.cc + Era5File.cc Era5Nc2Mdv.cc - main.cc + HtInterp.cc + Main.cc ) # include directories diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.cc b/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.cc index 34a3eb05bf..af2e44ffcb 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.cc +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.cc @@ -471,6 +471,12 @@ int Era5Nc2Mdv::_createVol(const vector &pathsAtTime, } // ipath + // convert temp field units to C + + if (_params.convert_temperature_to_celcius) { + _convertTempToC(mdvx); + } + // create height field from geopotential, for interpolation onto height levels _addHeightField(mdvx); @@ -479,6 +485,12 @@ int Era5Nc2Mdv::_createVol(const vector &pathsAtTime, interp.interpVlevelsToHeight(mdvx); } + // rename fields if requested + + if (_params.rename_output_fields) { + _renameFields(mdvx); + } + // write output file if (_params.debug) { @@ -749,3 +761,62 @@ int Era5Nc2Mdv::_addHeightField(DsMdvx &mdvx) } +//////////////////////////////////////////////////////// +// convert temperature field units to C +// +// Returns 0 on success, -1 on failure + +int Era5Nc2Mdv::_convertTempToC(DsMdvx &mdvx) + +{ + + MdvxField *tField = mdvx.getField(_params.temperature_field_name); + if (tField == NULL) { + cerr << "WARNING - Era5Nc2Mdv::_convertTempToC" << endl; + cerr << " Cannot find temperature field: " + << _params.temperature_field_name <getVol(); + int64_t nPoints = tField->getVolNumValues(); + for (int64_t ii = 0; ii < nPoints; ii++) { + double kelvin = tData[ii]; + double celcius = kelvin - 273.16; + tData[ii] = celcius; + } + tField->setUnits("C"); + + return 0; + +} + +//////////////////////////////////////////////////////// +// rename fields before write +// Returns 0 on success, -1 on failure + +void Era5Nc2Mdv::_renameFields(DsMdvx &mdvx) + +{ + + for (int ifield = 0; ifield < _params.output_fields_n; ifield++) { + + const Params::output_field_t &ofld = _params._output_fields[ifield]; + + MdvxField *field = mdvx.getField(ofld.input_field_name); + if (field == NULL) { + cerr << "WARNING - Era5Nc2Mdv::_renameFields" << endl; + cerr << " Cannot find field: " + << ofld.input_field_name <setFieldName(ofld.output_field_name); + field->setFieldNameLong(ofld.output_long_name); + field->setUnits(ofld.output_units); + + } + +} + diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.hh b/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.hh index 9afed8cb2f..0aac8ae75d 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.hh +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.hh @@ -121,7 +121,9 @@ private: int _getLevelIndex(double level); int _addHeightField(DsMdvx &mdvx); int _addPressureField(DsMdvx &mdvx); - + int _convertTempToC(DsMdvx &mdvx); + void _renameFields(DsMdvx &mdvx); + }; #endif diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.test b/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.test index 80644d581f..234862951f 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.test +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/Era5Nc2Mdv.test @@ -1,11 +1,11 @@ /********************************************************************** - * TDRP params for Era5Nc2Mdv + * TDRP params for ./Era5Nc2Mdv **********************************************************************/ //====================================================================== // -// Era5Nc2Mdv reads output files from the WRF model and writes MDV data. -// It also allows the computation of some derived products. +// Era5Nc2Mdv reads ERA5 NetCDF files, created using a CISL translator, +// and converts to MDV CF-NetCDF format. // //====================================================================== @@ -88,19 +88,6 @@ end_time = "2023 07 01 00 00 00"; // //====================================================================== -///////////// soilparm_path /////////////////////////// -// -// path to SOILPARM.TBL config file that was used when running WRF. -// -// Information in this table is neccessary to calculate -// MOIST_AVAIL_FIELD. -// -// -// Type: string -// - -soilparm_path = "./SOILPARM.TBL"; - ///////////// input_dir /////////////////////////////// // // Directory for input data - ARCHIVE mode. @@ -115,112 +102,32 @@ input_dir = "$(HOME)/data/ERA5/levelFiles"; //====================================================================== // -// SPECIFY FIELD NAMES AND OUTPUT ENCODING. +// CONVERT TEMP TO C. // //====================================================================== -///////////// output_fields /////////////////////////// -// -// Output field details. -// -// Set the details for the output fields. The output_field_name is the -// ndtCDF variable name. The standard name is set to the MDV long name. -// If the long name or standard name are empty, the existing names are -// used. +///////////// convert_temperature_to_celcius ////////// // +// The temperature is read in degrees Kelvin. This option allows us to +// convert to degrees C. // -// Type: struct -// typedef struct { -// string input_field_name; -// string output_field_name; -// string standard_name; -// string output_units; -// output_encoding_t encoding; -// Options: -// OUTPUT_ENCODING_FLOAT32 -// OUTPUT_ENCODING_INT16 -// OUTPUT_ENCODING_INT08 -// } // -// 1D array - variable length. +// Type: boolean // -output_fields = { - { - input_field_name = "D", - output_field_name = "divergence", - standard_name = "divergence_of_wind", - output_units = "1/s", - encoding = OUTPUT_ENCODING_FLOAT32 - } - , - { - input_field_name = "Q", - output_field_name = "specific_humidity", - standard_name = "specific_humidity", - output_units = "kg/kg", - encoding = OUTPUT_ENCODING_FLOAT32 - } - , - { - input_field_name = "R", - output_field_name = "RH", - standard_name = "relative_humidity", - output_units = "%", - encoding = OUTPUT_ENCODING_FLOAT32 - } - , - { - input_field_name = "T", - output_field_name = "temperature", - standard_name = "air_temperature", - output_units = "K", - encoding = OUTPUT_ENCODING_FLOAT32 - } - , - { - input_field_name = "U", - output_field_name = "u", - standard_name = "eastward_wind", - output_units = "m/s", - encoding = OUTPUT_ENCODING_FLOAT32 - } - , - { - input_field_name = "V", - output_field_name = "v", - standard_name = "northward_wind", - output_units = "m/s", - encoding = OUTPUT_ENCODING_FLOAT32 - } - , - { - input_field_name = "W", - output_field_name = "w", - standard_name = "vertical_velocity", - output_units = "m/s", - encoding = OUTPUT_ENCODING_FLOAT32 - } - , - { - input_field_name = "Z", - output_field_name = "z", - standard_name = "geopotential_height", - output_units = "m", - encoding = OUTPUT_ENCODING_FLOAT32 - } -}; +convert_temperature_to_celcius = FALSE; -///////////// convert_temperature_to_celcius ////////// +///////////// temperature_field_name ////////////////// // -// The temperature is read in degrees Kelvin. This option allows us to -// convert to degrees C. +// NetCDF variable name of temperature field in input data. // +// This is the field to be converted to C. // -// Type: boolean +// +// Type: string // -convert_temperature_to_celcius = FALSE; +temperature_field_name = "T"; //====================================================================== // @@ -243,10 +150,10 @@ interp_to_height_levels = TRUE; ///////////// geopotential_field_name ///////////////// // -// Z. -// // NetCDF variable name of geopotential height in input data. // +// We use this field to provide heights for interpolation. +// // // Type: string // @@ -334,65 +241,91 @@ min_height_from_pressure_levels = 0; output_dir = "$(HOME)/data/ERA5/mdv"; -///////////// output_level_type /////////////////////// -// -// Option to choose vertical levels for output file. -// -// If FLIGHT_LEVELS, PRESSURE_LEVELS or HEIGHT_LEVELS, vertical levels -// will be interpolated accordingly. If NATIVE_VERTICAL_LEVELS, no -// interpolation is done and the data is output on the original vertical -// levels (i.e. sigma, eta, etc.). -// -// -// Type: enum -// Options: -// FLIGHT_LEVELS -// PRESSURE_LEVELS -// HEIGHT_LEVELS -// NATIVE_VERTICAL_LEVELS -// - -output_level_type = HEIGHT_LEVELS; - //====================================================================== // -// FILE HEADER INFO. +// SPECIFY OUTPUT FIELD NAMES AND UNITS. // //====================================================================== -///////////// data_set_info /////////////////////////// +///////////// rename_output_fields //////////////////// // -// Data set info. +// Option to rename the fields, and set the units, before writing. // -// This is placed in the MDV master header for documentation purposes. // -// -// Type: string +// Type: boolean // -data_set_info = "This MDV file was created by Era5Nc2Mdv."; +rename_output_fields = TRUE; -///////////// data_set_name /////////////////////////// -// -// Data set name. -// -// This is placed in the MDV master header for documentation purposes. -// -// -// Type: string +///////////// output_fields /////////////////////////// // - -data_set_name = "WRF model output."; - -///////////// data_set_source ///////////////////////// +// Output field details. // -// Data set source details. +// Set the details for the output fields. The output_field_name is the +// ndtCDF variable name. The standard name is set to the MDV long name. +// If the long name or standard name are empty, the existing names are +// used. // -// This is placed in the MDV master header for documentation purposes. // +// Type: struct +// typedef struct { +// string input_field_name; +// string output_field_name; +// string output_long_name; +// string output_units; +// } // -// Type: string +// 1D array - variable length. // -data_set_source = "WRF output from somewhere."; +output_fields = { + { + input_field_name = "D", + output_field_name = "div", + output_long_name = "divergence_of_wind", + output_units = "1/s" + } + , + { + input_field_name = "Q", + output_field_name = "spec_hum", + output_long_name = "specific_humidity", + output_units = "kg/kg" + } + , + { + input_field_name = "R", + output_field_name = "RH", + output_long_name = "relative_humidity", + output_units = "%" + } + , + { + input_field_name = "T", + output_field_name = "temp", + output_long_name = "air_temperature", + output_units = "K" + } + , + { + input_field_name = "U", + output_field_name = "u", + output_long_name = "wind_east_component", + output_units = "m/s" + } + , + { + input_field_name = "V", + output_field_name = "v", + output_long_name = "wind_north_component", + output_units = "m/s" + } + , + { + input_field_name = "W", + output_field_name = "w", + output_long_name = "vertical_velocity", + output_units = "m/s" + } +}; diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/Params.cc b/codebase/apps/ingest/src/Era5Nc2Mdv/Params.cc index 43cf56a818..4cfba85001 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/Params.cc +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/Params.cc @@ -559,7 +559,7 @@ memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 0"); - tt->comment_hdr = tdrpStrDup("Era5Nc2Mdv reads output files from the WRF model and writes MDV data. It also allows the computation of some derived products."); + tt->comment_hdr = tdrpStrDup("Era5Nc2Mdv reads ERA5 NetCDF files, created using a CISL translator, and converts to MDV CF-NetCDF format."); tt->comment_text = tdrpStrDup(""); tt++; @@ -658,18 +658,6 @@ tt->comment_text = tdrpStrDup(""); tt++; - // Parameter 'soilparm_path' - // ctype is 'char*' - - memset(tt, 0, sizeof(TDRPtable)); - tt->ptype = STRING_TYPE; - tt->param_name = tdrpStrDup("soilparm_path"); - tt->descr = tdrpStrDup("path to SOILPARM.TBL config file that was used when running WRF."); - tt->help = tdrpStrDup("Information in this table is neccessary to calculate MOIST_AVAIL_FIELD."); - tt->val_offset = (char *) &soilparm_path - &_start_; - tt->single_val.s = tdrpStrDup("./SOILPARM.TBL"); - tt++; - // Parameter 'input_dir' // ctype is 'char*' @@ -687,108 +675,10 @@ memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 4"); - tt->comment_hdr = tdrpStrDup("SPECIFY FIELD NAMES AND OUTPUT ENCODING"); + tt->comment_hdr = tdrpStrDup("CONVERT TEMP TO C."); tt->comment_text = tdrpStrDup(""); tt++; - // Parameter 'output_fields' - // ctype is '_output_field_t' - - memset(tt, 0, sizeof(TDRPtable)); - tt->ptype = STRUCT_TYPE; - tt->param_name = tdrpStrDup("output_fields"); - tt->descr = tdrpStrDup("Output field details."); - tt->help = tdrpStrDup("Set the details for the output fields. The output_field_name is the ndtCDF variable name. The standard name is set to the MDV long name. If the long name or standard name are empty, the existing names are used."); - tt->array_offset = (char *) &_output_fields - &_start_; - tt->array_n_offset = (char *) &output_fields_n - &_start_; - tt->is_array = TRUE; - tt->array_len_fixed = FALSE; - tt->array_elem_size = sizeof(output_field_t); - tt->array_n = 8; - tt->struct_def.name = tdrpStrDup("output_field_t"); - tt->struct_def.nfields = 5; - tt->struct_def.fields = (struct_field_t *) - tdrpMalloc(tt->struct_def.nfields * sizeof(struct_field_t)); - tt->struct_def.fields[0].ftype = tdrpStrDup("string"); - tt->struct_def.fields[0].fname = tdrpStrDup("input_field_name"); - tt->struct_def.fields[0].ptype = STRING_TYPE; - tt->struct_def.fields[0].rel_offset = - (char *) &_output_fields->input_field_name - (char *) _output_fields; - tt->struct_def.fields[1].ftype = tdrpStrDup("string"); - tt->struct_def.fields[1].fname = tdrpStrDup("output_field_name"); - tt->struct_def.fields[1].ptype = STRING_TYPE; - tt->struct_def.fields[1].rel_offset = - (char *) &_output_fields->output_field_name - (char *) _output_fields; - tt->struct_def.fields[2].ftype = tdrpStrDup("string"); - tt->struct_def.fields[2].fname = tdrpStrDup("standard_name"); - tt->struct_def.fields[2].ptype = STRING_TYPE; - tt->struct_def.fields[2].rel_offset = - (char *) &_output_fields->standard_name - (char *) _output_fields; - tt->struct_def.fields[3].ftype = tdrpStrDup("string"); - tt->struct_def.fields[3].fname = tdrpStrDup("output_units"); - tt->struct_def.fields[3].ptype = STRING_TYPE; - tt->struct_def.fields[3].rel_offset = - (char *) &_output_fields->output_units - (char *) _output_fields; - tt->struct_def.fields[4].ftype = tdrpStrDup("output_encoding_t"); - tt->struct_def.fields[4].fname = tdrpStrDup("encoding"); - tt->struct_def.fields[4].ptype = ENUM_TYPE; - tt->struct_def.fields[4].rel_offset = - (char *) &_output_fields->encoding - (char *) _output_fields; - tt->struct_def.fields[4].enum_def.name = tdrpStrDup("output_encoding_t"); - tt->struct_def.fields[4].enum_def.nfields = 3; - tt->struct_def.fields[4].enum_def.fields = (enum_field_t *) tdrpMalloc - (tt->struct_def.fields[4].enum_def.nfields * sizeof(enum_field_t)); - tt->struct_def.fields[4].enum_def.fields[0].name = tdrpStrDup("OUTPUT_ENCODING_FLOAT32"); - tt->struct_def.fields[4].enum_def.fields[0].val = OUTPUT_ENCODING_FLOAT32; - tt->struct_def.fields[4].enum_def.fields[1].name = tdrpStrDup("OUTPUT_ENCODING_INT16"); - tt->struct_def.fields[4].enum_def.fields[1].val = OUTPUT_ENCODING_INT16; - tt->struct_def.fields[4].enum_def.fields[2].name = tdrpStrDup("OUTPUT_ENCODING_INT08"); - tt->struct_def.fields[4].enum_def.fields[2].val = OUTPUT_ENCODING_INT08; - tt->n_struct_vals = 40; - tt->struct_vals = (tdrpVal_t *) - tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); - tt->struct_vals[0].s = tdrpStrDup("D"); - tt->struct_vals[1].s = tdrpStrDup("divergence"); - tt->struct_vals[2].s = tdrpStrDup("divergence_of_wind"); - tt->struct_vals[3].s = tdrpStrDup("1/s"); - tt->struct_vals[4].e = OUTPUT_ENCODING_FLOAT32; - tt->struct_vals[5].s = tdrpStrDup("Q"); - tt->struct_vals[6].s = tdrpStrDup("specific_humidity"); - tt->struct_vals[7].s = tdrpStrDup("specific_humidity"); - tt->struct_vals[8].s = tdrpStrDup("kg/kg"); - tt->struct_vals[9].e = OUTPUT_ENCODING_FLOAT32; - tt->struct_vals[10].s = tdrpStrDup("R"); - tt->struct_vals[11].s = tdrpStrDup("RH"); - tt->struct_vals[12].s = tdrpStrDup("relative_humidity"); - tt->struct_vals[13].s = tdrpStrDup("%"); - tt->struct_vals[14].e = OUTPUT_ENCODING_FLOAT32; - tt->struct_vals[15].s = tdrpStrDup("T"); - tt->struct_vals[16].s = tdrpStrDup("temperature"); - tt->struct_vals[17].s = tdrpStrDup("air_temperature"); - tt->struct_vals[18].s = tdrpStrDup("K"); - tt->struct_vals[19].e = OUTPUT_ENCODING_FLOAT32; - tt->struct_vals[20].s = tdrpStrDup("U"); - tt->struct_vals[21].s = tdrpStrDup("u"); - tt->struct_vals[22].s = tdrpStrDup("eastward_wind"); - tt->struct_vals[23].s = tdrpStrDup("m/s"); - tt->struct_vals[24].e = OUTPUT_ENCODING_FLOAT32; - tt->struct_vals[25].s = tdrpStrDup("V"); - tt->struct_vals[26].s = tdrpStrDup("v"); - tt->struct_vals[27].s = tdrpStrDup("northward_wind"); - tt->struct_vals[28].s = tdrpStrDup("m/s"); - tt->struct_vals[29].e = OUTPUT_ENCODING_FLOAT32; - tt->struct_vals[30].s = tdrpStrDup("W"); - tt->struct_vals[31].s = tdrpStrDup("w"); - tt->struct_vals[32].s = tdrpStrDup("vertical_velocity"); - tt->struct_vals[33].s = tdrpStrDup("m/s"); - tt->struct_vals[34].e = OUTPUT_ENCODING_FLOAT32; - tt->struct_vals[35].s = tdrpStrDup("Z"); - tt->struct_vals[36].s = tdrpStrDup("z"); - tt->struct_vals[37].s = tdrpStrDup("geopotential_height"); - tt->struct_vals[38].s = tdrpStrDup("m"); - tt->struct_vals[39].e = OUTPUT_ENCODING_FLOAT32; - tt++; - // Parameter 'convert_temperature_to_celcius' // ctype is 'tdrp_bool_t' @@ -801,6 +691,18 @@ tt->single_val.b = pFALSE; tt++; + // Parameter 'temperature_field_name' + // ctype is 'char*' + + memset(tt, 0, sizeof(TDRPtable)); + tt->ptype = STRING_TYPE; + tt->param_name = tdrpStrDup("temperature_field_name"); + tt->descr = tdrpStrDup("NetCDF variable name of temperature field in input data."); + tt->help = tdrpStrDup("This is the field to be converted to C."); + tt->val_offset = (char *) &temperature_field_name - &_start_; + tt->single_val.s = tdrpStrDup("T"); + tt++; + // Parameter 'Comment 5' memset(tt, 0, sizeof(TDRPtable)); @@ -918,73 +820,84 @@ tt->single_val.s = tdrpStrDup("/tmp/ERA5"); tt++; - // Parameter 'output_level_type' - // ctype is '_output_level_type_t' - - memset(tt, 0, sizeof(TDRPtable)); - tt->ptype = ENUM_TYPE; - tt->param_name = tdrpStrDup("output_level_type"); - tt->descr = tdrpStrDup("Option to choose vertical levels for output file."); - tt->help = tdrpStrDup("If FLIGHT_LEVELS, PRESSURE_LEVELS or HEIGHT_LEVELS, vertical levels will be interpolated accordingly. If NATIVE_VERTICAL_LEVELS, no interpolation is done and the data is output on the original vertical levels (i.e. sigma, eta, etc.)."); - tt->val_offset = (char *) &output_level_type - &_start_; - tt->enum_def.name = tdrpStrDup("output_level_type_t"); - tt->enum_def.nfields = 4; - tt->enum_def.fields = (enum_field_t *) - tdrpMalloc(tt->enum_def.nfields * sizeof(enum_field_t)); - tt->enum_def.fields[0].name = tdrpStrDup("FLIGHT_LEVELS"); - tt->enum_def.fields[0].val = FLIGHT_LEVELS; - tt->enum_def.fields[1].name = tdrpStrDup("PRESSURE_LEVELS"); - tt->enum_def.fields[1].val = PRESSURE_LEVELS; - tt->enum_def.fields[2].name = tdrpStrDup("HEIGHT_LEVELS"); - tt->enum_def.fields[2].val = HEIGHT_LEVELS; - tt->enum_def.fields[3].name = tdrpStrDup("NATIVE_VERTICAL_LEVELS"); - tt->enum_def.fields[3].val = NATIVE_VERTICAL_LEVELS; - tt->single_val.e = HEIGHT_LEVELS; - tt++; - // Parameter 'Comment 7' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 7"); - tt->comment_hdr = tdrpStrDup("FILE HEADER INFO"); + tt->comment_hdr = tdrpStrDup("SPECIFY OUTPUT FIELD NAMES AND UNITS"); tt->comment_text = tdrpStrDup(""); tt++; - // Parameter 'data_set_info' - // ctype is 'char*' - - memset(tt, 0, sizeof(TDRPtable)); - tt->ptype = STRING_TYPE; - tt->param_name = tdrpStrDup("data_set_info"); - tt->descr = tdrpStrDup("Data set info."); - tt->help = tdrpStrDup("This is placed in the MDV master header for documentation purposes."); - tt->val_offset = (char *) &data_set_info - &_start_; - tt->single_val.s = tdrpStrDup("This MDV file was created by Era5Nc2Mdv."); - tt++; - - // Parameter 'data_set_name' - // ctype is 'char*' + // Parameter 'rename_output_fields' + // ctype is 'tdrp_bool_t' memset(tt, 0, sizeof(TDRPtable)); - tt->ptype = STRING_TYPE; - tt->param_name = tdrpStrDup("data_set_name"); - tt->descr = tdrpStrDup("Data set name."); - tt->help = tdrpStrDup("This is placed in the MDV master header for documentation purposes."); - tt->val_offset = (char *) &data_set_name - &_start_; - tt->single_val.s = tdrpStrDup("WRF model output."); + tt->ptype = BOOL_TYPE; + tt->param_name = tdrpStrDup("rename_output_fields"); + tt->descr = tdrpStrDup("Option to rename the fields, and set the units, before writing."); + tt->help = tdrpStrDup(""); + tt->val_offset = (char *) &rename_output_fields - &_start_; + tt->single_val.b = pFALSE; tt++; - // Parameter 'data_set_source' - // ctype is 'char*' + // Parameter 'output_fields' + // ctype is '_output_field_t' memset(tt, 0, sizeof(TDRPtable)); - tt->ptype = STRING_TYPE; - tt->param_name = tdrpStrDup("data_set_source"); - tt->descr = tdrpStrDup("Data set source details."); - tt->help = tdrpStrDup("This is placed in the MDV master header for documentation purposes."); - tt->val_offset = (char *) &data_set_source - &_start_; - tt->single_val.s = tdrpStrDup("WRF output from somewhere."); + tt->ptype = STRUCT_TYPE; + tt->param_name = tdrpStrDup("output_fields"); + tt->descr = tdrpStrDup("Output field details."); + tt->help = tdrpStrDup("Set the details for the output fields. The output_field_name is the ndtCDF variable name. The standard name is set to the MDV long name. If the long name or standard name are empty, the existing names are used."); + tt->array_offset = (char *) &_output_fields - &_start_; + tt->array_n_offset = (char *) &output_fields_n - &_start_; + tt->is_array = TRUE; + tt->array_len_fixed = FALSE; + tt->array_elem_size = sizeof(output_field_t); + tt->array_n = 4; + tt->struct_def.name = tdrpStrDup("output_field_t"); + tt->struct_def.nfields = 4; + tt->struct_def.fields = (struct_field_t *) + tdrpMalloc(tt->struct_def.nfields * sizeof(struct_field_t)); + tt->struct_def.fields[0].ftype = tdrpStrDup("string"); + tt->struct_def.fields[0].fname = tdrpStrDup("input_field_name"); + tt->struct_def.fields[0].ptype = STRING_TYPE; + tt->struct_def.fields[0].rel_offset = + (char *) &_output_fields->input_field_name - (char *) _output_fields; + tt->struct_def.fields[1].ftype = tdrpStrDup("string"); + tt->struct_def.fields[1].fname = tdrpStrDup("output_field_name"); + tt->struct_def.fields[1].ptype = STRING_TYPE; + tt->struct_def.fields[1].rel_offset = + (char *) &_output_fields->output_field_name - (char *) _output_fields; + tt->struct_def.fields[2].ftype = tdrpStrDup("string"); + tt->struct_def.fields[2].fname = tdrpStrDup("output_long_name"); + tt->struct_def.fields[2].ptype = STRING_TYPE; + tt->struct_def.fields[2].rel_offset = + (char *) &_output_fields->output_long_name - (char *) _output_fields; + tt->struct_def.fields[3].ftype = tdrpStrDup("string"); + tt->struct_def.fields[3].fname = tdrpStrDup("output_units"); + tt->struct_def.fields[3].ptype = STRING_TYPE; + tt->struct_def.fields[3].rel_offset = + (char *) &_output_fields->output_units - (char *) _output_fields; + tt->n_struct_vals = 16; + tt->struct_vals = (tdrpVal_t *) + tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); + tt->struct_vals[0].s = tdrpStrDup("D"); + tt->struct_vals[1].s = tdrpStrDup("divergence"); + tt->struct_vals[2].s = tdrpStrDup("divergence_of_wind"); + tt->struct_vals[3].s = tdrpStrDup("1/s"); + tt->struct_vals[4].s = tdrpStrDup("Q"); + tt->struct_vals[5].s = tdrpStrDup("specific_humidity"); + tt->struct_vals[6].s = tdrpStrDup("specific_humidity"); + tt->struct_vals[7].s = tdrpStrDup("kg/kg"); + tt->struct_vals[8].s = tdrpStrDup("T"); + tt->struct_vals[9].s = tdrpStrDup("temperature"); + tt->struct_vals[10].s = tdrpStrDup("air_temperature"); + tt->struct_vals[11].s = tdrpStrDup("K"); + tt->struct_vals[12].s = tdrpStrDup("W"); + tt->struct_vals[13].s = tdrpStrDup("w"); + tt->struct_vals[14].s = tdrpStrDup("vertical_velocity"); + tt->struct_vals[15].s = tdrpStrDup("m/s"); tt++; // trailing entry has param_name set to NULL diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/Params.hh b/codebase/apps/ingest/src/Era5Nc2Mdv/Params.hh index c11d399760..63f82c5bbc 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/Params.hh +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/Params.hh @@ -79,35 +79,13 @@ public: FILELIST = 1 } mode_t; - typedef enum { - OUTPUT_ENCODING_FLOAT32 = 0, - OUTPUT_ENCODING_INT16 = 1, - OUTPUT_ENCODING_INT08 = 2 - } output_encoding_t; - - typedef enum { - FLIGHT_LEVELS = 0, - PRESSURE_LEVELS = 1, - HEIGHT_LEVELS = 2, - NATIVE_VERTICAL_LEVELS = 3 - } output_level_type_t; - - typedef enum { - _MDV_COMPRESSION_NONE = 0, - _MDV_COMPRESSION_RLE = 1, - _MDV_COMPRESSION_LZO = 2, - _MDV_COMPRESSION_ZLIB = 3, - _MDV_COMPRESSION_BZIP = 4 - } compression_t; - // struct typedefs typedef struct { char* input_field_name; char* output_field_name; - char* standard_name; + char* output_long_name; char* output_units; - output_encoding_t encoding; } output_field_t; /////////////////////////// @@ -412,15 +390,12 @@ public: char* end_time; - char* soilparm_path; - char* input_dir; - output_field_t *_output_fields; - int output_fields_n; - tdrp_bool_t convert_temperature_to_celcius; + char* temperature_field_name; + tdrp_bool_t interp_to_height_levels; char* geopotential_field_name; @@ -434,13 +409,10 @@ public: char* output_dir; - output_level_type_t output_level_type; - - char* data_set_info; + tdrp_bool_t rename_output_fields; - char* data_set_name; - - char* data_set_source; + output_field_t *_output_fields; + int output_fields_n; char _end_; // end of data region // needed for zeroing out data @@ -449,7 +421,7 @@ private: void _init(); - mutable TDRPtable _table[27]; + mutable TDRPtable _table[24]; const char *_className; diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.cc b/codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.cc deleted file mode 100644 index ff3cf93364..0000000000 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.cc +++ /dev/null @@ -1,251 +0,0 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2016 -// ** 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. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -////////////////////////////////////////////////////////// -// PresInterp.cc -// -// This class provides the pressure at any given flight level -// between -10 and 500. (based upon SigmaInterp) -// -// Internally some variables still refer to sigma. This is a reminant -// of the old SigmaInterp, but calculations are done based upon pressure -// and not sigma. External references to sigma have been removed, and -// internal references should be taken to refer to a general vertical -// coordinate system, and not specifically sigma. -// -// Paul Prestopnik, RAP, NCAR, P.O.Box 3000, Boulder, CO, 80307-3000, USA -// -// Jan 2008 -// -////////////////////////////////////////////////////////// - - -#include "PresInterp.hh" -#include -#include -#include -#include -using namespace std; - -const double PresInterp::MISSING_DOUBLE = -9999.9; - -////////////// -// Constructor - -PresInterp::PresInterp () - -{ - -} - -////////////// -// Destructor - -PresInterp::~PresInterp () - -{ - -} - -//////////////////////////////////////////////////////////////// -// set levels -// -// Before calling prepareInterp, you need to set pressure, height -// or flight levels. So you need to call one of the following: -// * setPressureLevels() -// * setHeightLevels() -// * setFlightLevels() - -void PresInterp::setPressureLevels(int n_levels, const double *pressure) - -{ - _pressure.clear(); - for (int i = 0; i < n_levels; i++) { - _pressure.push_back(pressure[i]); - } -} - -void PresInterp::setPressureLevels(const vector pressure) - -{ - _pressure.clear(); - for (size_t i = 0; i < pressure.size(); i++) { - _pressure.push_back(pressure[i]); - } -} - -void PresInterp::setHeightLevels(int n_levels, const double *height) - -{ - _pressure.clear(); - for (int i = 0; i < n_levels; i++) { - _pressure.push_back(_isa.ht2pres(height[i])); - } -} - -void PresInterp::setHeightLevels(const vector height) - -{ - _pressure.clear(); - for (size_t i = 0; i < height.size(); i++) { - _pressure.push_back(_isa.ht2pres(height[i])); - } -} - -void PresInterp::setFlightLevels(int n_levels, const double *flevel) - -{ - _pressure.clear(); - for (int i = 0; i < n_levels; i++) { - _pressure.push_back(_isa.flevel2pres(flevel[i])); - } -} - -void PresInterp::setFlightLevels(const vector flevel) - -{ - _pressure.clear(); - for (size_t i = 0; i < flevel.size(); i++) { - _pressure.push_back(_isa.flevel2pres(flevel[i])); - } -} - -//////////////// -// prepareInterp -// -// Loads interpolation info for a sigma pressure profile for -// a given point. -// - -void PresInterp::prepareInterp(const vector &p_sigma) - -{ - - // load up interp info - - _interpIndex.clear(); - int jstart = 0; - for (size_t ii = 0; ii < _pressure.size(); ii++) { - - PresInterp_interp_t intp; - intp.valid = FALSE; - double pres = _pressure[ii]; - - for (size_t j = jstart; j < p_sigma.size() - 1; j++) { - if (p_sigma[j] >= pres && p_sigma[j+1] <= pres) { - intp.lowerIsigma = j; - intp.upperIsigma = j + 1; - double dp = p_sigma[j] - p_sigma[j+1]; - intp.wtLower = (pres - p_sigma[j+1]) / dp; - intp.wtUpper = (p_sigma[j] - pres) / dp; - intp.valid = TRUE; - jstart = j; - break; - } - } // j - - _interpIndex.push_back(intp); - - } // ii - - // load up vertNeeded - - _vertNeeded.clear(); - for (size_t i = 0; i < p_sigma.size(); i++) { - _vertNeeded.push_back(FALSE); - } - - for (size_t ii = 0; ii < _pressure.size(); ii++) { - PresInterp_interp_t &intp = _interpIndex[ii]; - if (intp.valid) { - _vertNeeded[intp.lowerIsigma] = TRUE; - _vertNeeded[intp.upperIsigma] = TRUE; - } - } - -} - -/////////// -// doInterp -// -// Interpolate a field from sigma to flight levels. -// -// Passed in is the array for the field column in sigma levels. -// -// If copy_lowest_downwards is true, the lowest non-missing data will -// be copied down to the lowest level. -// -// Fills out vector with interpolated data. - -void PresInterp::doInterp(const vector &field_sigma, - vector &interp_data, - bool copy_lowest_downwards) -{ - int lowestValid = -1; - interp_data.clear(); - - for (size_t ii = 0; ii < _pressure.size(); ii++) { - PresInterp_interp_t &intp = _interpIndex[ii]; - double val; - if (intp.valid) { - val = (field_sigma[intp.lowerIsigma] * intp.wtLower + - field_sigma[intp.upperIsigma] * intp.wtUpper); - if (lowestValid == -1) { - lowestValid = ii; - } - } else { - val = MISSING_DOUBLE; - } - interp_data.push_back(val); - } // ii - - // copy downwards if relevant - - double bottomVal = MISSING_DOUBLE; - for (size_t i = 0; i < field_sigma.size(); i++) { - if (field_sigma[i] != MISSING_DOUBLE) { - bottomVal = field_sigma[i]; - break; - } - } - - if (copy_lowest_downwards) { - for (int i = lowestValid - 1; i >= 0; i--) { - interp_data[i] = bottomVal; - } - } - -} - -//////////////////////// -// print pressure array - -void PresInterp::printPressureArray(ostream &out) - -{ - out << "----> PresInterp: pressure array <----" << endl; - for (size_t i = 0; i < _pressure.size(); i++) { - out << "i, pressure: " << i << ", " << _pressure[i] << endl; - } -} - diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.hh b/codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.hh deleted file mode 100644 index eb22ad7307..0000000000 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/PresInterp.hh +++ /dev/null @@ -1,138 +0,0 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2016 -// ** 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. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -///////////////////////////////////////////////////////////// -// PresInterp.h -// -// This class wraps interpolation of Pressure levels to other -// vertical level types (based upon SigmaInterp) -// -// Internally some variables still refer to sigma. This is a reminant -// of the old SigmaInterp, but calculations are done based upon pressure -// and not sigma. External references to sigma have been removed, and -// internal references should be taken to refer to a general vertical -// coordinate system, and not specifically sigma. -// -// Paul Prestopnik, RAP, NCAR, P.O.Box 3000, Boulder, CO, 80307-3000, USA -// -// Jan 2008 -// -///////////////////////////////////////////////////////////// - -#ifndef PresInterp_H -#define PresInterp_H - -#include -#include -#include -using namespace std; - -typedef struct { - int valid; - int upperIsigma; - int lowerIsigma; - double wtUpper; - double wtLower; -} PresInterp_interp_t; - -class PresInterp { - -public: - - // constructor - - PresInterp (); - - // destructor - - ~PresInterp (); - - // Before calling prepareInterp, you need to set pressure, height - // or flight levels. So you need to call one of the following: - // - setPressureLevels() - // - setHeightLevels() - // - setFlightLevels() - - void setPressureLevels(int n_levels, const double *pressure); - void setPressureLevels(const vector pressure); - - void setHeightLevels(int n_levels, const double *height); - void setHeightLevels(const vector height); - - void setFlightLevels(int n_levels, const double *flevel); - void setFlightLevels(const vector flevel); - - // Prepare interpolation info for a sigma pressure profile for - // a given point. - - void prepareInterp(const vector &p_sigma); - - // Interpolate a field from sigma to flight levels. - // - // Passed in is the array for the field column in sigma levels. - // - // If copy_lowest_downwards is true, the lowest non-missing data will - // be copied down to the lowest level. - // - // Fills out vector with interpolated data. - - void doInterp(const vector &field_sigma, - vector &interp_data, - bool copy_lowest_downwards); - - // print pressure array - - void printPressureArray(ostream &out); - - // flags to indicate whether a given vertical level is - // required for interpolation - - const vector &getVertNeeded() { return _vertNeeded; } - -protected: - -private: - - static const double MISSING_DOUBLE; - - // interp index - - vector _interpIndex; - - // flags to indicate whether a given vertical level is - // required for interpolation - - vector _vertNeeded; - - // pressures - - vector _pressure; - - // ICAO standard atmosphere object - - IcaoStdAtmos _isa; - -}; - -#endif - diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/__makefile.template b/codebase/apps/ingest/src/Era5Nc2Mdv/__makefile.template index f2657cfea0..cc4e3966f8 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/__makefile.template +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/__makefile.template @@ -25,9 +25,9 @@ # # Makefile for Era5Nc2Mdv program # -# RAP, NCAR, Boulder, CO, 80307, USA +# Mike Dixon, EOL, NCAR, Boulder, CO, 80307, USA # -# June 2006 +# Oct 2023 # ########################################################################### @@ -53,20 +53,17 @@ LOC_CPPC_CFLAGS = HDRS = \ $(PARAMS_HH) \ Args.hh \ - ReadFile.hh \ - HtInterp.hh \ - OutputFile.hh \ - Era5Nc2Mdv.hh - + Era5File.hh \ + Era5Nc2Mdv.hh \ + HtInterp.hh CPPC_SRCS = \ $(PARAMS_CC) \ Args.cc \ - ReadFile.cc \ - HtInterp.cc \ - OutputFile.cc \ + Era5File.cc \ Era5Nc2Mdv.cc \ - main.cc + HtInterp.cc \ + Main.cc include $(LROSE_CORE_DIR)/build/make_include/lrose_make_tdrp_macros diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.cc b/codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.cc deleted file mode 100644 index ebdebe9ca5..0000000000 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.cc +++ /dev/null @@ -1,450 +0,0 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2016 -// ** 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. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/////////////////////////////////////////////////// -// OutputFile - adapted from code by Mike Dixon for -// MM5Ingest -// -/////////////////////////////////////////////////// - -#include - -#include -#include -#include -#include -#include -#include - -#include "OutputFile.hh" -#include "Params.hh" -#include "Era5Nc2Mdv.hh" -#include "HtInterp.hh" -using namespace std; - -OutputFile::OutputFile(Params *params) -{ - _paramsPtr = params; - _mdvObj = new DsMdvx; - _htInterp = new HtInterp(params); -} - -OutputFile::~OutputFile() -{ - clear(); - delete _mdvObj; - delete _htInterp; -} - -void -OutputFile::clear() -{ - _mdvObj->clear(); -} - -int OutputFile::numFields() -{ - return _mdvObj->getNFields(); -} - -int -OutputFile::writeVol( time_t genTime, long int leadSecs ) -{ - - PMU_auto_register("In OutputFile::writeVol"); - - if(numFields() == 0) { - cerr << "ERROR: No fields added" << endl << flush; - return( RI_FAILURE ); - } - - // interp to height levels if required - - if (_paramsPtr->interp_vlevels_to_height) { - if (_htInterp->interpVlevelsToHeight(_mdvObj)) { - cerr << "ERROR - OutputFile::writeVol" << endl; - return -1; - } - } - - // convert field encoding and compression - - if (_paramsPtr->process_everything) { - - // loop through fields, converting and compressing - - Mdvx::encoding_type_t encoding = mdvEncoding(_paramsPtr->encoding_type); - Mdvx::compression_type_t compression = mdvCompression(_paramsPtr->compression_type); - - for (size_t ii = 0; ii < _mdvObj->getNFields(); ii++) { - MdvxField *field = _mdvObj->getField(ii); - field->convertType(encoding, compression); - } // ii - - } else { - - // loop through fields, converting and compressing - - Mdvx::compression_type_t compression = mdvCompression(_paramsPtr->compression_type); - - for (size_t ii = 0; ii < _mdvObj->getNFields(); ii++) { - MdvxField *field = _mdvObj->getField(ii); - string fieldName(field->getFieldHeader().field_name); - // find encoding for this particular fields - Mdvx::encoding_type_t encoding = mdvEncoding(_paramsPtr->encoding_type); - for (int jj = 0; jj < _paramsPtr->output_fields_n; jj++) { - Params::out_field_t ofld = _paramsPtr->_output_fields[jj]; - string mdvName(ofld.mdv_name); - if (mdvName == fieldName) { - encoding = mdvEncoding(ofld.encoding_type); - } - } - field->convertType(encoding, compression); - } // ii - - } - - // latest data info - - if ( _paramsPtr->writeLdataInfo ) { - _mdvObj->setWriteLdataInfo(); - } else { - _mdvObj->clearWriteLdataInfo(); - } - - if(_paramsPtr->writeLdataInfo && _paramsPtr->debug) { - cerr << "Writing LdataInfo..." << endl << flush; - } - - // Write non forecast style file - - if( _paramsPtr->write_non_forecast ) { - if (_paramsPtr->data_is_non_forecast) { - _setMasterHdr( genTime, 0, true); - } else { - if( _paramsPtr->non_forecast_timestamp == Params::TIMESTAMP_FCAST_TIME) { - _setMasterHdr( genTime, leadSecs, false ); - } - else { - _setMasterHdr( genTime, 0, false ); - } - } - if(_paramsPtr->debug) { - cerr << "Writing non-forecast style to dir: " - << _paramsPtr->non_forecast_mdv_url << endl; - } - if( _mdvObj->writeToDir( _paramsPtr->non_forecast_mdv_url ) ) { - cerr << "ERROR: Could not write file: " - << _mdvObj->getErrStr() << endl << flush; - return( RI_FAILURE ); - } - } - - // Write forecast style file - - if( _paramsPtr->write_forecast ) { - _setMasterHdr( genTime, leadSecs, false ); - _mdvObj->setWriteAsForecast(); - if(_paramsPtr->debug) { - cerr << "Writing forecast style to dir: " - << _paramsPtr->forecast_mdv_url << endl; - } - if( _mdvObj->writeToDir( _paramsPtr->forecast_mdv_url ) ) { - cerr << "ERROR: Could not write file: " - << _mdvObj->getErrStr() << endl << flush; - return( RI_FAILURE ); - } - } - - cerr << "File written: " << _mdvObj->getPathInUse() << endl; - - // Clean up - - clear(); - - return( RI_SUCCESS ); -} - -void -OutputFile::_setMasterHdr( time_t genTime, long int leadSecs, bool isObs ) -{ - - Mdvx::master_header_t masterHdr; - - // Clear out master header - - memset(&masterHdr, 0, sizeof(Mdvx::master_header_t) ); - - // Fill the master header - - masterHdr.record_len1 = sizeof( Mdvx::master_header_t ); - masterHdr.struct_id = Mdvx::MASTER_HEAD_MAGIC_COOKIE_64; - masterHdr.revision_number = 1; - masterHdr.num_data_times = 1; - masterHdr.index_number = 0; - masterHdr.data_dimension = 3; - - if (isObs) { - masterHdr.data_collection_type = Mdvx::DATA_MEASURED; - } else { - masterHdr.data_collection_type = Mdvx::DATA_FORECAST; - } - masterHdr.vlevel_included = TRUE; - masterHdr.grid_orientation = Mdvx::ORIENT_SN_WE; - masterHdr.data_ordering = Mdvx::ORDER_XYZ; - masterHdr.sensor_lon = 0.0; - masterHdr.sensor_lat = 0.0; - masterHdr.sensor_alt = 0.0; - - masterHdr.time_gen = genTime; - masterHdr.time_begin = genTime + leadSecs; - masterHdr.time_end = genTime + leadSecs; - masterHdr.time_centroid = genTime + leadSecs; - masterHdr.time_expire = genTime + leadSecs; - masterHdr.forecast_time = genTime + leadSecs; - masterHdr.forecast_delta = leadSecs; - - STRncopy(masterHdr.data_set_info, _paramsPtr->data_set_info, MDV_INFO_LEN); - STRncopy(masterHdr.data_set_name, _paramsPtr->data_set_name, MDV_NAME_LEN); - STRncopy(masterHdr.data_set_source, _paramsPtr->data_set_source, MDV_NAME_LEN); - - masterHdr.record_len2 = sizeof( Mdvx::master_header_t ); - - _mdvObj->setMasterHeader( masterHdr ); - _mdvObj->updateMasterHeader(); - -} - -void -OutputFile::addField( MdvxField *field, Mdvx::encoding_type_t encoding) -{ - // Remap Data - - if(_paramsPtr->remap_output) { - _remap(field); - } - - // Add field to volume - - _mdvObj->addField( field ); - -} - -void -OutputFile::_remap(MdvxField* field) -{ - - MdvxRemapLut lut; - - switch( _paramsPtr->out_projection_info.type) { - case Params::PROJ_FLAT: - field->remap2Flat(lut, _paramsPtr->out_grid_info.nx, _paramsPtr->out_grid_info.ny, - _paramsPtr->out_grid_info.minx, _paramsPtr->out_grid_info.miny, - _paramsPtr->out_grid_info.dx, _paramsPtr->out_grid_info.dy, - _paramsPtr->out_projection_info.origin_lat, - _paramsPtr->out_projection_info.origin_lon, - _paramsPtr->out_projection_info.rotation); - break; - - case Params::PROJ_LATLON: - field->remap2Latlon(lut, _paramsPtr->out_grid_info.nx, _paramsPtr->out_grid_info.ny, - _paramsPtr->out_grid_info.minx, _paramsPtr->out_grid_info.miny, - _paramsPtr->out_grid_info.dx, _paramsPtr->out_grid_info.dy ); - break; - - case Params::PROJ_LAMBERT_CONF: - if(field->getFieldHeader().proj_type == Mdvx::PROJ_LAMBERT_CONF) - _remapLambertLambert(field); - else - field->remap2Lc2(lut, _paramsPtr->out_grid_info.nx, _paramsPtr->out_grid_info.ny, - _paramsPtr->out_grid_info.minx, _paramsPtr->out_grid_info.miny, - _paramsPtr->out_grid_info.dx, _paramsPtr->out_grid_info.dy, - _paramsPtr->out_projection_info.origin_lat, - _paramsPtr->out_projection_info.origin_lon, - _paramsPtr->out_projection_info.ref_lat_1, - _paramsPtr->out_projection_info.ref_lat_2 ); - break; - default: - cerr <<"-- unknown projection; remapping failed." << endl; - } - -} - -void OutputFile::_remapLambertLambert(MdvxField* field) -{ - - // field is encoded as bytes -- convert back to float - field->convertType(); - - - Mdvx::field_header_t fhdr = field->getFieldHeader(); - - int nx = _paramsPtr->out_grid_info.nx; - int ny = _paramsPtr->out_grid_info.ny; - int nz = fhdr.nz; - - MdvxProj inproj, outproj; - outproj.initLambertConf(_paramsPtr->out_projection_info.origin_lat, - _paramsPtr->out_projection_info.origin_lon, - _paramsPtr->out_projection_info.ref_lat_1, - _paramsPtr->out_projection_info.ref_lat_2); - - outproj.setGrid(nx, ny, _paramsPtr->out_grid_info.dx, _paramsPtr->out_grid_info.dy, - _paramsPtr->out_grid_info.minx, _paramsPtr->out_grid_info.miny); - - inproj.init(fhdr); - - float *odata = new float[nx*ny*nz]; - float *idata = (float *)field->getVol(); - - double lat, lon; - double ix, iy; - for(int y = 0; y < ny; y++) - { - for(int x = 0; x < nx; x++) - { - - outproj.xyIndex2latlon(x, y, lat, lon); - - int ingrid = inproj.latlon2xyIndex(lat, lon, ix, iy); - - // If we are within 1/100th of the dx past the end of the grid - // allow it to be set to the end of the grid. - // (rounding issue from projection library) - if(ix > fhdr.nx-1 && ix < fhdr.nx -.99) - ix = fhdr.nx-1; - if(iy > fhdr.ny-1 && iy < fhdr.ny -.99) - iy = fhdr.ny-1; - - if(ingrid != -1 && ix >= 0 && iy >= 0) - for(int z = 0; z < nz; z++) - odata[(z*ny*nx)+(y*nx)+x] = _interp2(&fhdr, ix, iy, z, idata); - else - for(int z = 0; z < nz; z++) - odata[(z*ny*nx)+(y*nx)+x] = fhdr.missing_data_value; - } - } - - fhdr.nx = _paramsPtr->out_grid_info.nx; - fhdr.ny = _paramsPtr->out_grid_info.ny; - fhdr.grid_minx = _paramsPtr->out_grid_info.minx; - fhdr.grid_miny = _paramsPtr->out_grid_info.miny; - fhdr.grid_dx = _paramsPtr->out_grid_info.dx; - fhdr.grid_dy = _paramsPtr->out_grid_info.dy; - fhdr.proj_type = _paramsPtr->out_projection_info.type; - fhdr.proj_origin_lat = _paramsPtr->out_projection_info.origin_lat; - fhdr.proj_origin_lon = _paramsPtr->out_projection_info.origin_lon; - fhdr.proj_param[0] = _paramsPtr->out_projection_info.ref_lat_1; - fhdr.proj_param[1] = _paramsPtr->out_projection_info.ref_lat_2; - fhdr.volume_size = - fhdr.nx * fhdr.ny * fhdr.nz * fhdr.data_element_nbytes; - - field->setFieldHeader(fhdr); - field->setVolData(odata, fhdr.volume_size, Mdvx::ENCODING_FLOAT32); - - delete []odata; - -} - -float OutputFile::_interp2(Mdvx::field_header_t *fieldHdr, double x, double y, int z, float *field) -{ - int ix = floor(x); - int iy = floor(y); - int ix1 = ix+1; - int iy1 = iy+1; - - // Allow wraping in longitude if x is between -.5 and 0, and a global lat/lon model - if(x > -.5 && ix == -1 && fieldHdr->proj_type == 0 && fieldHdr->proj_origin_lon == 0 && - (fieldHdr->nx * fieldHdr->grid_dx) + fieldHdr->grid_minx > 360.0) - ix = floor((360.0 - fieldHdr->grid_minx) / fieldHdr->grid_dx); - if(field == NULL || ix < 0 || y < 0 || ix1 > fieldHdr->nx || iy1 > fieldHdr->ny) - return fieldHdr->missing_data_value; - if(z < 0) - z = 0; - if(z >= fieldHdr->nz) - z = fieldHdr->nz -1; - if(field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix] == fieldHdr->missing_data_value || - field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix1] == fieldHdr->missing_data_value || - field[(z*fieldHdr->ny*fieldHdr->nx)+((iy1)*fieldHdr->nx)+ix] == fieldHdr->missing_data_value || - field[(z*fieldHdr->ny*fieldHdr->nx)+((iy1)*fieldHdr->nx)+ix1] == fieldHdr->missing_data_value) - return fieldHdr->missing_data_value; - - float val; - // Allow being exactly on the last point in the grid (x or y or both) - if(ix1 == fieldHdr->nx && iy1 == fieldHdr->ny) - val = field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix] * (1-(x-ix)); - else if(ix1 == fieldHdr->nx) - val = field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix] * (1-(y-iy)) + - field[(z*fieldHdr->ny*fieldHdr->nx)+((iy1)*fieldHdr->nx)+ix] * (y-iy); - else if(iy1 == fieldHdr->ny) - val = field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix] * (1-(x-ix)) + - field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix1] * (x-ix); - else // Normal 2D interpolation - val = (field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix] * (1-(x-ix)) + - field[(z*fieldHdr->ny*fieldHdr->nx)+(iy*fieldHdr->nx)+ix1] * (x-ix)) * (1-(y-iy)) + - (field[(z*fieldHdr->ny*fieldHdr->nx)+((iy1)*fieldHdr->nx)+ix] * (1-(x-ix)) + - field[(z*fieldHdr->ny*fieldHdr->nx)+((iy1)*fieldHdr->nx)+ix1] * (x-ix)) * (y-iy); - - if(val != val) - return fieldHdr->missing_data_value; - else - return val; - -} - -Mdvx::encoding_type_t - OutputFile::mdvEncoding(Params::encoding_type_t paramEncoding) - -{ - switch(paramEncoding) { - case Params::ENCODING_INT8: - return Mdvx::ENCODING_INT8; - case Params::ENCODING_INT16: - return Mdvx::ENCODING_INT16; - case Params::ENCODING_ASIS: - case Params::ENCODING_FLOAT32: - default: - return Mdvx::ENCODING_FLOAT32; - } -} - -Mdvx::compression_type_t - OutputFile::mdvCompression(Params::compression_type_t paramCompression) - -{ - switch(paramCompression) { - case Params::COMPRESSION_NONE: - return Mdvx::COMPRESSION_NONE; - case Params::COMPRESSION_RLE: - case Params::COMPRESSION_LZO: - case Params::COMPRESSION_ASIS: - case Params::COMPRESSION_ZLIB: - return Mdvx::COMPRESSION_ZLIB; - case Params::COMPRESSION_BZIP: - return Mdvx::COMPRESSION_BZIP; - case Params::COMPRESSION_GZIP: - default: - return Mdvx::COMPRESSION_GZIP; - } -} - diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.hh b/codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.hh deleted file mode 100644 index d3eebed8c0..0000000000 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/OutputFile.hh +++ /dev/null @@ -1,97 +0,0 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2016 -// ** 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. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -/////////////////////////////////////////////////// -// OutputFile - adapted from code by Mike Dixon for -// MM5Ingest -// -/////////////////////////////////////////////////// -#ifndef _OUTPUT_FILE_ -#define _OUTPUT_FILE_ - -// -// Forward class declarations -// -#include "Params.hh" -class MdvxField; -class DsMdvx; -class HtInterp; - -class OutputFile { - -public: - - OutputFile( Params *params ); - - ~OutputFile(); - - inline void setVerticalType( const int& vt ){_verticalType = vt;} - - void addField(MdvxField* inputField, Mdvx::encoding_type_t encoding); - - int writeVol(time_t gen_time, long int lead_secs ); - - void clear(); - - int numFields(); - - static Mdvx::encoding_type_t - mdvEncoding(Params::encoding_type_t paramEncoding); - - static Mdvx::compression_type_t - mdvCompression(Params::compression_type_t paramCompression); - -protected: - -private: - - typedef struct { - double ht; - int indexLower; - int indexUpper; - double ghtLower; - double ghtUpper; - double wtLower; - double wtUpper; - } interp_pt_t; - - Params *_paramsPtr; - - DsMdvx *_mdvObj; - - HtInterp *_htInterp; - - int _verticalType; - - void _remap(MdvxField* inputField); - - void _setMasterHdr( time_t genTime, long int leadSecs, bool isObs ); - - void _remapLambertLambert(MdvxField* inputField); - - float _interp2(Mdvx::field_header_t *fieldHdr, - double x, double y, int z, float *field); - -}; - -#endif diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/main.cc b/codebase/apps/ingest/src/Era5Nc2Mdv/orig/main.cc deleted file mode 100644 index ad259eb456..0000000000 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/main.cc +++ /dev/null @@ -1,84 +0,0 @@ -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -// ** Copyright UCAR (c) 1990 - 2016 -// ** 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. -// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* -//////////////////////////////////////////////////////////////////// -// Main entry point for Era5Nc2Mdv application -// -// Converts Grib2 files into MDV format -// Tested GRIB2 Models: -// gfs004 (gfs half degree resolution) -// dgex218 (Downscaled Gfs with Eta Extensions, 10km resolution) -// eta218 (Eta/Nam 10km resolution) -// NDFD (National Digital Forecast Database CONUS operational fields) -// -// -Jason Craig- Jun 2006 -//////////////////////////////////////////////////////////////////// - -#include -#include -#include - -#include "Era5Nc2Mdv.hh" -#include "Args.hh" -using namespace std; - -static void dieGracefully( int signal ); - -// Global program object -Era5Nc2Mdv *Prog = (Era5Nc2Mdv *)NULL; - - -//********************************************************************* -int main( int argc, char **argv ) -{ - - // Create program object by requesting a instance - Prog = Era5Nc2Mdv::Inst(argc, argv); - if (!Prog->okay) - return(-1); - - // - // Trap signals for a clean exit - // - PORTsignal( SIGINT, dieGracefully ); - PORTsignal( SIGTERM, dieGracefully ); - PORTsignal( SIGQUIT, dieGracefully ); - PORTsignal( SIGKILL, dieGracefully ); - - Prog->run(); - - delete Prog; - - return (0); -} - - -void dieGracefully( int signal ) -{ - // Delete the program object. - - //if (Prog != (Era5Nc2Mdv *)NULL) - //delete Prog; - - exit( signal ); -} diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/paramdef.orig b/codebase/apps/ingest/src/Era5Nc2Mdv/orig/paramdef.orig deleted file mode 100644 index 975e191ae2..0000000000 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/orig/paramdef.orig +++ /dev/null @@ -1,520 +0,0 @@ -/* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* */ -/* ** Copyright UCAR (c) 1990 - 2016 */ -/* ** 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. */ -/* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* */ -/********************************************************* - * parameter definitions for Era5Nc2Mdv - * - */ - -commentdef { - p_header = "Era5Nc2Mdv PARAMETER FILE"; - p_text = "Era5Nc2Mdv creates MDV from ERA5 NetCDF files, created using NCAR/CISL software\n"; -} - -commentdef { - p_header = "PROGRAM MODES OF OPERATION."; -} - -paramdef int { - p_default = 0; - p_descr = "Debug option"; - p_help = "0 = No Debug info\n" - "1 = Regular Debug info\n" - "2 = Full Grib2 file output (see printSec params)."; -} debug; - -paramdef string { - p_default = "Test"; - p_descr = "Instance"; - p_help = "Process instance for registration with process mapper"; -} instance; - -paramdef int { - p_default = 1200; - p_descr = "Interval for procmap registration"; - p_help = "Set to a high value if processing takes a long time. This will prevent the auto_restarter from killing and restarting the app."; -} procmap_register_interval_secs; - -paramdef string { - p_default = "/scr/cirrus2/rsfdata/projects/nexrad-mrms/ERA5/levelFiles"; - p_descr = "Input directory"; - p_help = "Directory which contains input grib2 files. Used only " - "if files are not specified on the command line"; -} input_dir; - -paramdef string { - p_default = ""; - p_descr = "Input file suffix"; - p_help = "Input file suffixes will be checked against this string. " - "Used only if files are not specified on the command line"; -} input_suffix; - -paramdef string { - p_default = ""; - p_descr = "Input file substring check."; - p_help = "Input files will be checked against this string." - "Can be used to filter different forecast times." - "Used only if files are not specified on the command line"; -} input_substring; - -paramdef string { - p_default = {}; - p_descr = "Input file substrings check."; - p_help = "Input files will be checked against these strings. " - "Can be used to filter different forecast times. " - "Used only if files are not specified on the command line " - "and input_substring is set to an empty string."; -} input_substrings[]; - -paramdef int { - p_min = 60; - p_default = 10800; - p_descr = "Max age (in seconds) of input data"; - p_help = "Used only if files are not specified on the command line"; -} max_input_data_age; - -paramdef boolean { - p_default = TRUE; - p_descr = "If TRUE, watch input_dir for change in _latest_data_info."; - p_help = "If FALSE, watch input_dir for new files."; -} latest_data_info_avail; - -paramdef boolean { - p_default = TRUE; - p_descr = "Option to recurse when searching for new files."; - p_help = "Only applies if latest_data_info_avail is FALSE."; -} recursive_search; - -paramdef boolean { - p_default = TRUE; - p_descr = "Option to only process the latest file in directory."; - p_help = "If TRUE, only the latest file will be processed. If FALSE, previously-written files will be processed."; -} latest_file_only; - -paramdef int { - p_default = 5; - p_descr = "How often to check for new data (secs)."; -} data_check_interval_secs; - -commentdef { - p_header = "PRINT SECTIONS PARAMETERS"; - p_text = "Parameters only used with -printSec or debug > 1\n" - "For each grib message prints the sections defined below\n"; -} - -paramdef boolean { - p_default = FALSE; - p_descr = "If TRUE prints the Indicator Section."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_is; - -paramdef boolean { - p_default = TRUE; - p_descr = "If TRUE prints the Identification Section."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_ids; - -paramdef boolean { - p_default = FALSE; - p_descr = "If TRUE prints the Local Use Section (if present)."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_lus; - -paramdef boolean { - p_default = TRUE; - p_descr = "If TRUE prints the Grid Definition Section."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_gds; - -paramdef boolean { - p_default = TRUE; - p_descr = "If TRUE prints the Product Definition Section."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_pds; - -paramdef boolean { - p_default = FALSE; - p_descr = "If TRUE prints the Data Representation Section."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_drs; - -paramdef boolean { - p_default = FALSE; - p_descr = "If TRUE prints the Bit-map Section."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_bms; - -paramdef boolean { - p_default = FALSE; - p_descr = "If TRUE prints the Data Section."; - p_help = "Only prints with -printSec or debug > 1"; -} printSec_ds; - -commentdef { - p_header = "MDV OUTPUT PARAMETERS"; -} - -paramdef boolean { - p_default = TRUE; - p_descr = "This option will infer the missing value from the data if possible."; - p_help = "Grib2 doesnt allow for setting a missing value unless complex data packing used. "; -} autoset_missing_value; - -paramdef boolean { - p_default = FALSE; - p_descr = "Option to limit the lead time of output files."; - p_help = "If set, we check the lead time before writing files."; -} check_lead_time; - -paramdef int { - p_default = 86400; - p_descr = "Maximum lead time for output files (secs)."; - p_help = "See 'check_lead_time'."; -} max_lead_time_secs; - -paramdef boolean -{ - p_default = FALSE; - p_descr = "Lead time subsampling flag"; - p_help = "Set to true to enable lead time subsampling."; -} lead_time_subsampling; - -paramdef int -{ - p_default = {}; - p_descr = "The subsampled lead times to process"; - p_descr = "Units are seconds. Used only when do_lead_time_subsampling " - "is TRUE. If it empty, all lead times are sampled, even when do_lead_time_subsampling=TRUE"; -} subsample_lead_times[]; - -paramdef boolean { - p_default = TRUE; - p_descr = "Write mdv files in a forecast directory structure"; - p_help = "If this is true, mdv files will be written in the " - "rap forecast directory structure. Note that if " - "write_non_forecast is also set to true, two mdv " - "files will be written"; -} write_forecast; - -paramdef string { - p_default = "mdvp:://localhost::./mdv"; - p_descr = "Url for mdv files in forecast structure"; - p_help = ""; -} forecast_mdv_url; - -paramdef boolean { - p_default = FALSE; - p_descr = "Write mdv files in a non-forecast directory structure"; - p_help = "If this is true, mdv files will be written in the " - "regular (non-forecast) rap directory structure. Note " - "that if write_forecast is also set to true, two mdv " - "files will be written. Note also that this option allows " - "for overwriting files, since the forecast time will be " - "used as the data time in this case. This is a temporary " - "option to allow for easier display of the data"; -} write_non_forecast; - -paramdef string { - p_default = "mdvp:://localhost::./mdv"; - p_descr = "Url for mdv files in non-forecast structure"; - p_help = ""; -} non_forecast_mdv_url; - -typedef enum { - TIMESTAMP_GEN_TIME, TIMESTAMP_FCAST_TIME -} timestamp_t; - -paramdef enum timestamp_t { - p_default = TIMESTAMP_FCAST_TIME; - p_descr = "This parameter allows user to timestamp non-forecast mdv files based " - "on the model's run time or the forecast time."; - p_help = "The choices are TIMESTAMP_GEN_TIME and TIMESTAMP_FCAST_TIME"; -} non_forecast_timestamp; - -paramdef boolean { - p_default = FALSE; - p_descr = "Write mdv files as regular data files"; - p_help = "If this is true, the output mdv files are assumed to be non-forecast data. If this flag is set true, the write_non_forecast flag must also be set true and the non_forecast_mdv_url must be set. If this flag is set false, and write_non_forecast_mdv_url is true, the output is assumed to be forecast data, but written into a regular (non-forecast) rap directory structure anyway"; -} data_is_non_forecast; - -paramdef boolean -{ - p_default = true; - p_descr = "Write _latest_data_info files for output data."; - p_help = "If false, will suppress writing of _latest_data_info files."; -} writeLdataInfo; - -paramdef string - { - p_default = "Converted to MDV with Era5Nc2Mdv."; - p_descr = "Data set info."; - p_help = "This is placed in the MDV master header for documentation purposes."; - } data_set_info; - -paramdef string { - p_default = "GFS model output."; - p_descr = "Data set name."; - p_help = "This is placed in the MDV master header for documentation purposes."; -} data_set_name; - -paramdef string { - p_default = "Grib2."; - p_descr = "Data set source details."; - p_help = "This is placed in the MDV master header for documentation purposes."; -} data_set_source; - -typedef enum { - ENCODING_ASIS = 0, - ENCODING_INT8 = 1, - ENCODING_INT16 = 2, - ENCODING_FLOAT32 = 5 -} encoding_type_t; - -typedef enum { - COMPRESSION_ASIS = -1, - COMPRESSION_NONE = 0, - COMPRESSION_RLE = 1, - COMPRESSION_LZO = 2, - COMPRESSION_ZLIB = 3, - COMPRESSION_BZIP = 4, - COMPRESSION_GZIP = 5 -} compression_type_t; - -typedef enum { - NO_CHANGE = 0, - MPS_TO_KNOTS = 1, - M_TO_KM = 2, - M_TO_100FT = 3, - PASCALS_TO_MBAR = 4, - KELVIN_TO_CELCIUS = 5, - KGPKG_TO_GPKG = 6, - PERCENT_TO_FRACTION = 7, - FRACTION_TO_PERCENT = 8, - M_TO_FT = 9, - M_TO_MI = 10, - M_TO_KFT = 11, - MM_S_TO_MM_HR = 12 -} out_units_t; - -typedef enum { - BAD_VALUE = 0, - UNKNOWN_VALUE = 1, - USER_DEFINED = 2, -} qc_default_t; - -typedef struct { - string param; - string level; - string mdv_name; - out_units_t units; - double upper_range_limit; - double lower_range_limit; - encoding_type_t encoding_type; - qc_default_t qc_default_type; - double qc_default_value; - int vert_level_min; - int vert_level_max; - int vert_level_dz; - boolean use_additional_bad_data_value; - double additional_bad_data_value; - boolean use_additional_missing_data_value; - double additional_missing_data_value; -} out_field_t; - -paramdef boolean { - p_default = TRUE; - p_descr = "Flag to process all fields"; - p_help = "If TRUE, all fields will be processed.\n" - "If FALSE, only fields listed in output_fields list will be processed"; -} process_everything; - -paramdef struct out_field_t { - p_descr = "List of output fields, which are descibed by the field parameter and vertical level type\n"; - p_help = "To determine the available params and levels, use the command line argument -printSummary -file [filename]\n" - " No Mdv output will be created, only a list of params and associated levels contained" - " in the GRIB file.\n" - "Note: process_everything must be set to FALSE to use this list.\n" - " \n" - "out_field_t structure definition:\n" - " param:string GRIB2 product ID.\n" - " level:string GRIB2 level ID.\n" - " mdv_name:string MDV short field name. Overrides default name.\n" - " Use empty string to keep default (param) name.\n" - " out_units:out_units_t simple unit conversion utility. Options are:\n" - " NO_CHANGE -- no change to units\n" - " MPS_TO_KNOTS -- convert m/s to knots\n" - " M_TO_KM -- convert meters to kilometers\n" - " M_TO_FT -- convert meters to feet, \n" - " M_TO_MI -- convert meters to miles, \n" - " M_TO_100FT -- convert meters to 100's of feet, \n" - " flight levels\n" - " PASCALS_TO_MBAR -- convert pascals to millibars\n" - " KELVIN_TO_CELCIUS -- convert degrees kelvin to to degrees\n" - " celcius\n" - " KGPKG_TO_GPKG -- convert kilogram per kilogram to gram\n" - " per kilogram\n" - " PERCENT_TO_FRACTION -- convert percentage to fraction, values\n" - " between 0 and 1\n" - " FRACTION_TO_PERCENT -- convert fraction to percentage, values\n" - " between 0 and 100\n" - " \n" - " upper_range_limit:double upper limit threshold for field.\n" - " lower_range_limit:double lower limit threshold for field. \n" - " When both upper and lower limits are set\n" - " to zero no thresholds are applied.\n" - " encoding_type:encoding_type_t Output variable encoding type\n" - " qc_default_type:qc_default_t Replacement value for inputs outside\n" - " of the range_limit\n" - " qc_default_value:double User defined replacement value.\n" - " vert_level_min: minimum integer level that will be processed(If set to -1,\n" - " no restrictions will be set.)\n" - " vert_level_max: maximum integer level that will be processed(If set to -1,\n" - " no restrictions will be set.)\n" - " vert_level_dz: integer change in vertical levels that will be processed.\n\n" - "Default behavior is to process everything with no changes"; - p_default = {{"PRES", "HYBL", "", NO_CHANGE, 0.0, 0.0, ENCODING_FLOAT32, BAD_VALUE, 0.0, -1, -1, 1, false, 0.0, false, 0.0}}; -} output_fields[]; - -paramdef enum encoding_type_t { - p_default = ENCODING_FLOAT32; - p_descr = "File encoding type, Used only when process_everything is true."; -} encoding_type; - -paramdef enum compression_type_t { - p_default = COMPRESSION_GZIP; - p_descr = "File compression type, Used only when process_everything is true."; -} compression_type; - -typedef struct { - boolean SpecifyScaling; - double scale; - double bias; -} Scaling_info_t; - -paramdef struct Scaling_info_t { - p_descr = "Options for user defined scale and bias."; - p_help = "Only applies if ENCODING type is INT8 or INT16.\n" - "If SpecifyScaling is true then the following scale " - "and bias values will be used. If false dynamic scaling " - "is applied."; - p_default = {FALSE, 0.50, -32.0}; -} output_scaling_info; - -paramdef boolean { - p_default = FALSE; - p_descr = "If TRUE remaps output."; - p_help = ""; -} remap_output; - -typedef enum { - PROJ_LATLON = 0, - PROJ_LAMBERT_CONF = 3, - PROJ_FLAT = 8 -} projection_t; - -typedef struct { - projection_t type; - double rotation; - double origin_lat; - double origin_lon; - double ref_lat_1; - double ref_lat_2; -} projection_info_t; - -paramdef struct projection_info_t { - p_descr = "This is the user defined projection"; - p_help = "If remap_output is true this defines the projection to remap to." - "\n\nThe choice of projections are PROJ_LATLON, PROJ_LAMBERT_CONF and " - "PROJ_FLAT.\n\nPROJ_LATLON is a latitude/longitude projection, and if " - "it is chosen the remaining parameters can be ignored.\n\nPROJ_FLAT is " - "a flat projection, and if it is chosen the parameters rotation, " - "origin_lat, origin_lon must be set.\n\nPROJ_LAMBERT_CONF is a Lambert " - "conformal projection, and if it is chosen the parameters origin_lat, " - "origin_lon, ref_lat_1 and ref_lat_2 must be set."; - p_default = {PROJ_LAMBERT_CONF, 0.0, 25.0, -95.0, 25.0, 25.0}; -} out_projection_info; - -typedef struct { - int nx; - int ny; - double minx; - double miny; - double dx; - double dy; -} grid_info_t; - -paramdef struct grid_info_t { - p_descr = "This is the user defined grid."; - p_help = "If remap_output is true this defines the grid info for the remap.\n\nFor a LATLON projection:\n minx = minLon\n miny = minLat\n dx = deltaLon\n dy = deltaLat."; - p_default = {301, 225, -3332.142334, -588.890442, 20.318001, 20.318001}; -} out_grid_info; - -paramdef string { - p_default = ""; - p_descr = "Option to override the vlevels in the vlevel header of the specified level types."; - p_help = "If not empty, will replace the vlevels of variables with the specified vlevel type with those specified in 'vlevel_array'.\n" - "Normal vlevel types to replace are: 'SIGL', 'SIGMA', or 'HYBL'.\n" - "Please note using this functionality can create incorrect levels, use carefully!"; -} override_vlevels; - -paramdef double { - p_default = 0; - p_descr = "vlevel values to override what is already in the file."; - p_help = "See 'override_vlevels'."; -} vlevel_array[]; - -commentdef { - p_header = "INTERPOLATE INTO HEIGHT LEVELS (km MSL)"; - p_text = "Option to interpolate the model data into height levels. This requires that (a) the vertical coords are pressure levels and (b) the geopotential height field is included in the input data."; -} - -paramdef boolean { - p_default = FALSE; - p_descr = "Option to interpolate onto height levels (km MSL)."; - p_help = "(a) The vertical coords of the input data set MUST be PRESSURE levels. (b) Also, geopotential height must be available in the data set. This field is used for the interpolation.\n"; -} interp_vlevels_to_height; - -paramdef string { - p_default = "HGT"; - p_descr = "Name of geopotential height field in MDV file."; - p_help = "See output_fields array.\n"; -} height_field_mdv_name; - -paramdef double { - p_default = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - p_descr = "Array of output height levels (km MSL)."; - p_help = "The data fields are intepolated onto this set of height levels."; -} height_levels[]; - -paramdef boolean { - p_default = FALSE; - p_descr = "Option to determine the heights from the pressure levels."; - p_help = "If TRUE, we use the ICAO standard atmosphere to compute the target heights from the pressure levels. In this case, the height_levels array is ignored.\n"; -} compute_heights_from_pressure_levels; - -paramdef double { - p_default = 0; - p_descr = "Minimum height when computing from pressure levels (km)."; - p_help = "Any heights below this are removed when converting from pressure levels."; -} min_height_from_pressure_levels; - diff --git a/codebase/apps/ingest/src/Era5Nc2Mdv/paramdef.Era5Nc2Mdv b/codebase/apps/ingest/src/Era5Nc2Mdv/paramdef.Era5Nc2Mdv index 02afbe8f7d..e8cb21acb2 100644 --- a/codebase/apps/ingest/src/Era5Nc2Mdv/paramdef.Era5Nc2Mdv +++ b/codebase/apps/ingest/src/Era5Nc2Mdv/paramdef.Era5Nc2Mdv @@ -34,7 +34,7 @@ commentdef { - p_header = "Era5Nc2Mdv reads output files from the WRF model and writes MDV data. It also allows the computation of some derived products."; + p_header = "Era5Nc2Mdv reads ERA5 NetCDF files, created using a CISL translator, and converts to MDV CF-NetCDF format."; } ///////////////////////////////////////////////////////////////////////// @@ -102,14 +102,6 @@ commentdef p_header = "INPUT DATA."; } -paramdef string -{ - p_descr = "path to SOILPARM.TBL config file that was used when running WRF."; - p_help = "Information in this table is neccessary to calculate " - "MOIST_AVAIL_FIELD."; - p_default = "./SOILPARM.TBL"; -} soilparm_path; - paramdef string { p_descr = "Directory for input data - ARCHIVE mode."; @@ -118,94 +110,27 @@ paramdef string } input_dir; ///////////////////////////////////////////////////////////////////////// -// Field names +// Convert temperature to C -commentdef { - p_header = "SPECIFY FIELD NAMES AND OUTPUT ENCODING"; +commentdef +{ + p_header = "CONVERT TEMP TO C."; } -typedef enum { - OUTPUT_ENCODING_FLOAT32, - OUTPUT_ENCODING_INT16, - OUTPUT_ENCODING_INT08 -} output_encoding_t; - -typedef struct { - string input_field_name; - string output_field_name; - string standard_name; - string output_units; - output_encoding_t encoding; -} output_field_t; - -paramdef struct output_field_t { - p_default = { - { "D", - "divergence", - "divergence_of_wind", - "1/s", - OUTPUT_ENCODING_FLOAT32 - } - , - { "Q", - "specific_humidity", - "specific_humidity", - "kg/kg", - OUTPUT_ENCODING_FLOAT32 - } - , - { "R", - "RH", - "relative_humidity", - "%", - OUTPUT_ENCODING_FLOAT32 - } - , - { "T", - "temperature", - "air_temperature", - "K", - OUTPUT_ENCODING_FLOAT32 - } - , - { "U", - "u", - "eastward_wind", - "m/s", - OUTPUT_ENCODING_FLOAT32 - } - , - { "V", - "v", - "northward_wind", - "m/s", - OUTPUT_ENCODING_FLOAT32 - } - , - { "W", - "w", - "vertical_velocity", - "m/s", - OUTPUT_ENCODING_FLOAT32 - } - , - { "Z", - "z", - "geopotential_height", - "m", - OUTPUT_ENCODING_FLOAT32 - } - }; - p_descr = "Output field details."; - p_help = "Set the details for the output fields. The output_field_name is the ndtCDF variable name. The standard name is set to the MDV long name. If the long name or standard name are empty, the existing names are used."; -} output_fields[]; - paramdef boolean { p_default = FALSE; p_descr = "The temperature is read in degrees Kelvin. This option allows us to convert to degrees C."; } convert_temperature_to_celcius; +paramdef string +{ + p_descr = "NetCDF variable name of temperature field in input data."; + p_help = "This is the field to be converted to C."; + p_default = "T"; +} temperature_field_name; + + ///////////////////////////////////////////////////////////////////////// // Interpolate to height levels @@ -263,60 +188,53 @@ paramdef string p_default = "/tmp/ERA5"; } output_dir; -typedef enum -{ - FLIGHT_LEVELS, - PRESSURE_LEVELS, - HEIGHT_LEVELS, - NATIVE_VERTICAL_LEVELS -} output_level_type_t; - -paramdef enum output_level_type_t -{ - p_descr = "Option to choose vertical levels for output file."; - p_help = "If FLIGHT_LEVELS, PRESSURE_LEVELS or HEIGHT_LEVELS, vertical levels will be interpolated accordingly. If NATIVE_VERTICAL_LEVELS, no interpolation is done and the data is output on the original vertical levels (i.e. sigma, eta, etc.)."; - p_default = HEIGHT_LEVELS; -} output_level_type; - -typedef enum { - _MDV_COMPRESSION_NONE = 0, - _MDV_COMPRESSION_RLE = 1, - _MDV_COMPRESSION_LZO = 2, - _MDV_COMPRESSION_ZLIB = 3, - _MDV_COMPRESSION_BZIP = 4 -} compression_t; - -/********************************************************* - * File header info. - */ +///////////////////////////////////////////////////////////////////////// +// Rename fields -commentdef -{ - p_header = "FILE HEADER INFO"; +commentdef { + p_header = "SPECIFY OUTPUT FIELD NAMES AND UNITS"; } -paramdef string -{ - p_descr = "Data set info."; - p_help = "This is placed in the MDV master header for " - "documentation purposes."; - p_default = "This MDV file was created by Era5Nc2Mdv."; -} data_set_info; - -paramdef string +paramdef boolean { - p_descr = "Data set name."; - p_help = "This is placed in the MDV master header for " - "documentation purposes."; - p_default = "WRF model output."; -} data_set_name; + p_default = FALSE; + p_descr = "Option to rename the fields, and set the units, before writing."; +} rename_output_fields; -paramdef string -{ - p_descr = "Data set source details."; - p_help = "This is placed in the MDV master header for " - "documentation purposes."; - p_default = "WRF output from somewhere."; -} data_set_source; +typedef struct { + string input_field_name; + string output_field_name; + string output_long_name; + string output_units; +} output_field_t; +paramdef struct output_field_t { + p_default = { + { "D", + "divergence", + "divergence_of_wind", + "1/s" + } + , + { "Q", + "specific_humidity", + "specific_humidity", + "kg/kg" + } + , + { "T", + "temperature", + "air_temperature", + "K" + } + , + { "W", + "w", + "vertical_velocity", + "m/s" + } + }; + p_descr = "Output field details."; + p_help = "Set the details for the output fields. The output_field_name is the ndtCDF variable name. The standard name is set to the MDV long name. If the long name or standard name are empty, the existing names are used."; +} output_fields[]; diff --git a/codebase/apps/ingest/src/Makefile b/codebase/apps/ingest/src/Makefile index f8f8423b23..24993356d9 100644 --- a/codebase/apps/ingest/src/Makefile +++ b/codebase/apps/ingest/src/Makefile @@ -23,6 +23,7 @@ SUB_DIRS = \ CwbSfc2Mdv \ EolMobileKml2Spdb \ EraGrib2Mdv \ + Era5Nc2Mdv \ GemVolXml2Dsr \ Gini2Mdv \ GoesRGLM2Spdb \ diff --git a/codebase/apps/ingest/src/__makefile.template b/codebase/apps/ingest/src/__makefile.template index f8f8423b23..24993356d9 100644 --- a/codebase/apps/ingest/src/__makefile.template +++ b/codebase/apps/ingest/src/__makefile.template @@ -23,6 +23,7 @@ SUB_DIRS = \ CwbSfc2Mdv \ EolMobileKml2Spdb \ EraGrib2Mdv \ + Era5Nc2Mdv \ GemVolXml2Dsr \ Gini2Mdv \ GoesRGLM2Spdb \