int datetime_strToTime(char* s, DateTime* t) // Input: s = time as string // Output: t = encoded time, // returns 1 if conversion successful, 0 if not // Purpose: converts a string time to a DateTime value. // Note: accepts time as hr:min:sec or as decimal hours. { int n, hr, min = 0, sec = 0; char *endptr; // Attempt to read time as decimal hours *t = strtod(s, &endptr); if ( *endptr == 0 ) { *t /= 24.0; return 1; } // Read time in hr:min:sec format *t = 0.0; n = sscanf(s, "%d:%d:%d", &hr, &min, &sec); if ( n == 0 ) return 0; *t = datetime_encodeTime(hr, min, sec); if ( (hr >= 0) && (min >= 0) && (sec >= 0) ) return 1; else return 0; }
void readRdiiFlows() // // Input: none // Output: none // Purpose: reads date and flow values of next RDII inflows from RDII file. // { int i, n; int yr = 0, mon = 0, day = 0, hr = 0, min = 0, sec = 0; // year, month, day, hour, minute, second float x; // RDII flow in original units char line[MAXLINE+1]; // line from RDII data file char s[MAXLINE+1]; // node ID label (not used) RdiiStartDate = NO_DATE; for (i=0; i<NumRdiiNodes; i++) { if ( feof(Frdii.file) ) return; fgets(line, MAXLINE, Frdii.file); n = sscanf(line, "%s %d %d %d %d %d %d %f", s, &yr, &mon, &day, &hr, &min, &sec, &x); if ( n < 8 ) return; RdiiNodeFlow[i] = x / Qcf[RdiiFlowUnits]; } RdiiStartDate = datetime_encodeDate(yr, mon, day) + datetime_encodeTime(hr, min, sec); RdiiEndDate = datetime_addSeconds(RdiiStartDate, RdiiStep); }
void readNewIfaceValues() // // Input: none // Output: none // Purpose: reads data from inflows interface file for next date. // { int i, j; char* s; int yr = 0, mon = 0, day = 0, hr = 0, min = 0, sec = 0; // year, month, day, hour, minute, second char line[MAXLINE+1]; // line from interface file // --- read a line for each interface node NewIfaceDate = NO_DATE; for (i=0; i<NumIfaceNodes; i++) { if ( feof(Finflows.file) ) return; fgets(line, MAXLINE, Finflows.file); // --- parse date & time from line if ( strtok(line, SEPSTR) == NULL ) return; s = strtok(NULL, SEPSTR); if ( s == NULL ) return; yr = atoi(s); s = strtok(NULL, SEPSTR); if ( s == NULL ) return; mon = atoi(s); s = strtok(NULL, SEPSTR); if ( s == NULL ) return; day = atoi(s); s = strtok(NULL, SEPSTR); if ( s == NULL ) return; hr = atoi(s); s = strtok(NULL, SEPSTR); if ( s == NULL ) return; min = atoi(s); s = strtok(NULL, SEPSTR); if ( s == NULL ) return; sec = atoi(s); // --- parse flow value s = strtok(NULL, SEPSTR); if ( s == NULL ) return; NewIfaceValues[i][0] = atof(s) / Qcf[IfaceFlowUnits]; // --- parse pollutant values for (j=1; j<=NumIfacePolluts; j++) { s = strtok(NULL, SEPSTR); if ( s == NULL ) return; NewIfaceValues[i][j] = atof(s); } } // --- encode date & time values NewIfaceDate = datetime_encodeDate(yr, mon, day) + datetime_encodeTime(hr, min, sec); }
int readStdLine(Project* project, char *line, DateTime day1, DateTime day2) // // Input: line = line of data from a standard rainfall data file // day1 = starting day of record of interest // day2 = ending day of record of interest // Output: returns -1 if past end of desired record, 0 if data line could // not be read successfully or 1 if line read successfully // Purpose: reads a line of data from a standard rainfall data file and // writes its data to the rain interface file. // { DateTime date1; DateTime date2; int year, month, day, hour, minute; float x; // --- parse data from input line if (!parseStdLine(project,line, &year, &month, &day, &hour, &minute, &x)) return 0; // --- see if date is within period of record requested date1 = datetime_encodeDate(year, month, day); if ( day1 != NO_DATE && date1 < day1 ) return 0; if ( day2 != NO_DATE && date1 > day2 ) return -1; // --- see if record is out of sequence date2 = date1 + datetime_encodeTime(hour, minute, 0); if ( date2 <= project->PreviousDate ) { report_writeErrorMsg(project,ERR_RAIN_FILE_SEQUENCE, project->Gage[project->GageIndex].fname); //(5.1.010) report_writeLine(project,line); return -1; } project->PreviousDate = date2; switch (project->RainType) { case RAINFALL_INTENSITY: x = x * project->Interval / 3600.0f; break; case CUMULATIVE_RAINFALL: if ( x >= project->RainAccum ) { x = x - project->RainAccum; project->RainAccum += x; } else project->RainAccum = x; break; } x *= (float)project->UnitsFactor; // --- save rainfall to binary interface file saveRainfall(project, date1, hour, minute, x, FALSE); return 1; }
void saveAccumRainfall(Project* project, DateTime date1, int hour, int minute, long v) // // Input: date1 = date of latest rainfall reading (in DateTime format) // hour = hour of day of latest rain reading // minute = minute of hour of latest rain reading // v = accumulated rainfall reading in hundreths of inches // Output: none // Purpose: divides accumulated rainfall evenly into individual recording // periods over the accumulation period and writes each period's // rainfall to the binary rainfall file. // { DateTime date2; int n, j; float x; // --- return if accumulated start date is missing if ( project->AccumStartDate == NO_DATE ) return; // --- find number of recording intervals over accumulation period date2 = date1 + datetime_encodeTime(hour, minute, 0); n = (datetime_timeDiff(date2, project->AccumStartDate) / project->Interval) + 1; // --- update count of rain or missing periods if ( v == 99999 ) { project->RainStats.periodsMissing += n; return; } project->RainStats.periodsRain += n; // --- divide accumulated amount evenly into each period x = (float)v / (float)n / 100.0f; // --- save this amount to file for each period if ( x > 0.0f ) { date2 = datetime_addSeconds(project->AccumStartDate, -project->TimeOffset); if ( project->RainStats.startDate == NO_DATE ) project->RainStats.startDate = date2; for (j = 0; j < n; j++) { fwrite(&date2, sizeof(DateTime), 1, project->Frain.file); fwrite(&x, sizeof(float), 1, project->Frain.file); date2 = datetime_addSeconds(date2, project->Interval); project->RainStats.endDate = date2; } } // --- reset start of accumulation period project->AccumStartDate = NO_DATE; }
DateTime datetime_addDays(DateTime date1, DateTime date2) // Input: date1 = an encoded date/time value // date2 = decimal days to be added to date1 // Output: returns date1 + date2 // Purpose: adds a given number of decimal days to a date/time. { double d1 = floor(date1); double d2 = floor(date2); int h1, m1, s1; int h2, m2, s2; datetime_decodeTime(date1, &h1, &m1, &s1); datetime_decodeTime(date2, &h2, &m2, &s2); return d1 + d2 + datetime_encodeTime(h1+h2, m1+m2, s1+s2); }
int datetime_strToTime(char* s, DateTime* t) // Input: s = time as string // Output: t = encoded time, // returns 1 if conversion successful, 0 if not // Purpose: converts a string time to a DateTime value. { int n, hr, min = 0, sec = 0; *t = 0.0; n = sscanf(s, "%d:%d:%d", &hr, &min, &sec); if ( n == 0 ) return 0; *t = datetime_encodeTime(hr, min, sec); if ( (hr >= 0) && (min >= 0) && (sec >= 0) ) return 1; else return 0; }
void setDefaults() // // Input: none // Output: none // Purpose: assigns default values to project variables. // { int i, j; // Project title & temp. file path for (i = 0; i < MAXTITLE; i++) strcpy(Title[i], ""); strcpy(TempDir, ""); // Interface files Frain.mode = SCRATCH_FILE; // Use scratch rainfall file Fclimate.mode = NO_FILE; Frunoff.mode = NO_FILE; Frdii.mode = NO_FILE; Fhotstart1.mode = NO_FILE; Fhotstart2.mode = NO_FILE; Finflows.mode = NO_FILE; Foutflows.mode = NO_FILE; Frain.file = NULL; Fclimate.file = NULL; Frunoff.file = NULL; Frdii.file = NULL; Fhotstart1.file = NULL; Fhotstart2.file = NULL; Finflows.file = NULL; Foutflows.file = NULL; Fout.file = NULL; Fout.mode = NO_FILE; // Analysis options UnitSystem = US; // US unit system FlowUnits = CFS; // CFS flow units InfilModel = HORTON; // Horton infiltration method RouteModel = KW; // Kin. wave flow routing method AllowPonding = FALSE; // No ponding at nodes InertDamping = SOME; // Partial inertial damping NormalFlowLtd = BOTH; // Default normal flow limitation ForceMainEqn = H_W; // Hazen-Williams eqn. for force mains LinkOffsets = DEPTH_OFFSET; // Use depth for link offsets LengtheningStep = 0; // No lengthening of conduits CourantFactor = 0.0; // No variable time step MinSurfArea = 0.0; // Force use of default min. surface area SkipSteadyState = FALSE; // Do flow routing in steady state periods IgnoreRainfall = FALSE; // Analyze rainfall/runoff IgnoreRDII = FALSE; // Analyze RDII //(5.1.004) IgnoreSnowmelt = FALSE; // Analyze snowmelt IgnoreGwater = FALSE; // Analyze groundwater IgnoreRouting = FALSE; // Analyze flow routing IgnoreQuality = FALSE; // Analyze water quality WetStep = 300; // Runoff wet time step (secs) DryStep = 3600; // Runoff dry time step (secs) RouteStep = 300.0; // Routing time step (secs) ReportStep = 900; // Reporting time step (secs) StartDryDays = 0.0; // Antecedent dry days MaxTrials = 0; // Force use of default max. trials HeadTol = 0.0; // Force use of default head tolerance SysFlowTol = 0.05; // System flow tolerance for steady state LatFlowTol = 0.05; // Lateral flow tolerance for steady state // Deprecated options SlopeWeighting = TRUE; // Use slope weighting Compatibility = SWMM4; // Use SWMM 4 up/dn weighting method // Starting & ending date/time StartDate = datetime_encodeDate(2004, 1, 1); StartTime = datetime_encodeTime(0,0,0); StartDateTime = StartDate + StartTime; EndDate = StartDate; EndTime = 0.0; ReportStartDate = NO_DATE; ReportStartTime = NO_DATE; SweepStart = 1; SweepEnd = 365; // Reporting options RptFlags.input = FALSE; RptFlags.continuity = TRUE; RptFlags.flowStats = TRUE; RptFlags.controls = FALSE; RptFlags.subcatchments = FALSE; RptFlags.nodes = FALSE; RptFlags.links = FALSE; RptFlags.nodeStats = FALSE; // Temperature data Temp.dataSource = NO_TEMP; Temp.tSeries = -1; Temp.ta = 70.0; Temp.elev = 0.0; Temp.anglat = 40.0; Temp.dtlong = 0.0; Temp.tmax = MISSING; // Wind speed data Wind.type = MONTHLY_WIND; for ( i=0; i<12; i++ ) Wind.aws[i] = 0.0; // Snowmelt parameters Snow.snotmp = 34.0; Snow.tipm = 0.5; Snow.rnm = 0.6; // Snow areal depletion curves for pervious and impervious surfaces for ( i=0; i<2; i++ ) { for ( j=0; j<10; j++) Snow.adc[i][j] = 1.0; } // Evaporation rates Evap.type = CONSTANT_EVAP; for (i=0; i<12; i++) { Evap.monthlyEvap[i] = 0.0; Evap.panCoeff[i] = 1.0; } Evap.recoveryPattern = -1; Evap.recoveryFactor = 1.0; Evap.tSeries = -1; Evap.dryOnly = FALSE; //// Following code segment added to release 5.1.007. //// //(5.1.007) // Climate adjustments for (i = 0; i < 12; i++) { Adjust.temp[i] = 0.0; // additive adjustments Adjust.evap[i] = 0.0; // additive adjustments Adjust.rain[i] = 1.0; // multiplicative adjustments } Adjust.rainFactor = 1.0; }
int readNWSLine(Project* project, char *line, int fileFormat, DateTime day1, DateTime day2) // // Input: line = line of data from rainfall data file // fileFormat = code of data file's format // day1 = starting day of record of interest // day2 = ending day of record of interest // Output: returns -1 if past end of desired record, 0 if data line could // not be read successfully or 1 if line read successfully // Purpose: reads a line of data from a rainfall data file and writes its // data to the rain interface file. // { char flag1, flag2, isMissing; DateTime date1; long result = 1; int k, y, m, d, n; int hour, minute; long v; float x; int lineLength = strlen(line)-1; int nameLength = 0; // --- get year, month, & day from line switch ( fileFormat ) { case NWS_TAPE: if ( lineLength <= 30 ) return 0; if (sscanf(&line[17], "%4d%2d%4d%3d", &y, &m, &d, &n) < 4) return 0; k = 30; break; case NWS_SPACE_DELIMITED: if ( project->hasStationName ) nameLength = 31; if ( lineLength <= 28 + nameLength ) return 0; k = 18 + nameLength; if (sscanf(&line[k], "%4d %2d %2d", &y, &m, &d) < 3) return 0; k = k + 10; break; case NWS_COMMA_DELIMITED: if ( lineLength <= 28 ) return 0; if ( sscanf(&line[18], "%4d,%2d,%2d", &y, &m, &d) < 3 ) return 0; k = 28; break; case NWS_ONLINE_60: case NWS_ONLINE_15: if ( lineLength <= project->DataOffset + 23 ) return 0; if ( sscanf(&line[project->DataOffset], "%4d%2d%2d", &y, &m, &d) < 3 ) return 0; k = project->DataOffset + 8; break; default: return 0; } // --- see if date is within period of record requested date1 = datetime_encodeDate(y, m, d); if ( day1 != NO_DATE && date1 < day1 ) return 0; if ( day2 != NO_DATE && date1 > day2 ) return -1; // --- read each recorded rainfall time, value, & codes from line while ( k < lineLength ) { flag1 = 0; flag2 = 0; v = 99999; hour = 25; minute = 0; switch ( fileFormat ) { case NWS_TAPE: n = sscanf(&line[k], "%2d%2d%6ld%c%c", &hour, &minute, &v, &flag1, &flag2); k += 12; break; case NWS_SPACE_DELIMITED: n = sscanf(&line[k], " %2d%2d %6ld %c %c", &hour, &minute, &v, &flag1, &flag2); k += 16; break; case NWS_COMMA_DELIMITED: n = sscanf(&line[k], ",%2d%2d,%6ld,%c,%c", &hour, &minute, &v, &flag1, &flag2); k += 16; break; case NWS_ONLINE_60: case NWS_ONLINE_15: n = sscanf(&line[k], " %2d:%2d", &hour, &minute); n += sscanf(&line[project->ValueOffset], "%8ld %c", &v, &flag1); // --- ending hour 0 is really hour 24 of previous day if ( hour == 0 ) { hour = 24; date1 -= 1.0; } k += lineLength; break; default: n = 0; } // --- check that we at least have an hour, minute & value // (codes might be left off of the line) if ( n < 3 || hour >= 25 ) break; // --- set special condition code & update daily & hourly counts setCondition(project,flag1); if ( project->Condition == DELETED_PERIOD || project->Condition == MISSING_PERIOD || flag1 == 'M' ) isMissing = TRUE; else if ( v >= 9999 ) isMissing = TRUE; else isMissing = FALSE; // --- handle accumulation codes if ( flag1 == 'a' ) { project->AccumStartDate = date1 + datetime_encodeTime(hour, minute, 0); } else if ( flag1 == 'A' ) { saveAccumRainfall(project,date1, hour, minute, v); } // --- handle all other conditions else { // --- convert rain measurement to inches & save it x = (float)v / 100.0f; if ( x > 0 || isMissing ) saveRainfall(project,date1, hour, minute, x, isMissing); } // --- reset condition code if special condition period ended if ( flag1 == 'A' || flag1 == '}' || flag1 == ']') project->Condition = 0; } return result; }