Welcome to PyTUFLOW’s documentation!#
PyTUFLOW is a library that acts as an API for your TUFLOW model. It allows easy interaction with the model results, contains a number of useful utilities for building TUFLOW models, and contains some useful parsers for files within the TUFLOW eco-system.
Check out the Usage section for further information, including how to install the project.
Changelog#
1.1#
Release date: 26 March 2026
Removed QGIS Dependency Requirement#
QGIS is no longer required for extracting data from mesh outputs. Prior to v1.1, PyTUFLOW required a QGIS environment to be able to extract data from mesh outputs (e.g. XMDF.time_series(), XMDF.section() etc). In place of QGIS, PyTUFLOW will use PyVista for mesh geometry operations and either NetCDF4 or h5py for extracting the dataset values (h5py is typically a little faster and will be preferred by PyTUFLOW).
This change comes with speed improvements for loading mesh outputs as well as significant speed improvements when extracting data along a linestring (e.g. for XMDF.section() and XMDF.curtain() methods). See the Optimised Mesh Outputs section for more details.
Removed GDAL Dependency Requirement#
GDAL is no longer required for GIS operations or data extraction. PyTUFLOW now uses GeoPandas for vector datasets and Rasterio for raster datasets. This change simplifies the installation process for PyTUFLOW.
GDAL can still be used in lieu of GeoPandas and Rasterio, however GeoPandas and Rasterio will be preferred by PyTUFLOW if they are available in the Python environment.
New Methods for Map Output Classes#
New methods have been added to the map output classes (XMDF, NCMesh, DAT, NCGrid, CATCHJson):
data_point(): Extract a single data point at a given time and location.maximum(): Extract the maximum value over the entire simulation for a given location or set of locations.minimum(): Extract the minimum value over the entire simulation for a given location or set of locations.surface(): Extract a 2D surface at a given time and data type.
Optimised Mesh Outputs#
New mesh drivers have been added for handling mesh outputs with QGIS libraries (nominally called “QGIS drivers”) and without QGIS libraries (nominally called “Python drivers”).
The best drivers will be chosen automatically based on the available libraries in your Python environment, but it is also possible to specify which drivers to use when initialising the output class. It is recommended to use the Python drivers where possible for speed improvements and to reduce the complexity of the Python environment. Python drivers also offer faster initialisation times since the mesh geometry is not loaded until it is required for data extraction.
The tables below summarise benchmarking results for the different drivers. The table is for comparison purposes only and the actual times will depend on the model size, computer hardware, and Python environment.
Model Name |
Active Cell Count |
Section() Line Cell Count* |
|---|---|---|
FMA_T2_10.00m |
109,030 |
1,205 |
FMA_T2_05.00m |
435,568 |
2,367 |
FMA_T2_02.50m |
1,741,084 |
4,690 |
* Section() line cell count relates to the last table
Model Name |
QGIS Drivers |
Python Drivers |
|---|---|---|
FMA_T2_10.00m |
2.76 |
2.15 |
FMA_T2_05.00m |
14.5 |
8.72 |
FMA_T2_02.50m |
58.8 |
35.2 |
Model Name |
QGIS Drivers |
Python Drivers |
|---|---|---|
FMA_T2_10.00m |
0.02 |
0.02 |
FMA_T2_05.00m |
0.09 |
0.06 |
FMA_T2_02.50m |
0.34 |
0.21 |
Model Name |
Legacy QGIS Drivers |
New QGIS Drivers** |
Python Drivers |
|---|---|---|---|
FMA_T2_10.00m |
28.0 |
0.76 |
0.07 |
FMA_T2_05.00m |
267 |
1.15 |
0.15 |
FMA_T2_02.50m |
-* |
2.99 |
0.59 |
* Did not finish within 30 minutes.
** “New QGIS Drivers” refers to optimisations made to the Python code in PyTUFLOW for using QGIS and does not refer to any changes in QGIS itself.
Optimised NetCDF Grid Output#
The NCGrid output class has been optimised for speed when extracting data. In particular, the NCGrid.section() has been optimised when finding the cells along a linestring. The NCGrid.section() method is now ~2x faster than in previous versions.
Some data caching has also been implemented for faster repeated calls to the same data type.
Optimised TPC Output#
Significant speed up for loading TPC results from a model that contains a lot of channels (in the order of > 500). For example, a test was run on a model that contained approximately 5,000 pipes, and the load time went from 15 seconds to < 1 second.
Installed TUFLOW Locations#
PyTUFLOW will now automatically find installed TUFLOW versions. That is, versions of TUFLOW installed via the .msi installer on Windows or the .deb and .rpm packages on Linux. This means that users can use the TCFRunState.run() method with installed versions of TUFLOW without needing to register the TUFLOW binary locations.
Minor New Features#
Added Flood Modeller DAT cross-section output class -
DATCrossSections. This is essentially a wrapper around theFmCrossSectionDatabaseDriverclass and allows users to interact with Flood Modeller DAT files in an easier way via theOutputclass methods - e.g.ids(),data_types(),section().Added
has_reference_timeproperty to all output classes. This property holds whether the loaded output contains an explicit reference time. Thereference_timeproperty will always return a value and as a consequence cannot be used for this purpose.Curtain plots will now return a fourth column for vector results that contain the vector projected onto the direction of the input linestring.
direction_of_velocityanddirection_of_unit_floware now recognised as separate scalar datasets. Previously, these would be assumed to be combined with the velocity and unit flow magnitude datasets respectively and then treated as a vector dataset. This change allows the datasets to be treated separately and the available datasets align more closely with what is actually in the NetCDF file. This also allows users to plot the direction datasets as scalar datasets.Calculated offsets in the
section()andcurtain()methods will now return ellipsoid distances if the results are using spherical coordinates.CATCHJson.time_series()andCATCHJson.profile()methods can now return results from multiple locations if the locations fall within different result domains (e.g. one point could sit within the TUFLOW HPC catchment result and the other within the 2D receiving TUFLOW FV receiving result).Additional context can now be added when extracting results from the
TPCresult class. For example, when extractingtime_series()results, it’s possible to add additional context such as the domain (e.g."channel"or"rl") by adding this context to the location with a"/"delimiter e.g."rl/flow_line".Comments in material files are now kept in the resulting DataFrame.
Adds a
line_numberproperty to theInputclass that represents the line in the control file the input command is on.Adds a
Scope.pretty_print()method.
Bug Fixes#
"water depth"data type is now correctly recognised as"depth".Max data types now correctly return maximum water surface elevation for 2D results for the
curtain()method.Fixed a bug where
"vector"was being removed from the data type"vector velocity"or"max vector velocity"when making calls to the plotting methods (time_series(),section()etc). Typically only matters for thecurtain()method where the raw vector data can be used rather than the scalar values.Changed the
NCGridreturn DataFrame column names to be consistent with other output classes. Previously the columns weredat_type/nameand now it isname/data_type.magnitude_of_velocityand are recognised asvelocity(affectsNCGridoutputs).Fixed a bug for Quadtree results prior to the TUFLOW
2026.0.0release. There was a bug in TUFLOW (fixed in2026.0.0) where Quadtree hardcoded PO geometry types to “R” (region/polygon) in theplot/GIS/PLOT.csvfile. This resulted in a downstream bug in PyTUFLOW when using any geometry filters in methods such asdata_types(). PyTUFLOW has been updated to double check the geometry types on load if encountering “R” geometries so results from TUFLOW versions prior to2026.0.0can still be used.Fixed a bug for
GPKG2DandGPKGRLclasses where using a"polygon"filter in either thedata_types()orids()methods would return an empty list even if there were PO or RL polygons in the results.Fixed a bug for
section()andcurtain()methods for Quadtree results when the line intersected transition zones which could cause additional points to be added to the resulting DataFrame withNaNvalues.Fixed a bug for
CATCHJson.time_series()method that incorrectly report an invalid data type if the location was not within the result domain that contained the data type (but the data type existed in another result domain). Example,"salinity"could exist within the TUFLOW FV receiving results but not in the TUFLOW HPC catchment results. If the location was within the TUFLOW HPC catchment results, then the method would incorrectly report that"salinity"was an invalid data type, even though it was a valid data type in the TUFLOW FV receiving results.FMTSoutput class no longer returns"bed level"and"pipes"from theFMTS.data_types()method if a.datfile is not provided.Fixed instances where an integer key would cause an error or an empty return when getting a value from a database e.g. in a material file.
TUFLOW cross-section database values now return the cross-section offset as the index in the returned DataFrame.
CATCHJson.time_series()andCATCHJson.profile()methods now search through all results. Previously, it would short circuit and return once it found any active results. This worked if only extracting from a single point, however if multiple points were passed in and they sat within different result domains, then the second point would return an invalid data type error since the method had already short circuited and returned the results from the first point.Better handling of corrupt TUFLOW version caches.
1.0.4#
Release date: 29 Jan 2026
Fixed a bug when loading a TCF file that contained a
"Set Variable == <Windows file path>"command where the value was set to a Windows file path that contained special character sequences (e.g.\U). This caused a Python error when the variable value was inserted into other commands. The value is now correctly escaped.Fixed several bugs and behaviour changes when using Pandas 3.x. These include:
Loading a TUFLOW
1d_xs.shpas a cross-section database and trying to retrieve a value which would cause a Python error.Behavioural change when loading a
material.csvdatabases that returned additional ‘Unnamed’ columns.Loading a
TPCoutput class and call methods such asdata_types()which would cause a Python error.Loading a
GPKG1Doutput class which would cause a Python error.
1.0.3#
Release date: 13 Jan 2026
Fixed a bug when reading a TCF file and the command
Write Check Files ==was used and the file path did not have a trailing slash. Previously, this could cause a Python error.
1.0.2#
Release date: 16 Dec 2025
Fixed a bug where a
"timeseries"filter would return an empty list when using thedata_types()orids()methods onGPKG2DandGPKGRLclasses.Added a timezone to the
NCGridreference time.Added a timezone to the
NCMeshreference time.Fixed a bug where outputs that had an uneven output times would result in the output time units being interpreted incorrectly e.g. a 300 second timestep would be output as a 300 hr timestep.
Fixed a bug when trying to load a TUFLOW cross-section database from a GPKG.
Fixed a bug for
NCGridwhere"3d"filters would cause a Python error.CrossSectionsoutput class now handles file not found errors more gracefully, such that the output is still loaded even if a cross-section file is missing.Fixed a bug for
CrossSectionsoutputs where the cross sections were being reloaded each time thesection()method was called.Fixed a bug where
"na"types forCrossSectionsoutputs were not returning any results when using thesection()method.Fixed a bug for ESTRY GPKG Time Series outputs where the
"pipes"data type was incorrectly outputting a pipe at each channel.Fixed a bug with the
BCTablesCheckoutput class where it would return an empty list iffilter_bywas set to"timeseries".Fixed a bug with the
HydTablesCheckoutput class where it would return an empty list iffilter_bywas set to"section".Fixed a bug where if there was a trailing or leading “/” in the
filter_byargument in thedata_types()ids(), andtimes()methods, then an empty return was almost guaranteed.Fixed a bug in when asking for the
"wetted perimeter"data type in theHydTablesCheck.section()output class would cause a python exception.Added proper format checking for SMS
DATfiles.Fixed a bug when loading a
DATfile (not from the.sup) where the file path attributefpathwas being being set incorrectly.Fixed time-series and section plotting for
DATfiles which was not working.Added the missing format checker for the
CATCHJsonclass.Added
fpathproperty toCATCHJsonclass to be consistent with other output classes.Added a timezone to the
CATCHJsonreference_time.Removed
WARNING Invalid data type:that was triggered incorrectly inCATCHJsonif the data type was not in one of the result files but it was present in another.Added timezone information to
FVBCTideoutput class.Fixed a bug where
UK Hazard Formula ==commands were seen as files and were then flagged as having missing files.Fixed a bug where
MI Projection == Coord ...commands were seen as files and were then flagged as having missing files.Fixed a bug with
GPKG1D.section()method when connecting two pipes and the"pits"data type was requested for ESTRY GPKG 1D outputs.Fixed generic Python warnings that were being triggered in various places in the code, in particular warning regarding
returnstatements infinallyblocks.
1.0.1#
Release date: 10 Oct 2025
Fixed a bug that would incorrectly flag
1d_nwkQchannel curve references (the reference to the pit database name) as files and then flag the file as missing.Fixed a bug for 1D results where if the
"section/3d"filter was passed into thedata_types()orids()methods, the return value would incorrectly return populated lists. The return is now an empty list since 1D results do not have any 3D results.
1.0.0#
Release date: 6 Oct 2025
First full release of PyTUFLOW.