1  The monitoring record

Blue Mountains City Council Healthy Waterways — statistical analysis

1.1 What this chapter is for

Two databases, 27 years, 2,062 macroinvertebrate samples and 2,688 water quality samples. This chapter covers what is in them, how they join, what had to be repaired before anything could be analysed, and what they cannot be asked to answer.

It opens with the reproduction test, because everything else rests on it. We recomputed the four macroinvertebrate factors and the overall health rating from the raw taxon records, without going near the Access queries, and compared the result with what you publish. It matches — on every sample where a comparison is possible, and on all three worked examples in the June 2025 methods document, to the decimal. That is the licence for the other eighteen chapters. When a later chapter disagrees with a published figure, the disagreement is about the data or about the method; it is never about whether we implemented your system correctly.

Two other things to keep in mind before you read any result.

  1. The monitoring network changed shape over 27 years. Different sites were visited in different years, so a plain year-on-year average of “waterway health” is partly a measure of which creeks were visited rather than of how the creeks are doing. Section 1.5 shows this directly, and it is the reason almost every model in the book carries a site term.

  2. The family count double-counts some families. We found this by reproducing it rather than by disagreeing with it: the Access query relabels the chironomid subfamilies after de-duplicating, so a sample holding Chironominae and Orthocladiinae counts Chironomidae twice (Section 1.2). Your own Lapstone Creek worked example does it. It is reproduced exactly here, because the published bands were calibrated on the inflated count and changing one without the other would be worse than leaving both.

The object-by-object reference — what every table and function in the data layer is, the validation tables, and the house rules a future analysis has to respect — is Appendix A. This chapter is the description; the appendix is the manual.

1.2 Your published numbers reproduce, exactly

The waterbug database contains a chain of Access queries (CalcsStep1CalcsStep4, all marked DONOTEDIT) that derives the family counts, abundances and EPT figures you publish. Nothing in this report reads the output of those queries. We recomputed all of it from the raw Waterbugdata records and then compared, which is a much stronger test than reading the answers would have been.

1.2.1 The three worked examples

The June 2025 methods document works three samples end to end — every factor score, the average, and the resulting rating. They are the only complete specification of the system that exists outside the Access queries, so they are the test that matters most.

Table 1.1: Recomputed macroinvertebrate factors against the three published worked examples. “W. Falls” is Wentworth Falls Lake.
Example SIGNAL-SF (pub.) SIGNAL-SF (ours) # fam (pub.) # fam (ours) # EPT (pub.) # EPT (ours) %EPT (pub.) %EPT (ours)
Lapstone Creek, Glenbrook 2024 5.00 5.00 15 15 1 1 0.50 0.49
Hat Hill Creek, Blackheath 2024 7.14 7.14 17 17 6 6 77.10 77.11
W. Falls Lake 2024 4.22 4.22 12 12 1 1 3.30 3.26
Table 1.2: Recomputed overall health rating against the three published worked examples. “W. Falls” is Wentworth Falls Lake.
Example Average factor score (published) Average factor score (ours) Rating (published) Rating (ours)
Lapstone Creek, Glenbrook 2024 1.50 1.50 Poor Poor
Hat Hill Creek, Blackheath 2024 4.00 4.00 Excellent Excellent
W. Falls Lake 2024 2.25 2.25 Fair Fair

All three reproduce: the same eight factor scores (four, for the wetland), the same average, the same rating. Lapstone Creek averages 1.50 and comes out Poor; Hat Hill Creek averages 4.00 and comes out Excellent; Wentworth Falls Lake averages 2.25 and comes out Fair. The only differences anywhere in Table 1.1 and Table 1.2 are in the printed %EPT, and there are three of them: the document shows 0.5, 77.1, and 3.3 where the arithmetic gives 0.4902, 77.1084, and 3.2609. The document publishes %EPT to one decimal place where Table 1.1 prints two, so all three are presentation rounding in the document, and none of them moves a factor score.

These three are pinned in the data layer’s own tests by sample code — 2003, 2038, 2052 — and not by site and year, which is not a key here (Section A.1.2).

1.2.2 And on the whole series, not only on three samples

Table 1.3: Agreement between recomputed metrics and the Access calculation chain (CalcsStep3A_C_OverallTotalsDONOTEDIT and CalcsStep4_EPT_DONOTEDIT). The strict family count is the one row expected to disagree: it is a different definition, not a failed reproduction.
Quantity Source Compared Agree Agreement
Family count Step 3A_C 2,050 2,050 100.00%
Family count (strict, true families only) Step 3A_C 2,050 55 2.68%
Total abundance Step 3A_C 2,050 2,050 100.00%
Total abundance Step 4 (TotalBugs) 2,050 2,050 100.00%
EPT individuals Step 4 (TotalEPT) 1,956 1,956 100.00%
%EPT Step 4 (%EPT) 0

Family count, total abundance and EPT individuals agree on every sample where a comparison is possible — 100.00%, not 99-point-something (Table 1.3). The one row that does not agree is the strict family count, which is supposed to disagree; it is a different definition and it is described below.

One quantity could not be checked this way. The %EPT column of CalcsStep4_EPT_DONOTEDIT is empty in the SQLite conversion: not one of the 2,050 samples that have a Step 4 row carries a value in it — it was a calculated column in Access and did not survive the export — so %EPT is reconciled against the worked examples only. (That is 2,050 and not the 2,062 samples in the record because the twelve empty samples have no row in the Access chain at all — the same reason CalcsStep3A_1 returns 2,050, two sections below.) A re-export with that column filled in would close the last gap (dq:ept-percent-column-export).

1.2.3 How the family count actually works

Reproducing the family count meant reverse-engineering the query. CalcsStep1 is a SELECT DISTINCT over (site, date, sample, family, count) in which the five chironomid subfamilies are relabelled “Chironomidae” after the de-duplication, and in which Collembola, Ostracoda, Copepoda and Cladocera are excluded. The family count is then the number of surviving rows. Implementing that rule exactly matches your figure for all 2,050 samples that have one.

Three things fall out of it. None is a mistake we are correcting — they are described because they are the reason two different family counts exist in this book, and because the third one is genuinely odd.

