Below is a step‐by‐step explanation of gage.c
, which implements rain gage functions in EPA SWMM5. A rain gage in SWMM is an object that provides rainfall data (either from a time series or external file) for one or more subcatchments. This file tracks:
- Gage parameters (data source, units, data intervals).
- Recorded rainfall (both current and historical).
- Updates to rainfall at each time step.
1. Purpose and Context
// gage.c
// Rain gage functions.
//
// Update History ...
-
This file is part of the runoff or global modules, providing the interface for reading and storing rainfall data from either:
- A time series (in
.inp
file or from external time series definitions), or - A rainfall interface file (binary data file).
- A time series (in
-
The main public functions declared in
headers.h
and defined here are:gage_readParams
: parse input line for a gage.gage_validate
: checks correctness.gage_initState
: initializes gage states.gage_setState
: sets current rainfall at a certain time.gage_getPrecip
: returns the rainfall (and whether it's rain or snow).gage_getNextRainDate
: next date/time with non-zero rainfall.gage_updatePastRain
: maintains an array of previous hours' rainfall totals.gage_getPastRain
: retrieves the N-hour rainfall total.gage_setReportRainfall
: sets the gage’s rainfall specifically for reporting.
2. Data Flow
- Each
Gage[j]
object has fields like:dataSource
:RAIN_TSERIES
orRAIN_FILE
.rainType
:RAINFALL_INTENSITY
,RAINFALL_VOLUME
, orCUMULATIVE_RAINFALL
.rainInterval
: recording interval (seconds).rainfall
: the current rainfall intensity (in/hr or mm/hr).apiRainfall
: rainfall that might have been directly set via an API call (bypasses default reading).startDate
,endDate
: the start and end times of the current rainfall record.nextDate
,nextRainfall
: the next rainfall record after the current interval, etc.
3. Reading Gage Parameters
3.1 gage_readParams(j, tok, ntoks)
int gage_readParams(int j, char* tok[], int ntoks)
-
Parses a line from the SWMM input file describing a gage’s configuration, storing the values in
Gage[j]
. -
The data format can be:
- Time Series:
GageID RainType RecdFreq SCF TIMESERIES TSeriesName
- File:
GageID RainType RecdFreq SCF FILE FileName Station Units StartDate
- Time Series:
-
The function delegates to either:
readGageSeriesFormat(...)
(forTIMESERIES
lines),readGageFileFormat(...)
(forFILE
lines).
Key fields:
rainType
can be:RAINFALL_INTENSITY
,RAINFALL_VOLUME
, orCUMULATIVE_RAINFALL
.
rainInterval
= how often data is recorded (seconds).snowFactor
= an adjustment factor for snowfall catch deficiency.rainUnits
= US or SI units for file-based gages.
3.2 readGageSeriesFormat(tok, ntoks, x[])
static int readGageSeriesFormat(char* tok[], int ntoks, double x[])
- Handles time series format lines.
- Looks up the type of rainfall from
RainTypeWords
. - Converts the user’s input of
RecdFreq
into seconds. - Finds the time series index for the name
tok[5]
.
3.3 readGageFileFormat(tok, ntoks, x[])
static int readGageFileFormat(char* tok[], int ntoks, double x[])
- For lines referencing an external Rainfall file.
- Also sets start/end date for the file if provided.
- The user can supply:
Station ID
,Units
(like “IN” or “MM”),StartDate
(the earliest date to read from file).
4. Validation: gage_validate(j)
- For a gage that’s not used by any subcatchment (
isUsed == FALSE
), no checks are done. - If it uses a time series that’s also used by another gage, we set
coGage
so they share the same data. - If intervals mismatch or are bigger than time series intervals, we produce warnings/errors.
5. Initialization: gage_initState(j)
void gage_initState(int j)
- Called at simulation start:
- If
IgnoreRainfall = TRUE
, setsrainfall=0.0
. - If
RAIN_FILE
, sets file pointer to the start of record, setsunitsFactor
if needed, etc. getFirstRainfall(j)
: obtains the first date & rainfall record from the time series or file.- If the first record starts after
StartDateTime
, adjusts accordingly. - Calls
initPastRain(j)
to reset the past hour accumulation array.
- If
6. Updating Rainfall: gage_setState(j, t)
void gage_setState(int j, DateTime t)
- Called each step to update the gage’s rainfall at time
t
. - If
coGage >= 0
, just copy that gage’s rainfall. - If the user’s code set
apiRainfall
, use that. - Otherwise, we compare
t
to the current interval[startDate, endDate]
.- If
t < startDate
=> 0.0 rainfall, - If
startDate <= t < endDate
=> samerainfall
, - If
t >= endDate
=> shift to the next interval by callinggetNextRainfall(j)
, etc.
- If
7. Past Hourly Rainfall: gage_updatePastRain
& gage_getPastRain
-
gage_updatePastRain(j, tStep)
:- The current rainfall intensity is
Gage[j].rainfall / 3600.
( ft or mm per second). - It accumulates partial amounts in
pastRain[]
array, each entry representing an hour’s total. - If
pastInterval
has reached 3600 seconds, shift the array by 1 hour.
- The current rainfall intensity is
-
gage_getPastRain(j, n)
:- Returns sum of the past
n
hours of rainfall from thepastRain[]
array.
- Returns sum of the past
This supports logic like control rules that might require “past 6-hour rainfall total.”
8. Next Rain Date: gage_getNextRainDate(j, aDate)
DateTime gage_getNextRainDate(int j, DateTime aDate)
- Returns the date/time after
aDate
when the next rainfall interval starts. - If
coGage >= 0
, the co-gage’s next date is used.
9. Retrieving Actual or Reported Rain
-
gage_getPrecip(j, &rainfall, &snowfall)
:- Distinguishes rain vs. snow. If
Temp.ta <= Snow.snotmp
, we treat it as snow timessnowFactor
; else it’s rain. - The total precipitation is
(rainfall + snowfall)
in ft/sec or mm/sec.
- Distinguishes rain vs. snow. If
-
gage_setReportRainfall(j, reportDate)
:- For writing results. If
coGage >= 0
, again copy. If we are exactly on the boundary between intervals, we might use the “next” rainfall. - Or if the user set an API rainfall, that’s used.
- For writing results. If
10. Internal Routines
10.1 initPastRain(j)
- Zeros out the
Gage[j].pastRain[]
array and setspastInterval=0
.
10.2 getFirstRainfall(j)
& getNextRainfall(j)
- For the first/next record from:
- A file: read
DateTime
andfloat volume
fromFrain.file
. Convert to in/hr or mm/hr. - A time series: from
Tseries[k]
.
- A file: read
- Skips zero rainfall records (for
getNextRainfall
) so we can keep distinct intervals for real wet/dry transitions.
10.3 convertRainfall(j, r)
- Switches on
rainType
:RAINFALL_INTENSITY
=> no transformation.RAINFALL_VOLUME
=> convert total volume to intensity =(volume / interval) * 3600
.CUMULATIVE_RAINFALL
=> difference from last accumulation is the new volume.
- Multiplies by
unitsFactor
if in metric and also a globalAdjust.rainFactor
.
11. Summary
gage.c
handles:
- Reading gage definitions from the SWMM input file (time series or external file).
- Initialization and per-step updates of rainfall states.
- Distinguishing rain vs. snow.
- Managing past hourly rainfall accumulation arrays.
It ensures each subcatchment referencing a gage sees the correct rainfall for that step, optionally referencing the same time series or file as other gages.
No comments:
Post a Comment