IED Class#

Summary#

The IED class is used to read, write and update Flood Modeller’s ied file format. The class can be initiated with the full filepath of an ied file to load an existing ied, or with no path to create a new ied file in memory.

from floodmodeller_api import IED

ied = IED('path/to/event.ied') # Loads existing IED into memory
new_ied = IED() # Used to create new 'blank' IEF

Once you have initialised an IED class, the individual boundary units will be accessible as a dictionary in the .boundaries attribute:

# Print string representation of all boundary units.
print(ied.boundaries)

# Print each individual boundary unit name
for name, unit in ied.boundaries.items():
    print (name)

Tip

If present, other units are accessible in the .sections, .conduits, .structures and .losses attributes respectively - see DAT section for more information on working with these unit types.

Each boundary unit class will typically contain all parameters as class attributes, plus the main data table saved in .data as a pandas.Series(). These can all be updated directly, and will be reflected in the IED file after calling IED.update() or IED.save(). For example, to access the flow-time data for a QTBDY unit you could run:

# Access the boundary units available in IED class object 'ied', with the name 'inflow_1'
ied.boundaries['inflow_1']
>>> <floodmodeller_api Unit Class: QTBDY(name=qflow_new)>

type(ied.boundaries['inflow_1']) # You can test the type to ensure it is a QTBDY unit
>>> <_class 'units.QTBDY'>

ied.boundaries['inflow_1'].data # Flow data can be accessed via the 'data' attribute
>>> Time
    0.0   0.0
    1.0   0.5
    2.0   2.0
    3.0   4.5
    4.0   8.0
    5.0  12.5
    6.0  18.0
    7.0  24.5
    8.0  32.0
    9.0  40.5
    Name: Flow, Length: 10, dtype: float64

If the name of a unit is updated using the .name attribute, when the class is next updated the unit will then only be accessible using the updated name within the boundaries dictionary object.

Individual units can be deleted entirely by calling:

del ied.boundaries['inflow_1'] # Specificy name of unit to delete

New units can also be created and/or added into an IED by simply adding a new element to the boundaries dictionary using the name as the key and a valid unit class as the element. For example to add a brand new blank HTBDY into an ied, you could run:

new_htbdy = HTBDY(name='ds_bdy') # Initialises a new HTBDY unit with name 'ds_bdy'
ied.boundaries['ds_bdy'] = new_htbdy # Add new element to boundaries dictionary

Tip

Full details on all the various boundary unit classes can be found in the Boundary units section.

You can get all of the units currently unsupported by the api that have been read in from the ied file:

ied._unsupported
>>> {
        <floodmodeller_api Unit Class: FSSR16BDY(name=resin, type=False)>
    }

Or if you want to get both supported & unsupported units:

ied._all_units
>>> {
        <floodmodeller_api Unit Class: FSSR16BDY(name=resin, type=False)>,
        <floodmodeller_api Unit Class: QTBDY(name=CS26)>,
        <floodmodeller_api Unit Class: QHBDY(name=DS4)>
    }

Reference#

class floodmodeller_api.IED(ied_filepath: str | Path | None = None, from_json: bool = False)#

Reads and write Flood Modeller event data format ‘.ied’ :param ied_filepath: Full filepath to ied file. If not specified, a new IED class will be created. :type ied_filepath: str, optional

Output:

Initiates ‘IED’ class object

Raises:
  • TypeError – Raised if ied_filepath does not point to a .ied file

  • FileNotFoundError – Raised if ied_filepath points to a file which does not exist

update() None#

Updates the existing IED based on any altered attributes

save(filepath: str | Path) None#

Saves the IED to the given location, if pointing to an existing file it will be overwritten. Once saved, the IED() class will continue working from the saved location, therefore any further calls to IED.update() will update in the latest saved location rather than the original source IED used to construct the class

diff(other: IED, force_print: bool = False) None#

Compares the IED class against another IED class to check whether they are equivalent, or if not, what the differences are. Two instances of an IED class are deemed equivalent if all of their attributes are equal except for the filepath and raw data. For example, two IED files from different filepaths that had the same data except maybe some differences in decimal places and some default parameters ommitted, would be classed as equaivalent as they would produce the same IED instance and write the exact same data.

The result is printed to the console. If you need to access the returned data, use the method IED._get_diff()

Parameters:
  • other (floodmodeller_api.IED) – Other instance of an IED class

  • force_print (bool) – Forces the API to print every difference found, rather than just the first 25 differences. Defaults to False.

to_json() str#

Converts the object instance into a JSON string representation.

Returns:

A JSON string representing the object instance.

Return type:

str

classmethod from_json(json_string: str)#

Creates an object instance from a JSON string.

Parameters:

json_string (str) – A JSON string representation of the object.

Returns:

An object instance of the class.

Examples#

Example 1 - Altering the flow hydrograph in all QTBDYs

The following example demonstrates how the IED class could be used to edit the flow hydrograph within all QTBDY units within an IED file.

# Import modules
from floodmodeller_api import IED
from floodmodeller_api.units import QTBDY # importing the QTBDY Unit class to enable checking unit type

# Read IED file into new IED Class object
ied = IED('path/to/event.ied')

# Define custom function to alter the flow hydrograph to have a minimum flow of 30% of peak flow ONLY on the falling limb
def update_hydrograph (qtbdy_unit):
    hydrograph = qtbdy_unit.data # Get hydrograph from qtbdy unit
    peak_flow = hydrograph.max() # Get peak flow value
    peak_flow_idx = hydrograph.loc[hydrograph == peak_flow].index # Get index of peak flow
    for time, flow in hydrograph.items(): # Iterate through hydrograph series
        if time > peak_flow_idx: # For only flows after peak flow i.e. falling limb
            if flow < peak_flow * 0.3: # If the flow is less than 30% of the peak
                hydrograph.loc[time] = peak_flow * 0.3 # Maintain minimum flow of 30% of peak for remainder of hydrograph

# Iterate through all QTBDY units
for name, unit in ied.boundaries.items():
    if type(unit) == QTBDY: # check if unit is a QTBDY type
        update_hydrograph(unit) # Call the custom function defined above to alter hydrograph

ied.update() # Update the changes in the IED file

Example 2 - Adding a new QHBDY from csv data

This example demonstrates how a new QHBDY unit could be created from a csv containing flow-head relationship and added into an existing IED file. In this example the csv data is in the following format:

flow,   head
0.0,    0.000000
0.5,    4.000000
1.0,    6.000000
1.5,    7.333333
2.0,    8.333333
...
13.0,   15.417679
13.5,   15.565827
14.0,   15.708684
14.5,   15.846615
15.0,   15.979949

Code:

# Import modules
from floodmodeller_api import IED
from floodmodeller_api.units import QHBDY # importing the QHBDY Unit class
import pandas as pd

# Read in QH csv
qh_data = pd.read_csv('path\to\data.csv', index_col=0, squeeze=True) # squeeze = True to read in as a Series object

# Create new QHBDY Unit
new_qhbdy = QHBDY(name='DS_1', data=qh_data, comment='New downstream boundary') # Additional info such as unit name and comment are added.

# Read existing IED file
ied = IED('path/to/event.ied')

# Add in the new QHBDY
ied.boundaries['DS_1'] = new_qhbdy # Added as new key in 'boundaries' dictionary with matching name

# Update the existing IED file
ied.update()