Chironomids count more than once. A sample recording Chironominae = 46 and Orthocladiinae = 10 produces two rows both labelled “Chironomidae”, so Chironomidae counts as two families. This is what happens in the Lapstone Creek worked example, whose published count of 15 families includes Chironomidae twice.

Duplicate records are handled inconsistently. Where the same taxon is entered twice for a sample with different counts, both rows survive the DISTINCT and the taxon counts twice; where the two counts happen to be identical, they collapse to one. Whether a taxon counts once or twice therefore turns on a coincidence in the abundance figures.

The numerator and the denominator use different taxon sets. The family count excludes the four microfauna taxa; the total abundance and the %EPT denominator include them.

The size of it: across 2,050 non-empty samples the published family count exceeds a strict count of true family-level taxa by a median of 3 taxa (mean 3.01, range 0 to 14). Both are carried. n_families reproduces the published figure and drives the health rating; n_families_strict is the defensible ecological count. Chapters 13 to 16 come back to whether the strict count should replace it — the catch being that the published percentile bands were calibrated on the inflated definition, so swapping one without re-deriving the other would make things worse rather than better. Which of the three quirks you would actually want fixed is a question for you, not for us (dq:family-count-defects).

1.2.4 The rating, as implemented

health_score implements the rating exactly as the methods document sets it out. A stream sample gets eight factor scores — four against other Blue Mountains urban streams and four against reference streams — and a wetland sample gets four against a combined regional wetland comparison. The average of those scores maps to an ordered rating from Very Poor to Excellent.

Bar chart of sample counts by rating, with the count printed above each bar. The bars run left to right in rating order — Very Poor 50, Poor 294, Fair 777, Good 579, Excellent 349 — and are all one colour. By height the order is different — Fair tallest at 777, then Good at 579, then Excellent at 349, then Poor at 294, then Very Poor at 50.
Figure 1.1: Distribution of recomputed waterway health ratings across the 2,049 gradeable macroinvertebrate samples, 1998-2024. The 13 samples that yielded too few animals to score a full factor set are excluded rather than being rated off the incomplete set.

2,049 of the 2,062 samples are gradeable, and their mean average-factor-score is 2.872 — inside the Fair band, which is the middle class of a scale running 0 to 5 in five classes each 1.00 score points wide. The distribution is the one every later chapter works from, so here it is once: Very Poor 50, Poor 294, Fair 777, Good 579, Excellent 349.

The band tables are held as data rather than as code, so a different set of bands can be dropped into the same scoring (Section A.1). That is not a housekeeping detail. It is what makes chapters 14 and 15 possible: the revised bands proposed there are run through exactly the same scoring code as the published ones, so any difference in the answer is a difference in the bands and not in the arithmetic.

1.2.5 The samples that are no longer rated

Twelve samples have no taxon records at all. These are genuinely empty rather than missing — a visit happened and nothing was recorded — and they are absent from your own CalcsStep3A_1 family-count query too, which is why that query returns 2,050 rows and not 2,062. They are kept in every table with is_empty_sample = TRUE, zero counts and a missing SIGNAL average, because the mean grade of no families is undefined, not zero.

One further sample (750, Glenbrook Lagoon 2018) is not empty but recorded a single taxon, too few animals to score all four wetland factors.

All thirteen samples — the twelve empty ones and the partial one — used to receive a rating anyway. With four of the eight stream factor scores — or three of the four wetland scores — set to zero, they averaged 0.00 and were rated Very Poor. That is a zero meaning “nothing was found”, not “the sensitive animals were absent”, and those are different statements about a creek. They are now left unrated.

That single change is the whole of the difference between a Very Poor count of 63 — what the rating system produces if you let it score a partial factor set, and therefore the figure in anything computed before this report — and the 50 quoted here. Nothing has been deleted; the unmasked values are kept, and the rule for reconciling a figure against the old convention is in Appendix A.

Nine of the thirteen are consecutive sample codes (1579 to 1587), all from 2018, at nine different creeks. That is either a remarkable season or a lost laboratory batch, and nothing in the database says which — chapter 15 asks whether the field sheets survive (dq:unrateable-field-sheets).

1.3 The data behind this chapter

Each question and request below is set out again in What we need from you, with what it blocks, what an answer is worth and what it would cost you to find, ranked against every other ask in the report.

1.3.1 What this chapter uses, and where it came from

The rating system is implemented from the June 2025 methods document, including its three worked examples, which are the only end-to-end test of the implementation we have.

The document supplies the factor score tables, the desirable ranges, and the three-tier reference / slightly disturbed / urban site classification in its Appendix 2. None of those three attributes is in either database, so they are read from the document and carried on sites.

Blocks: Nothing. Value: low. Costs you: minutes. Refer to it as dq:p-methods-document.

Everything in this report comes out of two of your Access databases — BMCC_WaterbugDatabase and WQDatabase — converted to SQLite and read without modification.

The waterbug side gives 2,062 macroinvertebrate samples at 134 sites from 1998 to 2024, with 31,271 taxon records and the CalcsStep1CalcsStep4 query chain that derives your published figures. The water quality side registers 137 sites, 135 of which carry at least one sample, and gives 2,688 samples with 3,608 measurement rows. Nothing is written back: the SQLite files are read-only inputs and the originals are untouched.

Blocks: Nothing. Value: low. Costs you: minutes. Refer to it as dq:p-two-databases.

1.3.2 What is wrong with it

129 of the 137 register sites now have a position good enough to delineate a catchment from; the remaining 8 have candidate positions far enough apart to give materially different catchments and are withheld rather than averaged.

An averaged position is a place nobody sampled. The eight are 27GLNR, L4, L13, M23, P7, U13, U39 and U44, and resolving them is the highest-value site question on this list.

Blocks: Any catchment, climate or fire covariate at those eight sites, two of which are reference sites. Value: low. Costs you: minutes. Refer to it as dq:pr-eight-positions-withheld.

The published family count exceeds a strict count of true families by a median of 3 taxa, because each of the five chironomid subfamilies is relabelled “Chironomidae” after the de-duplication step, so one family can count up to five times.

Reproduced exactly from CalcsStep1, so this is a description of your calculation rather than a disagreement with it. Both counts are carried: n_families reproduces the published figure and drives the rating, n_families_strict is the defensible count. They must never be mixed inside one analysis.

