Checking for missing content type metadata ...
This resource contains content types with missing metadata required to make it public or discoverable. Show missing content type metadata.
Click on the edit button ( ) below to edit this resource.
Checking for non-preferred file/folder path names (may take a long time depending on the number of files/folders) ...
This resource contains some files/folders that have non-preferred characters in their name. Show non-conforming files/folders.
This resource contains content types with files that need to be updated to match with metadata changes. Show content type files that need updating.
| Authors: |
|
|
|---|---|---|
| Owners: |
|
This resource does not have an owner who is an active HydroShare user. Contact CUAHSI (help@cuahsi.org) for information on this resource. |
| Type: | Resource | |
| Storage: | The size of this resource is 527.8 MB | |
| Created: | Oct 30, 2024 at 2:27 a.m. (UTC) | |
| Last updated: | Nov 07, 2026 at 10:47 p.m. (UTC) | |
| Citation: | See how to cite this resource | |
| Content types: | CSV Content |
| Sharing Status: | Public |
|---|---|
| Views: | 2569 |
| Downloads: | 355 |
| +1 Votes: | Be the first one to this. |
| Comments: | No comments (yet) |
Abstract
This resource provides the complete reproducibility package for the study Developing Testing Datasets for Benchmarking Automated Quality Control Algorithm Performance with Aquatic Sensor Data. It contains a labeled benchmark dataset derived from 2020–2024 observations at five Logan River Observatory monitoring sites in northern Utah, USA. The resource includes raw aquatic and climate sensor data, manually quality-controlled data, field notes, configuration files, Python code, and the resulting labeled time-series and anomaly-event datasets.
The workflow identifies technician-QC-derived anomaly events by comparing raw and manually corrected observations, then assigns point-level and event-level labels, anomaly patterns, inferred causes, and event features. The benchmark covers water temperature, pH, dissolved oxygen, water stage, and specific conductance. It is intended to support transparent, reproducible evaluation and comparison of automated quality-control and anomaly-detection methods for aquatic sensor time series, and to provide a reusable workflow that can be extended to other monitoring networks and hydrologic settings.
Subject Keywords
Coverage
Spatial
Temporal
| Start Date: | |
|---|---|
| End Date: |
Content
README.md
Benchmark Datasets for Automated Quality Control of Aquatic Sensor Data
This resource contains benchmark datasets for testing automated quality control (QC) methods on aquatic sensor data, together with the Python workflow that produced them and the scripts that reproduce the figures and tables of the associated manuscript. The manuscript and the thesis that describes the workflow in detail are listed under "Related Resources" in this resource's metadata.
Summary
Script.pycompares raw and technician-corrected sensor data, extracts anomaly events, identifies their patterns, and assigns an anomaly type label (MNT, CAL, LDC, CS, PF, SLM, LWL, VIN) to each anomaly event and datapoint.batch_runner.pyrunsScript.pyfor every combination of variable, site and year.Initial_Settings.yamlsets the dataset to process and the thresholds used for labeling, so the analysis can be changed without editing the script.- The benchmark covers 5 variables (specific conductance, water temperature, pH, dissolved oxygen, stage) at 5 Logan River Observatory (LRO) sites for 2020-2024 (125 datasets, 15-minute data).
Manuscript_Reproducibility.zip/reproduces Figures 6-21 and Tables 3-5 of the manuscript.
Labels are technician-QC-derived reference labels: a datapoint is anomalous when the manually corrected value differs from the raw value. They show where a technician made a correction, not independently verified sensor errors.
Quick start
1. Download the resource and unzip the input data
Download all files of this resource into one folder. Unzip InputDatasets.zip in that same folder,
so that the folder InputDatasets/ (with Raw_data/, QC_data/ and FieldNote_data/ inside it)
sits next to Script.py. Other zip files (Plots.zip and Results.zip) are not needed, you just need to unzip the InputDatasets.zip for running the workflow and regenerating results. The Plots.zip and Results.zip are just the results of the previous runs and you need unzip them in case if you need to access to the ready benchmark dataset. Also, the Manuscript_Reproducibility.zip file is only for reproducing the figures used in the manuscript.
2. Create the Python environment
Python 3.10 or 3.11 is required:
conda create -n aquatic-benchmark python=3.10 -y
conda activate aquatic-benchmark
pip install -r requirements.txt
3. Choose the dataset in Initial_Settings.yaml
Set Variable, site, year, Climate_site and Unit (see "Generating the benchmark datasets"
below). For example, to process specific conductance at the Main Street site in 2024:
Variable: SpCond
site: LR_MainStreet_BA
year: 2024
Climate_site: LR_GC_C
Unit: uS/cm
4. Run the workflow
From the folder that contains Script.py, run one dataset:
python Script.py
or all 125 datasets (this updates Initial_Settings.yaml automatically for each run):
python batch_runner.py
The full batch takes about 30 minutes. Results are written to Results/<variable>_<site>_<year>/ and plots to Plots/<variable>_<site>_<year>/.
5. (Optional) Reproduce the manuscript figures and tables
python Manuscript_Reproducibility.zip/1_Dataset_Figures/make_figures_6_14.py
python Manuscript_Reproducibility.zip/1_Dataset_Figures/make_figure_15.py
python Manuscript_Reproducibility.zip/2_ML_Demonstration/isolation_forest.py
python Manuscript_Reproducibility.zip/2_ML_Demonstration/oc_svm.py
python Manuscript_Reproducibility.zip/2_ML_Demonstration/comparison_plots.py
python Manuscript_Reproducibility.zip/2_ML_Demonstration/event_level.py
See "Reproducing the manuscript figures and tables" below for which file produces which figure.
Version
This is the version of the workflow and benchmark data used for the manuscript published in
Environmental Modelling & Software (see Related Resources for reference to the associated paper).
Changes from prior versions are documented in the CHANGES.txt file included in this resource.
Repository structure
The files and folders in this resource are:
AquaticBenchmarkDataset/
|-- Script.py main workflow (one dataset per run)
|-- batch_runner.py runs Script.py for all variable/site/year combinations
|-- Initial_Settings.yaml settings for Script.py
|-- map_columns.py optional: prepares your own input files (column names, file names)
|-- Column_Mapping.yaml column mapping used by map_columns.py
|-- requirements.txt Python packages
|-- CHANGES.txt changes from the previous version
|-- README.md this file
|-- InputDatasets.zip/ distributed as InputDatasets
| |-- Raw_data/RawAquatic/ RawAquatic_<site>_<year>.csv
| |-- Raw_data/RawClimate/ DataSetClimate_<climate site>_<year>.csv
| |-- QC_data/ QC_data_<variable>_<site>_<year>.csv (manually corrected data)
| |-- FieldNote_data/ FieldNotes_<variable>_<site>_<year>.csv
|-- Results.zip/<variable>_<site>_<year>/
| |-- File_1. Final labeling.csv
| |-- File_2_Final_labeling_with_class_dictionary.csv
| |-- File_3. List of the Events.csv
|-- Plots.zip/<variable>_<site>_<year>/ interactive HTML plots of each dataset
|-- Manuscript_Reproducibility.zip/ scripts for the manuscript figures and tables (see below)
Contents of each Results.zip/<variable>_<site>_<year>/ folder:
File_1. Final labeling.csv: time series with all intermediate indicators.File_2_Final_labeling_with_class_dictionary.csv: raw value, corrected value, and class label (0 = normal, 1-8 = anomaly type).File_3. List of the Events.csv: one row per anomaly event (start, end, duration, pattern, label).
Script.py creates Results/ and Plots/ if they do not exist. The input files in
InputDatasets/ (from InputDatasets.zip) must be present before running.
Setup
Python 3.10 or 3.11 is required (the pinned numpy and pandas versions do not support Python 3.12 or later). To create the environment:
conda create -n aquatic-benchmark python=3.10 -y
conda activate aquatic-benchmark
pip install -r requirements.txt
Generating the benchmark datasets
Run both scripts from this folder (the folder that contains Script.py); they use relative paths.
One dataset. Edit Initial_Settings.yaml, then run:
python Script.py
Main settings in Initial_Settings.yaml:
Variable: variable to process:SpCond,WaterTemp_EXO,pH,ODO, orStage.site: aquatic site code (e.g.,LR_Mendon_AA).year: year to process (e.g.,2024).Climate_site: climate site for air temperature (LR_TG_CforLR_TG_BA,LR_GC_Cfor the other sites).Unit: unit of the variable, used in plots (e.g.,mfor stage).CrossVariable: variable checked to separate power failure (PF) from sensor/logger malfunction (SLM) (e.g.,BattVolt).Time_Step_of_data: time step of the data (15T= 15 minutes).CalibrationList: keywords that identify calibration visits in the field notes (e.g.,Cal,Calibration).ThrV_1toThrV_4,PerThr_3,n: thresholds for the low-water-level (LWL) indicators.
Your own data (column mapping). Script.py reads its input files from the folders and file
names shown in "Repository structure" and uses a standard set of column names:
- raw aquatic file:
LocalDateTime,BattVolt,EXOVolt,ODO,Stage,pH,SpCond,WaterTemp_EXO,TurbMed - climate file:
LocalDateTime,AirTemp_EE08_avg - manually corrected file:
LocalDateTime,<Variable>_QC1,QualifierCode - field notes file:
Event Number,Combined Time,Begin: End time,Method
The LRO files in InputDatasets/ already follow this convention. For data with other column
names, list your four files and your column names in Column_Mapping.yaml, set Variable,
site, Climate_site and year in Initial_Settings.yaml, and run:
python map_columns.py
python Script.py
map_columns.py renames the columns, adds the optional columns you do not have (EXOVolt, ODO,
pH, TurbMed, QualifierCode) as empty columns, checks that the required columns are present
(including water temperature, specific conductance and stage, which are used to assign the event
types), and saves the four files with the standard names in InputDatasets/. Values are copied
unchanged; only the header row is changed. Existing files are not replaced unless
overwrite: true is set in Column_Mapping.yaml.
All 125 datasets. batch_runner.py updates Initial_Settings.yaml for each combination
(backups are saved in .config_backups/), runs Script.py, and logs each run in
batch_runs_log.csv:
python batch_runner.py
The variables, sites and years to run are listed at the top of batch_runner.py (VARIABLES,
SITES, YEARS).
Reproducing the manuscript figures and tables
If you plan to reproduce the figures used in the paper, first you need to unzip theManuscript_Reproducibility.zip/, Results.zip/, and InputDatasets.zip/ files.
The scripts in Manuscript_Reproducibility.zip/ only read Results.zip/; they do not change it. Each
script finds the nearest Results.zip/ folder above its own location, so it can be run from any
working directory. Generate Results.zip/ first if it is not present.
Dataset figures (about 1 minute):
python Manuscript_Reproducibility.zip/1_Dataset_Figures/make_figures_6_14.py
python Manuscript_Reproducibility.zip/1_Dataset_Figures/make_figure_15.py
ML demonstration (run in this order; oc_svm.py takes several minutes):
python Manuscript_Reproducibility.zip/2_ML_Demonstration/isolation_forest.py
python Manuscript_Reproducibility.zip/2_ML_Demonstration/oc_svm.py
python Manuscript_Reproducibility.zip/2_ML_Demonstration/comparison_plots.py
python Manuscript_Reproducibility.zip/2_ML_Demonstration/event_level.py
Which script produces which figure or table (paths are relative to Manuscript_Reproducibility.zip/):
- Figures 6-14:
1_Dataset_Figures/make_figures_6_14.pyproduces1_Dataset_Figures/Figure_06_...pngtoFigure_14_...png. - Figure 15:
1_Dataset_Figures/make_figure_15.pyproduces1_Dataset_Figures/Figure_15_anomalous_datapoints_by_month.png. - Figure 16:
2_ML_Demonstration/oc_svm.pyproduces2_ML_Demonstration/outputs/oc_svm/ocsvm_confusion_matrix_TEST.png. - Figure 17:
2_ML_Demonstration/oc_svm.pyproduces2_ML_Demonstration/outputs/oc_svm/ocsvm_metrics_bars_TEST.png. - Figure 18:
2_ML_Demonstration/isolation_forest.pyproduces2_ML_Demonstration/outputs/isolation_forest/iforest_confusion_matrix_TEST.png. - Figure 19:
2_ML_Demonstration/isolation_forest.pyproduces2_ML_Demonstration/outputs/isolation_forest/iforest_metrics_bars_TEST.png. - Figure 20:
2_ML_Demonstration/comparison_plots.pyproduces2_ML_Demonstration/outputs/comparison_plots/hourly_anomalies_2024_test.png. - Figure 21:
2_ML_Demonstration/comparison_plots.pyproduces2_ML_Demonstration/outputs/comparison_plots/monthly_anomalies_2024_test.png. - Table 3:
2_ML_Demonstration/oc_svm.pyproduces2_ML_Demonstration/outputs/oc_svm/ocsvm_per_type_recall_TEST.csv. - Table 4:
2_ML_Demonstration/isolation_forest.pyproduces2_ML_Demonstration/outputs/isolation_forest/iforest_per_type_recall_TEST.csv. - Metrics in Sections 4.3.1 and 4.3.2 (precision, recall, F1, accuracy, PR-AUC, ROC-AUC, confusion
matrix, selected hyperparameters and threshold):
2_ML_Demonstration/outputs/oc_svm/ocsvm_metrics_TEST.csvand2_ML_Demonstration/outputs/isolation_forest/iforest_metrics_TEST.csv. - Table 5 (event-level evaluation in Section 4.3):
2_ML_Demonstration/event_level.pyproduces2_ML_Demonstration/outputs/event_level/Table_5_event_level_TEST.csv(unrounded values inevent_level_metrics_TEST.csvin the same folder).
The numbers behind Figures 6-15 are saved as CSV files in 1_Dataset_Figures/tables/.
ML demonstration: data and settings
- Data:
Results.zip/SpCond_LR_MainStreet_BA_<year>/File_2_Final_labeling_with_class_dictionary.csv, 2020-2024 (specific conductance, Main Street site). - Input: raw sensor values only (column
SpCond_QC0 (uS/cm)); corrected values are not used. - Labels: column
class(0 = normal, 1-8 = anomaly type); binary target =class != 0. - Split: train 2020-01-01 to 2022-12-31, validation 2023-01-01 to 2023-12-31, test 2024-01-01 to 2024-12-31 (calendar years, no shuffling).
- Fitting: models are fit on normal observations (class 0) only. Hyperparameters and the decision-threshold quantile are selected on the 2023 validation period by maximizing F1. The final model is refit on the normal observations of 2020-2023 and applied once to 2024.
- Scores: anomaly score =
-decision_function(...), so a higher score means more anomalous. A datapoint is flagged as anomalous when its score is at or above the selected threshold. - PR-AUC:
sklearn.metrics.average_precision_score(y_true, score), anomaly = positive class. A random ranking gives a PR-AUC equal to the share of anomalous datapoints in the test period (about 0.75 in 2024). ROC-AUC:sklearn.metrics.roc_auc_score(random = 0.5). - Exclusions: rows with any feature that cannot be computed are removed. These are (a) the first rows of the record, before the minimum rolling-window length is reached (the first usable row is 2020-01-01 23:30), and (b) rows whose raw value is missing (13 rows in 2020-2024, all labeled as anomalies) plus the one or two rows after each of them, whose difference features are undefined. Rows used (of 175,392): train 105,105 (111 excluded); validation 35,034 (6 excluded); test 35,130 of 35,136 (6 excluded). The number of rows in each split is printed to the console at the start of each run.
Tested environment
The Manuscript_Reproducibility.zip/ scripts were run in the environment above (Python 3.10.22,
numpy 1.24.0, pandas 1.5.3, matplotlib 3.6.3, scikit-learn 1.1.3) and gave identical results with a
newer environment (Python 3.13.11, numpy 2.4.2, pandas 2.3.3, matplotlib 3.10.8, scikit-learn 1.8.0).
Related Geospatial Features
This HydroShare resource is linked to the following geospatial features
Learn more about Related Geospatial Features
We highly recommend that you add Spatial Coverage to this resource before searching for related geospatial features. Otherwise query times can be excessive.
| ${value.text} | ${value.text} |
Click a point to search for features that overlap with that location.
Select a feature for more information.
Related Resources
| This resource is described by | Kahrizi, E., & Horsburgh, J. S. (in revision). Developing testing datasets for benchmarking automated Quality Control algorithm performance with aquatic sensor data. Environmental Modelling & Software. |
| This resource is referenced by | Kahrizi, E. (2025). Developing Standardized Testing Datasets for Benchmarking Automated Quality Control Algorithm Performance With Aquatic Sensor Data [Master's thesis, Utah State University]. https://doi.org/10.26076/e916-19da |
Credits
Funding Agencies
This resource was created using funding from the following sources:
| Agency Name | Award Title | Award Number |
|---|---|---|
| Cooperative Institute for Research to Operations in Hydrology (CIROH) | None | NA22NWS4320003 |
| Utah Water Research Laboratory, Utah State University | None | None |
How to Cite
This resource is shared under the Creative Commons Attribution CC BY.
http://creativecommons.org/licenses/by/4.0/
Comments
There are currently no comments
New Comment