/* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* */ /* ** Copyright UCAR */ /* ** 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. */ /* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* */ //////////////////////////////////////////// // Params.cc // // TDRP C++ code file for class 'Params'. // // Code for program MdvMerge2 // // This file has been automatically // generated by TDRP, do not modify. // ///////////////////////////////////////////// /** * * @file Params.cc * * @class Params * * This class is automatically generated by the Table * Driven Runtime Parameters (TDRP) system * * @note Source is automatically generated from * paramdef file at compile time, do not modify * since modifications will be overwritten. * * * @author Automatically generated * */ #include "Params.hh" #include //////////////////////////////////////////// // Default constructor // Params::Params() { // zero out table memset(_table, 0, sizeof(_table)); // zero out members memset(&_start_, 0, &_end_ - &_start_); // class name _className = "Params"; // initialize table _init(); // set members tdrpTable2User(_table, &_start_); _exitDeferred = false; } //////////////////////////////////////////// // Copy constructor // Params::Params(const Params& source) { // sync the source object source.sync(); // zero out table memset(_table, 0, sizeof(_table)); // zero out members memset(&_start_, 0, &_end_ - &_start_); // class name _className = "Params"; // copy table tdrpCopyTable((TDRPtable *) source._table, _table); // set members tdrpTable2User(_table, &_start_); _exitDeferred = false; } //////////////////////////////////////////// // Destructor // Params::~Params() { // free up freeAll(); } //////////////////////////////////////////// // Assignment // void Params::operator=(const Params& other) { // sync the other object other.sync(); // free up any existing memory freeAll(); // zero out table memset(_table, 0, sizeof(_table)); // zero out members memset(&_start_, 0, &_end_ - &_start_); // copy table tdrpCopyTable((TDRPtable *) other._table, _table); // set members tdrpTable2User(_table, &_start_); _exitDeferred = other._exitDeferred; } //////////////////////////////////////////// // loadFromArgs() // // Loads up TDRP using the command line args. // // Check usage() for command line actions associated with // this function. // // argc, argv: command line args // // char **override_list: A null-terminated list of overrides // to the parameter file. // An override string has exactly the format of an entry // in the parameter file itself. // // char **params_path_p: // If this is non-NULL, it is set to point to the path // of the params file used. // // bool defer_exit: normally, if the command args contain a // print or check request, this function will call exit(). // If defer_exit is set, such an exit is deferred and the // private member _exitDeferred is set. // Use exidDeferred() to test this flag. // // Returns 0 on success, -1 on failure. // int Params::loadFromArgs(int argc, char **argv, char **override_list, char **params_path_p, bool defer_exit) { int exit_deferred; if (_tdrpLoadFromArgs(argc, argv, _table, &_start_, override_list, params_path_p, _className, defer_exit, &exit_deferred)) { return (-1); } else { if (exit_deferred) { _exitDeferred = true; } return (0); } } //////////////////////////////////////////// // loadApplyArgs() // // Loads up TDRP using the params path passed in, and applies // the command line args for printing and checking. // // Check usage() for command line actions associated with // this function. // // const char *param_file_path: the parameter file to be read in // // argc, argv: command line args // // char **override_list: A null-terminated list of overrides // to the parameter file. // An override string has exactly the format of an entry // in the parameter file itself. // // bool defer_exit: normally, if the command args contain a // print or check request, this function will call exit(). // If defer_exit is set, such an exit is deferred and the // private member _exitDeferred is set. // Use exidDeferred() to test this flag. // // Returns 0 on success, -1 on failure. // int Params::loadApplyArgs(const char *params_path, int argc, char **argv, char **override_list, bool defer_exit) { int exit_deferred; if (tdrpLoadApplyArgs(params_path, argc, argv, _table, &_start_, override_list, _className, defer_exit, &exit_deferred)) { return (-1); } else { if (exit_deferred) { _exitDeferred = true; } return (0); } } //////////////////////////////////////////// // isArgValid() // // Check if a command line arg is a valid TDRP arg. // bool Params::isArgValid(const char *arg) { return (tdrpIsArgValid(arg)); } //////////////////////////////////////////// // load() // // Loads up TDRP for a given class. // // This version of load gives the programmer the option to load // up more than one class for a single application. It is a // lower-level routine than loadFromArgs, and hence more // flexible, but the programmer must do more work. // // const char *param_file_path: the parameter file to be read in. // // char **override_list: A null-terminated list of overrides // to the parameter file. // An override string has exactly the format of an entry // in the parameter file itself. // // expand_env: flag to control environment variable // expansion during tokenization. // If TRUE, environment expansion is set on. // If FALSE, environment expansion is set off. // // Returns 0 on success, -1 on failure. // int Params::load(const char *param_file_path, char **override_list, int expand_env, int debug) { if (tdrpLoad(param_file_path, _table, &_start_, override_list, expand_env, debug)) { return (-1); } else { return (0); } } //////////////////////////////////////////// // loadFromBuf() // // Loads up TDRP for a given class. // // This version of load gives the programmer the option to // load up more than one module for a single application, // using buffers which have been read from a specified source. // // const char *param_source_str: a string which describes the // source of the parameter information. It is used for // error reporting only. // // char **override_list: A null-terminated list of overrides // to the parameter file. // An override string has exactly the format of an entry // in the parameter file itself. // // const char *inbuf: the input buffer // // int inlen: length of the input buffer // // int start_line_num: the line number in the source which // corresponds to the start of the buffer. // // expand_env: flag to control environment variable // expansion during tokenization. // If TRUE, environment expansion is set on. // If FALSE, environment expansion is set off. // // Returns 0 on success, -1 on failure. // int Params::loadFromBuf(const char *param_source_str, char **override_list, const char *inbuf, int inlen, int start_line_num, int expand_env, int debug) { if (tdrpLoadFromBuf(param_source_str, _table, &_start_, override_list, inbuf, inlen, start_line_num, expand_env, debug)) { return (-1); } else { return (0); } } //////////////////////////////////////////// // loadDefaults() // // Loads up default params for a given class. // // See load() for more detailed info. // // Returns 0 on success, -1 on failure. // int Params::loadDefaults(int expand_env) { if (tdrpLoad(NULL, _table, &_start_, NULL, expand_env, FALSE)) { return (-1); } else { return (0); } } //////////////////////////////////////////// // sync() // // Syncs the user struct data back into the parameter table, // in preparation for printing. // // This function alters the table in a consistent manner. // Therefore it can be regarded as const. // void Params::sync(void) const { tdrpUser2Table(_table, (char *) &_start_); } //////////////////////////////////////////// // print() // // Print params file // // The modes supported are: // // PRINT_SHORT: main comments only, no help or descriptions // structs and arrays on a single line // PRINT_NORM: short + descriptions and help // PRINT_LONG: norm + arrays and structs expanded // PRINT_VERBOSE: long + private params included // void Params::print(FILE *out, tdrp_print_mode_t mode) { tdrpPrint(out, _table, _className, mode); } //////////////////////////////////////////// // checkAllSet() // // Return TRUE if all set, FALSE if not. // // If out is non-NULL, prints out warning messages for those // parameters which are not set. // int Params::checkAllSet(FILE *out) { return (tdrpCheckAllSet(out, _table, &_start_)); } ////////////////////////////////////////////////////////////// // checkIsSet() // // Return TRUE if parameter is set, FALSE if not. // // int Params::checkIsSet(const char *paramName) { return (tdrpCheckIsSet(paramName, _table, &_start_)); } //////////////////////////////////////////// // freeAll() // // Frees up all TDRP dynamic memory. // void Params::freeAll(void) { tdrpFreeAll(_table, &_start_); } //////////////////////////////////////////// // usage() // // Prints out usage message for TDRP args as passed // in to loadFromArgs(). // void Params::usage(ostream &out) { out << "TDRP args: [options as below]\n" << " [ -params/--params path ] specify params file path\n" << " [ -check_params/--check_params] check which params are not set\n" << " [ -print_params/--print_params [mode]] print parameters\n" << " using following modes, default mode is 'norm'\n" << " short: main comments only, no help or descr\n" << " structs and arrays on a single line\n" << " norm: short + descriptions and help\n" << " long: norm + arrays and structs expanded\n" << " verbose: long + private params included\n" << " short_expand: short with env vars expanded\n" << " norm_expand: norm with env vars expanded\n" << " long_expand: long with env vars expanded\n" << " verbose_expand: verbose with env vars expanded\n" << " [ -tdrp_debug] debugging prints for tdrp\n" << " [ -tdrp_usage] print this usage\n"; } //////////////////////////////////////////// // arrayRealloc() // // Realloc 1D array. // // If size is increased, the values from the last array // entry is copied into the new space. // // Returns 0 on success, -1 on error. // int Params::arrayRealloc(const char *param_name, int new_array_n) { if (tdrpArrayRealloc(_table, &_start_, param_name, new_array_n)) { return (-1); } else { return (0); } } //////////////////////////////////////////// // array2DRealloc() // // Realloc 2D array. // // If size is increased, the values from the last array // entry is copied into the new space. // // Returns 0 on success, -1 on error. // int Params::array2DRealloc(const char *param_name, int new_array_n1, int new_array_n2) { if (tdrpArray2DRealloc(_table, &_start_, param_name, new_array_n1, new_array_n2)) { return (-1); } else { return (0); } } //////////////////////////////////////////// // _init() // // Class table initialization function. // // void Params::_init() { TDRPtable *tt = _table; // Parameter 'Comment 0' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 0"); tt->comment_hdr = tdrpStrDup("MdvMerge2 takes MDV data from a number of separate input directories and merges them into a single MDV file as a mosaic."); tt->comment_text = tdrpStrDup(""); tt++; // Parameter 'Comment 1' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 1"); tt->comment_hdr = tdrpStrDup("DEBUGGING AND PROCESS CONTROL."); tt->comment_text = tdrpStrDup(""); tt++; // Parameter 'debug' // ctype is '_debug_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = ENUM_TYPE; tt->param_name = tdrpStrDup("debug"); tt->descr = tdrpStrDup("Debug option"); tt->help = tdrpStrDup("If set, debug messages will be printed with the appropriate level of detail."); tt->val_offset = (char *) &debug - &_start_; tt->enum_def.name = tdrpStrDup("debug_t"); tt->enum_def.nfields = 3; tt->enum_def.fields = (enum_field_t *) tdrpMalloc(tt->enum_def.nfields * sizeof(enum_field_t)); tt->enum_def.fields[0].name = tdrpStrDup("DEBUG_OFF"); tt->enum_def.fields[0].val = DEBUG_OFF; tt->enum_def.fields[1].name = tdrpStrDup("DEBUG_NORM"); tt->enum_def.fields[1].val = DEBUG_NORM; tt->enum_def.fields[2].name = tdrpStrDup("DEBUG_VERBOSE"); tt->enum_def.fields[2].val = DEBUG_VERBOSE; tt->single_val.e = DEBUG_OFF; tt++; // Parameter 'instance' // ctype is 'char*' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRING_TYPE; tt->param_name = tdrpStrDup("instance"); tt->descr = tdrpStrDup("Process instance"); tt->help = tdrpStrDup("Used for registration with procmap."); tt->val_offset = (char *) &instance - &_start_; tt->single_val.s = tdrpStrDup("test"); tt++; // Parameter 'procmap_register_interval_secs' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("procmap_register_interval_secs"); tt->descr = tdrpStrDup("Interval for procmap registration"); tt->help = tdrpStrDup("Set to a high value if processing takes a long time. This will prevent the auto_restarter from killing and restarting the app. If this value is less than or equal to the PROCMAP_REGISTER_INTERVAL (60) then that value will be used."); tt->val_offset = (char *) &procmap_register_interval_secs - &_start_; tt->has_min = TRUE; tt->min_val.i = 60; tt->single_val.i = 60; tt++; // Parameter 'Comment 2' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 2"); tt->comment_hdr = tdrpStrDup("OPERATIONAL MODE AND TRIGGERING."); tt->comment_text = tdrpStrDup(""); tt++; // Parameter 'mode' // ctype is '_mode_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = ENUM_TYPE; tt->param_name = tdrpStrDup("mode"); tt->descr = tdrpStrDup("Operation mode"); tt->help = tdrpStrDup("Program may be run in two modes, ARCHIVE and REALTIME.\n\nIn REALTIME mode, the analysis is performed at regular times or as new data arrives.\n\nIn ARCHIVE mode, the file list is obtained from the command line or a start and end time are specified."); tt->val_offset = (char *) &mode - &_start_; tt->enum_def.name = tdrpStrDup("mode_t"); tt->enum_def.nfields = 2; tt->enum_def.fields = (enum_field_t *) tdrpMalloc(tt->enum_def.nfields * sizeof(enum_field_t)); tt->enum_def.fields[0].name = tdrpStrDup("ARCHIVE"); tt->enum_def.fields[0].val = ARCHIVE; tt->enum_def.fields[1].name = tdrpStrDup("REALTIME"); tt->enum_def.fields[1].val = REALTIME; tt->single_val.e = REALTIME; tt++; // Parameter 'trigger' // ctype is '_trigger_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = ENUM_TYPE; tt->param_name = tdrpStrDup("trigger"); tt->descr = tdrpStrDup("Trigger mechanism."); tt->help = tdrpStrDup("\nTIME_TRIGGER: program is triggered at constant time intervals - see time_trigger_interval.\n\nFILE_TRIGGER: the program triggers when all the URLs that must update have updated, and the requisite number of URLs have updated, and the required minimum time between triggers has elapsed.\n\nFCST_FILES_TRIGGER: program triggers when all lead times listed in fcstLeadTimes[] are available in the fcst_file_trigger_url, and then attempts to process these lead times for the input_urls."); tt->val_offset = (char *) &trigger - &_start_; tt->enum_def.name = tdrpStrDup("trigger_t"); tt->enum_def.nfields = 3; tt->enum_def.fields = (enum_field_t *) tdrpMalloc(tt->enum_def.nfields * sizeof(enum_field_t)); tt->enum_def.fields[0].name = tdrpStrDup("TIME_TRIGGER"); tt->enum_def.fields[0].val = TIME_TRIGGER; tt->enum_def.fields[1].name = tdrpStrDup("FILE_TRIGGER"); tt->enum_def.fields[1].val = FILE_TRIGGER; tt->enum_def.fields[2].name = tdrpStrDup("FCST_FILES_TRIGGER"); tt->enum_def.fields[2].val = FCST_FILES_TRIGGER; tt->single_val.e = TIME_TRIGGER; tt++; // Parameter 'fcst_file_trigger_url' // ctype is 'char*' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRING_TYPE; tt->param_name = tdrpStrDup("fcst_file_trigger_url"); tt->descr = tdrpStrDup("Trigger URL"); tt->help = tdrpStrDup("URL for triggering in latest_data mode\n"); tt->val_offset = (char *) &fcst_file_trigger_url - &_start_; tt->single_val.s = tdrpStrDup("mdvp:://localhost::./mdv/vil"); tt++; // Parameter 'fcstLeadTimes' // ctype is 'double' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = DOUBLE_TYPE; tt->param_name = tdrpStrDup("fcstLeadTimes"); tt->descr = tdrpStrDup("Forecast lead times, in seconds, that are available in forecast directory input url"); tt->help = tdrpStrDup("Only used if mode is set to FCST_FILES_TRIGGER."); tt->array_offset = (char *) &_fcstLeadTimes - &_start_; tt->array_n_offset = (char *) &fcstLeadTimes_n - &_start_; tt->is_array = TRUE; tt->array_len_fixed = FALSE; tt->array_elem_size = sizeof(double); tt->array_n = 5; tt->array_vals = (tdrpVal_t *) tdrpMalloc(tt->array_n * sizeof(tdrpVal_t)); tt->array_vals[0].d = 0; tt->array_vals[1].d = 300; tt->array_vals[2].d = 600; tt->array_vals[3].d = 900; tt->array_vals[4].d = 1200; tt++; // Parameter 'time_trigger_interval' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("time_trigger_interval"); tt->descr = tdrpStrDup("Interval for TIME_TRIGGER - secs."); tt->help = tdrpStrDup("For TIME_TRIGGER, this is the interval between trigger events. Time triggers are synchronized to the hour, and occur at constant intervals thereafter."); tt->val_offset = (char *) &time_trigger_interval - &_start_; tt->has_min = TRUE; tt->min_val.i = 1; tt->single_val.i = 300; tt++; // Parameter 'time_trigger_offset' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("time_trigger_offset"); tt->descr = tdrpStrDup("Time trigger offset - secs."); tt->help = tdrpStrDup("Time triggers occur on the hour and at constant intervals thereafter until the next hour. This parameters allows you to schedule the trigger to be offset from the anchored time by the specified number of secs. For example, if you set time_trigger_interval to 600 (10 mins) and time_trigger_offset to 420 (7 minutes), the trigger will occur at 7, 17, 27, 37, 47 and 57 mins after the hour."); tt->val_offset = (char *) &time_trigger_offset - &_start_; tt->single_val.i = 0; tt++; // Parameter 'time_trigger_margin' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("time_trigger_margin"); tt->descr = tdrpStrDup("Max time diff for searching for files relative to the trigger time - secs."); tt->help = tdrpStrDup("When matching files up with the trigger time, the difference between the trigger time and file time must be less than this margin."); tt->val_offset = (char *) &time_trigger_margin - &_start_; tt->single_val.i = 600; tt++; // Parameter 'past_only' // ctype is 'tdrp_bool_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = BOOL_TYPE; tt->param_name = tdrpStrDup("past_only"); tt->descr = tdrpStrDup("Only search in the past when matching files with the trigger time."); tt->help = tdrpStrDup("If TRUE, the search is forced to look for files before the trigger time. This is helpful when running in archive mode and you don't want to get data that has a future time stamp."); tt->val_offset = (char *) &past_only - &_start_; tt->single_val.b = pFALSE; tt++; // Parameter 'min_time_between_file_triggers' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("min_time_between_file_triggers"); tt->descr = tdrpStrDup("Minimum time between triggering in REALTIME FILE_TRIGGER mode, in seconds."); tt->help = tdrpStrDup("This prevents the arrival of files in FILE_TRIGGER mode from triggering at intervals less than this amount."); tt->val_offset = (char *) &min_time_between_file_triggers - &_start_; tt->single_val.i = 120; tt++; // Parameter 'min_number_updated_urls' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("min_number_updated_urls"); tt->descr = tdrpStrDup("Minumum number of URLs to update for trigger."); tt->help = tdrpStrDup(""); tt->val_offset = (char *) &min_number_updated_urls - &_start_; tt->single_val.i = 1; tt++; // Parameter 'max_realtime_valid_age' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("max_realtime_valid_age"); tt->descr = tdrpStrDup("Maximum file age in REALTIME file triggered mode, seconds."); tt->help = tdrpStrDup("Applies to all URLs specified."); tt->val_offset = (char *) &max_realtime_valid_age - &_start_; tt->single_val.i = 600; tt++; // Parameter 'sleepAfterTrigger' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("sleepAfterTrigger"); tt->descr = tdrpStrDup("Number of seconds to sleep after triggering before processing the data. The intent is to allow realtime URLs that come in nearly simultaneously (satellite) to have a chance to catch up."); tt->help = tdrpStrDup("Only applies in REALTIME mode."); tt->val_offset = (char *) &sleepAfterTrigger - &_start_; tt->single_val.i = 0; tt++; // Parameter 'Comment 3' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 3"); tt->comment_hdr = tdrpStrDup("FIELD SPECIFICATIONS."); tt->comment_text = tdrpStrDup(""); tt++; // Parameter 'vlevelLimits' // ctype is '_vlevelLimits_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("vlevelLimits"); tt->descr = tdrpStrDup("Option to apply vlevel limits prior to reading MDV data."); tt->help = tdrpStrDup("Default is not to do this. If this option is selected,\nonly selected levels are included in the MDV read, which\ncan be handy when making a composite of 0.5 degree scans\nfrom a multi-layered dataset."); tt->val_offset = (char *) &vlevelLimits - &_start_; tt->struct_def.name = tdrpStrDup("vlevelLimits_t"); tt->struct_def.nfields = 3; tt->struct_def.fields = (struct_field_t *) tdrpMalloc(tt->struct_def.nfields * sizeof(struct_field_t)); tt->struct_def.fields[0].ftype = tdrpStrDup("boolean"); tt->struct_def.fields[0].fname = tdrpStrDup("applyVlevelLimits"); tt->struct_def.fields[0].ptype = BOOL_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &vlevelLimits.applyVlevelLimits - (char *) &vlevelLimits; tt->struct_def.fields[1].ftype = tdrpStrDup("double"); tt->struct_def.fields[1].fname = tdrpStrDup("vlevelMin"); tt->struct_def.fields[1].ptype = DOUBLE_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &vlevelLimits.vlevelMin - (char *) &vlevelLimits; tt->struct_def.fields[2].ftype = tdrpStrDup("double"); tt->struct_def.fields[2].fname = tdrpStrDup("vlevelMax"); tt->struct_def.fields[2].ptype = DOUBLE_TYPE; tt->struct_def.fields[2].rel_offset = (char *) &vlevelLimits.vlevelMax - (char *) &vlevelLimits; tt->n_struct_vals = 3; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].b = pFALSE; tt->struct_vals[1].d = 0.45; tt->struct_vals[2].d = 0.55; tt++; // Parameter 'planeNumLimits' // ctype is '_planeNumLimits_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("planeNumLimits"); tt->descr = tdrpStrDup("Option to apply inclusive vertical plane number\nlimits prior to reading MDV data. Lowest plane is 0."); tt->help = tdrpStrDup("Default is not to do this. If this option is selected,\nonly the selected plane numbers are included in the\nMDV read. This can be handy when the desired output\nis a merge of the lowest elevation angle\nfrom a multi-layered dataset."); tt->val_offset = (char *) &planeNumLimits - &_start_; tt->struct_def.name = tdrpStrDup("planeNumLimits_t"); tt->struct_def.nfields = 3; tt->struct_def.fields = (struct_field_t *) tdrpMalloc(tt->struct_def.nfields * sizeof(struct_field_t)); tt->struct_def.fields[0].ftype = tdrpStrDup("boolean"); tt->struct_def.fields[0].fname = tdrpStrDup("applyPlaneNumLimits"); tt->struct_def.fields[0].ptype = BOOL_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &planeNumLimits.applyPlaneNumLimits - (char *) &planeNumLimits; tt->struct_def.fields[1].ftype = tdrpStrDup("int"); tt->struct_def.fields[1].fname = tdrpStrDup("planeNumMin"); tt->struct_def.fields[1].ptype = INT_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &planeNumLimits.planeNumMin - (char *) &planeNumLimits; tt->struct_def.fields[2].ftype = tdrpStrDup("int"); tt->struct_def.fields[2].fname = tdrpStrDup("planeNumMax"); tt->struct_def.fields[2].ptype = INT_TYPE; tt->struct_def.fields[2].rel_offset = (char *) &planeNumLimits.planeNumMax - (char *) &planeNumLimits; tt->n_struct_vals = 3; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].b = pFALSE; tt->struct_vals[1].i = 0; tt->struct_vals[2].i = 0; tt++; // Parameter 'use_specified_vlevels' // ctype is 'tdrp_bool_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = BOOL_TYPE; tt->param_name = tdrpStrDup("use_specified_vlevels"); tt->descr = tdrpStrDup("Option to output unevenly-spaced vertical levels."); tt->help = tdrpStrDup("Created to handle meteorological data sets with denser vertical\nspacing near the surface. If TRUE, must set 'vlevel_array[] values'."); tt->val_offset = (char *) &use_specified_vlevels - &_start_; tt->single_val.b = pFALSE; tt++; // Parameter 'vlevel_array' // ctype is 'double' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = DOUBLE_TYPE; tt->param_name = tdrpStrDup("vlevel_array"); tt->descr = tdrpStrDup("vlevel values associated with use_specified_levels."); tt->help = tdrpStrDup("Only used when 'use_specified_vlevels' is TRUE."); tt->array_offset = (char *) &_vlevel_array - &_start_; tt->array_n_offset = (char *) &vlevel_array_n - &_start_; tt->is_array = TRUE; tt->array_len_fixed = FALSE; tt->array_elem_size = sizeof(double); tt->array_n = 1; tt->array_vals = (tdrpVal_t *) tdrpMalloc(tt->array_n * sizeof(tdrpVal_t)); tt->array_vals[0].d = 0; tt++; // Parameter 'merge_fields' // ctype is '_merge_field_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("merge_fields"); tt->descr = tdrpStrDup("Specifications for merged output field."); tt->help = tdrpStrDup("\n'name': specify the name of this field in the output MDV file. This is also probably the name of the fields in the input files. However, you may specify a different field name for the input - see input_url for details.\n\n'merge_method': MERGE_MIN - take the minimum value at a grid point; MERGE_MAX - take the maximum value at a grid point; MERGE_MEAN - take the mean value at a point; MERGE_SUM - sum all values at a point; MERGE_LATEST - take the latest valid data value at a grid point\n\nMERGE_CLOSEST - use the data with the closet origin to the grid point. CLOSEST requires a range field in the data so that for overlapping points we can determine which data set is closest to the grid point\n\n'merge_encoding': the type of data used to perform the merge. For best results FLOAT32 is recommended, especially for MERGE_SUM. However, this uses more memory. To conserve memory, use INT8 or INT16. If you select INT8 or INT16 you must also specify 'merge_scale' and 'merge_bias' to be used to represent the data in the merge.\n\n'output_encoding': determines the type for storing the merged data in the output file. This affects the size of the output file. Use FLOAT32 for maximum precision, INT8 for smallest files."); tt->array_offset = (char *) &_merge_fields - &_start_; tt->array_n_offset = (char *) &merge_fields_n - &_start_; tt->is_array = TRUE; tt->array_len_fixed = FALSE; tt->array_elem_size = sizeof(merge_field_t); tt->array_n = 1; tt->struct_def.name = tdrpStrDup("merge_field_t"); tt->struct_def.nfields = 6; 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("name"); tt->struct_def.fields[0].ptype = STRING_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &_merge_fields->name - (char *) _merge_fields; tt->struct_def.fields[1].ftype = tdrpStrDup("merge_method_t"); tt->struct_def.fields[1].fname = tdrpStrDup("merge_method"); tt->struct_def.fields[1].ptype = ENUM_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &_merge_fields->merge_method - (char *) _merge_fields; tt->struct_def.fields[1].enum_def.name = tdrpStrDup("merge_method_t"); tt->struct_def.fields[1].enum_def.nfields = 6; tt->struct_def.fields[1].enum_def.fields = (enum_field_t *) tdrpMalloc (tt->struct_def.fields[1].enum_def.nfields * sizeof(enum_field_t)); tt->struct_def.fields[1].enum_def.fields[0].name = tdrpStrDup("MERGE_MIN"); tt->struct_def.fields[1].enum_def.fields[0].val = MERGE_MIN; tt->struct_def.fields[1].enum_def.fields[1].name = tdrpStrDup("MERGE_MAX"); tt->struct_def.fields[1].enum_def.fields[1].val = MERGE_MAX; tt->struct_def.fields[1].enum_def.fields[2].name = tdrpStrDup("MERGE_MEAN"); tt->struct_def.fields[1].enum_def.fields[2].val = MERGE_MEAN; tt->struct_def.fields[1].enum_def.fields[3].name = tdrpStrDup("MERGE_SUM"); tt->struct_def.fields[1].enum_def.fields[3].val = MERGE_SUM; tt->struct_def.fields[1].enum_def.fields[4].name = tdrpStrDup("MERGE_LATEST"); tt->struct_def.fields[1].enum_def.fields[4].val = MERGE_LATEST; tt->struct_def.fields[1].enum_def.fields[5].name = tdrpStrDup("MERGE_CLOSEST"); tt->struct_def.fields[1].enum_def.fields[5].val = MERGE_CLOSEST; tt->struct_def.fields[2].ftype = tdrpStrDup("encoding_t"); tt->struct_def.fields[2].fname = tdrpStrDup("merge_encoding"); tt->struct_def.fields[2].ptype = ENUM_TYPE; tt->struct_def.fields[2].rel_offset = (char *) &_merge_fields->merge_encoding - (char *) _merge_fields; tt->struct_def.fields[2].enum_def.name = tdrpStrDup("encoding_t"); tt->struct_def.fields[2].enum_def.nfields = 3; tt->struct_def.fields[2].enum_def.fields = (enum_field_t *) tdrpMalloc (tt->struct_def.fields[2].enum_def.nfields * sizeof(enum_field_t)); tt->struct_def.fields[2].enum_def.fields[0].name = tdrpStrDup("INT8"); tt->struct_def.fields[2].enum_def.fields[0].val = INT8; tt->struct_def.fields[2].enum_def.fields[1].name = tdrpStrDup("INT16"); tt->struct_def.fields[2].enum_def.fields[1].val = INT16; tt->struct_def.fields[2].enum_def.fields[2].name = tdrpStrDup("FLOAT32"); tt->struct_def.fields[2].enum_def.fields[2].val = FLOAT32; tt->struct_def.fields[3].ftype = tdrpStrDup("double"); tt->struct_def.fields[3].fname = tdrpStrDup("merge_scale"); tt->struct_def.fields[3].ptype = DOUBLE_TYPE; tt->struct_def.fields[3].rel_offset = (char *) &_merge_fields->merge_scale - (char *) _merge_fields; tt->struct_def.fields[4].ftype = tdrpStrDup("double"); tt->struct_def.fields[4].fname = tdrpStrDup("merge_bias"); tt->struct_def.fields[4].ptype = DOUBLE_TYPE; tt->struct_def.fields[4].rel_offset = (char *) &_merge_fields->merge_bias - (char *) _merge_fields; tt->struct_def.fields[5].ftype = tdrpStrDup("encoding_t"); tt->struct_def.fields[5].fname = tdrpStrDup("output_encoding"); tt->struct_def.fields[5].ptype = ENUM_TYPE; tt->struct_def.fields[5].rel_offset = (char *) &_merge_fields->output_encoding - (char *) _merge_fields; tt->struct_def.fields[5].enum_def.name = tdrpStrDup("encoding_t"); tt->struct_def.fields[5].enum_def.nfields = 3; tt->struct_def.fields[5].enum_def.fields = (enum_field_t *) tdrpMalloc (tt->struct_def.fields[5].enum_def.nfields * sizeof(enum_field_t)); tt->struct_def.fields[5].enum_def.fields[0].name = tdrpStrDup("INT8"); tt->struct_def.fields[5].enum_def.fields[0].val = INT8; tt->struct_def.fields[5].enum_def.fields[1].name = tdrpStrDup("INT16"); tt->struct_def.fields[5].enum_def.fields[1].val = INT16; tt->struct_def.fields[5].enum_def.fields[2].name = tdrpStrDup("FLOAT32"); tt->struct_def.fields[5].enum_def.fields[2].val = FLOAT32; tt->n_struct_vals = 6; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].s = tdrpStrDup("DBZ"); tt->struct_vals[1].e = MERGE_MAX; tt->struct_vals[2].e = FLOAT32; tt->struct_vals[3].d = 0.5; tt->struct_vals[4].d = -32; tt->struct_vals[5].e = INT8; tt++; // Parameter 'range_field_name' // ctype is 'char*' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRING_TYPE; tt->param_name = tdrpStrDup("range_field_name"); tt->descr = tdrpStrDup("Name of range field in data set, giving range from the instrument to the grid point."); tt->help = tdrpStrDup("If MERGE_CLOSEST is used, we require a range field, from which to determine which data set origin is closest to the grid point. This is mostly used for radar data, and the range will be the range from the radar.\n"); tt->val_offset = (char *) &range_field_name - &_start_; tt->single_val.s = tdrpStrDup("range"); tt++; // Parameter 'fcst_data_time_type' // ctype is '_fcst_data_time_type_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = ENUM_TYPE; tt->param_name = tdrpStrDup("fcst_data_time_type"); tt->descr = tdrpStrDup("This parameter defines what time to put in the time array when using MERGE_LATEST. If one or more of the inputs is forecast data this gives the option to use its gen time or its valid time. The default is set to valid time in order for the algorithm to have the same behavior as it had before this parameter was added."); tt->help = tdrpStrDup("If set to GENTIME, then the forecast_delta is subtracted from the forecast time (valid time) and this time is used in the time array. If set to VALIDTIME the forecast time (valid time) is used in the time array. This option was added for the times where you want the non-forecast data to take priority over the forecast data. "); tt->val_offset = (char *) &fcst_data_time_type - &_start_; tt->enum_def.name = tdrpStrDup("fcst_data_time_type_t"); tt->enum_def.nfields = 2; tt->enum_def.fields = (enum_field_t *) tdrpMalloc(tt->enum_def.nfields * sizeof(enum_field_t)); tt->enum_def.fields[0].name = tdrpStrDup("GENTIME"); tt->enum_def.fields[0].val = GENTIME; tt->enum_def.fields[1].name = tdrpStrDup("VALIDTIME"); tt->enum_def.fields[1].val = VALIDTIME; tt->single_val.e = VALIDTIME; tt++; // Parameter 'Comment 4' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 4"); tt->comment_hdr = tdrpStrDup("INPUT DATA SPECIFICATIONS."); tt->comment_text = tdrpStrDup(""); tt++; // Parameter 'input_urls' // ctype is '_input_url_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("input_urls"); tt->descr = tdrpStrDup("Array of input data URLs and related information."); tt->help = tdrpStrDup("\n'url': specify the URL for the input data. For data on local disk, the URL this can just be the directory containing the input MDV data files. For data retrieved from a server, it is the URL for the server. A server URL takes the following form: 'mdvp:://host:port:directory_path'. The directory path is relative to $DATA_DIR or $RAP_DATA_DIR.\n\n'field_names': If the field names in the input file match those in the 'merge_fields' parameter you should set field_names to an empty string. If the field names differ, specify the input field names as a comma-delimted list. If you wish to specify field numbers instead of names, use a comma-delimited list of numbers. Do not mix names and numbers.\n\n'is_required': if true, the merge will only be performed if data from this URL is available. If false, the merge will go ahead even if no data is available from this URL.\n\n'must_update': if true, data from this URL must have updated since the previous merge before the merge can go ahead."); tt->array_offset = (char *) &_input_urls - &_start_; tt->array_n_offset = (char *) &input_urls_n - &_start_; tt->is_array = TRUE; tt->array_len_fixed = FALSE; tt->array_elem_size = sizeof(input_url_t); tt->array_n = 1; tt->struct_def.name = tdrpStrDup("input_url_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("url"); tt->struct_def.fields[0].ptype = STRING_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &_input_urls->url - (char *) _input_urls; tt->struct_def.fields[1].ftype = tdrpStrDup("string"); tt->struct_def.fields[1].fname = tdrpStrDup("field_names"); tt->struct_def.fields[1].ptype = STRING_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &_input_urls->field_names - (char *) _input_urls; tt->struct_def.fields[2].ftype = tdrpStrDup("boolean"); tt->struct_def.fields[2].fname = tdrpStrDup("is_required"); tt->struct_def.fields[2].ptype = BOOL_TYPE; tt->struct_def.fields[2].rel_offset = (char *) &_input_urls->is_required - (char *) _input_urls; tt->struct_def.fields[3].ftype = tdrpStrDup("boolean"); tt->struct_def.fields[3].fname = tdrpStrDup("must_update"); tt->struct_def.fields[3].ptype = BOOL_TYPE; tt->struct_def.fields[3].rel_offset = (char *) &_input_urls->must_update - (char *) _input_urls; tt->n_struct_vals = 4; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].s = tdrpStrDup("mdvp:://localhost::mdv/radar/cart"); tt->struct_vals[1].s = tdrpStrDup(""); tt->struct_vals[2].b = pFALSE; tt->struct_vals[3].b = pFALSE; tt++; // Parameter 'Comment 5' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = COMMENT_TYPE; tt->param_name = tdrpStrDup("Comment 5"); tt->comment_hdr = tdrpStrDup("OUTPUT DATA SPECIFICATIONS."); tt->comment_text = tdrpStrDup(""); tt++; // Parameter 'output_url' // ctype is 'char*' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRING_TYPE; tt->param_name = tdrpStrDup("output_url"); tt->descr = tdrpStrDup("Output data URL."); tt->help = tdrpStrDup("URL for output data files. Has the form mdvp:://host:port:directory_path."); tt->val_offset = (char *) &output_url - &_start_; tt->single_val.s = tdrpStrDup("mdvp:://localhost::mdv/radar/merged"); tt++; // Parameter 'output_timestamp_correction' // ctype is 'int' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = INT_TYPE; tt->param_name = tdrpStrDup("output_timestamp_correction"); tt->descr = tdrpStrDup("Correction to the output time relative to the trigger time - secs."); tt->help = tdrpStrDup("You may need to correct for latency in the data system. For example, the NEXRAD data arrives about 5 mins late, so we need to correct the trigger time to account for this latency in the data. The correction is ADDED to the trigger time, so to correct for latency you need to use a negative correction."); tt->val_offset = (char *) &output_timestamp_correction - &_start_; tt->single_val.i = 0; tt++; // Parameter 'write_ldata' // ctype is 'tdrp_bool_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = BOOL_TYPE; tt->param_name = tdrpStrDup("write_ldata"); tt->descr = tdrpStrDup("Write Ldata info file, when in not in REALTIME mode"); tt->help = tdrpStrDup(""); tt->val_offset = (char *) &write_ldata - &_start_; tt->single_val.b = pTRUE; tt++; // Parameter 'write_as_forecast' // ctype is 'tdrp_bool_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = BOOL_TYPE; tt->param_name = tdrpStrDup("write_as_forecast"); tt->descr = tdrpStrDup("Set to true to write as forecast data (g_HHMMSS/f_00000000.mdv\n Otherwise, output will just be written to a day dir.\n "); tt->help = tdrpStrDup("Defaults to FALSE"); tt->val_offset = (char *) &write_as_forecast - &_start_; tt->single_val.b = pFALSE; tt++; // Parameter 'output_projection' // ctype is '_output_projection_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = ENUM_TYPE; tt->param_name = tdrpStrDup("output_projection"); tt->descr = tdrpStrDup("Projection of output grid."); tt->help = tdrpStrDup("FLAT: (x,y) Cartesian data in km from a given origin, typical of local radar data.\n\nLATLON - lat/lon grid with constant grid spacing (Mercator).\n\nLAMBERT - Lambert Conformal projection."); tt->val_offset = (char *) &output_projection - &_start_; tt->enum_def.name = tdrpStrDup("output_projection_t"); tt->enum_def.nfields = 3; tt->enum_def.fields = (enum_field_t *) tdrpMalloc(tt->enum_def.nfields * sizeof(enum_field_t)); tt->enum_def.fields[0].name = tdrpStrDup("OUTPUT_PROJ_FLAT"); tt->enum_def.fields[0].val = OUTPUT_PROJ_FLAT; tt->enum_def.fields[1].name = tdrpStrDup("OUTPUT_PROJ_LATLON"); tt->enum_def.fields[1].val = OUTPUT_PROJ_LATLON; tt->enum_def.fields[2].name = tdrpStrDup("OUTPUT_PROJ_LAMBERT"); tt->enum_def.fields[2].val = OUTPUT_PROJ_LAMBERT; tt->single_val.e = OUTPUT_PROJ_LATLON; tt++; // Parameter 'output_origin' // ctype is '_output_origin_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("output_origin"); tt->descr = tdrpStrDup("Origin of output grid."); tt->help = tdrpStrDup("Applies to OUTPUT_PROJ_FLAT and OUTPUT_PROJ_LAMBERT."); tt->val_offset = (char *) &output_origin - &_start_; tt->struct_def.name = tdrpStrDup("output_origin_t"); tt->struct_def.nfields = 2; tt->struct_def.fields = (struct_field_t *) tdrpMalloc(tt->struct_def.nfields * sizeof(struct_field_t)); tt->struct_def.fields[0].ftype = tdrpStrDup("double"); tt->struct_def.fields[0].fname = tdrpStrDup("lat"); tt->struct_def.fields[0].ptype = DOUBLE_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &output_origin.lat - (char *) &output_origin; tt->struct_def.fields[1].ftype = tdrpStrDup("double"); tt->struct_def.fields[1].fname = tdrpStrDup("lon"); tt->struct_def.fields[1].ptype = DOUBLE_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &output_origin.lon - (char *) &output_origin; tt->n_struct_vals = 2; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].d = 40; tt->struct_vals[1].d = -104; tt++; // Parameter 'output_rotation' // ctype is 'double' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = DOUBLE_TYPE; tt->param_name = tdrpStrDup("output_rotation"); tt->descr = tdrpStrDup("Rotation of output grid."); tt->help = tdrpStrDup("Applicable to OUTPUT_PROJ_FLAT."); tt->val_offset = (char *) &output_rotation - &_start_; tt->single_val.d = 0; tt++; // Parameter 'output_std_parallels' // ctype is '_output_std_parallels_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("output_std_parallels"); tt->descr = tdrpStrDup("Standard parallels."); tt->help = tdrpStrDup("Applicable to OUTPUT_PROJ_LAMBERT only."); tt->val_offset = (char *) &output_std_parallels - &_start_; tt->struct_def.name = tdrpStrDup("output_std_parallels_t"); tt->struct_def.nfields = 2; tt->struct_def.fields = (struct_field_t *) tdrpMalloc(tt->struct_def.nfields * sizeof(struct_field_t)); tt->struct_def.fields[0].ftype = tdrpStrDup("double"); tt->struct_def.fields[0].fname = tdrpStrDup("lat_1"); tt->struct_def.fields[0].ptype = DOUBLE_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &output_std_parallels.lat_1 - (char *) &output_std_parallels; tt->struct_def.fields[1].ftype = tdrpStrDup("double"); tt->struct_def.fields[1].fname = tdrpStrDup("lat_2"); tt->struct_def.fields[1].ptype = DOUBLE_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &output_std_parallels.lat_2 - (char *) &output_std_parallels; tt->n_struct_vals = 2; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].d = 20; tt->struct_vals[1].d = 45; tt++; // Parameter 'output_grid' // ctype is '_grid_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("output_grid"); tt->descr = tdrpStrDup("Output grid parameters."); tt->help = tdrpStrDup("For OUTPUT_PROJ_LATLON, minx, miny, dx and dy are in degrees. Otherwise they are in km."); tt->val_offset = (char *) &output_grid - &_start_; tt->struct_def.name = tdrpStrDup("grid_t"); tt->struct_def.nfields = 9; tt->struct_def.fields = (struct_field_t *) tdrpMalloc(tt->struct_def.nfields * sizeof(struct_field_t)); tt->struct_def.fields[0].ftype = tdrpStrDup("long"); tt->struct_def.fields[0].fname = tdrpStrDup("nx"); tt->struct_def.fields[0].ptype = LONG_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &output_grid.nx - (char *) &output_grid; tt->struct_def.fields[1].ftype = tdrpStrDup("long"); tt->struct_def.fields[1].fname = tdrpStrDup("ny"); tt->struct_def.fields[1].ptype = LONG_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &output_grid.ny - (char *) &output_grid; tt->struct_def.fields[2].ftype = tdrpStrDup("long"); tt->struct_def.fields[2].fname = tdrpStrDup("nz"); tt->struct_def.fields[2].ptype = LONG_TYPE; tt->struct_def.fields[2].rel_offset = (char *) &output_grid.nz - (char *) &output_grid; tt->struct_def.fields[3].ftype = tdrpStrDup("double"); tt->struct_def.fields[3].fname = tdrpStrDup("minx"); tt->struct_def.fields[3].ptype = DOUBLE_TYPE; tt->struct_def.fields[3].rel_offset = (char *) &output_grid.minx - (char *) &output_grid; tt->struct_def.fields[4].ftype = tdrpStrDup("double"); tt->struct_def.fields[4].fname = tdrpStrDup("miny"); tt->struct_def.fields[4].ptype = DOUBLE_TYPE; tt->struct_def.fields[4].rel_offset = (char *) &output_grid.miny - (char *) &output_grid; tt->struct_def.fields[5].ftype = tdrpStrDup("double"); tt->struct_def.fields[5].fname = tdrpStrDup("minz"); tt->struct_def.fields[5].ptype = DOUBLE_TYPE; tt->struct_def.fields[5].rel_offset = (char *) &output_grid.minz - (char *) &output_grid; tt->struct_def.fields[6].ftype = tdrpStrDup("double"); tt->struct_def.fields[6].fname = tdrpStrDup("dx"); tt->struct_def.fields[6].ptype = DOUBLE_TYPE; tt->struct_def.fields[6].rel_offset = (char *) &output_grid.dx - (char *) &output_grid; tt->struct_def.fields[7].ftype = tdrpStrDup("double"); tt->struct_def.fields[7].fname = tdrpStrDup("dy"); tt->struct_def.fields[7].ptype = DOUBLE_TYPE; tt->struct_def.fields[7].rel_offset = (char *) &output_grid.dy - (char *) &output_grid; tt->struct_def.fields[8].ftype = tdrpStrDup("double"); tt->struct_def.fields[8].fname = tdrpStrDup("dz"); tt->struct_def.fields[8].ptype = DOUBLE_TYPE; tt->struct_def.fields[8].rel_offset = (char *) &output_grid.dz - (char *) &output_grid; tt->n_struct_vals = 9; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].l = 360; tt->struct_vals[1].l = 180; tt->struct_vals[2].l = 1; tt->struct_vals[3].d = -180; tt->struct_vals[4].d = -90; tt->struct_vals[5].d = 1; tt->struct_vals[6].d = 1; tt->struct_vals[7].d = 1; tt->struct_vals[8].d = 1; tt++; // Parameter 'output_compression' // ctype is '_output_compression_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = ENUM_TYPE; tt->param_name = tdrpStrDup("output_compression"); tt->descr = tdrpStrDup("Compression method for output fields."); tt->help = tdrpStrDup(""); tt->val_offset = (char *) &output_compression - &_start_; tt->enum_def.name = tdrpStrDup("output_compression_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("COMPRESSION_NONE"); tt->enum_def.fields[0].val = COMPRESSION_NONE; tt->enum_def.fields[1].name = tdrpStrDup("COMPRESSION_RLE"); tt->enum_def.fields[1].val = COMPRESSION_RLE; tt->enum_def.fields[2].name = tdrpStrDup("COMPRESSION_ZLIB"); tt->enum_def.fields[2].val = COMPRESSION_ZLIB; tt->enum_def.fields[3].name = tdrpStrDup("COMPRESSION_GZIP"); tt->enum_def.fields[3].val = COMPRESSION_GZIP; tt->single_val.e = COMPRESSION_ZLIB; tt++; // Parameter 'output_data_set_name' // ctype is 'char*' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRING_TYPE; tt->param_name = tdrpStrDup("output_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 *) &output_data_set_name - &_start_; tt->single_val.s = tdrpStrDup("Unknown"); tt++; // Parameter 'output_data_set_source' // ctype is 'char*' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRING_TYPE; tt->param_name = tdrpStrDup("output_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 *) &output_data_set_source - &_start_; tt->single_val.s = tdrpStrDup("Merged data created by MdvMerge2."); tt++; // Parameter 'copyMetaDataFromInput' // ctype is 'tdrp_bool_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = BOOL_TYPE; tt->param_name = tdrpStrDup("copyMetaDataFromInput"); tt->descr = tdrpStrDup("Option to copy data set name, source and info strings\nfrom the last master header read."); tt->help = tdrpStrDup("May be useful for tracking data sets. If set to TRUE then\nthe output_data_set_name and output_data_set_source entries\nin this param file are ignored."); tt->val_offset = (char *) ©MetaDataFromInput - &_start_; tt->single_val.b = pFALSE; tt++; // Parameter 'remap_input_grids' // ctype is '_remap_input_grids_t' memset(tt, 0, sizeof(TDRPtable)); tt->ptype = STRUCT_TYPE; tt->param_name = tdrpStrDup("remap_input_grids"); tt->descr = tdrpStrDup("Option to do remapping on input URLs. For the vast majority\nof cases this should be an empty array. The default given is\nsimply an example, and unless the urls given are actually used\n(which is unlikely) it will have no effect."); tt->help = tdrpStrDup("For lat/lon projections, minx, miny, dx and dy are in degrees.\nOtherwise they are in km. The url string must match one of the input\nURLs specified. The gridType string should be set to one of FLAT,\nLATLON or LAMBERT. originLat and originLon are not used for\nLATLON projections."); tt->array_offset = (char *) &_remap_input_grids - &_start_; tt->array_n_offset = (char *) &remap_input_grids_n - &_start_; tt->is_array = TRUE; tt->array_len_fixed = FALSE; tt->array_elem_size = sizeof(remap_input_grids_t); tt->array_n = 2; tt->struct_def.name = tdrpStrDup("remap_input_grids_t"); tt->struct_def.nfields = 13; 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("url"); tt->struct_def.fields[0].ptype = STRING_TYPE; tt->struct_def.fields[0].rel_offset = (char *) &_remap_input_grids->url - (char *) _remap_input_grids; tt->struct_def.fields[1].ftype = tdrpStrDup("string"); tt->struct_def.fields[1].fname = tdrpStrDup("gridType"); tt->struct_def.fields[1].ptype = STRING_TYPE; tt->struct_def.fields[1].rel_offset = (char *) &_remap_input_grids->gridType - (char *) _remap_input_grids; tt->struct_def.fields[2].ftype = tdrpStrDup("long"); tt->struct_def.fields[2].fname = tdrpStrDup("nx"); tt->struct_def.fields[2].ptype = LONG_TYPE; tt->struct_def.fields[2].rel_offset = (char *) &_remap_input_grids->nx - (char *) _remap_input_grids; tt->struct_def.fields[3].ftype = tdrpStrDup("long"); tt->struct_def.fields[3].fname = tdrpStrDup("ny"); tt->struct_def.fields[3].ptype = LONG_TYPE; tt->struct_def.fields[3].rel_offset = (char *) &_remap_input_grids->ny - (char *) _remap_input_grids; tt->struct_def.fields[4].ftype = tdrpStrDup("double"); tt->struct_def.fields[4].fname = tdrpStrDup("minx"); tt->struct_def.fields[4].ptype = DOUBLE_TYPE; tt->struct_def.fields[4].rel_offset = (char *) &_remap_input_grids->minx - (char *) _remap_input_grids; tt->struct_def.fields[5].ftype = tdrpStrDup("double"); tt->struct_def.fields[5].fname = tdrpStrDup("miny"); tt->struct_def.fields[5].ptype = DOUBLE_TYPE; tt->struct_def.fields[5].rel_offset = (char *) &_remap_input_grids->miny - (char *) _remap_input_grids; tt->struct_def.fields[6].ftype = tdrpStrDup("double"); tt->struct_def.fields[6].fname = tdrpStrDup("dx"); tt->struct_def.fields[6].ptype = DOUBLE_TYPE; tt->struct_def.fields[6].rel_offset = (char *) &_remap_input_grids->dx - (char *) _remap_input_grids; tt->struct_def.fields[7].ftype = tdrpStrDup("double"); tt->struct_def.fields[7].fname = tdrpStrDup("dy"); tt->struct_def.fields[7].ptype = DOUBLE_TYPE; tt->struct_def.fields[7].rel_offset = (char *) &_remap_input_grids->dy - (char *) _remap_input_grids; tt->struct_def.fields[8].ftype = tdrpStrDup("double"); tt->struct_def.fields[8].fname = tdrpStrDup("lambertTruelat1"); tt->struct_def.fields[8].ptype = DOUBLE_TYPE; tt->struct_def.fields[8].rel_offset = (char *) &_remap_input_grids->lambertTruelat1 - (char *) _remap_input_grids; tt->struct_def.fields[9].ftype = tdrpStrDup("double"); tt->struct_def.fields[9].fname = tdrpStrDup("lambertTruelat2"); tt->struct_def.fields[9].ptype = DOUBLE_TYPE; tt->struct_def.fields[9].rel_offset = (char *) &_remap_input_grids->lambertTruelat2 - (char *) _remap_input_grids; tt->struct_def.fields[10].ftype = tdrpStrDup("double"); tt->struct_def.fields[10].fname = tdrpStrDup("flatEarthRotation"); tt->struct_def.fields[10].ptype = DOUBLE_TYPE; tt->struct_def.fields[10].rel_offset = (char *) &_remap_input_grids->flatEarthRotation - (char *) _remap_input_grids; tt->struct_def.fields[11].ftype = tdrpStrDup("double"); tt->struct_def.fields[11].fname = tdrpStrDup("originLat"); tt->struct_def.fields[11].ptype = DOUBLE_TYPE; tt->struct_def.fields[11].rel_offset = (char *) &_remap_input_grids->originLat - (char *) _remap_input_grids; tt->struct_def.fields[12].ftype = tdrpStrDup("double"); tt->struct_def.fields[12].fname = tdrpStrDup("originLon"); tt->struct_def.fields[12].ptype = DOUBLE_TYPE; tt->struct_def.fields[12].rel_offset = (char *) &_remap_input_grids->originLon - (char *) _remap_input_grids; tt->n_struct_vals = 26; tt->struct_vals = (tdrpVal_t *) tdrpMalloc(tt->n_struct_vals * sizeof(tdrpVal_t)); tt->struct_vals[0].s = tdrpStrDup("mdvp:://exampleHost::example/dir/struct1"); tt->struct_vals[1].s = tdrpStrDup("FLAT"); tt->struct_vals[2].l = 400; tt->struct_vals[3].l = 400; tt->struct_vals[4].d = -199.5; tt->struct_vals[5].d = -199.5; tt->struct_vals[6].d = 1; tt->struct_vals[7].d = 1; tt->struct_vals[8].d = 60; tt->struct_vals[9].d = 40; tt->struct_vals[10].d = 0; tt->struct_vals[11].d = 40; tt->struct_vals[12].d = -105; tt->struct_vals[13].s = tdrpStrDup("mdvp:://exampleHost::example/dir/struct2"); tt->struct_vals[14].s = tdrpStrDup("FLAT"); tt->struct_vals[15].l = 400; tt->struct_vals[16].l = 400; tt->struct_vals[17].d = -199.5; tt->struct_vals[18].d = -199.5; tt->struct_vals[19].d = 1; tt->struct_vals[20].d = 1; tt->struct_vals[21].d = 60; tt->struct_vals[22].d = 40; tt->struct_vals[23].d = 0; tt->struct_vals[24].d = 41; tt->struct_vals[25].d = -107; tt++; // trailing entry has param_name set to NULL tt->param_name = NULL; return; }