Blocks: Nothing immediately — but the published percentile bands were calibrated on the inflated count, so any move to the strict count means re-deriving them. Value: low. Costs you: minutes. Refer to it as dq:pr-family-count-inflated.

1.3.3 Questions only you can answer

A handful of sites carry a stored lat/lon and an easting/northing that point to different places — 81NFB by 580 m, and 35GFB, 18BKT, 80BMG and 41NWL by over 170 m. Which of each pair is right?

We would rather you adjudicated these than us: a wrong pour point is a wrong catchment, and the catchment is what everything else in the report hangs off. U39 is a separate case — its northing is six digits (626800) where it should be seven, and we have reconstructed it as 6262800. Tell us if that is wrong.

Refer to it as dq:coordinate-pair-conflicts.

We found three quirks in the way the family count comes out of CalcsStep1. Which of them are deliberate, and which would you want fixed in the next version?

One, the five chironomid subfamilies are relabelled “Chironomidae” after the SELECT DISTINCT, so a sample with Chironominae and Orthocladiinae counts Chironomidae twice — your own Lapstone Creek worked example counts 15 families including Chironomidae twice. Two, where a taxon is entered twice for one sample with different counts both rows survive and it counts twice, but if the two counts happen to be identical they collapse to one. Three, the family count excludes Collembola, Ostracoda, Copepoda and Cladocera but the abundance and %EPT denominators include them. We have reproduced all three exactly and changed nothing; whether they should change is your call, not ours.

Refer to it as dq:family-count-defects.

Eight sites have two or three plausible positions on the map. Which one is right? Start with 27GLNR — it is a reference site and its two candidates are 1.6 km apart.

The eight are 27GLNR, L4, L13, M23, P7, U13, U39 and U44 (SITE-SUBSETS.md is the register). For seven of the eight the rival positions are between 700 m and 2.1 km apart, which is far enough to give a materially different catchment, so we have withheld them rather than average them — an averaged position is a place nobody sampled. U39 is the eighth and a different problem: its register northing is 626800, six digits where a seven-digit MGA northing belongs. For most of these the register easting/northing picks one point and the creek name picks another, and that is not our call to make.

Refer to it as dq:site-coords-ambiguous.

Are U42 and 07GBH (12 m apart), P2-M6 and 74EBB (24 m), and 32EWD and 32.2EWD (98 m) three sites recorded under two codes each, or six distinct sites?

As pour points each pair is one catchment, so the distinction matters for how the samples are treated: two codes on one site means the samples are not independent, and it also moves the published site counts. One of the three pairs, 32EWD and 32.2EWD, is also on the relocated-site pairs table in chapter 1 (Table 1.8), where the .2 code convention reads it as one site moved to a different reach rather than as one site coded twice. Those are two different answers to this question, and the relocation reading is the register’s convention rather than a confirmed fact, so answering this settles both.

Refer to it as dq:duplicate-site-codes.

Fourteen pairs of site codes in the register are a relocation — 09BBH to 09.2BBH, 59BLA to 59.2BLA and twelve others. Do you want each pair reported as one continuous series, or as two?

A relocated site is a different reach, so we have kept them separate and flagged the relationship rather than splicing them. But you are the ones who will read the trend for Centennial Glen Creek, and if a break in the series at 2024 is going to confuse the reporting, that is worth knowing now. Either answer is fine; what we would rather avoid is the choice being made silently.

Refer to it as dq:relocated-site-splice.

77EWD is recorded at 530 m, which puts it in the higher band by the methods document’s own under-500 m rule, but Appendix 2 assigns it to the lower band. Which one did you intend?

It changes that site’s conductivity and salinity desirable ranges and nothing else. We use the altitude-derived band and carry the Appendix 2 value alongside it so the choice can be tested either way.

Refer to it as dq:site-77ewd-altitude-zone.

Can you confirm the town and creek behind the ambiguous codes? LN is used for both Lawson and Linden, C02 turns up in two coding schemes 2.9 km apart, and 32EWD is Garnett Dam but is typed as a stream in the register.

Anything joined on site code inherits these. The 32EWD one has a second consequence: a waterbody typed as a stream is scored against the stream trigger values and the edge band table, neither of which was derived for it. It also has two names in this report — Garnett Dam here, and Garnett Creek in the relocated-site pairs table (Table 1.8), which takes the name from the waterway column of the register. Whichever is right, one name would be better than two.

Refer to it as dq:site-code-decoding.

Some samples carry the same taxon twice with two different counts. Is that two picks of the same sample, a correction that was never deleted, or a typing slip — and would the lab sheets tell us?

We sum them, which is the only choice that does not throw a record away, and the family count is left exactly as your query produces it. But the duplicates are the reason a taxon sometimes counts twice and sometimes once, so knowing what they are would settle the question above as well.

Refer to it as dq:duplicate-taxon-rows.

Methods Appendix 2 lists a slightly disturbed site as 38.2NHV; both databases spell it 38.2NVH (Glenbrook Creek tributary, Valley Heights). Which is right?

We have assumed the document has the typo and mapped it to the database spelling, because 38.2NHV appears nowhere else. It matters because the slightly disturbed tier is half the population the desirable ranges were derived from.

Refer to it as dq:appendix2-site-code-typo.

If a position genuinely cannot be recovered for a site, do you want to retire it formally — or leave it on the books?

Either answer is fine. What we would like to avoid is a site quietly dropping out of the analyses because nobody ever decided, and then somebody noticing in five years and asking what happened to it. It should be a decision you took, and the report should record it as one.

Refer to it as dq:retire-orphan-sites-decision.

1.3.4 What would answer them

Were either of the Hazelbrook bifenthrin locations (87GHZ, 88GHZ) ever sampled before 2023, perhaps under an older site code? Even one visit would do.

There are two bifenthrin contaminations in this archive, eleven years and seventeen kilometres apart, and both are missing the same thing. The 2012 Jamison Creek kill has a control and two impact sites sampled together from five days after the kill was found out to 2024, which is the strongest thing here — but the control and the near impact site were both established after the event, so it has no “before” either (chapter 17). Hazelbrook is the same shape and smaller: the incident is recorded, the sampling only starts afterwards, so the pair is a description rather than a test. It is also the one where a pre-incident sample might plausibly still exist under an older site code, which is why the ask is here and not there. Fifteen minutes of somebody’s memory, or a look at the site register.

