int readGageSeriesFormat(char* tok[], int ntoks, double x[]) { int m, ts; DateTime aTime; if ( ntoks < 6 ) return error_setInpError(ERR_ITEMS, ""); // --- determine type of rain data m = findmatch(tok[1], RainTypeWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]); x[1] = (double)m; // --- get data time interval & convert to seconds if ( getDouble(tok[2], &x[2]) ) x[2] = floor(x[2]*3600 + 0.5); else if ( datetime_strToTime(tok[2], &aTime) ) { x[2] = floor(aTime*SECperDAY + 0.5); } else return error_setInpError(ERR_DATETIME, tok[2]); if ( x[2] <= 0.0 ) return error_setInpError(ERR_DATETIME, tok[2]); // --- get snow catch deficiency factor if ( !getDouble(tok[3], &x[3]) ) return error_setInpError(ERR_DATETIME, tok[3]);; // --- get time series index ts = project_findObject(TSERIES, tok[5]); if ( ts < 0 ) return error_setInpError(ERR_NAME, tok[5]); x[0] = (double)ts; strcpy(tok[2], ""); return 0; }
int readGageFileFormat(char* tok[], int ntoks, double x[]) { int m, u; DateTime aDate; DateTime aTime; // --- determine type of rain data m = findmatch(tok[1], RainTypeWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]); x[1] = (double)m; // --- get data time interval & convert to seconds if ( getDouble(tok[2], &x[2]) ) x[2] *= 3600; else if ( datetime_strToTime(tok[2], &aTime) ) { x[2] = floor(aTime*SECperDAY + 0.5); } else return error_setInpError(ERR_DATETIME, tok[2]); if ( x[2] <= 0.0 ) return error_setInpError(ERR_DATETIME, tok[2]); // --- get snow catch deficiency factor if ( !getDouble(tok[3], &x[3]) ) return error_setInpError(ERR_NUMBER, tok[3]); // --- get rain depth units u = findmatch(tok[7], RainUnitsWords); if ( u < 0 ) return error_setInpError(ERR_KEYWORD, tok[7]); x[6] = (double)u; // --- get start date (if present) if ( ntoks > 8 && *tok[8] != '*') { if ( !datetime_strToDate(tok[8], &aDate) ) return error_setInpError(ERR_DATETIME, tok[8]); x[4] = (float) aDate; } return 0; }
int project_readOption(char* s1, char* s2) // // Input: s1 = option keyword // s2 = string representation of option's value // Output: returns error code // Purpose: reads a project option from a pair of string tokens. // // NOTE: all project options have default values assigned in setDefaults(). // { int k, m, h, s; double tStep; char strDate[25]; DateTime aTime; DateTime aDate; // --- determine which option is being read k = findmatch(s1, OptionWords); if ( k < 0 ) return error_setInpError(ERR_KEYWORD, s1); switch ( k ) { // --- choice of flow units case FLOW_UNITS: m = findmatch(s2, FlowUnitWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); FlowUnits = m; if ( FlowUnits <= MGD ) UnitSystem = US; else UnitSystem = SI; break; // --- choice of infiltration modeling method case INFIL_MODEL: m = findmatch(s2, InfilModelWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); InfilModel = m; break; // --- choice of flow routing method case ROUTE_MODEL: m = findmatch(s2, RouteModelWords); if ( m < 0 ) m = findmatch(s2, OldRouteModelWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); if ( m == NO_ROUTING ) IgnoreRouting = TRUE; else RouteModel = m; if ( RouteModel == EKW ) RouteModel = KW; break; // --- simulation start date case START_DATE: if ( !datetime_strToDate(s2, &StartDate) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- simulation start time of day case START_TIME: if ( !datetime_strToTime(s2, &StartTime) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- simulation ending date case END_DATE: if ( !datetime_strToDate(s2, &EndDate) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- simulation ending time of day case END_TIME: if ( !datetime_strToTime(s2, &EndTime) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- reporting start date case REPORT_START_DATE: if ( !datetime_strToDate(s2, &ReportStartDate) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- reporting start time of day case REPORT_START_TIME: if ( !datetime_strToTime(s2, &ReportStartTime) ) { return error_setInpError(ERR_DATETIME, s2); } break; // --- day of year when street sweeping begins or when it ends // (year is arbitrarily set to 1947 so that the dayOfYear // function can be applied) case SWEEP_START: case SWEEP_END: strcpy(strDate, s2); strcat(strDate, "/1947"); if ( !datetime_strToDate(strDate, &aDate) ) { return error_setInpError(ERR_DATETIME, s2); } m = datetime_dayOfYear(aDate); if ( k == SWEEP_START ) SweepStart = m; else SweepEnd = m; break; // --- number of antecedent dry days case START_DRY_DAYS: StartDryDays = atof(s2); if ( StartDryDays < 0.0 ) { return error_setInpError(ERR_NUMBER, s2); } break; // --- runoff or reporting time steps // (input is in hrs:min:sec format, time step saved as seconds) case WET_STEP: case DRY_STEP: case REPORT_STEP: if ( !datetime_strToTime(s2, &aTime) ) { return error_setInpError(ERR_DATETIME, s2); } datetime_decodeTime(aTime, &h, &m, &s); h += 24*(int)aTime; s = s + 60*m + 3600*h; if ( s <= 0 ) return error_setInpError(ERR_NUMBER, s2); switch ( k ) { case WET_STEP: WetStep = s; break; case DRY_STEP: DryStep = s; break; case REPORT_STEP: ReportStep = s; break; } break; // --- type of damping applied to inertial terms of dynamic wave routing case INERT_DAMPING: m = findmatch(s2, InertDampingWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); else InertDamping = m; break; // --- Yes/No options (NO = 0, YES = 1) case ALLOW_PONDING: case SLOPE_WEIGHTING: case SKIP_STEADY_STATE: case IGNORE_RAINFALL: case IGNORE_SNOWMELT: case IGNORE_GWATER: case IGNORE_ROUTING: case IGNORE_QUALITY: case IGNORE_RDII: //(5.1.004) m = findmatch(s2, NoYesWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); switch ( k ) { case ALLOW_PONDING: AllowPonding = m; break; case SLOPE_WEIGHTING: SlopeWeighting = m; break; case SKIP_STEADY_STATE: SkipSteadyState = m; break; case IGNORE_RAINFALL: IgnoreRainfall = m; break; case IGNORE_SNOWMELT: IgnoreSnowmelt = m; break; case IGNORE_GWATER: IgnoreGwater = m; break; case IGNORE_ROUTING: IgnoreRouting = m; break; case IGNORE_QUALITY: IgnoreQuality = m; break; case IGNORE_RDII: IgnoreRDII = m; break; //(5.1.004) } break; case NORMAL_FLOW_LTD: m = findmatch(s2, NormalFlowWords); if ( m < 0 ) m = findmatch(s2, NoYesWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); NormalFlowLtd = m; break; case FORCE_MAIN_EQN: m = findmatch(s2, ForceMainEqnWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); ForceMainEqn = m; break; case LINK_OFFSETS: m = findmatch(s2, LinkOffsetWords); if ( m < 0 ) return error_setInpError(ERR_KEYWORD, s2); LinkOffsets = m; break; // --- compatibility option for selecting solution method for // dynamic wave flow routing (NOT CURRENTLY USED) case COMPATIBILITY: if ( strcomp(s2, "3") ) Compatibility = SWMM3; else if ( strcomp(s2, "4") ) Compatibility = SWMM4; else if ( strcomp(s2, "5") ) Compatibility = SWMM5; else return error_setInpError(ERR_KEYWORD, s2); break; // --- routing or lengthening time step (in decimal seconds) // (lengthening time step is used in Courant stability formula // to artificially lengthen conduits for dynamic wave flow routing // (a value of 0 means that no lengthening is used)) case ROUTE_STEP: case LENGTHENING_STEP: if ( !getDouble(s2, &tStep) ) { if ( !datetime_strToTime(s2, &aTime) ) { return error_setInpError(ERR_NUMBER, s2); } else { datetime_decodeTime(aTime, &h, &m, &s); h += 24*(int)aTime; s = s + 60*m + 3600*h; tStep = s; } } if ( k == ROUTE_STEP ) { if ( tStep <= 0.0 ) return error_setInpError(ERR_NUMBER, s2); RouteStep = tStep; } else LengtheningStep = MAX(0.0, tStep); break; // --- safety factor applied to variable time step estimates under // dynamic wave flow routing (value of 0 indicates that variable // time step option not used) case VARIABLE_STEP: if ( !getDouble(s2, &CourantFactor) ) return error_setInpError(ERR_NUMBER, s2); if ( CourantFactor < 0.0 || CourantFactor > 2.0 ) return error_setInpError(ERR_NUMBER, s2); break; // --- minimum surface area (ft2 or sq. meters) associated with nodes // under dynamic wave flow routing case MIN_SURFAREA: MinSurfArea = atof(s2); break; // --- minimum conduit slope (%) case MIN_SLOPE: if ( !getDouble(s2, &MinSlope) ) return error_setInpError(ERR_NUMBER, s2); if ( MinSlope < 0.0 || MinSlope >= 100 ) return error_setInpError(ERR_NUMBER, s2); MinSlope /= 100.0; break; // --- maximum trials / time step for dynamic wave routing case MAX_TRIALS: m = atoi(s2); if ( m < 0 ) return error_setInpError(ERR_NUMBER, s2); MaxTrials = m; break; // --- head convergence tolerance for dynamic wave routing case HEAD_TOL: if ( !getDouble(s2, &HeadTol) ) { return error_setInpError(ERR_NUMBER, s2); } break; // --- steady state tolerance on system inflow - outflow case SYS_FLOW_TOL: if ( !getDouble(s2, &SysFlowTol) ) { return error_setInpError(ERR_NUMBER, s2); } SysFlowTol /= 100.0; break; // --- steady state tolerance on nodal lateral inflow case LAT_FLOW_TOL: if ( !getDouble(s2, &LatFlowTol) ) { return error_setInpError(ERR_NUMBER, s2); } LatFlowTol /= 100.0; break; case TEMPDIR: // Temporary Directory sstrncpy(TempDir, s2, MAXFNAME); break; } return 0; }
int addPremise(int r, int type, char* tok[], int nToks) // // Input: r = control rule index // type = type of premise (IF, AND, OR) // tok = array of string tokens containing premise statement // nToks = number of string tokens // Output: returns an error code // Purpose: adds a new premise to a control rule. // { int node = -1; int link = -1; int obj, attrib, op, n; double value; struct TPremise* p; // --- check for proper number of tokens if ( nToks < 5 ) return ERR_ITEMS; // --- get object type obj = findmatch(tok[1], ObjectWords); if ( obj < 0 ) return error_setInpError(ERR_KEYWORD, tok[1]); // --- get object name n = 2; switch (obj) { case r_NODE: node = project_findObject(NODE, tok[n]); if ( node < 0 ) return error_setInpError(ERR_NAME, tok[n]); break; case r_LINK: case r_PUMP: case r_ORIFICE: case r_WEIR: case r_OUTLET: link = project_findObject(LINK, tok[n]); if ( link < 0 ) return error_setInpError(ERR_NAME, tok[n]); break; default: n = 1; } n++; // --- get attribute name attrib = findmatch(tok[n], AttribWords); if ( attrib < 0 ) return error_setInpError(ERR_KEYWORD, tok[n]); // --- check that property belongs to object type if ( obj == r_NODE ) switch (attrib) { case r_DEPTH: case r_HEAD: case r_INFLOW: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else if ( obj == r_LINK ) switch (attrib) { case r_DEPTH: case r_FLOW: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else if ( obj == r_PUMP ) switch (attrib) { case r_FLOW: case r_STATUS: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else if ( obj == r_ORIFICE || obj == r_WEIR || obj == r_OUTLET ) switch (attrib) //(5.0.010 - LR) { case r_SETTING: break; default: return error_setInpError(ERR_KEYWORD, tok[n]); } else switch (attrib) { case r_TIME: case r_DATE: case r_CLOCKTIME: //(5.0.014 - LR) case r_DAY: //(5.0.014 - LR) case r_MONTH: break; //(5.0.014 - LR) default: return error_setInpError(ERR_KEYWORD, tok[n]); } // --- get operand n++; op = findExactMatch(tok[n], OperandWords); if ( op < 0 ) return error_setInpError(ERR_KEYWORD, tok[n]); n++; if ( n >= nToks ) return error_setInpError(ERR_ITEMS, ""); // --- get value switch (attrib) { case r_STATUS: value = findmatch(tok[n], StatusWords); if ( value < 0.0 ) return error_setInpError(ERR_KEYWORD, tok[n]); break; case r_TIME: case r_CLOCKTIME: if ( !datetime_strToTime(tok[n], &value) ) return error_setInpError(ERR_DATETIME, tok[n]); break; case r_DATE: if ( !datetime_strToDate(tok[n], &value) ) return error_setInpError(ERR_DATETIME, tok[n]); break; case r_DAY: if ( !getDouble(tok[n], &value) ) //(5.0.014 - LR) return error_setInpError(ERR_NUMBER, tok[n]); //(5.0.014 - LR) if ( value < 1.0 || value > 7.0 ) //(5.0.014 - LR) return error_setInpError(ERR_DATETIME, tok[n]); //(5.0.014 - LR) break; //(5.0.014 - LR) case r_MONTH: //(5.0.014 - LR) if ( !getDouble(tok[n], &value) ) //(5.0.014 - LR) return error_setInpError(ERR_NUMBER, tok[n]); //(5.0.014 - LR) if ( value < 1.0 || value > 12.0 ) //(5.0.014 - LR) return error_setInpError(ERR_DATETIME, tok[n]); //(5.0.014 - LR) break; //(5.0.014 - LR) default: if ( !getDouble(tok[n], &value) ) return error_setInpError(ERR_NUMBER, tok[n]); } // --- check if another clause is on same line //(5.0.010 - LR) n++; //(5.0.010 - LR) if ( n < nToks && findmatch(tok[n], RuleKeyWords) >= 0 ) return ERR_RULE; //(5.0.010 - LR) // --- create the premise object p = (struct TPremise *) malloc(sizeof(struct TPremise)); if ( !p ) return ERR_MEMORY; p->type = type; p->node = node; p->link = link; p->attribute = attrib; p->operand = op; p->value = value; p->next = NULL; if ( Rules[r].firstPremise == NULL ) { Rules[r].firstPremise = p; } else { Rules[r].lastPremise->next = p; } Rules[r].lastPremise = p; return 0; }
int table_parseFileLine(char* line, TTable* table, double* x, double* y) // // Input: table = pointer to a TTable structure // x = pointer to a date (as decimal days) // y = pointer to a time series value // Output: updates values of x and y; // returns -1 if line was a comment, // TRUE if line successfully parsed, // FALSE if line could not be parsed // Purpose: parses a line of time series data from an external file. // { int n; char s1[50], s2[50], s3[50]; char* tStr; // time as string char* yStr; // value as string double yy; // value as double DateTime d; // day portion of date/time value DateTime t; // time portion of date/time value // --- get 3 string tokens from line and check if its a comment n = sscanf(line, "%s %s %s", s1, s2, s3); // --- return if line is blank or is a comment tStr = strtok(line, SEPSTR); if ( tStr == NULL || *tStr == ';' ) return -1; // --- line only has a time and a value if ( n == 2 ) { // --- calendar date is same as last recorded date d = table->lastDate; tStr = s1; yStr = s2; } // --- line has date, time and a value else if ( n == 3 ) { // --- convert date string to numeric value if ( !datetime_strToDate(s1, &d) ) return FALSE; // --- update last recorded calendar date table->lastDate = d; tStr = s2; yStr = s3; } else return FALSE; // --- convert time string to numeric value if ( getDouble(tStr, &t) ) t /= 24.0; else if ( !datetime_strToTime(tStr, &t) ) return FALSE; // --- convert value string to numeric value if ( !getDouble(yStr, &yy) ) return FALSE; // --- assign values to current date and value *x = d + t; *y = yy; return TRUE; }
int table_readTimeseries(char* tok[], int ntoks) // // Input: tok[] = array of string tokens // ntoks = number of tokens // Output: returns an error code // Purpose: reads a tokenized line of data for a time series table. // { int j; // time series index int k; // token index int state; // 1: next token should be a date // 2: next token should be a time // 3: next token should be a value double x, y; // time & value table entries DateTime d; // day portion of date/time value DateTime t; // time portion of date/time value // --- check for minimum number of tokens if ( ntoks < 3 ) return error_setInpError(ERR_ITEMS, ""); // --- check that time series exists in database j = project_findObject(TSERIES, tok[0]); if ( j < 0 ) return error_setInpError(ERR_NAME, tok[0]); // --- if first line of data, assign ID pointer if ( Tseries[j].ID == NULL ) Tseries[j].ID = project_findID(TSERIES, tok[0]); // --- check if time series data is in an external file if ( strcomp(tok[1], w_FILE ) ) { sstrncpy(Tseries[j].file.name, tok[2], MAXFNAME); Tseries[j].file.mode = USE_FILE; return 0; } // --- parse each token of input line x = 0.0; k = 1; state = 1; // start off looking for a date while ( k < ntoks ) { switch(state) { case 1: // look for a date entry if ( datetime_strToDate(tok[k], &d) ) { Tseries[j].lastDate = d; k++; } // --- next token must be a time state = 2; break; case 2: // look for a time entry if ( k >= ntoks ) return error_setInpError(ERR_ITEMS, ""); // --- first check for decimal hours format if ( getDouble(tok[k], &t) ) t /= 24.0; // --- then for an hrs:min format else if ( !datetime_strToTime(tok[k], &t) ) return error_setInpError(ERR_NUMBER, tok[k]); // --- save date + time in x x = Tseries[j].lastDate + t; // --- next token must be a numeric value k++; state = 3; break; case 3: // --- extract a numeric value from token if ( k >= ntoks ) return error_setInpError(ERR_ITEMS, ""); if ( ! getDouble(tok[k], &y) ) return error_setInpError(ERR_NUMBER, tok[k]); // --- add date/time & value to time series table_addEntry(&Tseries[j], x, y); // --- start over looking first for a date k++; state = 1; break; } } return 0; }