Reading a ShakeMap at 2 a.m.: Lessons from a Bad Import

这篇内容暂时只有 English 版本,以下是原文。

Last spring I was on rotation for a regional seismic network’s overnight desk. At 02:14 local time a magnitude 5.6 event came in about 30 km from a mid-sized city. I pulled the ShakeMap export (GeoJSON, roughly 12,000 grid cells at 1 km spacing, about 9 MB) into a small in-house responder dashboard so I could push estimated shaking to the duty officer. The map rendered. The colors looked plausible. Then I noticed the station list in the sidebar showed only 3 stations contributing, when our trigger had listed 14. The map was not wrong, exactly. It was unconstrained, and it was about to be described to a city emergency manager as if it were constrained.

What I did: I stopped treating the map as a picture and started treating it as an artifact with provenance. First, a quick sanity check on the import against the raw XML feed:

import json, xml.etree.ElementTree as ET

# station count should survive the exporter
shakemap = json.load(open("event.geojson"))
stations = [f for f in shakemap["features"] if f["properties"].get("type") == "station"]
xml = ET.parse("event.xml").getroot()
xml_stations = xml.findall(".//station")
print(f"geojson stations: {len(stations)}  xml stations: {len(xml_stations)}")

That printed 3 and 14. The exporter had dropped stations whose waveforms failed a QC filter but left the interpolation grid untouched, so the contour field was still drawn from a weak constraint set. I re-ran the export with the filter disabled for display purposes and flagged the QC failures in the sidebar instead of hiding them:

shakemap-export --event event.xml --grid 1km --stations all \
  --flag-qc --out event.geojson

The second pass showed 14 stations, 8 of them flagged, and the contour pattern changed noticeably near the epicenter, which was the whole point. I sent the duty officer both the map and the station count with the QC flags in the message body, not as an attachment.

Why: a ShakeMap is an interpolation plus a set of assumptions, and the number of contributing stations is the cheapest proxy for how much the picture is extrapolating. Hiding QC-failed stations makes the map look cleaner and makes the uncertainty invisible, which is the wrong trade for anyone downstream making a decision about a school or a bridge. The cost is real, though: an all-stations export is noisier, slower to render, and a responder reading a flagged map may over-discount good data. My compromise was to keep the full station set in the tool but show flags rather than delete rows.

Where this breaks: dense urban grids with many stations can make the all-stations view visually useless, and I have seen the flagging metadata disagree with the XML feed when the exporter version and the ShakeMap engine version are out of sync. I also learned the hard way that a missing station is not the same as a quiet station: one of the three retained records was a strong-motion instrument with a clipped trace, which inflated the near-field intensity estimate. I did not catch that from the GeoJSON alone; it only showed up when I went back to the raw counts. And none of this helps if the event is offshore with sparse coverage, where the grid is mostly extrapolation no matter what you do.

If you have run a responder-facing map, how do you surface the difference between constrained and extrapolated shaking without turning the display into a wall of caveats?

0
赞同度 100% · 0 条评论 · 2 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。