Refer to it as dq:hazelbrook-pre2023.

Do the written site descriptions still exist for the ambiguous sites — the “Rian’s Pool, adjacent to the oval” ones? Who would have kept them?

A description like that is the only thing that lets a position be picked off imagery or a map. Without one, the choice between two candidate points cannot be made at all, by us or by anyone else. This is the enabling document for the question above rather than an ask in its own right.

Refer to it as dq:site-written-descriptions.

Could someone re-export CalcsStep4_EPT from Access with the %EPT column populated? It was a calculated column and it came across empty in all 2,062 rows.

It is the one published quantity we cannot check against the whole series — we match your family counts, abundances and EPT counts on every sample, but %EPT only against the three worked examples. A five-minute export turns the last unchecked figure into a checked one.

Refer to it as dq:ept-percent-column-export.

Is there a crosswalk between site codes and the geometry in the five bioindicators/ sampling-point layers and Firesites? None of them carry a site code.

These are layers you already hold and we already have copies of. Without a code on the geometry they cannot be joined to anything, so they are currently unusable — which is a shame, because they are the only spatial record of several sampling programs.

Refer to it as dq:site-code-crosswalk.

Are there intact copies of AllMAcroSites22_8_18.TAB (its .DAT sibling is missing) and GISRRatings2018.TAB?

Low priority — we used the .xlsx twins instead and they were fine. It would give a fifth independent lineage to check the recovered coordinates against, which is the only reason it is on the list at all.

Refer to it as dq:intact-site-tab-files.

Are the original field GPS records still anywhere? Stored precision runs from 1 m to 500 m — twelve sites are rounded to 100 m and two to 500 m.

A 500 m rounding cannot choose between candidate points 700 m apart, so several of the ambiguous sites are ambiguous only because precision was thrown away on the way into the database. Going forward the fix is simply to store what the handset gives you.

Refer to it as dq:site-gps-precision.

1.5 Temporal and spatial coverage

How much monitoring happened, and where, is not steady across the record.

Two panels of vertical bars, one above the other — no lines, and nothing stacked. The upper panel shows macroinvertebrate samples per year, peaking at 142 in 2000 and falling to 31 in 2011, then running between 67 and 93 a year from 2016. The lower panel shows distinct sites visited per year, rising from 25 in 1998 to between 64 and 72 from 2017 onward.
Figure 1.2: Macroinvertebrate sampling effort by year. Both the number of samples and the number of distinct sites visited vary substantially. The leanest years are 2008, 2009, and 2011, and they are not a continuous run — 2010 sits among them with 72 samples at 49 sites, more of both than either neighbour. From 2016 the site count never falls below sixty again.

The two panels of Figure 1.2 do not move together. The sample count swings by a factor of 4.6 across the record, the site count by 2.9, so a year can be busy at few sites or thin across many. Both matter, and they matter differently.

1.5.1 The unbalanced panel

The single most important thing to know about this dataset is that the set of sites monitored changes from year to year. Statisticians call that an unbalanced panel, and it is not a defect in the monitoring — it is what 27 years of a real program looks like. It does mean that some obvious ways of summarising the data give the wrong answer. Figure 1.3 shows every site against every year; each filled cell is a year in which that site was sampled at least once.

A matrix of filled cells, 134 site rows by 27 year columns, ordered by the year each site was first sampled. Filled cells form irregular horizontal bands rather than a solid block, and no row is filled in all 27 years. Of the 25 sites that start in 1998, 19 are still being sampled after 2005 and 6 stop by then. A further 20 sites are added from 2016 onward, 15 of them still sampled in 2024. In all, 101 of the 134 rows have at least one blank year inside their own span.
Figure 1.3: Site-by-year sampling matrix. Each row is a monitoring site, ordered by the first year it was sampled; each filled cell is a year in which that site was visited. Rows are deliberately unlabelled — at this many sites the codes print too small to read at page size, and what the figure is for is the shape of the blank years, not any individual site. The blocks of white are the problem: the sites contributing to a year’s average are not the same sites as the year before.
Table 1.5: How many sites a fully balanced panel would contain, for different starting years. A balanced panel is one where every site appears in every year, so an average over it means the same thing each year.
Panel start Years Sites sampled in every year
2006 19 0
2010 15 1
2012 13 16
2015 10 30
2017 8 51

No site was sampled in every year from 2006 to 2024. Insisting on a balanced panel therefore costs either sites or years (Table 1.5): you are left with 16 sites if you start in 2012, 30 if you start in 2015 and 51 if you start in 2017 — against 134 sites in the network.

Why this matters in practice: if the average health score rises from one year to the next, that can happen because the creeks improved, or because a different set of creeks was visited. The two are indistinguishable in a raw annual mean, and the composition effect here is large — the network more than doubles in size across the record.

What a site random effect does, since most of this book uses one. Instead of averaging every sample together and hoping the site mix cancels out, the model gives each site its own baseline level and then asks what is left over after those baselines are taken out. The year-to-year change is estimated within sites, from creeks compared against themselves, so a year that happens to include more good creeks does not read as an improvement. The cost is that it assumes the site baselines are drawn from a common distribution, which is a mild assumption here and a very useful one: it lets a site with two samples contribute what it can without pretending to be as informative as a site with twenty. Where a chapter uses a balanced panel instead, it says so, and it says which one.

The house rule that follows from it is collected with the others in Appendix A, and every chapter in this report says which panel or which site term it used.

1.5.2 Which sites, and where they are

Table 1.6: Attributes of the macroinvertebrate monitoring network. Every row counts out of the 134 sites in the waterbug database; the categories overlap — a site can appear in several rows (e.g., a reference site can also be currently active).
Category Sites
Sites in the macroinvertebrate database 134
Core reporting sites 27
Currently active sites 75
Historic (register note reads ‘Historic’) 31
Reference sites 17
‘Slightly disturbed’ sites (methods Appendix 2) 22
Wetland sites 9

