libraryextensions/http/demos/Seismic.xtl
Seismic.xtl -- the earthquake report (quakes.xtl, quakes-live.xtl): a USGS feed CSV into SQLite, SQL to select and group, X_eTaL arrays to compute, pictures to see it. An ordinary X_eTaL library beside them (not Quakes.xtl: on a case-insensitive file system that is quakes.xtl). Import: "se:" u_se< "Seismic"
ʰr̲ound : Float -> Float
ʰr̲ound ← { v → (f̲loat f̲loor 0.5 + 100.0 × v) ÷ 100.0 }
Used in: ˡr̲eport
ˡr̲eport : Char -> Char
se:r_eport "path.csv": prints the report and draws its pictures
ˡr̲eport ← { csv → x ← db sq:e̲xec "drop table if exists quakes" n ← db sq:i̲mport "quakes=" c̲at csv ⍝ -- 1. SQL: what is there a ← p̲rint! "quakes, the smallest and largest magnitude, the mean depth (km):" a ← p̲rint! ʰr̲ound r̲avel db sq:n̲ums "select count(*), min(mag), max(mag), avg(depth) from quakes" a ← p̲rint! "from, to (UTC):" a ← p̲rint! db sq:t̲exts "select substr(min(time), 1, 16), substr(max(time), 1, 16) from quakes" ⍝ -- 2. SQL groups: the largest three, and quakes per day a ← p̲rint! "the largest three: magnitude, place" a ← p̲rint! db sq:t̲exts "select printf('%.1f', mag) || ' ' || place from quakes order by mag desc limit 3" a ← p̲rint! "quakes per day:" a ← p̲rint! r̲avel db sq:n̲ums "select count(*) from quakes group by substr(time, 1, 10) order by substr(time, 1, 10)" ⍝ -- 3. arrays: magnitudes in half-unit bins (2.45 rounds into the ⍝ first), and the Gutenberg-Richter law: the count at or above each ⍝ magnitude falls about tenfold per unit -- its b-value is about 1. ⍝ Outside the US this feed lists quakes from about 4.5 up, so b is ⍝ estimated above 4.5 (Aki's maximum likelihood: log10 e over the ⍝ mean magnitude's excess, magnitudes given to 0.1) m ← r̲avel db sq:n̲ums "select mag from quakes" b ← 1 + 0 m̲ax f̲loor (m − 2.5) ÷ 0.5 h ← '+ r̲/₂ (r̲ange 10) '= t̲able b a ← p̲rint! "quakes in [2.5, 3), [3, 3.5), ... [7, 7.5):" a ← p̲rint! h t ← 2.5 + 0.5 × f̲loat (r̲ange 8) − 1 c ← '+ r̲/₂ t '≤ t̲able m k ← '+ r̲/ c > 0 t ← k t̲ake t g ← (l̲og f̲loat k t̲ake c) ÷ l̲og 10.0 a ← p̲rint! "log10 of the count at or above 2.5, 3, 3.5, ...:" a ← p̲rint! ʰr̲ound g big ← (m ≥ 4.5) r̲eplicate m a ← p̲rint! "quakes of 4.5 and up, and their b-value (Aki):" a ← p̲rint! (f̲loat t̲ally big) c̲at ʰr̲ound 0.4342944819 ÷ (ʰm̲ean big) − 4.45 ⍝ -- 4. pictures ⍝ a world map: quakes counted in 10-degree cells, 18 rows (north at ⍝ the top) by 36 columns (from 180 W), one array index per quake ll ← db sq:n̲ums "select latitude, longitude from quakes" row ← 17 m̲in f̲loor (90.0 − 1 s̲elect₂ ll) ÷ 10.0 col ← 35 m̲in f̲loor (180.0 + 2 s̲elect₂ ll) ÷ 10.0 w ← '+ r̲/₂ (r̲ange 648) '= t̲able 1 + col + 36 × row p ← ⎕S̲HOW ⎕G̲RID 18 36 r̲eshape (w > 0) + (w > 2) + w > 8 ⍝ the magnitude histogram as bars, a cell per 5 quakes, and the law ⍝ as a line h5 ← c̲eiling (f̲loat h) ÷ 5.0 p ← ⎕S̲HOW ⎕G̲RID (r̲ev r̲ange 'm̲ax r̲/ h5) '≤ t̲able h5 p ← ⎕S̲HOW ⎕P̲ATH (2 c̲at t̲ally t) r̲eshape t c̲at g "drawn: the map, the histogram, the Gutenberg-Richter line" }