Saturday, December 28, 2024

SWMM5 swmm_output.c Summary

 Below is a step‐by‐step explanation of how swmm_output.c works. It is a C library that reads from a SWMM (Storm Water Management Model) binary output file, providing functions to:

  1. Open/Close the output file,
  2. Retrieve metadata (time steps, units, number of elements), and
  3. Extract time‐series or snapshot data (for subcatchments, nodes, links, and system).

It also manages an error mechanism via errormanager.h.


1. Purpose

/*
 * swmm_output.c - SWMM Output API
 *
 *  Author: Colleen Barr, ...
 *  Modified by: Michael E. Tryby, Bryant McDonnell
 */

This file defines a higher‐level API for reading SWMM’s binary results. A SWMM run produces a file containing flows, depths, water quality, etc. This API:

  • Opens that file,
  • Verifies it’s a valid SWMM output file,
  • Reads the internal file structure (metadata, offsets),
  • Retrieves data for subcatchments, nodes, links, pollutants, system variables, etc.

The main interface is via an opaque handle (SMO_Handle), which the library user requests and manipulates through the various SMO_* functions.


2. Data Structures

2.1 data_t

An internal struct that holds:

  1. File Info: path, FILE* file,
  2. Element Info: Nsubcatch, Nnodes, Nlinks, Npolluts, number of time periods Nperiods, etc.
  3. Positions/Offsets: for file sections (object IDs, results, etc.).
  4. An array elementNames storing strings for each subcatch/node/link/pollut.
  5. An embedded error_handle_t used for error management.

This struct is not exposed externally. Instead, callers see a SMO_Handle pointer (which is cast to data_t* internally).

2.2 File Format Constants

  • INT4, REAL4: 32-bit int/float types.
  • F_OFF: 64-bit integer type for large file support (off_t or __int64).
  • RECORDSIZE 4: data is stored in 4-byte increments for integers or floats.
  • DATESIZE 8: date/time is stored in an 8-byte double.
  • NELEMENTTYPES 5: subcatch, node, link, system, pollutant sets?

3. Key Functions

3.1 Initialization / Cleanup

  1. SMO_init(SMO_Handle *p_handle)

    • Allocates a data_t*, zero‐initialized with calloc.
    • Creates an error_handle_t by calling new_errormanager(&errorLookup).
    • Returns 0 if successful, -1 if allocation fails.
  2. SMO_close(SMO_Handle* p_handle)

    • Frees resources in data_t.
    • Closes the file if open, frees elementNames[], calls dst_errormanager, then frees data_t.
    • Sets the user’s *p_handle = NULL.

3.2 Opening the SWMM Output File

int SMO_open(SMO_Handle p_handle, const char *path)
{
    ...
    // open file in "rb" mode
    // call validateFile(p_data)
    // read essential metadata from the file header
    ...
}
  • validateFile() checks:
    • The “magic number” at start/end,
    • Nperiods is > 0,
    • an error code from the run in the file epilogue.
  • Reads counts of subcatchments, nodes, links, pollutants, plus offset positions in the file (IDPos, ObjPropPos, ResultsPos).
  • Also reads StartDate, ReportStep, and calculates BytesPerPeriod.

3.3 Retrieving Version, Units, Project Size

  • SMO_getVersion(...)
    • Reads integer in file near offset 2 * RECORDSIZE, which indicates SWMM version (like 52000).
  • SMO_getProjectSize(...)
    • Returns an array of counts: [Nsubcatch, Nnodes, Nlinks, 1, Npolluts].
  • SMO_getUnits(...) or SMO_getFlowUnits(...)
    • Gets integer code for flow units (CFS, GPM, etc.), and sets if the system is US or SI.
  • SMO_getPollutantUnits(...)
    • Retrieves concentration units for each pollutant (mg/L, ug/L, etc.).

3.4 Getting Time Steps

  • SMO_getTimes(...) can query:
    • SMO_reportStep: reporting time step in seconds,
    • SMO_numPeriods: total number of reported periods (Nperiods).

3.5 Getting Element Names

  • SMO_getElementName(...)
    • If p_data->elementNames is not yet built, calls initElementNames().
      • initElementNames() reads from IDPos in the file, for each object a 4‐byte length, followed by that many characters.
    • Depending on type (subcatch, node, link, pollut), it picks the correct index in elementNames[].
    • Allocates a buffer for the name.

3.6 Extracting Time Series

  • SMO_getSubcatchSeries(...) / SMO_getNodeSeries(...) / SMO_getLinkSeries(...) / SMO_getSystemSeries(...):
    • Return arrays of data for a particular object over a range of time indices (startPeriod to endPeriod).
    • Internally loops from k = 0 to len, calling getSubcatchValue(...) or getNodeValue(...), etc.

3.7 Snapshot Data (Single Period, Many Elements)

  • SMO_getSubcatchAttribute(...) for a single period and all subcatchments.
  • SMO_getNodeAttribute(...) for a single period and all nodes, etc.
  • Also variants for SMO_getLinkAttribute(...) and SMO_getSystemAttribute(...).

3.8 Low-Level Readers: getSubcatchValue(...), getNodeValue(...), etc.

These functions compute an offset in the output file that depends on:

  1. The current time period (timeIndex).
  2. The element’s index and variable code.
  3. The known layout (BytesPerPeriod, subcatch/node/link count, etc.).

They call:

_fseek(p_data->file, offset, SEEK_SET);
fread(&value, RECORDSIZE, 1, p_data->file);

to read a single float from the file.


4. Additional Utility

  • SMO_free(void **array): A convenience function to free memory allocated by the library for arrays (like time series). Sets pointer to NULL.
  • _fopen, _fseek, _ftell: Wrappers ensuring large file support or cross‐platform differences.

5. Error Handling

The code uses set_error(...) to store an integer code in p_data->error_handle->error_status (like 411, 422, 423, etc.). Then:

  • SMO_checkError(...) retrieves that code and calls check_error(...) (which returns a message string).
  • SMO_clearError(...) resets the code to 0.

errorLookup(...) is the local function mapping an error code to a message constant from messages.h.


6. Summary

swmm_output.c is a self-contained library to:

  1. Open a SWMM results file (binary),
  2. Check basic validity,
  3. Provide convenient functions to get metadata (counts, units, times),
  4. Read time series or snapshot data for subcatchments, nodes, links, pollutants, system,
  5. Return data as arrays of floats or single floats,
  6. Manage errors with an internal mechanism.

Hence, it abstracts the SWMM binary file format details away from the user, offering a simpler API for post-processing or analyzing SWMM results programmatically.

No comments:

SWMM5 Delphi GUI Dbackdrp.pas Summary

 The Dbackdrp unit provides a dialog form for selecting a backdrop image for the study area map within the SWMM (Storm Water Management Mod...