Two of the categories in Table 1.6 are not in either database. The three-tier reference / slightly disturbed / urban classification the desirable ranges were derived from, and the altitude band that selects the conductivity and salinity ranges, both come from Appendix 2 of the methods document; the databases carry only a coarser four-way Classification field and a recorded altitude. The historic flag is ours, read off the site register’s notes field where it reads exactly Historic — it is not a rule about the site code. The 31 sites it selects span six code prefixes, of which the legacy K, L and M series account for seventeen. Core reporting sites and currently active sites are Council’s own designations, carried through unchanged.

Two places where the document and the databases disagree. Appendix 2 lists a slightly disturbed site as 38.2NHV; both databases use 38.2NVH (Glenbrook Creek tributary, Valley Heights), which appears to be a typo in the document and is mapped as one (dq:appendix2-site-code-typo).

And one site disagrees on altitude zone:

Table 1.7: The one site where the altitude zone derived from its recorded altitude disagrees with methods Appendix 2.
Site Waterway Altitude (m ASL) Zone from altitude Zone in Appendix 2
77EWD Wilsons Glen Creek 530 higher lower

77EWD (Table 1.7) is recorded at 530 m, which puts it in the higher band by the document’s own under-500 m rule, yet Appendix 2 assigns it to the lower band. We use the altitude-derived value and carry the Appendix 2 value alongside it (altitude_zone_appendix) so a chapter can test whether the choice matters. It moves one site’s conductivity and salinity ranges and nothing else (dq:site-77ewd-altitude-zone).

Where the sites are. The coordinates were never missing. easting and northing are populated for every one of the 137 register rows and every one of the 134 waterbug rows. What was sparse is the stored Latitude/Longitude pair — 85 of the 137 register sites, 82 of the 134 bug sites — and that pair used to be the only position the data layer read. That is the whole of why 52 sites have been called unlocatable. Reading the eastings and northings instead recovers 44 further positions.

So 129 of the 137 register sites — 126 of the 134 bug sites — now have a position good enough to delineate a catchment from. The remaining eight (27GLNR, L4, L13, M23, P7, U13, U39, U44) have candidate positions far enough apart to give materially different catchments, and are withheld rather than averaged, because an averaged position is a place nobody sampled. Resolving them is one of the two site questions this chapter rates high value, and the more expensive of the two to answer (dq:site-coords-ambiguous). A further seven sites carried two stored positions more than 100 m apart and were adjudicated one at a time against the DEM, the creek lines and the recorded distance from source; the eastings and northings won five of the seven (dq:coordinate-pair-conflicts).

None of the 44 newly positioned sites is a current monitoring site, and all of them are pre-GPS codes, so this is a recovery of the early record rather than a correction to anything being sampled now. Each of these counts, and the population it is taken out of, is in Section A.1.3.

Relocated sites. Your convention is that a code of the form NN.2XXX replaces NNXXX when a site has to move, for safety, access or habitat reasons. Fourteen pairs in the register follow it:

Table 1.8: Relocated site pairs, identified from the site notes and the ‘.2’ code convention. One of the 14 replacement sites has no location recorded in the site table.
Earlier site Replacement site Waterway Location
05GMVR 05.2GMVR Asgard Brook D/S of Asgard Swamp trail crossing
09BBH 09.2BBH Centennial Glen Creek Upstream Centennial Falls, d/s trib junction
15GKT 15.2GKT Yosemite Creek Minnehaha Falls Reserve
17GLA 17.2GLA Govetts Creek Via Sewage Pumping Stn 75 Rawson Pde
22BWF 22.2BWF Lillians Glen Via West/Bate St
23BWF 23.2BWF Jamison Creek Weeping Rock
25GWF 25.2GWF Wentworth Creek Evans St firetrail (Bruce’s Walk track)
28EHZR 28.2EHZR Ingar Creek D/S Ingar campground
32EWD 32.2EWD Garnett Creek Not recorded
37NSP 37.2NSP Magdala Creek Fairy Dell Track
38NVH 38.2NVH Glenbrook Creek tributary Valley Heights
43NYK 43.2NYK Frasers Creek U/stream of Yellow Rock tributary junction, via Yellow Rock Creek Trail
45NBX 45.2NBX Cripple Creek 920m downstream of landfill
59BLA 59.2BLA Leura Falls Trib u/s Chelmsford Dr Leura Falls Creek Tributary

A relocated site is a different reach of the creek, so the data layer flags the relationship and deliberately does not merge the two series (the house rule). Whether you would rather see them reported as one series is a decision worth making explicitly rather than by default (dq:relocated-site-splice).

One caveat on Table 1.8. 32EWD and 32.2EWD are read as a relocation here because they follow the code convention, but the same pair is 98 m apart and appears earlier in this chapter’s data section as a candidate for one site recorded under two codes (dq:duplicate-site-codes). Only one of those readings can be right, and the convention is not evidence.

1.6 Taxonomy reconciliation

Three separate things had to be reconciled before a taxon name could be counted: the spelling of the name itself, how coarsely the animal was identified, and whether the index used to score it has a grade for it at all. None of the three is a defect in the recording. All three change what a family count or a sensitivity score means, and the third changes it over time.

1.6.1 Taxon names

Table 1.9: Taxon names in Waterbugdata that needed repair, or that have no SIGNAL grade to look up. Names with trailing whitespace are shown with explicit quotes so the whitespace is visible on the page.
Name as recorded Records Fixed by normalising? Matches SIGNAL lookup?
"oligochaeta" 120 yes yes
"ostracoda" 78 - NO
"Ostracoda" 48 - NO
"Copepoda" 30 - NO
"Cladocera" 29 - NO
"isopoda" 25 yes yes
"Spercheidae" 2 - NO
"Stratiomyidae " 2 yes yes
"Gomphomacromiidae" 1 - NO

Matching taxon names on a lower-case, whitespace-trimmed key resolves oligochaeta, isopoda and Stratiomyidae (trailing space) in Table 1.9. That leaves six name variants genuinely absent from the SIGNAL lookup:

  • ostracoda and Ostracoda (two case variants of one taxon), Copepoda and Cladocera — microcrustacea, recorded only sporadically. These are not family-level identifications, which is why the ordinations drop them: the AUSRIVAS manual identifies Ostracoda to subclass (Turak et al. 2004), and mixing a subclass with families confounds taxonomic resolution with composition. Copepoda and Cladocera carry no AUSRIVAS taxa code and no SIGNAL grade at all.
  • Spercheidae (2 records) and Gomphomacromiidae (1 record) — real families that were never added to the SIGNAL grade table.

