Skip to content

Gracefully handle missing availability service - #13

Open
lkeyson-earthscope wants to merge 21 commits into
mainfrom
handle-availability
Open

Gracefully handle missing availability service#13
lkeyson-earthscope wants to merge 21 commits into
mainfrom
handle-availability

Conversation

@lkeyson-earthscope

@lkeyson-earthscope lkeyson-earthscope commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

The FDSN fdsnws-availability service and MUSTANG's ts_* time-series metrics (e.g. ts_percent_availability_total, ts_num_gaps) are currently down for an undetermined period. Though their return will likely occur at the same time, these two services could go down and come back independently of each other. This PR lets PIQQA reports keep generating while either or both are unavailable, and switch back onto them automatically (no manual flag/config change) once they recover.

What changed
Independent health checks, one per service, run once per report:

  • doAvailability() probes fdsnws-availability directly (PIQQA.py) and only treats it as down on an explicit HTTP 410 (or another HTTP error / connection failure) - no longer relies on a getcode() == 410 check that could never actually be reached (urlopen raises HTTPError for 4xx/5xx rather than returning a response object).
  • reportUtils.checkTsMetricsExist() (new) independently probes MUSTANG for ts_percent_availability_total against a stable reference station (IU.ANMO), so we don't conflate "availability service is down" with "ts_ metrics are down" - they're detected and handled separately.

Fallback paths when a service is down:

  • reportUtils.get_extents_from_mustang() (new) computes data start/end extents from MUSTANG's percent_availability measurements when fdsnws-availability is unreachable, replacing the availability-service lookup used to determine data start/end for PDF and spectrogram plots. If it cannot retrieve percent_availability metrics, it will use the report dates.
  • reportUtils.getDataStartEnd() (new) wraps the "get start/end for a target" logic (previously duplicated 4x across doPDFs/doSpectrograms) and picks between getAvailability() and get_extents_from_mustang() based on the availability-service flag.
  • doAvailability() skips straight to the percent_availability fallback (instead of attempting ts_percent_availability_total and only falling back after a failed retry-with-sleep) when checkTsMetricsExist() has already determined ts_ metrics are down — avoids ~5-10s of wasted retries per channel group.
  • doBoxPlots() drops ts_num_gaps_total and substitutes num_gaps for ts_num_gaps in the requested metric list when ts_ metrics are down.

Updated urls:

  • service.iris.edu --> service.earthscope.org

This MR also bumps python to 3.12, off of end-of-life 3.9.

Example report that was run on the latest code:
UW_2026.zip

@lkeyson-earthscope
lkeyson-earthscope marked this pull request as draft July 28, 2026 14:21
@lkeyson-earthscope
lkeyson-earthscope marked this pull request as ready for review July 28, 2026 16:37
@lkeyson-earthscope lkeyson-earthscope self-assigned this Jul 28, 2026

@gillian-earthscope gillian-earthscope left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly just comments about updating IRIS references to EarthScope

Comment thread reportUtils.py
Comment on lines +346 to +349
testURL = (
f"https://service.earthscope.org/mustang/measurements/1/query?"
f"metric=ts_percent_availability_total&net=IU&sta=ANMO&loc=00&chan=BHZ&"
f"format=text&timewindow={startDate},{endDate}&nodata=404"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest using the metrics web service for a query that is not dependent on a network or time window:
https://service.earthscope.org/mustang/metrics/1/query?metric=ts_percent_availability_total&output=html&nodata=404

Comment thread reportUtils.py
except urllib.error.HTTPError as e:
if e.code == 410:
print(
f"WARNING: {serviceKey}-availability service is down, falling back to MUSTANG percent_availability for data extents"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTTP code 410 is specific for the reason "Gone". Suggest this warning instead of "down":

"WARNING: EarthScope {serviceKey}-availability service is gone, falling back to MUSTANG percent_availability for data extents"

Comment thread PIQQA.py
@@ -1728,8 +1792,8 @@
f"This report is intended as a quick, broad overview of the quality of the data archived for the network "
f"and time period specified above. IRIS' goal in generating these reports is to give PIs for temporary "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EarthScope's goal

Comment thread PIQQA.py
f"and time period specified above. IRIS' goal in generating these reports is to give PIs for temporary "
f"experiments better insight into the quality of their data archived at the DMC, as well as to demonstrate "
f'the utility provided by the IRIS DMC quality assurance system <a href="http://service.iris.edu/mustang/?" target="_blank">MUSTANG</a> '
f'the utility provided by the IRIS DMC quality assurance system <a href="http://service.earthscope.org/mustang/?" target="_blank">MUSTANG</a> '

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EarthScope quality assurance system

Comment thread PIQQA.py
@@ -1768,7 +1839,7 @@
f"are from the IRIS DMC {availabilityServiceLink}. "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IRIS DMC -> EarthScope

Comment thread PIQQA.py
f"<br/><br/>"
f"The report will include selected channels if specified, or all available channels if not. To see the complete metadata holdings for this experiment, visit this link:"
f'<p><a href="http://ds.iris.edu/mda/{network}/?starttime={startDate}T00:00:00&endtime={endDate}T23:59:59" target="_blank"> '
f"IRIS Metadata Aggregator (MDA) for {network}: {startDate} to {endDate}</a></p>\n"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EarthScope Metadata Aggregator

Comment thread PIQQA.py
f"and the many metrics and products it generates. "
f"For PIs, we hope that these reports will "
f"inform the range of data availability, continuity, and noise levels existing across the network and potentially "
f"which stations are problematic and might be avoided for ongoing data analysis. For PASSCAL, these reports may provide lessons "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PASSCAL -> the EarthScope Primary Instrument Center (EPIC)

Comment thread PIQQA.py
@@ -1728,8 +1792,8 @@
f"This report is intended as a quick, broad overview of the quality of the data archived for the network "
f"and time period specified above. IRIS' goal in generating these reports is to give PIs for temporary "
f"experiments better insight into the quality of their data archived at the DMC, as well as to demonstrate "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

archived at EarthScope

Comment thread PIQQA.py
f"<li> Available data extents in blue </li> "
f"<li> Gaps in black </li>"
f"</ol>"
f"The metadata extents are retrieved from the IRIS DMC {stationServiceLink}, "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IRIS DMC -> EarthScope

Comment thread PIQQA.py
if not services:
availabilityIntroText = (
f"{availabilityIntroText} <br/><br/>"
f"<b>Note:</b> the availability service was unavailable when this report was generated, "

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EarthScope availability service ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants