This repository is the research and development counterpart to the production monitoring platform. It is where anomaly detection models are built, tested against historical events, and validated!
New here? Start with the User Manual. Currently deployed: Dusk Crayfish (as of 2026-08-20).
The creek is monitored at eleven locations: UC Botanical Gardens, Women's Faculty Club (south fork 0), Stephens Hall (south fork 1), Downstream of Sather Gate (south fork 2), Weill Hall (south fork 3), Kingman Hall Garden, University House, Giannini Hall (north fork 0), Wickson Footbridge (north fork 1, also sometimes labeled as scnf010), Oxford Street, and Codornices Creek. The eleventh site, Codornices, is a separate watershed monitored as a standalone point.
The two forks do not behave alike. More urban activity drains into the north fork, so it runs dirtier than the south fork: a higher baseline conductivity and wider swings. Thresholds are fitted per node for that reason, and a deviation at a north fork site is not comparable to the same number at a south fork one.
Every site runs an EnviroDIY Mayfly Data Logger, sampling every 15 minutes. Which sensors are present at which site varies, and that is recorded in the inventory config instead of being inferred from the data, so it is able to tell when a sensor is down and when a sensor was never installed.
| Metric | Probe | Protocol |
|---|---|---|
| Conductivity, temperature, depth | METER HYDROS 21 CTD | SDI-12 |
| Dissolved oxygen | AtlasScientific DO | analog or I2C, depending on probe generation |
| Floating conductivity | AtlasScientific Mini Conductivity K 1.0 | I2C |
| pH | AtlasScientific pH | I2C |
Conductivity, temperature and depth come from one probe, so a site has all three or none. The rest are installed separately.
Floating conductivity sits in a sealed float inside a perforated housing and reads the top of the water column, which is what separates a surface contaminant like oil from one that mixes through.
Three legacy Balance Hydrologics sites are read from a separate system and serve only the past seven days, so a gap older than a week at those sites was never retrievable rather than broken.
Those stations predate SCMG. Berkeley monitored the creek with Balance Hydrologics equipment first, which was bulky, heavy, expensive to install and wired for mains and LAN. The Mayfly sites replaced that with something small, solar powered and wireless, which is why they need no trenching and no network drop, and also why they occasionally go quiet when the sun does.
Support modules attach to any model. They are not models themselves and have no weights of their own. Some explain a detection after it happens while others cover something a model structurally cannot see (adds tests, so switching one on makes the model slightly less sensitive elsewhere).
Dusk Crayfish is the model currently running, as of 2026-08-20. Update the date whenever the deployment changes. Nothing else in the code records which model is live.
Dusk Crayfish learns the creek's normal behavior from sensor data and flags deviations that look like spills or contamination events, without being trained on labeled anomalies. It treats the creek as a connected graph of sensor sites and combines a graph neural network with a Long Short Term Memory architecture to reason about both where a sensor sits in the flow and how its readings change over time.
The map below shows the sensors on the actual creek, with each fork tracing the real water flow down to the Oxford Street confluence. To see the creek in more detail, view the map on the Strawberry Creek website.
The physical sensor network along Strawberry Creek, overlaid on the creek's real flow. Both forks converge at the Oxford Street confluence. This is the full field deployment, not the modeled graph: four of these sites are modeled, north_fork_0, south_fork_1, south_fork_2, and Oxford.
The model is trained and validated on a four-node core of that network, the main flow path where conductivity data is reliable. The remaining sites are brought in as their data ingestion is completed. The north path runs straight from north_fork_0 to Oxford because the footbridge node between them was retired; the water still flows that way, there is just no sensor reporting in between.
graph LR
%% Focused Horizontal Network Layout with No Legend
subgraph ST_Backbone [DuskCrayfish Network Topology]
%% Active South Fork Path
SF1([South Fork 1]) --> SF2([South Fork 2])
%% Active North Fork Path, contracted through the retired footbridge node
NF0([North Fork 0])
%% Convergence Sink
SF2 --> OX{Oxford Street}
NF0 --> OX
%% Isolated Node kept inline horizontally to the right of the sink
CC[[Codornices Creek]]
OX ~~~ CC
end
%% Color Palette Configurations
classDef nodeStyle fill:#1e3a8a,stroke:#3b82f6,stroke-width:2px,color:#fff;
classDef targetStyle fill:#065f46,stroke:#10b981,stroke-width:2px,color:#fff;
classDef controlStyle fill:#334155,stroke:#94a3b8,stroke-width:2px,color:#cbd5e1,stroke-dasharray: 5 5;
class SF1,SF2,NF0 nodeStyle;
class OX targetStyle;
class CC controlStyle;
Dusk Crayfish Active Graph Topology: the 4-node subnetwork the model actually trains and serves on.
The system pulls sensor readings, merges in weather, learns what normal looks like across the whole network, and then scores new data by how badly the model fails to predict it. A large, sustained prediction error on conductivity that shows up across connected sites is the signature of a real event.
The model is unsupervised. It is trained only to predict the next reading from recent history. Anything it cannot predict well is, by definition, something it has not seen before, which is what an anomaly is.
Everything about installing, running and changing this system lives in the User Manual. It is the place to start, and it is beginner friendly (including to those who have never written in Python and/or have never used a terminal before).
It covers setting up Python and a virtual environment from scratch, running each mode with the output you should expect on your screen, editing the sensor inventory, running the tests, and what to do when something goes wrong. Work through it in order the first time.
| I want to | Go to |
|---|---|
| Install it for the first time | Getting set up |
| Run it and understand what it prints | Running the system |
| Work out why the results look wrong | When it looks like the model is wrong |
| Know what each model does | The models |
| Take a sensor out of service | The inventory |
| Change some code and commit it | Making a change to the code |
| Run the tests | Running the tests |
| Fix an error I am seeing | Common problems |
See CONTRIBUTORS.md for everyone who has helped, including those whose contributions do not appear in the commit history.