Collembola is a separate case and is not one of those six: it is in the SIGNAL lookup but excluded by the calculation chain (Section 1.2).

All of these are kept rather than dropped, and flagged, so a chapter that wants them out takes them out deliberately. They carry no SIGNAL grade, which is the next section’s problem.

EPT membership is a second place where two definitions had to be reconciled: it comes from the EPTList table, cross-checked against order membership in TAXONOMY_FAMLEVEL, and the two agree on every taxon that occurs in the data.

1.6.2 Family-level versus coarse identifications

Table 1.10: Taxonomic resolution of the records, counted as distinct taxon names across the whole series.
Category Taxa
Distinct taxa recorded 138
True family-level identifications 119
Coarse taxa (order or higher) 14
Chironomid subfamilies (finer than family) 5

Not every record is identified to family (Table 1.10). Oligochaeta, Acarina, Amphipoda, Isopoda, Nematoda, Hirudinea, Turbellaria and the microcrustacea are order-level or higher. In the other direction the Chironomidae are often recorded as subfamilies, which is finer than family. Both matter for a metric called “number of families”, and both are why Section 1.2 has two of them.

1.6.3 SIGNAL-SF coverage over time

Two sensitivity indices run through this report and they are not the same thing. SIGNAL is the family-level biotic index in which each family carries a sensitivity grade and a sample’s score is the mean grade of the families present (Chessman 1995). The original grades were expert judgement; they were later re-derived from field data against measured water quality (Chessman et al. 1997) and then revised nationally as SIGNAL 2 (Chessman 2003), which is the version in general Australian use. SIGNAL-SF is the short-form variant your rating system uses, and it grades a smaller set of taxa. One of the two papers that introduced SIGNAL tested it on the Nepean and on Blue Mountains creeks (Growns et al. 1995), so the index was shown to work on the water you monitor early on. That is a demonstration of local relevance, not a calibration: the grades were not fitted here.

One panel carrying two lines by year from 1998 to 2024, coloured in the legend's order — individuals without a SIGNAL-SF grade in dark blue, taxa without one in orange. The taxa line stays between 0.10 and 0.28 across the whole record and takes its four lowest values in 2000, 2001, 2008, and 2009. The individuals line is the more variable of the two, falling to 0.04 in 2000, climbing to a peak of 0.39 in 2014, and running between 0.21 and 0.31 over the 10 years after that peak.
Figure 1.4: The share of each macroinvertebrate sample that has no SIGNAL-SF grade, by year. Between 10% and 28% of the taxa in a typical sample, and between 4% and 39% of the individuals, carry no SIGNAL-SF grade and are invisible to the index. The four lowest years — 2000, 2001, 2008, and 2009, the same four on both series — are the years chironomid identification practice changed, not years of better grade coverage.

SIGNAL-SF grades are missing for 91 of the 233 names in the SIGNAL lookup, overwhelmingly the coarse taxa — Oligochaeta, Acarina, and Chironomidae when not identified to subfamily. Those taxa simply drop out of the average.

Across the 27 years the mean proportion of taxa in a sample carrying no grade runs from 10% to 28%, and the proportion of individuals from 4% to 39%, peaking in 2014. A change in how much of the sample the index can see is a change in the index, whatever the creek is doing, so this is a real confound for any SIGNAL-SF trend.

And the four years the index appears to see best — 2000, 2001, 2008, 2009 — are the four years chironomid identification practice changed. Chironomidae is the largest single ungraded group, so when it is recorded coarsely or not at all, prop_count_no_sf_grade drops for a reason that has nothing to do with grade coverage. In those years the column measures identification practice, and a model using it as a covariate is partly controlling for the wrong thing. Chapter 3 owns this: it sets out what happened in each of those years, how large the effect on the family count and %EPT is, and what a chironomid-free sensitivity check does to the answer. What every other chapter has to do about it is the chironomid caveat.

1.7 Water quality

The water quality side of the record is in materially worse condition than the macroinvertebrate side. It is still usable — most of it, for most purposes — but it needed more repair, and the repairs are set out here once so that every later chapter can work from the same description. Nothing has been deleted, substituted or imputed: where a reading has been set aside, the sample it belongs to carries a flag saying so, and the counts all appear in the validation table in Appendix A (Section A.1).

1.7.1 Repeated readings

Table 1.11: Number of replicate probe readings per water quality sample, over the samples that have any measurement at all.
Probe readings per sample Samples
1 1,150
2 76
3 703
4 32
5 3
6 6

tblWaterQuality holds 3,608 rows for 1,981 distinct sample codes, not one row per sample. A further seven rows carry no sample code at all; every populated field in them is zero, so nothing is lost, but they can be joined to nothing. The extra rows are replicate probe readings taken minutes apart at the same visit — 703 sample codes have exactly three (Table 1.11), which is standard practice with a multiparameter probe. They differ mainly in the recorded time and the probe values; the laboratory parameters (alkalinity, phosphate, nitrate-N, faecal coliforms, ammonium) are usually entered once and left blank on the remaining replicates.

What we did: aggregate each sample to one row by taking the mean of each parameter over its non-missing replicates. For probe parameters that averages the replicates, which is what they are for. For laboratory parameters a single replicate is usually populated, so the mean of one value is that value — but not always. 326 (parameter, sample code) pairs carry more than one populated laboratory result (alkalinity 45, phosphate 67, nitrate-N 67, faecal coliforms 16, ammonium 131) and have been averaged, so for those the stored value appears in no laboratory record. Where the two results differ, anyone reading an individual site visit off a table has no way of telling that the number is an average. Every affected case is identifiable, and Section A.1.2 says which column to read to find them.

Faecal coliforms are averaged arithmetically even though plate counts are log-normal and the ANZECC/ARMCANZ guidelines express every coliform figure as a median (ANZECC and ARMCANZ 2000). (Geometric means for faecal indicators are the formulation of the recreational water guidelines, a separate document; ANZECC Volume 1 does not use them for coliforms.) That affects 16 sample codes; changing the rule is your call rather than ours, and chapter 7 puts the question (dq:coliform-mean-decision).

718 of the 2,688 water quality samples have no measurement row at all; 434 of those are recreational samples whose results live in tblRecWaterQuality. They are kept with has_measurements = FALSE rather than dropped, so a sample count is never silently a measurement count.

1.7.2 Six things that had to be repaired

1. A large block of laboratory results is left-censored — that is, the reading is not a measured concentration but a statement that the concentration was below what the method could see. No reading in tblWaterQuality is stored with a <; every parameter column is numeric, and a below-limit result is written as a plain zero. The < survives only in the field notes — a Lawson Creek sample of 12 September 2008 reads “Phos <0.1, Nitrate <0.1” and a Grose River tributary sample of 13 February 2009 reads “Phos<0.01, Nitrate <0.01”, and both are stored as 0.0. So there is a large block of readings at or below the limit of the method, written as exact zeros, which behave exactly like non-detects. The flags test each reading against its parameter’s detection limit where one is known, rather than looking for zeros, because for faecal coliforms the convention changed part way through the record.

Table 1.12: Laboratory parameters with a block of non-detects and the share of readings affected. The faecal coliform limit is confirmed; phosphate and nitrate are inferred from the grid the results were reported on, not stated by the method; for ammonium and alkalinity no limit could be inferred, so their non-detect counts are counts of exact zeros. The phosphate row names its species question because nothing in the record answers it.
Parameter Measured Non-detects Detection limit
Phosphate (ppm, as PO4 or as P) 1,127 606 (53.8%) 0.01 (inferred)
Faecal coliforms (CFU/100 mL) 1,119 471 (42.1%) 10 (confirmed)
Nitrate-N (ppm) 1,029 56 (5.4%) 0.01 (inferred)
Ammonium (mg/L) 134 73 (54.5%) none inferred
Alkalinity (ppm CaCO3) 1,238 4 (0.3%) none inferred

Nothing records which phosphate the phosphate column is. The field is AvailPhosphate and the unit is ppm, and neither database, nor the field sheets, nor the methods document says whether that is phosphate expressed as PO4 or as P. The two differ by a factor of three, so every phosphate concentration in ppm anywhere in this report — the detection limit above, the desirable range in Table 1.13, and any level a later chapter quotes — means one thing under the first convention and a number three times smaller under the second. Counts, shares and rates of change taken from that same column are untouched by it, and so are pass rates against the 2024 desirable ranges, which were derived from percentiles of these same readings so that both sides of a pass or a fail carry whatever convention the kit used. Nitrate-N declares its species in its name and phosphate does not, which is the whole of the difference between them. Chapter 7 (Section 7.5) sizes the ambiguity where it bites hardest, and dq:phosphate-units is the one-line question that would settle it.

One of the five parameters in Table 1.12 has a confirmed limit. Faecal coliforms are censored at 10 CFU/100 mL, and the field notes in tblSamples say so directly — “FC <10CFU/100ml” against a recorded value, and, in July 2024, “0 colonies in 10ml but 1 in 1ml sample” against a recorded 100. A 1 mL and a 10 mL aliquot are plated and the colony count multiplied by 100 and by 10, so 10 is the smallest number the method can produce. That matters more than it sounds, because from 2020 a non-detect started being written down as 5 rather than 0, and a flag that only caught the zeros would have shown the non-detect rate halving from 2021 with nothing happening in the creeks. The coliform flag therefore catches everything below the limit, however it was written, and stands at 471 of 1,119 readings (42.1%).

The phosphate and nitrate limits are shakier. Neither is documented anywhere. Both are inferred at 0.01 ppm from the grid the results were written on: no phosphate or nitrate value below 0.01 ppm exists in tblWaterQuality in any year, the smallest positive reading of each is 0.01 ppm, and the readings step in units of 0.01 for twenty-two years without a break.

The ten values in the analysis data that sit under that grid — seven phosphate and three nitrate-N, all between 22 February and 27 April 2012 — are not readings. Each is exactly half a grid step, because each is the average of a laboratory duplicate in which one replicate read zero and the other 0.01.

What the grid establishes is the resolution the results were recorded at, not the floor of the method that produced them, and those need not be the same number. The only two surviving statements of a floor are field notes, and they disagree by a factor of ten: “Phos <0.1, Nitrate <0.1” in September 2008 and “Phos<0.01, Nitrate <0.01” five months later, each written beside a stored zero. So the limit is unconfirmed rather than unstable, which is the better of the two problems — but it is unconfirmed in both directions. 0.01 ppm is the finest thing the record can express; the true floor may be coarser than that, and nothing here can rule it out. Chapter 3 works out what the choice of floor does to the estimates.

That the phosphate zeros are non-detects at all — rather than measured absence — is supported from outside this database. A regional laboratory sampling the same catchments to the AUSRIVAS protocol recorded total phosphorus below its own stated limit in most of its Blue Mountains samples, with an explicit < where your database has a zero. It is an argument by analogy, across a different determinand and a period that does not overlap yours; chapter 7 (Section 7.5.1) sets out both the evidence and its limits.

Each of these five parameters is flagged where it is censored, and nothing is substituted or modelled away — that is a deliberate choice rather than an oversight, and the reasoning is in Appendix A. What no chapter here does is report “phosphate is within the desirable range in 76% of samples” — 1,044 stream comparisons across the whole record — without saying that just over half the readings are non-detects. As written, that is a statement about detection frequency dressed as a statement about concentration. Chapter 7 quotes a different and higher figure for the same parameter because it scores the 2022–2024 report-card window rather than the whole record; both are pass rates and neither is a concentration.

Confirming the remaining limits, and the date any test kit changed, is the single cheapest thing that would improve the water quality series: wq_detection_limits$confirmed is still FALSE for four of the five parameters, and the field notes that settled the coliform limit suggest the rest are findable (dq:lab-detection-limits).

2. Impossible values were screened out before aggregation. 641 raw readings failed a documented plausibility screen and were set to NA before the replicate averaging above, so that an impossible reading could not contaminate its sample’s mean: 568 total dissolved solids, 68 conductivity, three pH, one salinity and one turbidity. Nothing is destroyed silently — the bounds and the per-reading flags are both in the data layer (Section A.1). The bounds are deliberately generous: they exclude only the physically impossible, never the merely unusual, so a 185% dissolved oxygen saturation from a wetland bloom and a 41.9 °C summer reading both survive. This screen moves published figures: pH now runs from 3.53 rather than from 0.033 (a “pH” of 0.033 is a millivolt reading), the 2006 median conductivity is 45.5 µS/cm rather than 0, the salinity maximum is 0.59 PSU rather than 18.2 (which is half seawater), and the turbidity maximum is 658 NTU rather than 3,014.8.

3. Total dissolved solids change units by a factor of 1,000 in 2021. The Aqua TROLL writes g/L into a column named TDS(mg/L) from 1 January 2021. The TDS-to-conductivity ratio is about 0.645 for 2017 to 2020 — the textbook mg/L relationship — and 0.00065 from 2021. A harmonised series was built alongside the stored one (n = 1,004, median 47.5 mg/L); which of the two to analyse is a house rule, because the stored one looks perfectly usable and is not.

4. Pre-2020 salinity is quantised at 0.01 PSU. 776 samples are recorded on a 0.01 PSU grid against 954 at full precision. The published higher-altitude desirable range is 0.02 to 0.03 PSU — one quantisation step wide — so no exceedance rate or trend computed on pre-2020 PSU values is interpretable. The affected samples are flagged, and electrical conductivity, recorded to 0.1–1 µS/cm throughout, is the salinity indicator used across the whole series here.

5. Ammonia and total suspended solids are withheld. tblWaterQuality holds 423 non-missing nh3 values and 68 tss values, and every populated value is exactly 0.000. Both columns are withheld from wq so that no chapter can report “mean ammonia 0.000 mg/L across 148 samples” out of what is in effect an empty column. Neither database can support any statement about ammonia or total suspended solids. ammonium is a real, if sparse, series (134 samples) and is retained.

6. A handful of individual readings are data entry, not measurement. Every value in both databases was written on paper and then typed in, and nineteen individual readings did not survive the trip: a dissolved oxygen cell holding, to the digit, the turbidity value in the column beside it; a conductivity of 16 µS/cm between two replicates of 166 and 167 taken two minutes later; an alkalinity written as a literal 1 in a season where the other replicate of the same water reads 11.5 to 70. Each was identified by another reading of the same water contradicting it, never by being unusual on its own, and each is documented with its evidence in wq_transcription_suspect and in audit/TRANSCRIPTION-ERRORS.md. They are set to NA before the replicate averaging, because the averaging is what makes them dangerous: one mis-typed cell otherwise moves the stored value of a whole sample.

Those nineteen readings sit in eighteen (sample, parameter) pairs — one sample had two bad readings of the same parameter. In the fourteen pairs where a good replicate survived to say so, the bad cell had moved the sample’s stored value by between 40% and 139%. The other four had no surviving reading of that parameter, so those samples are now missing it rather than carrying a wrong value. The affected samples are flagged, and chapter 6 (Section 6.3.3) tabulates the before-and-after values.

Nineteen bad cells is a very low rate for 27 years of hand-entered records, and it reads as reassurance rather than as alarm. The rest — values that look suspect but that nothing in the data can correct — is left in place, flagged rather than altered.

Two more breaks are documented and not corrected, because correcting them needs information the databases do not hold: turbidity is dominated by which instrument was in the water rather than by the water, and faecal coliforms step by about a hundredfold across the summer of 2004–05. Both are chapter 3’s, which dates them, sizes them and says what a trend crossing either of them is worth; what every chapter has to do about it is the instrument-era rule.

1.7.3 Trigger values

Table 1.13: Blue Mountains ecological water quality desirable ranges (2024 revision), as implemented. Derived from the 20th and 80th percentiles of reference and ‘slightly disturbed’ site data, January 2006 to August 2023; the last column is the number of measurements each range was computed from. EC (µS/cm) and Salinity (PSU) are derived separately for lower and higher altitude zones, while the other parameters pool all altitudes.
Parameter Altitude zone Desirable range Measurements
pH all 5.28 to 6.75 855
Turbidity (NTU) all 0 to 7.08 777
DO (% saturation) all 77.2 to 100.09 827
DO (mg/L) all 7.64 to 10.37 830
EC (µS/cm) lower 71.05 to 178.6 262
EC (µS/cm) higher 33.96 to 78.2 560
Salinity (PSU) lower 0.03 to 0.07 262
Salinity (PSU) higher 0.02 to 0.03 557
Alkalinity (ppm CaCO3) all 4 to 16 368
Phosphate (ppm, as PO4 or as P) all 0 to 0.044 369
Nitrate-N (ppm) all 0.04 to 0.176 368
Faecal coliforms (CFU/100mL) all 0 to 20 354
Figure 1.5

Electrical conductivity and salinity are compared against the altitude-zone-specific ranges of Table 1.13; 433 conductivity and salinity measurements come from sites with no recorded altitude and so have no applicable range at all. Figure 1.5 is the raw picture only; chapter 7 turns these comparisons into the report card, with the censoring and the instrument eras accounted for (Section 7.4).

These are early-warning triggers, not compliance standards. A result outside the desirable range is a condition worth following up, not a breach. The ranges follow the ANZECC and ARMCANZ framework, in which default trigger values are the 80th and/or 20th percentile of a regional reference distribution — the 80th for stressors that do harm at high concentrations, the 20th for those that do harm at low ones, and both together as a band only for stressors like pH, temperature and salinity that do harm at either end — and an exceedance is a prompt to investigate rather than a finding of harm (ANZECC and ARMCANZ 2000); the guidelines call the choice of cut-point “arbitrary (though reasonably conservative)” in the same passage. Deriving locally relevant values from local reference sites, which is what you have done, is what those guidelines recommend in preference to their own national defaults.

The published ranges are for streams. 2,500 of the 15,633 stored comparisons are wetland samples being judged against ranges derived from a site list of 32 stream sites and two wetlands — a stream distribution with a token of wetland in it rather than a wetland benchmark. They are kept and flagged rather than dropped, and they are excluded from the figure above. Chapter 11 takes up what that costs and what a wetland-specific set of ranges would need.

Provenance

Table 1.14: Build provenance for this chapter.
Item Value
Data layer built 2026-08-30 12:56
R version R version 4.4.3 (2025-02-28)
Source databases BMCC_WaterbugDatabase_converted.sqlite (2025-08-05 11:26); WQDatabase_converted.sqlite (2025-08-05 11:29)