Add seven additional robustness checks (3a–3g) and update paper

3a  Block-bootstrap surrogates (B=804 bins≈11 yr, n=5000): raw r(+15d)
    p=0.022 — marginally significant on undetrended series, driven by
    the shared solar-cycle trend not a causal signal.

3b  Partial correlation (sunspot-regressed, no filter): r(+15d) drops
    from 0.079 to 0.029 (63%) — confirms solar-cycle confounding without
    preprocessing circularity.

3c  Spectral coherence in solar-cycle band = 0.840 (>0.776 threshold);
    kNN mutual information at τ=+15d = 0.000 nats (p=1.000) — no
    nonlinear dependence at the claimed lag.

3d  Missing-data impact: 0% NaN at station thresholds 2/3/5; r(+15d)
    unchanged — missing data is not a confound.

3e  Bin-size sensitivity: dominant peak at τ≈-520d for 1/5/27-day bins;
    r at +15d scales with bin size (solar-cycle leakage, not physical).

3f  GK declustering removes 28.4% of events as aftershocks; r(+15d)
    changes by only Δ=0.014 — aftershock clustering not a confound.

3g  Per-solar-cycle analysis (cycles 21–24): r(+15d) all positive
    (0.018–0.073) but dominant peak lags scattered (-65/-125/+125/-125d)
    — phase-drifting solar-cycle artefact, not physical precursor.

Script fixes: vectorised block bootstrap (401×5000 → NumPy matmul),
  kNN MI with sorted searchsorted (O(N log N), no inflated values),
  coherence nperseg 512→2048 (resolves solar-cycle band), axhspan→axvspan.

Paper: new Methods subsections (block bootstrap, partial correlation,
  nonlinear dependence); new Results subsections for each check; updated
  Conclusions with 7-item robustness summary; Kraskov2004 and
  GardnerKnopoff1974 added to refs.bib; Homola2023 updated to arXiv
  preprint 2204.12310; eq:energy duplicate label fixed. PDF: 35 pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
root 2026-04-24 20:43:08 +02:00
parent 798b0744b5
commit 1d01fcf102
23 changed files with 1979 additions and 275 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View file

@ -14,132 +14,220 @@
\providecommand\HyField@AuxAddToFields[1]{}
\providecommand\HyField@AuxAddToCoFields[2]{}
\citation{Homola2023}
\citation{Kanamori1977}
\citation{Homola2023}
\citation{Stoupel1990,Urata2018}
\citation{Homola2023}
\citation{Bretherton1999}
\citation{Potgieter2013}
\citation{Odintsov2006,Tavares2011}
\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{4}{section.1}\protected@file@percent }
\newlabel{sec:intro}{{1}{4}{Introduction}{section.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{5}{section.1}\protected@file@percent }
\newlabel{sec:intro}{{1}{5}{Introduction}{section.1}{}}
\citation{USGS2024}
\citation{Kanamori1977}
\citation{SIDC2024}
\@writefile{toc}{\contentsline {section}{\numberline {2}Data}{5}{section.2}\protected@file@percent }
\newlabel{sec:data}{{2}{5}{Data}{section.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Cosmic-Ray Flux: NMDB Neutron Monitors}{5}{subsection.2.1}\protected@file@percent }
\newlabel{sec:nmdb}{{2.1}{5}{Cosmic-Ray Flux: NMDB Neutron Monitors}{subsection.2.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Seismic Activity: USGS Earthquake Catalogue}{5}{subsection.2.2}\protected@file@percent }
\newlabel{sec:usgs}{{2.2}{5}{Seismic Activity: USGS Earthquake Catalogue}{subsection.2.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Solar Activity: SIDC Sunspot Number}{5}{subsection.2.3}\protected@file@percent }
\newlabel{sec:sidc}{{2.3}{5}{Solar Activity: SIDC Sunspot Number}{subsection.2.3}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3}Methods}{5}{section.3}\protected@file@percent }
\newlabel{sec:methods}{{3}{5}{Methods}{section.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Cross-Correlation at Lag $\tau $}{5}{subsection.3.1}\protected@file@percent }
\newlabel{sec:xcorr}{{3.1}{5}{Cross-Correlation at Lag $\tau $}{subsection.3.1}{}}
\newlabel{eq:xcorr}{{1}{5}{Cross-Correlation at Lag $\tau $}{equation.3.1}{}}
\@writefile{toc}{\contentsline {section}{\numberline {2}Data}{6}{section.2}\protected@file@percent }
\newlabel{sec:data}{{2}{6}{Data}{section.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Cosmic-Ray Flux: NMDB Neutron Monitors}{6}{subsection.2.1}\protected@file@percent }
\newlabel{sec:nmdb}{{2.1}{6}{Cosmic-Ray Flux: NMDB Neutron Monitors}{subsection.2.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Seismic Activity: USGS Earthquake Catalogue}{6}{subsection.2.2}\protected@file@percent }
\newlabel{sec:usgs}{{2.2}{6}{Seismic Activity: USGS Earthquake Catalogue}{subsection.2.2}{}}
\newlabel{eq:energy}{{1}{6}{Seismic Activity: USGS Earthquake Catalogue}{equation.2.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Solar Activity: SIDC Sunspot Number}{6}{subsection.2.3}\protected@file@percent }
\newlabel{sec:sidc}{{2.3}{6}{Solar Activity: SIDC Sunspot Number}{subsection.2.3}{}}
\citation{Bartlett1946}
\citation{Bretherton1999}
\citation{Theiler1992,Schreiber2000}
\@writefile{toc}{\contentsline {section}{\numberline {3}Methods}{7}{section.3}\protected@file@percent }
\newlabel{sec:methods}{{3}{7}{Methods}{section.3}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Cross-Correlation at Lag $\tau $}{7}{subsection.3.1}\protected@file@percent }
\newlabel{sec:xcorr}{{3.1}{7}{Cross-Correlation at Lag $\tau $}{subsection.3.1}{}}
\newlabel{eq:xcorr}{{2}{7}{Cross-Correlation at Lag $\tau $}{equation.3.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Effective Degrees of Freedom}{7}{subsection.3.2}\protected@file@percent }
\newlabel{sec:neff}{{3.2}{7}{Effective Degrees of Freedom}{subsection.3.2}{}}
\newlabel{eq:neff_bartlett}{{3}{7}{Effective Degrees of Freedom}{equation.3.3}{}}
\newlabel{eq:neff_breth}{{4}{7}{Effective Degrees of Freedom}{equation.3.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Surrogate Significance Tests}{7}{subsection.3.3}\protected@file@percent }
\newlabel{sec:surrogates}{{3.3}{7}{Surrogate Significance Tests}{subsection.3.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.1}Phase Randomisation}{7}{subsubsection.3.3.1}\protected@file@percent }
\newlabel{sec:phase}{{3.3.1}{7}{Phase Randomisation}{subsubsection.3.3.1}{}}
\citation{Schreiber2000}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Effective Degrees of Freedom}{6}{subsection.3.2}\protected@file@percent }
\newlabel{sec:neff}{{3.2}{6}{Effective Degrees of Freedom}{subsection.3.2}{}}
\newlabel{eq:neff}{{2}{6}{Effective Degrees of Freedom}{equation.3.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Surrogate Significance Tests}{6}{subsection.3.3}\protected@file@percent }
\newlabel{sec:surrogates}{{3.3}{6}{Surrogate Significance Tests}{subsection.3.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.1}Phase Randomisation}{6}{subsubsection.3.3.1}\protected@file@percent }
\newlabel{sec:phase}{{3.3.1}{6}{Phase Randomisation}{subsubsection.3.3.1}{}}
\newlabel{eq:phase}{{3}{6}{Phase Randomisation}{equation.3.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.2}IAAFT Surrogates}{6}{subsubsection.3.3.2}\protected@file@percent }
\newlabel{sec:iaaft}{{3.3.2}{6}{IAAFT Surrogates}{subsubsection.3.3.2}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.3}Global $p$-Value}{6}{subsubsection.3.3.3}\protected@file@percent }
\newlabel{sec:pvalue}{{3.3.3}{6}{Global $p$-Value}{subsubsection.3.3.3}{}}
\newlabel{eq:pglobal}{{4}{6}{Global $p$-Value}{equation.3.4}{}}
\newlabel{eq:phase}{{5}{8}{Phase Randomisation}{equation.3.5}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.2}IAAFT Surrogates}{8}{subsubsection.3.3.2}\protected@file@percent }
\newlabel{sec:iaaft}{{3.3.2}{8}{IAAFT Surrogates}{subsubsection.3.3.2}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.3}Block-Bootstrap Surrogates}{8}{subsubsection.3.3.3}\protected@file@percent }
\newlabel{sec:blockbootstrap}{{3.3.3}{8}{Block-Bootstrap Surrogates}{subsubsection.3.3.3}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.4}Global $p$-Value}{8}{subsubsection.3.3.4}\protected@file@percent }
\newlabel{sec:pvalue}{{3.3.4}{8}{Global $p$-Value}{subsubsection.3.3.4}{}}
\newlabel{eq:pglobal}{{6}{8}{Global $p$-Value}{equation.3.6}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.5}GPU Acceleration}{8}{subsubsection.3.3.5}\protected@file@percent }
\newlabel{sec:gpu}{{3.3.5}{8}{GPU Acceleration}{subsubsection.3.3.5}{}}
\citation{HP1997}
\citation{RahnUhlig2002}
\citation{Cleveland1990}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.3.4}GPU Acceleration}{7}{subsubsection.3.3.4}\protected@file@percent }
\newlabel{sec:gpu}{{3.3.4}{7}{GPU Acceleration}{subsubsection.3.3.4}{}}
\newlabel{eq:matmul}{{5}{7}{GPU Acceleration}{equation.3.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Solar-Cycle Detrending}{7}{subsection.3.4}\protected@file@percent }
\newlabel{sec:detrend}{{3.4}{7}{Solar-Cycle Detrending}{subsection.3.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.5}Geographic Localisation Scan}{7}{subsection.3.5}\protected@file@percent }
\newlabel{sec:geo}{{3.5}{7}{Geographic Localisation Scan}{subsection.3.5}{}}
\newlabel{eq:matmul}{{7}{9}{GPU Acceleration}{equation.3.7}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.4}Solar-Cycle Detrending}{9}{subsection.3.4}\protected@file@percent }
\newlabel{sec:detrend}{{3.4}{9}{Solar-Cycle Detrending}{subsection.3.4}{}}
\newlabel{eq:hp_lambda}{{8}{9}{Solar-Cycle Detrending}{equation.3.8}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.5}Partial Correlation Analysis}{9}{subsection.3.5}\protected@file@percent }
\newlabel{sec:methods:partialcorr}{{3.5}{9}{Partial Correlation Analysis}{subsection.3.5}{}}
\newlabel{eq:partialcorr}{{9}{9}{Partial Correlation Analysis}{equation.3.9}{}}
\citation{Kraskov2004}
\citation{Benjamini1995}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Pre-Registered Out-of-Sample Validation}{8}{subsection.3.6}\protected@file@percent }
\newlabel{sec:prereg}{{3.6}{8}{Pre-Registered Out-of-Sample Validation}{subsection.3.6}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.7}Combined Timeseries: Sinusoidal Envelope Fit}{8}{subsection.3.7}\protected@file@percent }
\newlabel{sec:sinusoid}{{3.7}{8}{Combined Timeseries: Sinusoidal Envelope Fit}{subsection.3.7}{}}
\newlabel{eq:modA}{{6}{8}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.6}{}}
\newlabel{eq:modB}{{7}{8}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.7}{}}
\citation{Homola2023}
\newlabel{eq:bic}{{8}{9}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.8}{}}
\newlabel{eq:bf}{{9}{9}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.9}{}}
\@writefile{toc}{\contentsline {section}{\numberline {4}Results}{9}{section.4}\protected@file@percent }
\newlabel{sec:results}{{4}{9}{Results}{section.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}In-Sample Replication (1976--2019)}{9}{subsection.4.1}\protected@file@percent }
\newlabel{sec:res:insample}{{4.1}{9}{In-Sample Replication (1976--2019)}{subsection.4.1}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}IAAFT Surrogate Test}{9}{subsection.4.2}\protected@file@percent }
\newlabel{sec:res:surr}{{4.2}{9}{IAAFT Surrogate Test}{subsection.4.2}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3}Effect of Solar-Cycle Detrending}{9}{subsection.4.3}\protected@file@percent }
\newlabel{sec:res:detrend}{{4.3}{9}{Effect of Solar-Cycle Detrending}{subsection.4.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Cross-correlation function $r(\tau )$ for the raw (undetrended) CR index and global seismic metric, 1976--2019. The dominant peak at $\tau = -525$\nobreakspace {}days (vertical dashed line, red) corresponds to a half-solar-cycle lag; the claimed $\tau = +15$\nobreakspace {}days is marked with a vertical solid line (blue). The horizontal shaded band shows the na\"ive $\pm 2\sigma $ confidence interval (ignoring autocorrelation); the narrower band is the Bretherton-corrected interval.\relax }}{10}{figure.caption.2}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {3.6}Nonlinear Dependence Tests}{10}{subsection.3.6}\protected@file@percent }
\newlabel{sec:methods:nonlinear}{{3.6}{10}{Nonlinear Dependence Tests}{subsection.3.6}{}}
\@writefile{toc}{\contentsline {paragraph}{Spectral coherence.}{10}{section*.2}\protected@file@percent }
\newlabel{eq:coherence}{{10}{10}{Spectral coherence}{equation.3.10}{}}
\@writefile{toc}{\contentsline {paragraph}{Mutual information.}{10}{section*.3}\protected@file@percent }
\newlabel{eq:mi}{{11}{10}{Mutual information}{equation.3.11}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.7}Geographic Localisation Scan}{10}{subsection.3.7}\protected@file@percent }
\newlabel{sec:geo}{{3.7}{10}{Geographic Localisation Scan}{subsection.3.7}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.8}Pre-Registered Out-of-Sample Validation}{11}{subsection.3.8}\protected@file@percent }
\newlabel{sec:prereg}{{3.8}{11}{Pre-Registered Out-of-Sample Validation}{subsection.3.8}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.9}Combined Timeseries: Sinusoidal Envelope Fit}{11}{subsection.3.9}\protected@file@percent }
\newlabel{sec:sinusoid}{{3.9}{11}{Combined Timeseries: Sinusoidal Envelope Fit}{subsection.3.9}{}}
\newlabel{eq:modA}{{12}{11}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.12}{}}
\newlabel{eq:modB}{{13}{11}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.13}{}}
\newlabel{eq:bic}{{14}{11}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.14}{}}
\newlabel{eq:bf}{{15}{11}{Combined Timeseries: Sinusoidal Envelope Fit}{equation.3.15}{}}
\@writefile{toc}{\contentsline {section}{\numberline {4}Results}{12}{section.4}\protected@file@percent }
\newlabel{sec:results}{{4}{12}{Results}{section.4}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Raw Pairwise Correlations Between CR, Seismic, and Sunspot Data}{12}{subsection.4.1}\protected@file@percent }
\newlabel{sec:res:rawcorr}{{4.1}{12}{Raw Pairwise Correlations Between CR, Seismic, and Sunspot Data}{subsection.4.1}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.1}CR index: station distribution}{12}{subsubsection.4.1.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.2}Seismic energy metric}{12}{subsubsection.4.1.2}\protected@file@percent }
\newlabel{eq:energy_bin}{{16}{12}{Seismic energy metric}{equation.4.16}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.3}Sunspot number}{12}{subsubsection.4.1.3}\protected@file@percent }
\citation{Potgieter2013}
\citation{Odintsov2006}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.4}Correlation results}{13}{subsubsection.4.1.4}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{CR vs.\ seismicity.}{13}{section*.4}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{CR vs.\ sunspot number.}{13}{section*.5}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Sunspot vs.\ seismicity.}{13}{section*.6}\protected@file@percent }
\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.1.5}Interpretation: a confounding triangle}{13}{subsubsection.4.1.5}\protected@file@percent }
\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Raw pairwise correlation statistics across three time windows. Bonferroni correction applied for $3 \times 3 = 9$ tests. CR uses the per-bin station-median index ($\hat {x}^{(50)}$). Seismic energy is $\log _{10}\!\left (\DOTSB \sum@ \slimits@ 10^{1.5 M_W}\right )$. Sunspot is the 365-day smoothed daily count. $^{*}p_\text {Bonf}<0.05$, $^{**}p_\text {Bonf}<0.01$, $^{***}p_\text {Bonf}<0.001$.\relax }}{14}{table.caption.7}\protected@file@percent }
\providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}}
\newlabel{fig:homola}{{1}{10}{Cross-correlation function $r(\tau )$ for the raw (undetrended) CR index and global seismic metric, 1976--2019. The dominant peak at $\tau = -525$~days (vertical dashed line, red) corresponds to a half-solar-cycle lag; the claimed $\tau = +15$~days is marked with a vertical solid line (blue). The horizontal shaded band shows the na\"ive $\pm 2\sigma $ confidence interval (ignoring autocorrelation); the narrower band is the Bretherton-corrected interval.\relax }{figure.caption.2}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Null distribution of the peak cross-correlation statistic from 10{,}000 IAAFT surrogates for the raw (blue) and HP-detrended (orange) CR--seismic series. Vertical dashed lines mark the observed peak for each case. While the raw peak is improbably large under the null, the detrended peak is only marginally significant, and the correlation at the claimed $\tau =+15$\nobreakspace {}d is not.\relax }}{11}{figure.caption.3}\protected@file@percent }
\newlabel{fig:stress}{{2}{11}{Null distribution of the peak cross-correlation statistic from 10{,}000 IAAFT surrogates for the raw (blue) and HP-detrended (orange) CR--seismic series. Vertical dashed lines mark the observed peak for each case. While the raw peak is improbably large under the null, the detrended peak is only marginally significant, and the correlation at the claimed $\tau =+15$~d is not.\relax }{figure.caption.3}{}}
\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces Cross-correlation statistics at $\tau = +15$\nobreakspace {}days under four preprocessing conditions, in-sample window 1976--2019.\relax }}{12}{table.caption.4}\protected@file@percent }
\newlabel{tab:detrend}{{1}{12}{Cross-correlation statistics at $\tau = +15$~days under four preprocessing conditions, in-sample window 1976--2019.\relax }{table.caption.4}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Cross-correlation functions for the raw (blue) and HP-detrended (orange) series. The dominant peak at $\tau = -525$\nobreakspace {}days in the raw data (dashed blue) is absent after detrending, confirming it is a solar-cycle artefact. Neither series exhibits a significant peak at $\tau = +15$\nobreakspace {}days (vertical grey line).\relax }}{12}{figure.caption.5}\protected@file@percent }
\newlabel{fig:detrended}{{3}{12}{Cross-correlation functions for the raw (blue) and HP-detrended (orange) series. The dominant peak at $\tau = -525$~days in the raw data (dashed blue) is absent after detrending, confirming it is a solar-cycle artefact. Neither series exhibits a significant peak at $\tau = +15$~days (vertical grey line).\relax }{figure.caption.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4}Geographic Localisation}{13}{subsection.4.4}\protected@file@percent }
\newlabel{sec:res:geo}{{4.4}{13}{Geographic Localisation}{subsection.4.4}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Heatmap of BH-significant station--grid-cell pairs ($q = 0.05$). Each row is an NMDB station; each column is a $10° \times 10°$ seismic grid cell. Significant pairs (455/7{,}037) are scattered without obvious geographic clustering, inconsistent with a local coupling mechanism.\relax }}{13}{figure.caption.6}\protected@file@percent }
\newlabel{fig:geoheatmap}{{4}{13}{Heatmap of BH-significant station--grid-cell pairs ($q = 0.05$). Each row is an NMDB station; each column is a $10° \times 10°$ seismic grid cell. Significant pairs (455/7{,}037) are scattered without obvious geographic clustering, inconsistent with a local coupling mechanism.\relax }{figure.caption.6}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5}Pre-Registered Out-of-Sample Validation (2020--2025)}{13}{subsection.4.5}\protected@file@percent }
\newlabel{sec:res:oos}{{4.5}{13}{Pre-Registered Out-of-Sample Validation (2020--2025)}{subsection.4.5}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Optimal lag $\tau ^*(s,g)$ vs.\ great-circle distance $d(s,g)$ for all 7{,}037 station--cell pairs (grey) and BH-significant pairs (coloured by peak $|r|$). The OLS regression line (red) has slope $\beta = -0.45$\nobreakspace {}days/1000\,km ($p=0.21$), consistent with zero. A local propagation mechanism would predict a positive slope.\relax }}{14}{figure.caption.7}\protected@file@percent }
\newlabel{fig:geodistlag}{{5}{14}{Optimal lag $\tau ^*(s,g)$ vs.\ great-circle distance $d(s,g)$ for all 7{,}037 station--cell pairs (grey) and BH-significant pairs (coloured by peak $|r|$). The OLS regression line (red) has slope $\beta = -0.45$~days/1000\,km ($p=0.21$), consistent with zero. A local propagation mechanism would predict a positive slope.\relax }{figure.caption.7}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Out-of-sample cross-correlation function (2020--2025, $T=390$ bins, $10^5$ phase surrogates). The observed $r(\tau )$ (black) lies entirely within the surrogate 95th-percentile envelope (grey shading). The claimed signal at $\tau = +15$\nobreakspace {}d (vertical line) is $r = 0.045$ --- below the surrogate 95th percentile of 0.136.\relax }}{14}{figure.caption.8}\protected@file@percent }
\newlabel{fig:oosxcorr}{{6}{14}{Out-of-sample cross-correlation function (2020--2025, $T=390$ bins, $10^5$ phase surrogates). The observed $r(\tau )$ (black) lies entirely within the surrogate 95th-percentile envelope (grey shading). The claimed signal at $\tau = +15$~d (vertical line) is $r = 0.045$ --- below the surrogate 95th percentile of 0.136.\relax }{figure.caption.8}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6}Combined 1976--2025 Analysis: Sinusoidal Modulation}{14}{subsection.4.6}\protected@file@percent }
\newlabel{sec:res:combined}{{4.6}{14}{Combined 1976--2025 Analysis: Sinusoidal Modulation}{subsection.4.6}{}}
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Pre-registered prediction scorecard for the out-of-sample window.\relax }}{15}{table.caption.9}\protected@file@percent }
\newlabel{tab:prereg}{{2}{15}{Pre-registered prediction scorecard for the out-of-sample window.\relax }{table.caption.9}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Rolling $r(+15\,\text {d})$ in 18-month overlapping windows across the out-of-sample period. Error bars are bootstrap 95\% confidence intervals. The grey horizontal band shows the surrogate 95th percentile. The signal shows no consistent sign or trend.\relax }}{15}{figure.caption.10}\protected@file@percent }
\newlabel{fig:rolling}{{7}{15}{Rolling $r(+15\,\text {d})$ in 18-month overlapping windows across the out-of-sample period. Error bars are bootstrap 95\% confidence intervals. The grey horizontal band shows the surrogate 95th percentile. The signal shows no consistent sign or trend.\relax }{figure.caption.10}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Annual rolling $r(+15\,\text {d})$ across the full 1976--2025 period (grey points with 95\% bootstrap CI). The sinusoidal best-fit (red curve, $P = 9.95$\nobreakspace {}yr) closely tracks the oscillatory pattern, confirming that the CR--seismic correlation is modulated by the solar cycle. The vertical dashed line marks the in-sample/out-of-sample split (2020).\relax }}{15}{figure.caption.11}\protected@file@percent }
\newlabel{fig:combined}{{8}{15}{Annual rolling $r(+15\,\text {d})$ across the full 1976--2025 period (grey points with 95\% bootstrap CI). The sinusoidal best-fit (red curve, $P = 9.95$~yr) closely tracks the oscillatory pattern, confirming that the CR--seismic correlation is modulated by the solar cycle. The vertical dashed line marks the in-sample/out-of-sample split (2020).\relax }{figure.caption.11}{}}
\citation{Jeffreys1961}
\newlabel{tab:rawcorr}{{1}{14}{Raw pairwise correlation statistics across three time windows. Bonferroni correction applied for $3 \times 3 = 9$ tests. CR uses the per-bin station-median index ($\hat {x}^{(50)}$). Seismic energy is $\log _{10}\!\left (\sum 10^{1.5 M_W}\right )$. Sunspot is the 365-day smoothed daily count. $^{*}p_\text {Bonf}<0.05$, $^{**}p_\text {Bonf}<0.01$, $^{***}p_\text {Bonf}<0.001$.\relax }{table.caption.7}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}In-Sample Replication (1976--2019)}{14}{subsection.4.2}\protected@file@percent }
\newlabel{sec:res:insample}{{4.2}{14}{In-Sample Replication (1976--2019)}{subsection.4.2}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Raw pairwise scatter plots for the in-sample window (1976--2019, $N = 3{,}215$ five-day bins). \textbf {Left}: CR station-median index vs $\log _{10}$ seismic energy; horizontal error bars span the station $[\hat {x}^{(5)}, \hat {x}^{(95)}]$ spread. \textbf {Centre}: CR index vs 365-day smoothed sunspot number; the strong anti-correlation ($r = -0.82$) reflects the Forbush decrease mechanism. \textbf {Right}: Smoothed sunspot number vs $\log _{10}$ seismic energy; thin horizontal error bars show the daily sunspot spread within each 5-day bin. All points are coloured by decimal year (plasma colormap), revealing the solar-cycle drift: successive cycles trace the same anti-correlated arc in the centre panel. Black curves are LOWESS trend lines ($f = 0.4$).\relax }}{15}{figure.caption.8}\protected@file@percent }
\newlabel{fig:rawinsample}{{1}{15}{Raw pairwise scatter plots for the in-sample window (1976--2019, $N = 3{,}215$ five-day bins). \textbf {Left}: CR station-median index vs $\log _{10}$ seismic energy; horizontal error bars span the station $[\hat {x}^{(5)}, \hat {x}^{(95)}]$ spread. \textbf {Centre}: CR index vs 365-day smoothed sunspot number; the strong anti-correlation ($r = -0.82$) reflects the Forbush decrease mechanism. \textbf {Right}: Smoothed sunspot number vs $\log _{10}$ seismic energy; thin horizontal error bars show the daily sunspot spread within each 5-day bin. All points are coloured by decimal year (plasma colormap), revealing the solar-cycle drift: successive cycles trace the same anti-correlated arc in the centre panel. Black curves are LOWESS trend lines ($f = 0.4$).\relax }{figure.caption.8}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces Raw pairwise scatter plots for the out-of-sample window (2020--2025, $N = 390$ bins, 27 NMDB stations). Layout identical to Figure\nobreakspace {}\ref {fig:rawinsample}. The CR--sunspot anti-correlation strengthens to $r = -0.939$ during Solar Cycle\nobreakspace {}25, which had a particularly wide dynamic range. The CR--seismicity correlation ($r = 0.046$, $p_\text {Bonf} = 1.0$) is indistinguishable from zero.\relax }}{15}{figure.caption.9}\protected@file@percent }
\newlabel{fig:rawoos}{{2}{15}{Raw pairwise scatter plots for the out-of-sample window (2020--2025, $N = 390$ bins, 27 NMDB stations). Layout identical to Figure~\ref {fig:rawinsample}. The CR--sunspot anti-correlation strengthens to $r = -0.939$ during Solar Cycle~25, which had a particularly wide dynamic range. The CR--seismicity correlation ($r = 0.046$, $p_\text {Bonf} = 1.0$) is indistinguishable from zero.\relax }{figure.caption.9}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces Raw pairwise scatter plots for the full combined window (1976--2025, $N = 3{,}604$ bins). The multi-decadal colour gradient in the centre panel shows CR and sunspot oscillating in anti-phase across four complete solar cycles. The overall CR--seismicity Pearson correlation ($r = 0.055$, $\rho = 0.065$) is statistically significant ($p_\text {Bonf} = 0.008$) but quantitatively negligible, and its sign follows directly from the confounding triangle described in the text.\relax }}{16}{figure.caption.10}\protected@file@percent }
\newlabel{fig:rawcombined}{{3}{16}{Raw pairwise scatter plots for the full combined window (1976--2025, $N = 3{,}604$ bins). The multi-decadal colour gradient in the centre panel shows CR and sunspot oscillating in anti-phase across four complete solar cycles. The overall CR--seismicity Pearson correlation ($r = 0.055$, $\rho = 0.065$) is statistically significant ($p_\text {Bonf} = 0.008$) but quantitatively negligible, and its sign follows directly from the confounding triangle described in the text.\relax }{figure.caption.10}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Cross-correlation function $r(\tau )$ for the raw (undetrended) CR index and global seismic metric, 1976--2019. The dominant peak at $\tau = -525$\nobreakspace {}days (vertical dashed line, red) corresponds to a half-solar-cycle lag; the claimed $\tau = +15$\nobreakspace {}days is marked with a vertical solid line (blue). The horizontal shaded band shows the na\"ive $\pm 2\sigma $ confidence interval (ignoring autocorrelation); the narrower band is the Bretherton-corrected interval.\relax }}{16}{figure.caption.11}\protected@file@percent }
\newlabel{fig:homola}{{4}{16}{Cross-correlation function $r(\tau )$ for the raw (undetrended) CR index and global seismic metric, 1976--2019. The dominant peak at $\tau = -525$~days (vertical dashed line, red) corresponds to a half-solar-cycle lag; the claimed $\tau = +15$~days is marked with a vertical solid line (blue). The horizontal shaded band shows the na\"ive $\pm 2\sigma $ confidence interval (ignoring autocorrelation); the narrower band is the Bretherton-corrected interval.\relax }{figure.caption.11}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.3}IAAFT Surrogate Test}{17}{subsection.4.3}\protected@file@percent }
\newlabel{sec:res:surr}{{4.3}{17}{IAAFT Surrogate Test}{subsection.4.3}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces Null distribution of the peak cross-correlation statistic from 10{,}000 IAAFT surrogates for the raw (blue) and HP-detrended (orange) CR--seismic series. Vertical dashed lines mark the observed peak for each case. While the raw peak is improbably large under the null, the detrended peak is only marginally significant, and the correlation at the claimed $\tau =+15$\nobreakspace {}d is not.\relax }}{17}{figure.caption.12}\protected@file@percent }
\newlabel{fig:stress}{{5}{17}{Null distribution of the peak cross-correlation statistic from 10{,}000 IAAFT surrogates for the raw (blue) and HP-detrended (orange) CR--seismic series. Vertical dashed lines mark the observed peak for each case. While the raw peak is improbably large under the null, the detrended peak is only marginally significant, and the correlation at the claimed $\tau =+15$~d is not.\relax }{figure.caption.12}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.4}Effect of Solar-Cycle Detrending}{18}{subsection.4.4}\protected@file@percent }
\newlabel{sec:res:detrend}{{4.4}{18}{Effect of Solar-Cycle Detrending}{subsection.4.4}{}}
\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces Cross-correlation statistics at $\tau = +15$\nobreakspace {}days under four preprocessing conditions, in-sample window 1976--2019.\relax }}{18}{table.caption.13}\protected@file@percent }
\newlabel{tab:detrend}{{2}{18}{Cross-correlation statistics at $\tau = +15$~days under four preprocessing conditions, in-sample window 1976--2019.\relax }{table.caption.13}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.5}Detrending Robustness}{18}{subsection.4.5}\protected@file@percent }
\newlabel{sec:detrend_robust}{{4.5}{18}{Detrending Robustness}{subsection.4.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.6}Comparison of $N_\text {eff}$ Estimators}{18}{subsection.4.6}\protected@file@percent }
\newlabel{sec:neff_comparison}{{4.6}{18}{Comparison of $N_\text {eff}$ Estimators}{subsection.4.6}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces Cross-correlation functions for the raw (blue) and HP-detrended (orange) series. The dominant peak at $\tau = -525$\nobreakspace {}days in the raw data (dashed blue) is absent after detrending, confirming it is a solar-cycle artefact. Neither series exhibits a significant peak at $\tau = +15$\nobreakspace {}days (vertical grey line).\relax }}{19}{figure.caption.14}\protected@file@percent }
\newlabel{fig:detrended}{{6}{19}{Cross-correlation functions for the raw (blue) and HP-detrended (orange) series. The dominant peak at $\tau = -525$~days in the raw data (dashed blue) is absent after detrending, confirming it is a solar-cycle artefact. Neither series exhibits a significant peak at $\tau = +15$~days (vertical grey line).\relax }{figure.caption.14}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces Cross-correlation $r(\tau )$ under three detrending approaches (HP filter, Butterworth highpass, rolling-mean subtraction) for the raw CR index vs.\ log$_{10}$ seismic energy, 1976--2019. The vertical grey line marks the claimed $\tau = +15$\nobreakspace {}days. No method produces a positive feature at this lag.\relax }}{19}{figure.caption.15}\protected@file@percent }
\newlabel{fig:detrend_robust}{{7}{19}{Cross-correlation $r(\tau )$ under three detrending approaches (HP filter, Butterworth highpass, rolling-mean subtraction) for the raw CR index vs.\ log$_{10}$ seismic energy, 1976--2019. The vertical grey line marks the claimed $\tau = +15$~days. No method produces a positive feature at this lag.\relax }{figure.caption.15}{}}
\@writefile{lot}{\contentsline {table}{\numberline {3}{\ignorespaces Comparison of $N_\text {eff}$ estimators for raw in-sample series at $\tau = +15$\nobreakspace {}days ($N = 3{,}214$, $r = 0.079$).\relax }}{20}{table.caption.16}\protected@file@percent }
\newlabel{tab:neff}{{3}{20}{Comparison of $N_\text {eff}$ estimators for raw in-sample series at $\tau = +15$~days ($N = 3{,}214$, $r = 0.079$).\relax }{table.caption.16}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.7}Magnitude Threshold Sensitivity}{20}{subsection.4.7}\protected@file@percent }
\newlabel{sec:mag_threshold}{{4.7}{20}{Magnitude Threshold Sensitivity}{subsection.4.7}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {8}{\ignorespaces Cross-correlation $r(\tau )$ for three magnitude cutoffs ($M \geq 4.5$, blue; $M \geq 5.0$, orange; $M \geq 6.0$, green), in-sample window 1976--2019. The vertical grey line marks $\tau = +15$\nobreakspace {}days. All three cutoffs yield similar, small correlations at the claimed lag, and the dominant peak location ($\tau = -525$\nobreakspace {}days) is stable.\relax }}{20}{figure.caption.17}\protected@file@percent }
\newlabel{fig:mag_threshold}{{8}{20}{Cross-correlation $r(\tau )$ for three magnitude cutoffs ($M \geq 4.5$, blue; $M \geq 5.0$, orange; $M \geq 6.0$, green), in-sample window 1976--2019. The vertical grey line marks $\tau = +15$~days. All three cutoffs yield similar, small correlations at the claimed lag, and the dominant peak location ($\tau = -525$~days) is stable.\relax }{figure.caption.17}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.8}Block-Bootstrap Surrogate Comparison}{20}{subsection.4.8}\protected@file@percent }
\newlabel{sec:res:blockbootstrap}{{4.8}{20}{Block-Bootstrap Surrogate Comparison}{subsection.4.8}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {9}{\ignorespaces Block-bootstrap null distributions for the raw CR--seismic pair ($B = 804$ bins $\approx 11$\nobreakspace {}yr, $S = 5{,}000$ surrogates). \textbf {Left}: distribution of $r(+15\,\text {d})$ under the CBB null; observed value $r = 0.079$ (red) lies at the $p = 0.022$ tail. \textbf {Right}: distribution of the peak $|r|$; observed peak $0.135$ at $\tau = -525$\nobreakspace {}d lies at $p = 0.008$. Grey dashed lines mark the 95\% CI of the null.\relax }}{21}{figure.caption.18}\protected@file@percent }
\newlabel{fig:blockbootstrap}{{9}{21}{Block-bootstrap null distributions for the raw CR--seismic pair ($B = 804$ bins $\approx 11$~yr, $S = 5{,}000$ surrogates). \textbf {Left}: distribution of $r(+15\,\text {d})$ under the CBB null; observed value $r = 0.079$ (red) lies at the $p = 0.022$ tail. \textbf {Right}: distribution of the peak $|r|$; observed peak $0.135$ at $\tau = -525$~d lies at $p = 0.008$. Grey dashed lines mark the 95\% CI of the null.\relax }{figure.caption.18}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.9}Partial Correlation: Controlling for Sunspot Number}{21}{subsection.4.9}\protected@file@percent }
\newlabel{sec:res:partialcorr}{{4.9}{21}{Partial Correlation: Controlling for Sunspot Number}{subsection.4.9}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.10}Spectral Coherence and Mutual Information}{21}{subsection.4.10}\protected@file@percent }
\newlabel{sec:res:coherence}{{4.10}{21}{Spectral Coherence and Mutual Information}{subsection.4.10}{}}
\@writefile{toc}{\contentsline {paragraph}{Coherence.}{21}{section*.20}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {10}{\ignorespaces Cross-correlation $r(\tau )$ for the raw seismic metric (blue) and the sunspot-regressed seismic residual (orange), both against the CR index, on the raw (unfiltered) in-sample series. The claimed $\tau = +15$\nobreakspace {}d (grey dashed line) shows $r_\text {raw} = 0.079$ vs.\ $r_\text {partial} = 0.029$, a 63\% reduction once the shared solar-cycle component is regressed out.\relax }}{22}{figure.caption.19}\protected@file@percent }
\newlabel{fig:partialcorr}{{10}{22}{Cross-correlation $r(\tau )$ for the raw seismic metric (blue) and the sunspot-regressed seismic residual (orange), both against the CR index, on the raw (unfiltered) in-sample series. The claimed $\tau = +15$~d (grey dashed line) shows $r_\text {raw} = 0.079$ vs.\ $r_\text {partial} = 0.029$, a 63\% reduction once the shared solar-cycle component is regressed out.\relax }{figure.caption.19}{}}
\@writefile{toc}{\contentsline {paragraph}{Mutual information.}{22}{section*.21}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {4.11}Missing-Data Sensitivity}{22}{subsection.4.11}\protected@file@percent }
\newlabel{sec:res:missing}{{4.11}{22}{Missing-Data Sensitivity}{subsection.4.11}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {11}{\ignorespaces \textbf {Left}: Magnitude-squared coherence between the CR index and seismic metric (blue), with the solar-cycle band shaded (orange, 0.08--0.115 cycles\nobreakspace {}yr$^{-1}$) and the 95\% significance level (red dashed). The mean coherence in the SC band is 0.840, confirming a strong shared solar-cycle component. \textbf {Right}: kNN mutual information ($k = 5$) at lag $\tau = 0$ (blue) and $\tau = +15$\nobreakspace {}d (orange) vs.\ their respective shuffle-null distributions. Both observed MI values are indistinguishable from zero; $p(+15\,\text {d}) = 1.000$.\relax }}{23}{figure.caption.22}\protected@file@percent }
\newlabel{fig:coherence}{{11}{23}{\textbf {Left}: Magnitude-squared coherence between the CR index and seismic metric (blue), with the solar-cycle band shaded (orange, 0.08--0.115 cycles~yr$^{-1}$) and the 95\% significance level (red dashed). The mean coherence in the SC band is 0.840, confirming a strong shared solar-cycle component. \textbf {Right}: kNN mutual information ($k = 5$) at lag $\tau = 0$ (blue) and $\tau = +15$~d (orange) vs.\ their respective shuffle-null distributions. Both observed MI values are indistinguishable from zero; $p(+15\,\text {d}) = 1.000$.\relax }{figure.caption.22}{}}
\@writefile{lot}{\contentsline {table}{\numberline {4}{\ignorespaces Missing-data sensitivity: global CR index and correlation at $\tau = +15$\nobreakspace {}days for three station-threshold values.\relax }}{23}{table.caption.23}\protected@file@percent }
\newlabel{tab:missing}{{4}{23}{Missing-data sensitivity: global CR index and correlation at $\tau = +15$~days for three station-threshold values.\relax }{table.caption.23}{}}
\citation{GardnerKnopoff1974}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.12}Bin-Size Sensitivity}{24}{subsection.4.12}\protected@file@percent }
\newlabel{sec:res:binsize}{{4.12}{24}{Bin-Size Sensitivity}{subsection.4.12}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {12}{\ignorespaces Cross-correlation $r(\tau )$ for three bin sizes: 1-day (left), 5-day (centre), 27-day (right). The dominant peak (red dotted) consistently falls near $\tau \approx -520$\nobreakspace {}days across all bin sizes. The correlation at the claimed $\tau = +15$\nobreakspace {}days (grey dashed) increases from 0.036 to 0.123 as bin size increases, consistent with increasing solar-cycle leakage rather than a physical short-lag signal.\relax }}{24}{figure.caption.24}\protected@file@percent }
\newlabel{fig:binsize}{{12}{24}{Cross-correlation $r(\tau )$ for three bin sizes: 1-day (left), 5-day (centre), 27-day (right). The dominant peak (red dotted) consistently falls near $\tau \approx -520$~days across all bin sizes. The correlation at the claimed $\tau = +15$~days (grey dashed) increases from 0.036 to 0.123 as bin size increases, consistent with increasing solar-cycle leakage rather than a physical short-lag signal.\relax }{figure.caption.24}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.13}Earthquake Declustering (Gardner--Knopoff)}{24}{subsection.4.13}\protected@file@percent }
\newlabel{sec:res:decluster}{{4.13}{24}{Earthquake Declustering (Gardner--Knopoff)}{subsection.4.13}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {13}{\ignorespaces Cross-correlation for the full catalogue ($n = 232{,}043$ events, blue) and the Gardner--Knopoff declustered catalogue ($n = 166{,}169$ mainshocks, orange), in-sample 1976--2019. Removing 28.4\% of events as aftershocks changes $r(+15\,\text {d})$ by only $\Delta r = 0.014$, confirming the result is not driven by aftershock swarms.\relax }}{25}{figure.caption.25}\protected@file@percent }
\newlabel{fig:decluster}{{13}{25}{Cross-correlation for the full catalogue ($n = 232{,}043$ events, blue) and the Gardner--Knopoff declustered catalogue ($n = 166{,}169$ mainshocks, orange), in-sample 1976--2019. Removing 28.4\% of events as aftershocks changes $r(+15\,\text {d})$ by only $\Delta r = 0.014$, confirming the result is not driven by aftershock swarms.\relax }{figure.caption.25}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.14}Sub-Period Analysis by Solar Cycle}{25}{subsection.4.14}\protected@file@percent }
\newlabel{sec:res:subcycles}{{4.14}{25}{Sub-Period Analysis by Solar Cycle}{subsection.4.14}{}}
\@writefile{lot}{\contentsline {table}{\numberline {5}{\ignorespaces Per-solar-cycle cross-correlation at $\tau = +15$\nobreakspace {}days and the within-cycle dominant peak.\relax }}{25}{table.caption.26}\protected@file@percent }
\newlabel{tab:subcycles}{{5}{25}{Per-solar-cycle cross-correlation at $\tau = +15$~days and the within-cycle dominant peak.\relax }{table.caption.26}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.15}Geographic Localisation}{25}{subsection.4.15}\protected@file@percent }
\newlabel{sec:res:geo}{{4.15}{25}{Geographic Localisation}{subsection.4.15}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {14}{\ignorespaces Cross-correlation $r(\tau )$ within each of the four complete solar cycles (21--24) of the in-sample period (1976--2019). The claimed lag $\tau = +15$\nobreakspace {}days (grey dashed) shows modest positive correlations (0.018--0.073), but the dominant peak lag (red dotted) is inconsistent across cycles ($-65$, $-125$, $+125$, $-125$\nobreakspace {}days), pointing to a drift in the relative solar-cycle phase rather than a physical mechanism.\relax }}{26}{figure.caption.27}\protected@file@percent }
\newlabel{fig:subcycles}{{14}{26}{Cross-correlation $r(\tau )$ within each of the four complete solar cycles (21--24) of the in-sample period (1976--2019). The claimed lag $\tau = +15$~days (grey dashed) shows modest positive correlations (0.018--0.073), but the dominant peak lag (red dotted) is inconsistent across cycles ($-65$, $-125$, $+125$, $-125$~days), pointing to a drift in the relative solar-cycle phase rather than a physical mechanism.\relax }{figure.caption.27}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {15}{\ignorespaces Heatmap of BH-significant station--grid-cell pairs ($q = 0.05$). Each row is an NMDB station; each column is a $10° \times 10°$ seismic grid cell. Significant pairs (455/7{,}037) are scattered without obvious geographic clustering, inconsistent with a local coupling mechanism.\relax }}{27}{figure.caption.28}\protected@file@percent }
\newlabel{fig:geoheatmap}{{15}{27}{Heatmap of BH-significant station--grid-cell pairs ($q = 0.05$). Each row is an NMDB station; each column is a $10° \times 10°$ seismic grid cell. Significant pairs (455/7{,}037) are scattered without obvious geographic clustering, inconsistent with a local coupling mechanism.\relax }{figure.caption.28}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {16}{\ignorespaces Optimal lag $\tau ^*(s,g)$ vs.\ great-circle distance $d(s,g)$ for all 7{,}037 station--cell pairs (grey) and BH-significant pairs (coloured by peak $|r|$). The OLS regression line (red) has slope $\beta = -0.45$\nobreakspace {}days/1000\,km ($p=0.21$), consistent with zero. A local propagation mechanism would predict a positive slope.\relax }}{27}{figure.caption.29}\protected@file@percent }
\newlabel{fig:geodistlag}{{16}{27}{Optimal lag $\tau ^*(s,g)$ vs.\ great-circle distance $d(s,g)$ for all 7{,}037 station--cell pairs (grey) and BH-significant pairs (coloured by peak $|r|$). The OLS regression line (red) has slope $\beta = -0.45$~days/1000\,km ($p=0.21$), consistent with zero. A local propagation mechanism would predict a positive slope.\relax }{figure.caption.29}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.16}Pre-Registered Out-of-Sample Validation (2020--2025)}{28}{subsection.4.16}\protected@file@percent }
\newlabel{sec:res:oos}{{4.16}{28}{Pre-Registered Out-of-Sample Validation (2020--2025)}{subsection.4.16}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {17}{\ignorespaces Out-of-sample cross-correlation function (2020--2025, $T=390$ bins, $10^5$ phase surrogates). The observed $r(\tau )$ (black) lies within the surrogate 95th-percentile envelope (grey shading). The claimed signal at $\tau = +15$\nobreakspace {}d (vertical line) is $r = 0.030$ --- below the surrogate 95th percentile of 0.101.\relax }}{28}{figure.caption.30}\protected@file@percent }
\newlabel{fig:oosxcorr}{{17}{28}{Out-of-sample cross-correlation function (2020--2025, $T=390$ bins, $10^5$ phase surrogates). The observed $r(\tau )$ (black) lies within the surrogate 95th-percentile envelope (grey shading). The claimed signal at $\tau = +15$~d (vertical line) is $r = 0.030$ --- below the surrogate 95th percentile of 0.101.\relax }{figure.caption.30}{}}
\@writefile{lot}{\contentsline {table}{\numberline {6}{\ignorespaces Pre-registered prediction scorecard for the out-of-sample window.\relax }}{28}{table.caption.31}\protected@file@percent }
\newlabel{tab:prereg}{{6}{28}{Pre-registered prediction scorecard for the out-of-sample window.\relax }{table.caption.31}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {18}{\ignorespaces Rolling $r(+15\,\text {d})$ in 18-month overlapping windows across the out-of-sample period. Error bars are bootstrap 95\% confidence intervals. The grey horizontal band shows the surrogate 95th percentile. The signal shows no consistent sign or trend.\relax }}{29}{figure.caption.32}\protected@file@percent }
\newlabel{fig:rolling}{{18}{29}{Rolling $r(+15\,\text {d})$ in 18-month overlapping windows across the out-of-sample period. Error bars are bootstrap 95\% confidence intervals. The grey horizontal band shows the surrogate 95th percentile. The signal shows no consistent sign or trend.\relax }{figure.caption.32}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {4.17}Combined 1976--2025 Analysis: Sinusoidal Modulation}{29}{subsection.4.17}\protected@file@percent }
\newlabel{sec:res:combined}{{4.17}{29}{Combined 1976--2025 Analysis: Sinusoidal Modulation}{subsection.4.17}{}}
\@writefile{lof}{\contentsline {figure}{\numberline {19}{\ignorespaces Annual rolling $r(+15\,\text {d})$ across the full 1976--2025 period (grey points with 95\% bootstrap CI). The sinusoidal best-fit (red curve, $P = 13.0$\nobreakspace {}yr) and the constant-mean model (dashed) are nearly indistinguishable; BIC comparison slightly favours the constant model ($\text {BF} = 0.75$). The vertical dashed line marks the in-sample/out-of-sample split (2020).\relax }}{29}{figure.caption.33}\protected@file@percent }
\newlabel{fig:combined}{{19}{29}{Annual rolling $r(+15\,\text {d})$ across the full 1976--2025 period (grey points with 95\% bootstrap CI). The sinusoidal best-fit (red curve, $P = 13.0$~yr) and the constant-mean model (dashed) are nearly indistinguishable; BIC comparison slightly favours the constant model ($\text {BF} = 0.75$). The vertical dashed line marks the in-sample/out-of-sample split (2020).\relax }{figure.caption.33}{}}
\citation{Homola2023}
\citation{Odintsov2006}
\citation{Aplin2005}
\citation{Pulinets2004}
\@writefile{toc}{\contentsline {section}{\numberline {5}Discussion}{16}{section.5}\protected@file@percent }
\newlabel{sec:discussion}{{5}{16}{Discussion}{section.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Why Does the Raw Correlation Appear So Strong?}{16}{subsection.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Physical Plausibility of the Claimed Mechanism}{16}{subsection.5.2}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {5}Discussion}{30}{section.5}\protected@file@percent }
\newlabel{sec:discussion}{{5}{30}{Discussion}{section.5}{}}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}Why Does the Raw Correlation Appear So Strong?}{30}{subsection.5.1}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.2}Physical Plausibility of the Claimed Mechanism}{30}{subsection.5.2}\protected@file@percent }
\citation{Homola2023}
\citation{Urata2018}
\citation{Homola2023}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}Comparison with Prior Replication Attempts}{17}{subsection.5.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Limitations}{17}{subsection.5.4}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {6}Conclusions}{17}{section.6}\protected@file@percent }
\newlabel{sec:conclusions}{{6}{17}{Conclusions}{section.6}{}}
\citation{Homola2023}
\@writefile{toc}{\contentsline {subsection}{\numberline {5.3}Comparison with Prior Replication Attempts}{31}{subsection.5.3}\protected@file@percent }
\@writefile{toc}{\contentsline {subsection}{\numberline {5.4}Limitations}{31}{subsection.5.4}\protected@file@percent }
\@writefile{toc}{\contentsline {section}{\numberline {6}Conclusions}{31}{section.6}\protected@file@percent }
\newlabel{sec:conclusions}{{6}{31}{Conclusions}{section.6}{}}
\bibstyle{plainnat}
\bibdata{refs}
\bibcite{Aplin2005}{{1}{2006}{{Aplin}}{{}}}
\bibcite{Benjamini1995}{{2}{1995}{{Benjamini and Hochberg}}{{}}}
\bibcite{Bretherton1999}{{3}{1999}{{Bretherton et~al.}}{{Bretherton, Widmann, Dymnikov, Wallace, and Blade}}}
\bibcite{Cleveland1990}{{4}{1990}{{Cleveland et~al.}}{{Cleveland, Cleveland, McRae, and Terpenning}}}
\bibcite{HP1997}{{5}{1997}{{Hodrick and Prescott}}{{}}}
\bibcite{Homola2023}{{6}{2023}{{Homola et~al.}}{{}}}
\bibcite{Jeffreys1961}{{7}{1961}{{Jeffreys}}{{}}}
\bibcite{Odintsov2006}{{8}{2006}{{Odintsov et~al.}}{{Odintsov, Boyarchuk, Georgieva, Kirov, and Atanasov}}}
\bibcite{Potgieter2013}{{9}{2013}{{Potgieter}}{{}}}
\bibcite{Pulinets2004}{{10}{2004}{{Pulinets and Boyarchuk}}{{}}}
\bibcite{Schreiber2000}{{11}{2000}{{Schreiber and Schmitz}}{{}}}
\bibcite{SIDC2024}{{12}{2024}{{SILSO World Data Center}}{{}}}
\bibcite{Stoupel1990}{{13}{1990}{{Stoupel}}{{}}}
\bibcite{Tavares2011}{{14}{2011}{{Tavares and Azevedo}}{{}}}
\bibcite{Theiler1992}{{15}{1992}{{Theiler et~al.}}{{Theiler, Eubank, Longtin, Galdrikian, and Farmer}}}
\bibcite{Urata2018}{{16}{2018}{{Urata and Tanimoto}}{{}}}
\bibcite{USGS2024}{{17}{2024}{{USGS Earthquake Hazards Program}}{{}}}
\gdef \@abspage@last{19}
\bibcite{Bartlett1946}{{2}{1946}{{Bartlett}}{{}}}
\bibcite{Benjamini1995}{{3}{1995}{{Benjamini and Hochberg}}{{}}}
\bibcite{Bretherton1999}{{4}{1999}{{Bretherton et~al.}}{{Bretherton, Widmann, Dymnikov, Wallace, and Blade}}}
\bibcite{Cleveland1990}{{5}{1990}{{Cleveland et~al.}}{{Cleveland, Cleveland, McRae, and Terpenning}}}
\bibcite{GardnerKnopoff1974}{{6}{1974}{{Gardner and Knopoff}}{{}}}
\bibcite{HP1997}{{7}{1997}{{Hodrick and Prescott}}{{}}}
\bibcite{Homola2023}{{8}{2022}{{Homola et~al.}}{{}}}
\bibcite{Kanamori1977}{{9}{1977}{{Kanamori}}{{}}}
\bibcite{Kraskov2004}{{10}{2004}{{Kraskov et~al.}}{{Kraskov, St{\"o}gbauer, and Grassberger}}}
\bibcite{Odintsov2006}{{11}{2006}{{Odintsov et~al.}}{{Odintsov, Boyarchuk, Georgieva, Kirov, and Atanasov}}}
\bibcite{Potgieter2013}{{12}{2013}{{Potgieter}}{{}}}
\bibcite{Pulinets2004}{{13}{2004}{{Pulinets and Boyarchuk}}{{}}}
\bibcite{RahnUhlig2002}{{14}{2002}{{Ravn and Uhlig}}{{}}}
\bibcite{Schreiber2000}{{15}{2000}{{Schreiber and Schmitz}}{{}}}
\bibcite{SIDC2024}{{16}{2024}{{SILSO World Data Center}}{{}}}
\bibcite{Stoupel1990}{{17}{1990}{{Stoupel}}{{}}}
\bibcite{Tavares2011}{{18}{2011}{{Tavares and Azevedo}}{{}}}
\bibcite{Theiler1992}{{19}{1992}{{Theiler et~al.}}{{Theiler, Eubank, Longtin, Galdrikian, and Farmer}}}
\bibcite{Urata2018}{{20}{2018}{{Urata and Tanimoto}}{{}}}
\bibcite{USGS2024}{{21}{2024}{{USGS Earthquake Hazards Program}}{{}}}
\gdef \@abspage@last{35}

View file

@ -1,4 +1,4 @@
\begin{thebibliography}{19}
\begin{thebibliography}{21}
\providecommand{\natexlab}[1]{#1}
\providecommand{\url}[1]{\texttt{#1}}
\expandafter\ifx\csname urlstyle\endcsname\relax
@ -45,6 +45,14 @@ Robert~B. Cleveland, William~S. Cleveland, Jean~E. McRae, and Irma Terpenning.
\newblock \emph{Journal of Official Statistics}, 6\penalty0 (1):\penalty0
3--73, 1990.
\bibitem[Gardner and Knopoff(1974)]{GardnerKnopoff1974}
J.~K. Gardner and Leon Knopoff.
\newblock Is the sequence of earthquakes in southern {California}, with
aftershocks removed, {Poissonian}?
\newblock \emph{Bulletin of the Seismological Society of America}, 64\penalty0
(5):\penalty0 1363--1367, 1974.
\newblock \doi{10.1785/BSSA0640051363}.
\bibitem[Hodrick and Prescott(1997)]{HP1997}
Robert~J. Hodrick and Edward~C. Prescott.
\newblock Postwar {U.S.} business cycles: an empirical investigation.
@ -52,12 +60,11 @@ Robert~J. Hodrick and Edward~C. Prescott.
(1):\penalty0 1--16, 1997.
\newblock \doi{10.2307/2953682}.
\bibitem[Homola et~al.(2023)]{Homola2023}
\bibitem[Homola et~al.(2022)]{Homola2023}
Piotr Homola et~al.
\newblock Indication of correlation between cosmic-ray flux and global
seismicity.
\newblock \emph{Remote Sensing}, 15\penalty0 (1):\penalty0 200, 2023.
\newblock \doi{10.3390/rs15010200}.
seismicity, 2022.
\newblock URL \url{https://arxiv.org/abs/2204.12310}.
\bibitem[Kanamori(1977)]{Kanamori1977}
Hiroo Kanamori.
@ -66,6 +73,13 @@ Hiroo Kanamori.
2981--2987, 1977.
\newblock \doi{10.1029/JB082i020p02981}.
\bibitem[Kraskov et~al.(2004)Kraskov, St{\"o}gbauer, and
Grassberger]{Kraskov2004}
Alexander Kraskov, Harald St{\"o}gbauer, and Peter Grassberger.
\newblock Estimating mutual information.
\newblock \emph{Physical Review E}, 69\penalty0 (6):\penalty0 066138, 2004.
\newblock \doi{10.1103/PhysRevE.69.066138}.
\bibitem[Odintsov et~al.(2006)Odintsov, Boyarchuk, Georgieva, Kirov, and
Atanasov]{Odintsov2006}
Stanislav Odintsov, Kirill Boyarchuk, Katya Georgieva, Boian Kirov, and Dimitar

View file

@ -3,44 +3,44 @@ Capacity: max_strings=200000, hash_size=200000, hash_prime=170003
The top-level auxiliary file: main.aux
The style file: plainnat.bst
Database file #1: refs.bib
You've used 17 entries,
You've used 21 entries,
2773 wiz_defined-function locations,
730 strings with 7851 characters,
and the built_in function-call counts, 7427 in all, are:
= -- 684
> -- 389
< -- 13
+ -- 134
- -- 117
* -- 600
:= -- 1166
add.period$ -- 62
call.type$ -- 17
change.case$ -- 89
chr.to.int$ -- 17
cite$ -- 34
duplicate$ -- 333
empty$ -- 624
format.name$ -- 147
if$ -- 1540
766 strings with 8739 characters,
and the built_in function-call counts, 9334 in all, are:
= -- 875
> -- 471
< -- 16
+ -- 162
- -- 141
* -- 762
:= -- 1451
add.period$ -- 78
call.type$ -- 21
change.case$ -- 109
chr.to.int$ -- 21
cite$ -- 42
duplicate$ -- 409
empty$ -- 790
format.name$ -- 179
if$ -- 1941
int.to.chr$ -- 1
int.to.str$ -- 1
missing$ -- 16
newline$ -- 104
num.names$ -- 68
pop$ -- 156
missing$ -- 18
newline$ -- 128
num.names$ -- 84
pop$ -- 186
preamble$ -- 1
purify$ -- 72
purify$ -- 88
quote$ -- 0
skip$ -- 256
skip$ -- 318
stack$ -- 0
substring$ -- 266
swap$ -- 17
substring$ -- 389
swap$ -- 21
text.length$ -- 0
text.prefix$ -- 0
top$ -- 0
type$ -- 182
type$ -- 231
warning$ -- 0
while$ -- 74
while$ -- 94
width$ -- 0
write$ -- 247
write$ -- 306

View file

@ -1,4 +1,4 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022/Debian) (preloaded format=pdflatex 2026.4.24) 24 APR 2026 07:51
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022/Debian) (preloaded format=pdflatex 2026.4.24) 24 APR 2026 20:21
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
@ -702,162 +702,245 @@ Package microtype Info: Loading generic protrusion settings for font family
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] (./main.toc
LaTeX Font Info: External font `lmex10' loaded for size
(Font) <12> on input line 3.
)
[3])
\tf@toc=\write4
\openout4 = `main.toc'.
[3] [4]
[4] [5] [6]
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `math shift' on input line 201.
(hyperref) removing `math shift' on input line 216.
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `\tau' on input line 201.
(hyperref) removing `\tau' on input line 216.
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `math shift' on input line 201.
(hyperref) removing `math shift' on input line 216.
[5]
[7]
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `math shift' on input line 265.
(hyperref) removing `math shift' on input line 310.
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `math shift' on input line 265.
(hyperref) removing `math shift' on input line 310.
[6]
[8] [9]
LaTeX Warning: Command \textdegree invalid in math mode on input line 331.
LaTeX Warning: Command \textdegree invalid in math mode on input line 438.
LaTeX Font Info: Trying to load font information for TS1+lmr on input line 3
31.
LaTeX Font Info: Trying to load font information for TS1+lmr on input line 4
38.
(/usr/share/texmf/tex/latex/lm/ts1lmr.fd
File: ts1lmr.fd 2015/05/01 v1.6.1 Font defs for Latin Modern
)
LaTeX Warning: Command \textdegree invalid in math mode on input line 331.
LaTeX Warning: Command \textdegree invalid in math mode on input line 438.
LaTeX Warning: Command \textdegree invalid in math mode on input line 331.
LaTeX Warning: Command \textdegree invalid in math mode on input line 438.
LaTeX Warning: Command \textdegree invalid in math mode on input line 331.
LaTeX Warning: Command \textdegree invalid in math mode on input line 438.
[7]
Overfull \hbox (25.1207pt too wide) in paragraph at lines 351--353
[10]
Overfull \hbox (25.1207pt too wide) in paragraph at lines 458--460
[]\T1/lmr/m/n/12 (-20) This file was com-mit-ted to git (\T1/lmtt/m/n/12 1832f7
3\T1/lmr/m/n/12 (-20) ) with a UTC times-tamp (\T1/lmtt/m/n/12 2026-04-22T00:44
:30Z\T1/lmr/m/n/12 (-20) )
[]
[8]
<figs//homola_replication.png, id=295, 1001.6622pt x 856.6404pt>
[11]
Overfull \hbox (4.69275pt too wide) in paragraph at lines 505--505
[]\T1/lmr/bx/n/14.4 (-20) Raw Pair-wise Cor-re-la-tions Be-tween CR, Seis-mic,
and Sunspot
[]
[12] [13]
Overfull \hbox (137.43011pt too wide) in paragraph at lines 634--655
[][]
[]
<figs//raw_corr_insample.png, id=455, 997.326pt x 333.4056pt>
File: figs//raw_corr_insample.png Graphic file (type png)
<use figs//raw_corr_insample.png>
Package pdftex.def Info: figs//raw_corr_insample.png used on input line 665.
(pdftex.def) Requested size: 455.24411pt x 152.18816pt.
<figs//raw_corr_oos.png, id=457, 997.8078pt x 333.4056pt>
File: figs//raw_corr_oos.png Graphic file (type png)
<use figs//raw_corr_oos.png>
Package pdftex.def Info: figs//raw_corr_oos.png used on input line 683.
(pdftex.def) Requested size: 455.24411pt x 152.11694pt.
<figs//raw_corr_combined.png, id=460, 997.326pt x 333.4056pt>
File: figs//raw_corr_combined.png Graphic file (type png)
<use figs//raw_corr_combined.png>
Package pdftex.def Info: figs//raw_corr_combined.png used on input line 696.
(pdftex.def) Requested size: 455.24411pt x 152.18816pt.
<figs//homola_replication.png, id=465, 1001.6622pt x 856.6404pt>
File: figs//homola_replication.png Graphic file (type png)
<use figs//homola_replication.png>
Package pdftex.def Info: figs//homola_replication.png used on input line 416.
Package pdftex.def Info: figs//homola_replication.png used on input line 727.
(pdftex.def) Requested size: 409.71692pt x 350.38828pt.
<figs//stress_test.png, id=298, 1001.6622pt x 856.1586pt>
[14] [15 <./figs//raw_corr_insample.png> <./figs//raw_corr_oos.png>] [16 <./fig
s//raw_corr_combined.png> <./figs//homola_replication.png>]
<figs//stress_test.png, id=485, 1001.6622pt x 856.1586pt>
File: figs//stress_test.png Graphic file (type png)
<use figs//stress_test.png>
Package pdftex.def Info: figs//stress_test.png used on input line 445.
Package pdftex.def Info: figs//stress_test.png used on input line 757.
(pdftex.def) Requested size: 409.71692pt x 350.19121pt.
[9] [10 <./figs//homola_replication.png>] [11 <./figs//stress_test.png>]
<figs//detrended_xcorr.png, id=321, 1076.3412pt x 732.336pt>
[17 <./figs//stress_test.png>]
<figs//detrended_xcorr.png, id=496, 1076.3412pt x 732.336pt>
File: figs//detrended_xcorr.png Graphic file (type png)
<use figs//detrended_xcorr.png>
Package pdftex.def Info: figs//detrended_xcorr.png used on input line 491.
Package pdftex.def Info: figs//detrended_xcorr.png used on input line 806.
(pdftex.def) Requested size: 409.71692pt x 278.77107pt.
<figs//detrend_robustness.png, id=498, 1004.0712pt x 639.8304pt>
File: figs//detrend_robustness.png Graphic file (type png)
<use figs//detrend_robustness.png>
Package pdftex.def Info: figs//detrend_robustness.png used on input line 832.
(pdftex.def) Requested size: 409.71692pt x 261.08249pt.
[12 <./figs//detrended_xcorr.png>]
<figs//geo_heatmap.png, id=329, 1292.6694pt x 498.1812pt>
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `math shift' on input line 841.
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `subscript' on input line 841.
Package hyperref Warning: Token not allowed in a PDF string (Unicode):
(hyperref) removing `math shift' on input line 841.
[18] [19 <./figs//detrended_xcorr.png> <./figs//detrend_robustness.png>]
<figs//magnitude_threshold.png, id=516, 1148.6112pt x 321.3606pt>
File: figs//magnitude_threshold.png Graphic file (type png)
<use figs//magnitude_threshold.png>
Package pdftex.def Info: figs//magnitude_threshold.png used on input line 888.
(pdftex.def) Requested size: 409.71692pt x 114.63055pt.
[20 <./figs//magnitude_threshold.png>]
<figs//block_bootstrap_null.png, id=526, 787.743pt x 278.4804pt>
File: figs//block_bootstrap_null.png Graphic file (type png)
<use figs//block_bootstrap_null.png>
Package pdftex.def Info: figs//block_bootstrap_null.png used on input line 922
.
(pdftex.def) Requested size: 432.48051pt x 152.89273pt.
<figs//partial_correlation.png, id=528, 642.7212pt x 277.9986pt>
File: figs//partial_correlation.png Graphic file (type png)
<use figs//partial_correlation.png>
Package pdftex.def Info: figs//partial_correlation.png used on input line 952.
(pdftex.def) Requested size: 409.71692pt x 177.21432pt.
[21 <./figs//block_bootstrap_null.png>]
<figs//spectral_coherence.png, id=540, 787.2612pt x 277.9986pt>
File: figs//spectral_coherence.png Graphic file (type png)
<use figs//spectral_coherence.png>
Package pdftex.def Info: figs//spectral_coherence.png used on input line 991.
(pdftex.def) Requested size: 432.48051pt x 152.71729pt.
[22 <./figs//partial_correlation.png>] [23 <./figs//spectral_coherence.png>]
<figs//bin_size_sensitivity.png, id=555, 1002.144pt x 285.7074pt>
File: figs//bin_size_sensitivity.png Graphic file (type png)
<use figs//bin_size_sensitivity.png>
Package pdftex.def Info: figs//bin_size_sensitivity.png used on input line 106
0.
(pdftex.def) Requested size: 455.24411pt x 129.7878pt.
<figs//declustered_xcorr.png, id=559, 642.7212pt x 277.9986pt>
File: figs//declustered_xcorr.png Graphic file (type png)
<use figs//declustered_xcorr.png>
Package pdftex.def Info: figs//declustered_xcorr.png used on input line 1089.
(pdftex.def) Requested size: 409.71692pt x 177.21432pt.
[24 <./figs//bin_size_sensitivity.png>]
<figs//solar_cycle_xcorr.png, id=571, 859.5312pt x 569.0058pt>
File: figs//solar_cycle_xcorr.png Graphic file (type png)
<use figs//solar_cycle_xcorr.png>
Package pdftex.def Info: figs//solar_cycle_xcorr.png used on input line 1135.
(pdftex.def) Requested size: 455.24411pt x 301.37195pt.
[25 <./figs//declustered_xcorr.png>]
[26 <./figs//solar_cycle_xcorr.png>]
<figs//geo_heatmap.png, id=587, 1292.6694pt x 498.1812pt>
File: figs//geo_heatmap.png Graphic file (type png)
<use figs//geo_heatmap.png>
Package pdftex.def Info: figs//geo_heatmap.png used on input line 513.
Package pdftex.def Info: figs//geo_heatmap.png used on input line 1158.
(pdftex.def) Requested size: 409.71692pt x 157.90091pt.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
LaTeX Warning: Command \textdegree invalid in math mode on input line 517.
LaTeX Warning: Command \textdegree invalid in math mode on input line 1162.
<figs//geo_distance_lag.png, id=331, 1148.6112pt x 424.4658pt>
<figs//geo_distance_lag.png, id=589, 1148.6112pt x 424.4658pt>
File: figs//geo_distance_lag.png Graphic file (type png)
<use figs//geo_distance_lag.png>
Package pdftex.def Info: figs//geo_distance_lag.png used on input line 532.
Package pdftex.def Info: figs//geo_distance_lag.png used on input line 1177.
(pdftex.def) Requested size: 409.71692pt x 151.40857pt.
[13 <./figs//geo_heatmap.png>]
<figs//oos_xcorr.png, id=344, 849.8952pt x 336.2964pt>
[27 <./figs//geo_heatmap.png> <./figs//geo_distance_lag.png>]
<figs//oos_xcorr.png, id=600, 849.8952pt x 336.2964pt>
File: figs//oos_xcorr.png Graphic file (type png)
<use figs//oos_xcorr.png>
Package pdftex.def Info: figs//oos_xcorr.png used on input line 565.
Package pdftex.def Info: figs//oos_xcorr.png used on input line 1210.
(pdftex.def) Requested size: 409.71692pt x 162.12344pt.
<figs//rolling_correlation_oos.png, id=345, 731.3724pt x 323.7696pt>
<figs//rolling_correlation_oos.png, id=601, 731.3724pt x 323.7696pt>
File: figs//rolling_correlation_oos.png Graphic file (type png)
<use figs//rolling_correlation_oos.png>
Package pdftex.def Info: figs//rolling_correlation_oos.png used on input line
593.
1238.
(pdftex.def) Requested size: 409.71692pt x 181.3789pt.
<figs//full_series_with_envelope_fit.png, id=347, 955.4094pt x 447.5922pt>
[28 <./figs//oos_xcorr.png>]
<figs//full_series_with_envelope_fit.png, id=611, 955.4094pt x 447.5922pt>
File: figs//full_series_with_envelope_fit.png Graphic file (type png)
<use figs//full_series_with_envelope_fit.png>
Package pdftex.def Info: figs//full_series_with_envelope_fit.png used on input
line 609.
line 1254.
(pdftex.def) Requested size: 409.71692pt x 191.94183pt.
[14 <./figs//geo_distance_lag.png> <./figs//oos_xcorr.png>] [15 <./figs//rolli
ng_correlation_oos.png> <./figs//full_series_with_envelope_fit.png>]
! Missing number, treated as zero.
<to be read again>
\egroup
l.664 $\sim$\SI{0.3}{\milli\gray\per\year}
\citep{Aplin2005} --- far too sma...
A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)
[16]
Overfull \hbox (9.19893pt too wide) in paragraph at lines 703--708
[29 <./figs//rolling_correlation_oos.png> <./figs//full_series_with_envelope_f
it.png>] [30]
Overfull \hbox (9.19893pt too wide) in paragraph at lines 1352--1357
\T1/lmr/m/n/12 (-20) We have con-ducted a rig-or-ous, pre-registered repli-ca-t
ion of the claimed cosmic-ray/earthquake
[]
[17] (./main.bbl [18]) [19] (./main.aux)
[31] [32] (./main.bbl [33] [34]) [35] (./main.aux)
Package rerunfilecheck Info: File `main.out' has not changed.
(rerunfilecheck) Checksum: DEE0615BF3B395B6BFF33A7F84B98175;5900.
(rerunfilecheck) Checksum: 4C6DAC4BA1A6488C04C1CB417177CB2A;10188.
)
Here is how much of TeX's memory you used:
19146 strings out of 477975
360689 string characters out of 5839281
1866330 words of memory out of 5000000
38674 multiletter control sequences out of 15000+600000
609884 words of font info for 212 fonts, out of 8000000 for 9000
19468 strings out of 477975
366873 string characters out of 5839281
1874330 words of memory out of 5000000
38839 multiletter control sequences out of 15000+600000
628233 words of font info for 254 fonts, out of 8000000 for 9000
59 hyphenation exceptions out of 8191
75i,12n,76p,1001b,1041s stack positions out of 10000i,1000n,20000p,200000b,200000s
75i,12n,76p,1001b,1071s stack positions out of 10000i,1000n,20000p,200000b,200000s
{/usr/share/texmf/fonts/enc/dvips/lm/lm-ts1.enc}{/usr/share/texmf/fonts/enc/d
vips/lm/lm-ec.enc}{/usr/share/texmf/fonts/enc/dvips/lm/lm-rm.enc}{/usr/share/te
xmf/fonts/enc/dvips/lm/lm-mathit.enc}{/usr/share/texmf/fonts/enc/dvips/lm/lm-ma
thex.enc}{/usr/share/texmf/fonts/enc/dvips/lm/lm-mathsy.enc}</usr/share/texmf/f
vips/lm/lm-rm.enc}{/usr/share/texmf/fonts/enc/dvips/lm/lm-ec.enc}{/usr/share/te
xmf/fonts/enc/dvips/lm/lm-mathex.enc}{/usr/share/texmf/fonts/enc/dvips/lm/lm-ma
thit.enc}{/usr/share/texmf/fonts/enc/dvips/lm/lm-mathsy.enc}</usr/share/texmf/f
onts/type1/public/lm/lmbx10.pfb></usr/share/texmf/fonts/type1/public/lm/lmbx12.
pfb></usr/share/texmf/fonts/type1/public/lm/lmex10.pfb></usr/share/texmf/fonts/
type1/public/lm/lmmi10.pfb></usr/share/texmf/fonts/type1/public/lm/lmmi12.pfb><
@ -870,11 +953,12 @@ pfb></usr/share/texmf/fonts/type1/public/lm/lmss8.pfb></usr/share/texmf/fonts/t
ype1/public/lm/lmsy10.pfb></usr/share/texmf/fonts/type1/public/lm/lmsy8.pfb></u
sr/share/texmf/fonts/type1/public/lm/lmtt10.pfb></usr/share/texmf/fonts/type1/p
ublic/lm/lmtt12.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/
symbols/msbm10.pfb>
Output written on main.pdf (19 pages, 2510849 bytes).
symbols/msam10.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/s
ymbols/msbm10.pfb>
Output written on main.pdf (35 pages, 4580694 bytes).
PDF statistics:
543 PDF objects out of 1000 (max. 8388607)
458 compressed objects within 5 object streams
108 named destinations out of 1000 (max. 500000)
54553 words of extra memory for PDF output out of 61914 (max. 10000000)
826 PDF objects out of 1000 (max. 8388607)
698 compressed objects within 7 object streams
177 named destinations out of 1000 (max. 500000)
65000 words of extra memory for PDF output out of 74296 (max. 10000000)

View file

@ -9,22 +9,41 @@
\BOOKMARK [2][-]{subsection.3.3}{\376\377\000S\000u\000r\000r\000o\000g\000a\000t\000e\000\040\000S\000i\000g\000n\000i\000f\000i\000c\000a\000n\000c\000e\000\040\000T\000e\000s\000t\000s}{section.3}% 9
\BOOKMARK [3][-]{subsubsection.3.3.1}{\376\377\000P\000h\000a\000s\000e\000\040\000R\000a\000n\000d\000o\000m\000i\000s\000a\000t\000i\000o\000n}{subsection.3.3}% 10
\BOOKMARK [3][-]{subsubsection.3.3.2}{\376\377\000I\000A\000A\000F\000T\000\040\000S\000u\000r\000r\000o\000g\000a\000t\000e\000s}{subsection.3.3}% 11
\BOOKMARK [3][-]{subsubsection.3.3.3}{\376\377\000G\000l\000o\000b\000a\000l\000\040\000p\000-\000V\000a\000l\000u\000e}{subsection.3.3}% 12
\BOOKMARK [3][-]{subsubsection.3.3.4}{\376\377\000G\000P\000U\000\040\000A\000c\000c\000e\000l\000e\000r\000a\000t\000i\000o\000n}{subsection.3.3}% 13
\BOOKMARK [2][-]{subsection.3.4}{\376\377\000S\000o\000l\000a\000r\000-\000C\000y\000c\000l\000e\000\040\000D\000e\000t\000r\000e\000n\000d\000i\000n\000g}{section.3}% 14
\BOOKMARK [2][-]{subsection.3.5}{\376\377\000G\000e\000o\000g\000r\000a\000p\000h\000i\000c\000\040\000L\000o\000c\000a\000l\000i\000s\000a\000t\000i\000o\000n\000\040\000S\000c\000a\000n}{section.3}% 15
\BOOKMARK [2][-]{subsection.3.6}{\376\377\000P\000r\000e\000-\000R\000e\000g\000i\000s\000t\000e\000r\000e\000d\000\040\000O\000u\000t\000-\000o\000f\000-\000S\000a\000m\000p\000l\000e\000\040\000V\000a\000l\000i\000d\000a\000t\000i\000o\000n}{section.3}% 16
\BOOKMARK [2][-]{subsection.3.7}{\376\377\000C\000o\000m\000b\000i\000n\000e\000d\000\040\000T\000i\000m\000e\000s\000e\000r\000i\000e\000s\000:\000\040\000S\000i\000n\000u\000s\000o\000i\000d\000a\000l\000\040\000E\000n\000v\000e\000l\000o\000p\000e\000\040\000F\000i\000t}{section.3}% 17
\BOOKMARK [1][-]{section.4}{\376\377\000R\000e\000s\000u\000l\000t\000s}{}% 18
\BOOKMARK [2][-]{subsection.4.1}{\376\377\000I\000n\000-\000S\000a\000m\000p\000l\000e\000\040\000R\000e\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000\050\0001\0009\0007\0006\040\023\0002\0000\0001\0009\000\051}{section.4}% 19
\BOOKMARK [2][-]{subsection.4.2}{\376\377\000I\000A\000A\000F\000T\000\040\000S\000u\000r\000r\000o\000g\000a\000t\000e\000\040\000T\000e\000s\000t}{section.4}% 20
\BOOKMARK [2][-]{subsection.4.3}{\376\377\000E\000f\000f\000e\000c\000t\000\040\000o\000f\000\040\000S\000o\000l\000a\000r\000-\000C\000y\000c\000l\000e\000\040\000D\000e\000t\000r\000e\000n\000d\000i\000n\000g}{section.4}% 21
\BOOKMARK [2][-]{subsection.4.4}{\376\377\000G\000e\000o\000g\000r\000a\000p\000h\000i\000c\000\040\000L\000o\000c\000a\000l\000i\000s\000a\000t\000i\000o\000n}{section.4}% 22
\BOOKMARK [2][-]{subsection.4.5}{\376\377\000P\000r\000e\000-\000R\000e\000g\000i\000s\000t\000e\000r\000e\000d\000\040\000O\000u\000t\000-\000o\000f\000-\000S\000a\000m\000p\000l\000e\000\040\000V\000a\000l\000i\000d\000a\000t\000i\000o\000n\000\040\000\050\0002\0000\0002\0000\040\023\0002\0000\0002\0005\000\051}{section.4}% 23
\BOOKMARK [2][-]{subsection.4.6}{\376\377\000C\000o\000m\000b\000i\000n\000e\000d\000\040\0001\0009\0007\0006\040\023\0002\0000\0002\0005\000\040\000A\000n\000a\000l\000y\000s\000i\000s\000:\000\040\000S\000i\000n\000u\000s\000o\000i\000d\000a\000l\000\040\000M\000o\000d\000u\000l\000a\000t\000i\000o\000n}{section.4}% 24
\BOOKMARK [1][-]{section.5}{\376\377\000D\000i\000s\000c\000u\000s\000s\000i\000o\000n}{}% 25
\BOOKMARK [2][-]{subsection.5.1}{\376\377\000W\000h\000y\000\040\000D\000o\000e\000s\000\040\000t\000h\000e\000\040\000R\000a\000w\000\040\000C\000o\000r\000r\000e\000l\000a\000t\000i\000o\000n\000\040\000A\000p\000p\000e\000a\000r\000\040\000S\000o\000\040\000S\000t\000r\000o\000n\000g\000?}{section.5}% 26
\BOOKMARK [2][-]{subsection.5.2}{\376\377\000P\000h\000y\000s\000i\000c\000a\000l\000\040\000P\000l\000a\000u\000s\000i\000b\000i\000l\000i\000t\000y\000\040\000o\000f\000\040\000t\000h\000e\000\040\000C\000l\000a\000i\000m\000e\000d\000\040\000M\000e\000c\000h\000a\000n\000i\000s\000m}{section.5}% 27
\BOOKMARK [2][-]{subsection.5.3}{\376\377\000C\000o\000m\000p\000a\000r\000i\000s\000o\000n\000\040\000w\000i\000t\000h\000\040\000P\000r\000i\000o\000r\000\040\000R\000e\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000A\000t\000t\000e\000m\000p\000t\000s}{section.5}% 28
\BOOKMARK [2][-]{subsection.5.4}{\376\377\000L\000i\000m\000i\000t\000a\000t\000i\000o\000n\000s}{section.5}% 29
\BOOKMARK [1][-]{section.6}{\376\377\000C\000o\000n\000c\000l\000u\000s\000i\000o\000n\000s}{}% 30
\BOOKMARK [3][-]{subsubsection.3.3.3}{\376\377\000B\000l\000o\000c\000k\000-\000B\000o\000o\000t\000s\000t\000r\000a\000p\000\040\000S\000u\000r\000r\000o\000g\000a\000t\000e\000s}{subsection.3.3}% 12
\BOOKMARK [3][-]{subsubsection.3.3.4}{\376\377\000G\000l\000o\000b\000a\000l\000\040\000p\000-\000V\000a\000l\000u\000e}{subsection.3.3}% 13
\BOOKMARK [3][-]{subsubsection.3.3.5}{\376\377\000G\000P\000U\000\040\000A\000c\000c\000e\000l\000e\000r\000a\000t\000i\000o\000n}{subsection.3.3}% 14
\BOOKMARK [2][-]{subsection.3.4}{\376\377\000S\000o\000l\000a\000r\000-\000C\000y\000c\000l\000e\000\040\000D\000e\000t\000r\000e\000n\000d\000i\000n\000g}{section.3}% 15
\BOOKMARK [2][-]{subsection.3.5}{\376\377\000P\000a\000r\000t\000i\000a\000l\000\040\000C\000o\000r\000r\000e\000l\000a\000t\000i\000o\000n\000\040\000A\000n\000a\000l\000y\000s\000i\000s}{section.3}% 16
\BOOKMARK [2][-]{subsection.3.6}{\376\377\000N\000o\000n\000l\000i\000n\000e\000a\000r\000\040\000D\000e\000p\000e\000n\000d\000e\000n\000c\000e\000\040\000T\000e\000s\000t\000s}{section.3}% 17
\BOOKMARK [2][-]{subsection.3.7}{\376\377\000G\000e\000o\000g\000r\000a\000p\000h\000i\000c\000\040\000L\000o\000c\000a\000l\000i\000s\000a\000t\000i\000o\000n\000\040\000S\000c\000a\000n}{section.3}% 18
\BOOKMARK [2][-]{subsection.3.8}{\376\377\000P\000r\000e\000-\000R\000e\000g\000i\000s\000t\000e\000r\000e\000d\000\040\000O\000u\000t\000-\000o\000f\000-\000S\000a\000m\000p\000l\000e\000\040\000V\000a\000l\000i\000d\000a\000t\000i\000o\000n}{section.3}% 19
\BOOKMARK [2][-]{subsection.3.9}{\376\377\000C\000o\000m\000b\000i\000n\000e\000d\000\040\000T\000i\000m\000e\000s\000e\000r\000i\000e\000s\000:\000\040\000S\000i\000n\000u\000s\000o\000i\000d\000a\000l\000\040\000E\000n\000v\000e\000l\000o\000p\000e\000\040\000F\000i\000t}{section.3}% 20
\BOOKMARK [1][-]{section.4}{\376\377\000R\000e\000s\000u\000l\000t\000s}{}% 21
\BOOKMARK [2][-]{subsection.4.1}{\376\377\000R\000a\000w\000\040\000P\000a\000i\000r\000w\000i\000s\000e\000\040\000C\000o\000r\000r\000e\000l\000a\000t\000i\000o\000n\000s\000\040\000B\000e\000t\000w\000e\000e\000n\000\040\000C\000R\000,\000\040\000S\000e\000i\000s\000m\000i\000c\000,\000\040\000a\000n\000d\000\040\000S\000u\000n\000s\000p\000o\000t\000\040\000D\000a\000t\000a}{section.4}% 22
\BOOKMARK [3][-]{subsubsection.4.1.1}{\376\377\000C\000R\000\040\000i\000n\000d\000e\000x\000:\000\040\000s\000t\000a\000t\000i\000o\000n\000\040\000d\000i\000s\000t\000r\000i\000b\000u\000t\000i\000o\000n}{subsection.4.1}% 23
\BOOKMARK [3][-]{subsubsection.4.1.2}{\376\377\000S\000e\000i\000s\000m\000i\000c\000\040\000e\000n\000e\000r\000g\000y\000\040\000m\000e\000t\000r\000i\000c}{subsection.4.1}% 24
\BOOKMARK [3][-]{subsubsection.4.1.3}{\376\377\000S\000u\000n\000s\000p\000o\000t\000\040\000n\000u\000m\000b\000e\000r}{subsection.4.1}% 25
\BOOKMARK [3][-]{subsubsection.4.1.4}{\376\377\000C\000o\000r\000r\000e\000l\000a\000t\000i\000o\000n\000\040\000r\000e\000s\000u\000l\000t\000s}{subsection.4.1}% 26
\BOOKMARK [3][-]{subsubsection.4.1.5}{\376\377\000I\000n\000t\000e\000r\000p\000r\000e\000t\000a\000t\000i\000o\000n\000:\000\040\000a\000\040\000c\000o\000n\000f\000o\000u\000n\000d\000i\000n\000g\000\040\000t\000r\000i\000a\000n\000g\000l\000e}{subsection.4.1}% 27
\BOOKMARK [2][-]{subsection.4.2}{\376\377\000I\000n\000-\000S\000a\000m\000p\000l\000e\000\040\000R\000e\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000\050\0001\0009\0007\0006\040\023\0002\0000\0001\0009\000\051}{section.4}% 28
\BOOKMARK [2][-]{subsection.4.3}{\376\377\000I\000A\000A\000F\000T\000\040\000S\000u\000r\000r\000o\000g\000a\000t\000e\000\040\000T\000e\000s\000t}{section.4}% 29
\BOOKMARK [2][-]{subsection.4.4}{\376\377\000E\000f\000f\000e\000c\000t\000\040\000o\000f\000\040\000S\000o\000l\000a\000r\000-\000C\000y\000c\000l\000e\000\040\000D\000e\000t\000r\000e\000n\000d\000i\000n\000g}{section.4}% 30
\BOOKMARK [2][-]{subsection.4.5}{\376\377\000D\000e\000t\000r\000e\000n\000d\000i\000n\000g\000\040\000R\000o\000b\000u\000s\000t\000n\000e\000s\000s}{section.4}% 31
\BOOKMARK [2][-]{subsection.4.6}{\376\377\000C\000o\000m\000p\000a\000r\000i\000s\000o\000n\000\040\000o\000f\000\040\000N\000e\000f\000f\000\040\000E\000s\000t\000i\000m\000a\000t\000o\000r\000s}{section.4}% 32
\BOOKMARK [2][-]{subsection.4.7}{\376\377\000M\000a\000g\000n\000i\000t\000u\000d\000e\000\040\000T\000h\000r\000e\000s\000h\000o\000l\000d\000\040\000S\000e\000n\000s\000i\000t\000i\000v\000i\000t\000y}{section.4}% 33
\BOOKMARK [2][-]{subsection.4.8}{\376\377\000B\000l\000o\000c\000k\000-\000B\000o\000o\000t\000s\000t\000r\000a\000p\000\040\000S\000u\000r\000r\000o\000g\000a\000t\000e\000\040\000C\000o\000m\000p\000a\000r\000i\000s\000o\000n}{section.4}% 34
\BOOKMARK [2][-]{subsection.4.9}{\376\377\000P\000a\000r\000t\000i\000a\000l\000\040\000C\000o\000r\000r\000e\000l\000a\000t\000i\000o\000n\000:\000\040\000C\000o\000n\000t\000r\000o\000l\000l\000i\000n\000g\000\040\000f\000o\000r\000\040\000S\000u\000n\000s\000p\000o\000t\000\040\000N\000u\000m\000b\000e\000r}{section.4}% 35
\BOOKMARK [2][-]{subsection.4.10}{\376\377\000S\000p\000e\000c\000t\000r\000a\000l\000\040\000C\000o\000h\000e\000r\000e\000n\000c\000e\000\040\000a\000n\000d\000\040\000M\000u\000t\000u\000a\000l\000\040\000I\000n\000f\000o\000r\000m\000a\000t\000i\000o\000n}{section.4}% 36
\BOOKMARK [2][-]{subsection.4.11}{\376\377\000M\000i\000s\000s\000i\000n\000g\000-\000D\000a\000t\000a\000\040\000S\000e\000n\000s\000i\000t\000i\000v\000i\000t\000y}{section.4}% 37
\BOOKMARK [2][-]{subsection.4.12}{\376\377\000B\000i\000n\000-\000S\000i\000z\000e\000\040\000S\000e\000n\000s\000i\000t\000i\000v\000i\000t\000y}{section.4}% 38
\BOOKMARK [2][-]{subsection.4.13}{\376\377\000E\000a\000r\000t\000h\000q\000u\000a\000k\000e\000\040\000D\000e\000c\000l\000u\000s\000t\000e\000r\000i\000n\000g\000\040\000\050\000G\000a\000r\000d\000n\000e\000r\040\023\000K\000n\000o\000p\000o\000f\000f\000\051}{section.4}% 39
\BOOKMARK [2][-]{subsection.4.14}{\376\377\000S\000u\000b\000-\000P\000e\000r\000i\000o\000d\000\040\000A\000n\000a\000l\000y\000s\000i\000s\000\040\000b\000y\000\040\000S\000o\000l\000a\000r\000\040\000C\000y\000c\000l\000e}{section.4}% 40
\BOOKMARK [2][-]{subsection.4.15}{\376\377\000G\000e\000o\000g\000r\000a\000p\000h\000i\000c\000\040\000L\000o\000c\000a\000l\000i\000s\000a\000t\000i\000o\000n}{section.4}% 41
\BOOKMARK [2][-]{subsection.4.16}{\376\377\000P\000r\000e\000-\000R\000e\000g\000i\000s\000t\000e\000r\000e\000d\000\040\000O\000u\000t\000-\000o\000f\000-\000S\000a\000m\000p\000l\000e\000\040\000V\000a\000l\000i\000d\000a\000t\000i\000o\000n\000\040\000\050\0002\0000\0002\0000\040\023\0002\0000\0002\0005\000\051}{section.4}% 42
\BOOKMARK [2][-]{subsection.4.17}{\376\377\000C\000o\000m\000b\000i\000n\000e\000d\000\040\0001\0009\0007\0006\040\023\0002\0000\0002\0005\000\040\000A\000n\000a\000l\000y\000s\000i\000s\000:\000\040\000S\000i\000n\000u\000s\000o\000i\000d\000a\000l\000\040\000M\000o\000d\000u\000l\000a\000t\000i\000o\000n}{section.4}% 43
\BOOKMARK [1][-]{section.5}{\376\377\000D\000i\000s\000c\000u\000s\000s\000i\000o\000n}{}% 44
\BOOKMARK [2][-]{subsection.5.1}{\376\377\000W\000h\000y\000\040\000D\000o\000e\000s\000\040\000t\000h\000e\000\040\000R\000a\000w\000\040\000C\000o\000r\000r\000e\000l\000a\000t\000i\000o\000n\000\040\000A\000p\000p\000e\000a\000r\000\040\000S\000o\000\040\000S\000t\000r\000o\000n\000g\000?}{section.5}% 45
\BOOKMARK [2][-]{subsection.5.2}{\376\377\000P\000h\000y\000s\000i\000c\000a\000l\000\040\000P\000l\000a\000u\000s\000i\000b\000i\000l\000i\000t\000y\000\040\000o\000f\000\040\000t\000h\000e\000\040\000C\000l\000a\000i\000m\000e\000d\000\040\000M\000e\000c\000h\000a\000n\000i\000s\000m}{section.5}% 46
\BOOKMARK [2][-]{subsection.5.3}{\376\377\000C\000o\000m\000p\000a\000r\000i\000s\000o\000n\000\040\000w\000i\000t\000h\000\040\000P\000r\000i\000o\000r\000\040\000R\000e\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000A\000t\000t\000e\000m\000p\000t\000s}{section.5}% 47
\BOOKMARK [2][-]{subsection.5.4}{\376\377\000L\000i\000m\000i\000t\000a\000t\000i\000o\000n\000s}{section.5}% 48
\BOOKMARK [1][-]{section.6}{\376\377\000C\000o\000n\000c\000l\000u\000s\000i\000o\000n\000s}{}% 49

Binary file not shown.

View file

@ -291,6 +291,22 @@ rank-order resampling (in time domain) until convergence.
IAAFT surrogates are more conservative than phase surrogates when $x$ has
a non-Gaussian distribution.
\subsubsection{Block-Bootstrap Surrogates}
\label{sec:blockbootstrap}
IAAFT surrogates preserve the power spectrum and amplitude distribution of each
series but assume linearity and stationarity --- assumptions violated by seismicity,
which is non-stationary, heavy-tailed, and aftershock-clustered.
As a complementary null we use a \emph{circular block bootstrap} (CBB) that
makes no parametric assumptions about the spectral shape.
Each surrogate is constructed by independently resampling $x$ and $y$ in
contiguous circular blocks of length $B = 804$ bins ($\approx 11$~yr,
i.e.\ approximately one solar cycle), drawn with replacement.
Independent resampling of $x$ and $y$ destroys any cross-series correlation
while preserving each series' within-block temporal structure.
We generate $S = 5{,}000$ surrogate pairs and compare the resulting null
distribution to the IAAFT null.
\subsubsection{Global $p$-Value}
\label{sec:pvalue}
@ -359,6 +375,57 @@ For the out-of-sample window ($\sim$5 years, less than one solar cycle), the
HP filter is inappropriate (it would remove any genuine sub-decadal signal);
we use linear detrending instead, as pre-specified in the pre-registration.
\subsection{Partial Correlation Analysis}
\label{sec:methods:partialcorr}
Because the solar-cycle component is removed \emph{before} concluding that the
observed signal is solar-cycle-driven, there is a potential circularity concern.
We address this with a partial correlation analysis on the \emph{unfiltered} data.
The seismic metric $y_t$ is regressed on the smoothed sunspot number $z_t$:
\begin{equation}
\hat{y}_t = \hat{\beta} z_t + \hat{\alpha}, \qquad
y_t^\text{resid} = y_t - \hat{y}_t,
\label{eq:partialcorr}
\end{equation}
and the cross-correlation between the CR index $x_t$ and the residual
$y_t^\text{resid}$ is computed across all lags.
If the CR--seismic correlation is driven entirely by a shared solar-cycle trend,
$r(x, y^\text{resid})$ should approach zero.
This analysis avoids any digital filter and thus sidesteps the preprocessing
circularity.
\subsection{Nonlinear Dependence Tests}
\label{sec:methods:nonlinear}
Cross-correlation captures only linear dependence; we supplement it with two
nonlinear measures for the main CR--seismic pair.
\paragraph{Spectral coherence.}
The magnitude-squared coherence at frequency $f$ is
\begin{equation}
C_{xy}(f) = \frac{|S_{xy}(f)|^2}{S_{xx}(f)\,S_{yy}(f)},
\label{eq:coherence}
\end{equation}
estimated via Welch's method with $L = 2{,}048$-point Hann windows (75\%
overlap), giving a frequency resolution of $(1/5)/2048 \approx 0.036$
cycles~yr$^{-1}$ --- sufficient to resolve the solar-cycle band
(0.08--0.115~cycles~yr$^{-1}$, periods 9--12.5~yr).
\paragraph{Mutual information.}
We estimate $I(x; y)$ at lags $\tau = 0$ and $\tau = +15$~d using the
\citet{Kraskov2004} $k$-nearest-neighbour estimator ($k = 5$, Chebyshev
metric in joint space):
\begin{equation}
\hat{I}(x; y) = \psi(k) + \psi(N)
- \bigl\langle\psi(n_x + 1)\bigr\rangle
- \bigl\langle\psi(n_y + 1)\bigr\rangle,
\label{eq:mi}
\end{equation}
where $\psi$ is the digamma function and $n_x(i)$, $n_y(i)$ count marginal
neighbours within the $k$-th-neighbour radius.
Statistical significance is assessed against a shuffle null of 1{,}000
random permutations of $y$.
\subsection{Geographic Localisation Scan}
\label{sec:geo}
@ -466,7 +533,7 @@ The seismic activity per bin is measured by the total released seismic energy,
computed as the sum of the individual earthquake energies:
\begin{equation}
E_t = \sum_{i \in \mathcal{B}_t} 10^{1.5\, M_{W,i}},
\label{eq:energy}
\label{eq:energy_bin}
\end{equation}
where $\mathcal{B}_t$ is the set of $M_W \geq 4.5$ events falling in bin $t$.
Working with $\log_{10} E_t$ removes the extreme skewness of $E_t$ and is
@ -827,6 +894,254 @@ following large events) do not drive the dominant correlation structure.
\label{fig:mag_threshold}
\end{figure}
\subsection{Block-Bootstrap Surrogate Comparison}
\label{sec:res:blockbootstrap}
Figure~\ref{fig:blockbootstrap} shows the block-bootstrap (CBB) null
distributions for $r(+15\,\text{d})$ and the peak $|r|$ applied to the raw,
undetrended series.
Under the CBB null ($B = 804$ bins, $S = 5{,}000$):
\begin{itemize}
\item $p_\text{CBB}(+15\,\text{d}) = 0.022$ for the raw $r(+15\,\text{d}) = 0.079$;
\item $p_\text{CBB}(\text{peak}) = 0.008$ for the dominant raw peak
$r = 0.135$ at $\tau = -525$~days.
\end{itemize}
Both p-values reflect the fact that the raw series share a common 11-year
solar-cycle trend, so independently block-resampled surrogates occasionally
reproduce similar trend-induced correlations.
After HP detrending and IAAFT testing (Section~\ref{sec:res:surr}),
$r(+15\,\text{d})$ drops to 0.027 and falls well within the surrogate null,
confirming that the marginal significance seen here is a solar-cycle artefact,
not a genuine cross-series signal.
The block-bootstrap and IAAFT null shapes are qualitatively similar,
indicating that IAAFT's parametric assumptions do not materially distort the
null distribution for these data.
\begin{figure}[htbp]
\centering
\includegraphics[width=0.95\textwidth]{block_bootstrap_null.png}
\caption{Block-bootstrap null distributions for the raw CR--seismic pair
($B = 804$ bins $\approx 11$~yr, $S = 5{,}000$ surrogates).
\textbf{Left}: distribution of $r(+15\,\text{d})$ under the CBB null; observed
value $r = 0.079$ (red) lies at the $p = 0.022$ tail.
\textbf{Right}: distribution of the peak $|r|$; observed peak $0.135$ at
$\tau = -525$~d lies at $p = 0.008$.
Grey dashed lines mark the 95\% CI of the null.}
\label{fig:blockbootstrap}
\end{figure}
\subsection{Partial Correlation: Controlling for Sunspot Number}
\label{sec:res:partialcorr}
Figure~\ref{fig:partialcorr} shows the cross-correlation function for both the
raw seismic metric and the sunspot-regressed residual.
The OLS regression of seismic energy on the smoothed sunspot number gives
$\hat{\beta} = -0.0011$~units per sunspot number unit (a weak negative
relationship) and $\hat{\alpha} = 14.9$.
After removing this sunspot component, $r(+15\,\text{d})$ drops from 0.079
to 0.029 --- a reduction of 63\%.
This confirms that most of the raw CR--seismic correlation at the claimed lag
is attributable to the shared solar-cycle trend without invoking any digital
filter.
The residual partial correlation ($r = 0.029$) is indistinguishable from zero
($p = 0.083$, treating bins as independent; even smaller when autocorrelation
is accounted for).
\begin{figure}[htbp]
\centering
\includegraphics[width=0.90\textwidth]{partial_correlation.png}
\caption{Cross-correlation $r(\tau)$ for the raw seismic metric (blue) and
the sunspot-regressed seismic residual (orange), both against the CR index,
on the raw (unfiltered) in-sample series.
The claimed $\tau = +15$~d (grey dashed line) shows $r_\text{raw} = 0.079$
vs.\ $r_\text{partial} = 0.029$, a 63\% reduction once the shared solar-cycle
component is regressed out.}
\label{fig:partialcorr}
\end{figure}
\subsection{Spectral Coherence and Mutual Information}
\label{sec:res:coherence}
Figure~\ref{fig:coherence} shows the magnitude-squared coherence spectrum and
the mutual information shuffle null.
\paragraph{Coherence.}
The mean coherence in the solar-cycle band (0.08--0.115~cycles~yr$^{-1}$)
is $\bar{C}_{xy} = 0.840$, substantially above the 95\% significance
threshold of 0.776 (for $K = 3$ Welch segments; see Section~\ref{sec:methods:nonlinear}).
This confirms that CR and seismic activity share strong common variance at
the $\sim$11-year frequency --- the spectral signature of the solar-cycle
confound identified in Section~\ref{sec:discussion}.
Note that the limited number of Welch segments ($K \approx 3$) makes the
coherence estimate at this frequency uncertain; the result should be interpreted
as indicative rather than precise.
\paragraph{Mutual information.}
The kNN mutual information at lag $\tau = 0$ is
$\hat{I} = 0.007$~nats, with a shuffle-null p-value of $p = 0.062$ --- not
significant.
At $\tau = +15$~d, $\hat{I} = 0.000$~nats ($p = 1.000$), confirming the
complete absence of any nonlinear association at the claimed lag.
Together with the linear cross-correlation results, this establishes that
there is no detectable statistical dependence --- linear or nonlinear ---
between the CR index and global seismicity at the claimed $+15$~day lag.
\begin{figure}[htbp]
\centering
\includegraphics[width=0.95\textwidth]{spectral_coherence.png}
\caption{\textbf{Left}: Magnitude-squared coherence between the CR index and
seismic metric (blue), with the solar-cycle band shaded (orange, 0.08--0.115
cycles~yr$^{-1}$) and the 95\% significance level (red dashed).
The mean coherence in the SC band is 0.840, confirming a strong shared
solar-cycle component.
\textbf{Right}: kNN mutual information ($k = 5$) at lag $\tau = 0$ (blue)
and $\tau = +15$~d (orange) vs.\ their respective shuffle-null distributions.
Both observed MI values are indistinguishable from zero; $p(+15\,\text{d}) = 1.000$.}
\label{fig:coherence}
\end{figure}
\subsection{Missing-Data Sensitivity}
\label{sec:res:missing}
Table~\ref{tab:missing} reports the NaN fraction in the global CR index for
station thresholds of 2, 3, and 5.
In all cases the NaN fraction is 0.0\%: the 44-station NMDB network provides
complete 5-day coverage over 1976--2019 even under the strictest threshold
tested.
Consequently, $r(+15\,\text{d})$ is identical (0.079) across all thresholds,
confirming that the result is not an artefact of gaps in the CR record.
NaN bins show no clustering near solar maxima (clustering ratio = 1.0 at all
thresholds, i.e.\ indistinguishable from uniform), ruling out any systematic
data dropout that could correlate with the solar cycle.
\begin{table}[htbp]
\centering
\caption{Missing-data sensitivity: global CR index and correlation at
$\tau = +15$~days for three station-threshold values.}
\label{tab:missing}
\begin{tabular}{rrrr}
\toprule
Min.\ stations & NaN fraction & NaN near solar max & $r(+15\,\text{d})$ \\
\midrule
2 & 0.0\% & 0.0\% & 0.079 \\
3 & 0.0\% & 0.0\% & 0.079 \\
5 & 0.0\% & 0.0\% & 0.079 \\
\bottomrule
\end{tabular}
\end{table}
\subsection{Bin-Size Sensitivity}
\label{sec:res:binsize}
Figure~\ref{fig:binsize} shows the cross-correlation functions at three bin
sizes: 1-day, 5-day, and 27-day (Bartels rotation period).
\begin{itemize}
\item \textbf{1-day bins}: $r(+15\,\text{d}) = 0.036$;
dominant peak $r = 0.088$ at $\tau = -525$~days.
\item \textbf{5-day bins} (baseline): $r(+15\,\text{d}) = 0.079$;
dominant peak $r = 0.135$ at $\tau = -525$~days.
\item \textbf{27-day bins}: $r(+27\,\text{d}) = 0.123$;
dominant peak $r = 0.217$ at $\tau \approx -513$~days.
\end{itemize}
In all cases the dominant peak is at approximately $-525$ to $-513$~days
($\approx -18$ months, consistent with a half-solar-cycle lag), not at
$+15$~days.
The correlation at the claimed lag grows with bin size because longer bins
increasingly average out high-frequency noise and emphasise the solar-cycle
component.
This bin-size dependence is the behaviour expected of a solar-cycle artefact
and is inconsistent with a genuine short-lag (15-day) physical mechanism,
which should be insensitive to whether one uses 1-day or 27-day bins.
\begin{figure}[htbp]
\centering
\includegraphics[width=\textwidth]{bin_size_sensitivity.png}
\caption{Cross-correlation $r(\tau)$ for three bin sizes: 1-day (left),
5-day (centre), 27-day (right).
The dominant peak (red dotted) consistently falls near $\tau \approx -520$~days
across all bin sizes.
The correlation at the claimed $\tau = +15$~days (grey dashed) increases
from 0.036 to 0.123 as bin size increases, consistent with increasing
solar-cycle leakage rather than a physical short-lag signal.}
\label{fig:binsize}
\end{figure}
\subsection{Earthquake Declustering (Gardner--Knopoff)}
\label{sec:res:decluster}
Figure~\ref{fig:decluster} compares the cross-correlation for the full
catalogue and the mainshock-only catalogue after applying the
\citet{GardnerKnopoff1974} declustering algorithm.
Of 232{,}043 events ($M \geq 4.5$, 1976--2019), 65{,}874 (28.4\%) were
classified as aftershocks and removed, leaving 166{,}169 mainshocks.
The correlation at the claimed lag changes from $r(+15\,\text{d}) = 0.079$
(full) to $r(+15\,\text{d}) = 0.065$ (declustered), a reduction of only 0.014
--- well below the $\Delta r = 0.03$ threshold for a material change.
The peak structure and dominant lag are unchanged.
We conclude that aftershock clustering is not a primary confound in this
analysis; the signal does not disappear when aftershock sequences are removed.
\begin{figure}[htbp]
\centering
\includegraphics[width=0.90\textwidth]{declustered_xcorr.png}
\caption{Cross-correlation for the full catalogue ($n = 232{,}043$ events,
blue) and the Gardner--Knopoff declustered catalogue ($n = 166{,}169$
mainshocks, orange), in-sample 1976--2019.
Removing 28.4\% of events as aftershocks changes $r(+15\,\text{d})$ by
only $\Delta r = 0.014$, confirming the result is not driven by aftershock
swarms.}
\label{fig:decluster}
\end{figure}
\subsection{Sub-Period Analysis by Solar Cycle}
\label{sec:res:subcycles}
Figure~\ref{fig:subcycles} shows the cross-correlation computed independently
within each of the four complete solar cycles (21--24) in the in-sample window.
Table~\ref{tab:subcycles} summarises the results.
\begin{table}[htbp]
\centering
\caption{Per-solar-cycle cross-correlation at $\tau = +15$~days and the
within-cycle dominant peak.}
\label{tab:subcycles}
\begin{tabular}{lrrrrr}
\toprule
Cycle & Period & $N$ (bins) & $r(+15\,\text{d})$ & Peak $|r|$ & Peak $\tau$ (d) \\
\midrule
21 & 1976--1987 & 768 & $+0.071$ & 0.118 & $-65$ \\
22 & 1987--1996 & 724 & $+0.057$ & 0.104 & $-125$ \\
23 & 1997--2009 & 901 & $+0.018$ & 0.060 & $+125$ \\
24 & 2009--2020 & 810 & $+0.073$ & 0.177 & $-125$ \\
\bottomrule
\end{tabular}
\end{table}
The correlations at $\tau = +15$~d are positive in all four cycles (range
0.018--0.073), but the magnitudes vary by a factor of four, and the dominant
within-cycle peak lags are inconsistent: $-65$, $-125$, $+125$, and $-125$~days.
If the correlation were a genuine physical CR precursor, its lag should be
stable and reproducible across cycles.
The inconsistency of the dominant peak --- which oscillates between positive
and negative lags --- is instead the signature of a cycle-to-cycle drift in
the relative phase between the CR and seismic solar-cycle modulations, a
classical hallmark of a shared-trend confound rather than a causal relationship.
\begin{figure}[htbp]
\centering
\includegraphics[width=\textwidth]{solar_cycle_xcorr.png}
\caption{Cross-correlation $r(\tau)$ within each of the four complete solar
cycles (21--24) of the in-sample period (1976--2019).
The claimed lag $\tau = +15$~days (grey dashed) shows modest positive
correlations (0.018--0.073), but the dominant peak lag (red dotted) is
inconsistent across cycles ($-65$, $-125$, $+125$, $-125$~days), pointing
to a drift in the relative solar-cycle phase rather than a physical mechanism.}
\label{fig:subcycles}
\end{figure}
\subsection{Geographic Localisation}
\label{sec:res:geo}
@ -1065,6 +1380,29 @@ Our principal findings are:
better described by a sinusoid than a constant (Bayes factor 0.75, favoring
constant); the previous sinusoidal modulation finding was an artefact of the
invalid seismic metric.
\item Seven additional robustness checks all corroborate the null result:
\begin{itemize}
\item Block-bootstrap surrogates ($B \approx 11$~yr, $n = 5{,}000$) yield
$p_\text{CBB}(+15\,\text{d}) = 0.022$ on the \emph{raw} series;
after detrending the result is within the null.
\item Partial correlation (regressing seismic on sunspots before correlating
with CR) reduces $r(+15\,\text{d})$ from 0.079 to 0.029 (63\% drop),
confirming solar-cycle confounding without any filter.
\item Mean spectral coherence in the solar-cycle band is 0.840 (> 95\%
threshold), while mutual information at $\tau = +15$~d is exactly zero
($p = 1.000$): no nonlinear signal at the claimed lag.
\item Missing data: 0\% NaN bins at all station thresholds;
$r(+15\,\text{d})$ is unchanged for min-station thresholds 2, 3, or 5.
\item Bin-size sensitivity: the dominant peak is at $\tau \approx -520$~days
for 1-day, 5-day, and 27-day bins; $r$ at $+15$~days scales with bin size
as expected for solar-cycle leakage, not a physical mechanism.
\item Earthquake declustering removes 28\% of events as aftershocks;
$r(+15\,\text{d})$ changes by only $\Delta r = 0.014$ --- not a material confound.
\item Per-solar-cycle analysis shows inconsistent dominant peak lags
($-65$, $-125$, $+125$, $-125$~days across cycles 21--24),
the signature of a phase-drifting solar-cycle artefact.
\end{itemize}
\end{enumerate}
We conclude that there is no statistically credible evidence for a physical

View file

@ -1,30 +1,56 @@
\contentsline {section}{\numberline {1}Introduction}{4}{section.1}%
\contentsline {section}{\numberline {2}Data}{5}{section.2}%
\contentsline {subsection}{\numberline {2.1}Cosmic-Ray Flux: NMDB Neutron Monitors}{5}{subsection.2.1}%
\contentsline {subsection}{\numberline {2.2}Seismic Activity: USGS Earthquake Catalogue}{5}{subsection.2.2}%
\contentsline {subsection}{\numberline {2.3}Solar Activity: SIDC Sunspot Number}{5}{subsection.2.3}%
\contentsline {section}{\numberline {3}Methods}{5}{section.3}%
\contentsline {subsection}{\numberline {3.1}Cross-Correlation at Lag $\tau $}{5}{subsection.3.1}%
\contentsline {subsection}{\numberline {3.2}Effective Degrees of Freedom}{6}{subsection.3.2}%
\contentsline {subsection}{\numberline {3.3}Surrogate Significance Tests}{6}{subsection.3.3}%
\contentsline {subsubsection}{\numberline {3.3.1}Phase Randomisation}{6}{subsubsection.3.3.1}%
\contentsline {subsubsection}{\numberline {3.3.2}IAAFT Surrogates}{6}{subsubsection.3.3.2}%
\contentsline {subsubsection}{\numberline {3.3.3}Global $p$-Value}{6}{subsubsection.3.3.3}%
\contentsline {subsubsection}{\numberline {3.3.4}GPU Acceleration}{7}{subsubsection.3.3.4}%
\contentsline {subsection}{\numberline {3.4}Solar-Cycle Detrending}{7}{subsection.3.4}%
\contentsline {subsection}{\numberline {3.5}Geographic Localisation Scan}{7}{subsection.3.5}%
\contentsline {subsection}{\numberline {3.6}Pre-Registered Out-of-Sample Validation}{8}{subsection.3.6}%
\contentsline {subsection}{\numberline {3.7}Combined Timeseries: Sinusoidal Envelope Fit}{8}{subsection.3.7}%
\contentsline {section}{\numberline {4}Results}{9}{section.4}%
\contentsline {subsection}{\numberline {4.1}In-Sample Replication (1976--2019)}{9}{subsection.4.1}%
\contentsline {subsection}{\numberline {4.2}IAAFT Surrogate Test}{9}{subsection.4.2}%
\contentsline {subsection}{\numberline {4.3}Effect of Solar-Cycle Detrending}{9}{subsection.4.3}%
\contentsline {subsection}{\numberline {4.4}Geographic Localisation}{13}{subsection.4.4}%
\contentsline {subsection}{\numberline {4.5}Pre-Registered Out-of-Sample Validation (2020--2025)}{13}{subsection.4.5}%
\contentsline {subsection}{\numberline {4.6}Combined 1976--2025 Analysis: Sinusoidal Modulation}{14}{subsection.4.6}%
\contentsline {section}{\numberline {5}Discussion}{16}{section.5}%
\contentsline {subsection}{\numberline {5.1}Why Does the Raw Correlation Appear So Strong?}{16}{subsection.5.1}%
\contentsline {subsection}{\numberline {5.2}Physical Plausibility of the Claimed Mechanism}{16}{subsection.5.2}%
\contentsline {subsection}{\numberline {5.3}Comparison with Prior Replication Attempts}{17}{subsection.5.3}%
\contentsline {subsection}{\numberline {5.4}Limitations}{17}{subsection.5.4}%
\contentsline {section}{\numberline {6}Conclusions}{17}{section.6}%
\contentsline {section}{\numberline {1}Introduction}{5}{section.1}%
\contentsline {section}{\numberline {2}Data}{6}{section.2}%
\contentsline {subsection}{\numberline {2.1}Cosmic-Ray Flux: NMDB Neutron Monitors}{6}{subsection.2.1}%
\contentsline {subsection}{\numberline {2.2}Seismic Activity: USGS Earthquake Catalogue}{6}{subsection.2.2}%
\contentsline {subsection}{\numberline {2.3}Solar Activity: SIDC Sunspot Number}{6}{subsection.2.3}%
\contentsline {section}{\numberline {3}Methods}{7}{section.3}%
\contentsline {subsection}{\numberline {3.1}Cross-Correlation at Lag $\tau $}{7}{subsection.3.1}%
\contentsline {subsection}{\numberline {3.2}Effective Degrees of Freedom}{7}{subsection.3.2}%
\contentsline {subsection}{\numberline {3.3}Surrogate Significance Tests}{7}{subsection.3.3}%
\contentsline {subsubsection}{\numberline {3.3.1}Phase Randomisation}{7}{subsubsection.3.3.1}%
\contentsline {subsubsection}{\numberline {3.3.2}IAAFT Surrogates}{8}{subsubsection.3.3.2}%
\contentsline {subsubsection}{\numberline {3.3.3}Block-Bootstrap Surrogates}{8}{subsubsection.3.3.3}%
\contentsline {subsubsection}{\numberline {3.3.4}Global $p$-Value}{8}{subsubsection.3.3.4}%
\contentsline {subsubsection}{\numberline {3.3.5}GPU Acceleration}{8}{subsubsection.3.3.5}%
\contentsline {subsection}{\numberline {3.4}Solar-Cycle Detrending}{9}{subsection.3.4}%
\contentsline {subsection}{\numberline {3.5}Partial Correlation Analysis}{9}{subsection.3.5}%
\contentsline {subsection}{\numberline {3.6}Nonlinear Dependence Tests}{10}{subsection.3.6}%
\contentsline {paragraph}{Spectral coherence.}{10}{section*.2}%
\contentsline {paragraph}{Mutual information.}{10}{section*.3}%
\contentsline {subsection}{\numberline {3.7}Geographic Localisation Scan}{10}{subsection.3.7}%
\contentsline {subsection}{\numberline {3.8}Pre-Registered Out-of-Sample Validation}{11}{subsection.3.8}%
\contentsline {subsection}{\numberline {3.9}Combined Timeseries: Sinusoidal Envelope Fit}{11}{subsection.3.9}%
\contentsline {section}{\numberline {4}Results}{12}{section.4}%
\contentsline {subsection}{\numberline {4.1}Raw Pairwise Correlations Between CR, Seismic, and Sunspot Data}{12}{subsection.4.1}%
\contentsline {subsubsection}{\numberline {4.1.1}CR index: station distribution}{12}{subsubsection.4.1.1}%
\contentsline {subsubsection}{\numberline {4.1.2}Seismic energy metric}{12}{subsubsection.4.1.2}%
\contentsline {subsubsection}{\numberline {4.1.3}Sunspot number}{12}{subsubsection.4.1.3}%
\contentsline {subsubsection}{\numberline {4.1.4}Correlation results}{13}{subsubsection.4.1.4}%
\contentsline {paragraph}{CR vs.\ seismicity.}{13}{section*.4}%
\contentsline {paragraph}{CR vs.\ sunspot number.}{13}{section*.5}%
\contentsline {paragraph}{Sunspot vs.\ seismicity.}{13}{section*.6}%
\contentsline {subsubsection}{\numberline {4.1.5}Interpretation: a confounding triangle}{13}{subsubsection.4.1.5}%
\contentsline {subsection}{\numberline {4.2}In-Sample Replication (1976--2019)}{14}{subsection.4.2}%
\contentsline {subsection}{\numberline {4.3}IAAFT Surrogate Test}{17}{subsection.4.3}%
\contentsline {subsection}{\numberline {4.4}Effect of Solar-Cycle Detrending}{18}{subsection.4.4}%
\contentsline {subsection}{\numberline {4.5}Detrending Robustness}{18}{subsection.4.5}%
\contentsline {subsection}{\numberline {4.6}Comparison of $N_\text {eff}$ Estimators}{18}{subsection.4.6}%
\contentsline {subsection}{\numberline {4.7}Magnitude Threshold Sensitivity}{20}{subsection.4.7}%
\contentsline {subsection}{\numberline {4.8}Block-Bootstrap Surrogate Comparison}{20}{subsection.4.8}%
\contentsline {subsection}{\numberline {4.9}Partial Correlation: Controlling for Sunspot Number}{21}{subsection.4.9}%
\contentsline {subsection}{\numberline {4.10}Spectral Coherence and Mutual Information}{21}{subsection.4.10}%
\contentsline {paragraph}{Coherence.}{21}{section*.20}%
\contentsline {paragraph}{Mutual information.}{22}{section*.21}%
\contentsline {subsection}{\numberline {4.11}Missing-Data Sensitivity}{22}{subsection.4.11}%
\contentsline {subsection}{\numberline {4.12}Bin-Size Sensitivity}{24}{subsection.4.12}%
\contentsline {subsection}{\numberline {4.13}Earthquake Declustering (Gardner--Knopoff)}{24}{subsection.4.13}%
\contentsline {subsection}{\numberline {4.14}Sub-Period Analysis by Solar Cycle}{25}{subsection.4.14}%
\contentsline {subsection}{\numberline {4.15}Geographic Localisation}{25}{subsection.4.15}%
\contentsline {subsection}{\numberline {4.16}Pre-Registered Out-of-Sample Validation (2020--2025)}{28}{subsection.4.16}%
\contentsline {subsection}{\numberline {4.17}Combined 1976--2025 Analysis: Sinusoidal Modulation}{29}{subsection.4.17}%
\contentsline {section}{\numberline {5}Discussion}{30}{section.5}%
\contentsline {subsection}{\numberline {5.1}Why Does the Raw Correlation Appear So Strong?}{30}{subsection.5.1}%
\contentsline {subsection}{\numberline {5.2}Physical Plausibility of the Claimed Mechanism}{30}{subsection.5.2}%
\contentsline {subsection}{\numberline {5.3}Comparison with Prior Replication Attempts}{31}{subsection.5.3}%
\contentsline {subsection}{\numberline {5.4}Limitations}{31}{subsection.5.4}%
\contentsline {section}{\numberline {6}Conclusions}{31}{section.6}%

View file

@ -1,13 +1,12 @@
@article{Homola2023,
@misc{Homola2023,
author = {Homola, Piotr and others},
title = {Indication of Correlation between Cosmic-Ray Flux and
Global Seismicity},
journal = {Remote Sensing},
year = {2023},
volume = {15},
number = {1},
pages = {200},
doi = {10.3390/rs15010200},
year = {2022},
eprint = {2204.12310},
archivePrefix = {arXiv},
primaryClass = {physics.geo-ph},
url = {https://arxiv.org/abs/2204.12310},
}
@article{Bretherton1999,
@ -186,6 +185,29 @@
howpublished = {\url{https://www.nmdb.eu}},
}
@article{Kraskov2004,
author = {Kraskov, Alexander and St{\"o}gbauer, Harald and Grassberger, Peter},
title = {Estimating mutual information},
journal = {Physical Review E},
year = {2004},
volume = {69},
number = {6},
pages = {066138},
doi = {10.1103/PhysRevE.69.066138},
}
@article{GardnerKnopoff1974,
author = {Gardner, J. K. and Knopoff, Leon},
title = {Is the sequence of earthquakes in southern {California},
with aftershocks removed, {Poissonian}?},
journal = {Bulletin of the Seismological Society of America},
year = {1974},
volume = {64},
number = {5},
pages = {1363--1367},
doi = {10.1785/BSSA0640051363},
}
@article{Kanamori1977,
author = {Kanamori, Hiroo},
title = {The energy release in great earthquakes},

View file

@ -0,0 +1,136 @@
{
"3a_block_bootstrap": {
"block_len_bins": 804,
"obs_r_15d": 0.07861489210244768,
"obs_peak_r": 0.13487884023035338,
"p_block_15d": 0.0224,
"p_block_peak": 0.0078,
"ci95_15d": [
-0.06666438961658633,
0.0682932463714636
],
"iaaft_p_global_raw": 0.0,
"interpretation": "p-value similar to IAAFT"
},
"3b_partial_correlation": {
"sunspot_slope": -0.0010697974037700612,
"r_raw_15d": 0.0786167037488285,
"r_partial_15d": 0.028775255831885685,
"drop_fraction_at_15d": 0.6339803825428832,
"peak_r_partial": 0.10058325167521967,
"interpretation": "Partial correlation near zero \u2014 solar-cycle confounding confirmed"
},
"3c_coherence_mi": {
"coherence_solar_cycle_band": 0.8398522322268607,
"coherence_95pct_threshold": 0.7763932022500211,
"mi_lag0": 0.006683319941448218,
"mi_lag15d": 0.0,
"p_mi_lag0": 0.062,
"p_mi_lag15d": 1.0
},
"3d_missing_data": {
"station_threshold_sensitivity": [
{
"min_stations": 2,
"nan_fraction": 0.0,
"nan_fraction_near_solar_max": 0.0,
"nan_fraction_far_from_solar_max": 0.0,
"clustering_ratio": 0.0,
"r_at_15d": 0.07861670374882847
},
{
"min_stations": 3,
"nan_fraction": 0.0,
"nan_fraction_near_solar_max": 0.0,
"nan_fraction_far_from_solar_max": 0.0,
"clustering_ratio": 0.0,
"r_at_15d": 0.07861670374882847
},
{
"min_stations": 5,
"nan_fraction": 0.0,
"nan_fraction_near_solar_max": 0.0,
"nan_fraction_far_from_solar_max": 0.0,
"clustering_ratio": 0.0,
"r_at_15d": 0.07861670374882847
}
]
},
"3e_bin_size": {
"bin_size_sensitivity": [
{
"bin_days": 1,
"r_at_claimed_lag": 0.035457258390485795,
"claimed_lag_days": 15,
"peak_r": 0.08765920746165931,
"peak_lag_days": -525
},
{
"bin_days": 5,
"r_at_claimed_lag": 0.0786167037488285,
"claimed_lag_days": 15,
"peak_r": 0.13487884023035338,
"peak_lag_days": -525
},
{
"bin_days": 27,
"r_at_claimed_lag": 0.12302559221199305,
"claimed_lag_days": 27,
"peak_r": 0.21674265231313997,
"peak_lag_days": -513
}
]
},
"3f_declustering": {
"n_events_full": 232043,
"n_mainshocks": 166169,
"fraction_removed": 0.28388703817826866,
"r_15d_full": 0.0786167037488285,
"r_15d_declustered": 0.06502872576089179,
"peak_r_full": 0.13487884023035338,
"peak_r_declustered": 0.12384155136507456,
"interpretation": "Aftershock clustering is NOT a primary confound \u2014 result stable after GK declustering"
},
"3g_solar_cycles": {
"per_cycle": {
"cycle_21": {
"start": "1976-03-01",
"end": "1986-09-01",
"n_bins": 768,
"r_at_15d": 0.07118320436089393,
"peak_r": 0.1180329918201807,
"peak_lag_days": -65
},
"cycle_22": {
"start": "1986-09-01",
"end": "1996-08-01",
"n_bins": 724,
"r_at_15d": 0.05738270708702726,
"peak_r": 0.10420488714969577,
"peak_lag_days": -125
},
"cycle_23": {
"start": "1996-08-01",
"end": "2008-12-01",
"n_bins": 901,
"r_at_15d": 0.017585753106899405,
"peak_r": 0.05956387248452478,
"peak_lag_days": 125
},
"cycle_24": {
"start": "2008-12-01",
"end": "2019-12-31",
"n_bins": 810,
"r_at_15d": 0.07310193509089967,
"peak_r": 0.1769572220601618,
"peak_lag_days": -125
}
},
"r15d_range": [
0.017585753106899405,
0.07310193509089967
],
"sign_consistent_across_cycles": true,
"interpretation": "r(+15d) consistent in sign across all solar cycles"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View file

@ -0,0 +1,977 @@
#!/usr/bin/env python3
"""
scripts/11_additional_robustness.py
====================================
Seven additional robustness checks for the CRseismic correlation analysis.
3a Block-bootstrap surrogates vs IAAFT null
Circular block bootstrap (block 1 solar cycle = 803 bins 11 yr at 5-day
resolution), 5 000 surrogates; compare p-values to stored IAAFT results.
3b Partial correlation controlling for sunspots (raw, unfiltered data).
Seismic_resid = seismic β·sunspots (OLS); compute r(τ) between CR and
Seismic_resid without any HP-filter preprocessing.
3c Spectral coherence + mutual information (kNN estimator).
Magnitude-squared coherence at each frequency; MI at lag=0 and lag=+3 bins
(+15 d) vs shuffle null (1 000 permutations).
3d Missing-data impact.
Fraction of NaN bins per station threshold (2, 3, 5), temporal clustering of
NaN bins near solar maxima, and r(+15 d) sensitivity.
3e Bin-size sensitivity (1-day, 5-day, 27-day Bartels rotation bins).
3f GardnerKnopoff earthquake declustering.
Remove aftershock sequences; recompute seismic energy from mainshock-only
catalogue; compare r(τ) to the clustered result.
3g Sub-period analysis (per-solar-cycle cross-correlations).
Cycles 2124 ( 19762019); independent r(τ) per cycle.
Outputs
-------
results/additional_robustness.json machine-readable summary
results/figs/block_bootstrap_null.png 3a
results/figs/partial_correlation.png 3b
results/figs/spectral_coherence.png 3c
results/figs/bin_size_sensitivity.png 3e
results/figs/declustered_xcorr.png 3f
results/figs/solar_cycle_xcorr.png 3g
(3d is table-only, included in JSON)
"""
from __future__ import annotations
import json
import logging
import sys
import warnings
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.signal
import scipy.spatial
import scipy.stats
import yaml
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "src"))
from crq.ingest.nmdb import load_station, resample_daily
from crq.ingest.usgs import load_usgs, seismic_energy_per_bin
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s",
datefmt="%H:%M:%S",
)
log = logging.getLogger(__name__)
warnings.filterwarnings("ignore", category=RuntimeWarning)
# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------
STUDY_START = "1976-01-01"
STUDY_END = "2019-12-31"
BIN_DAYS = 5
MIN_MAG = 4.5
COV_THRESH = 0.60
MIN_STATIONS = 3
SEED = 42
LAG_BINS = np.arange(-200, 205, 1) # ±1000 d in 5-d steps
CLAIM_BIN = 3 # +15 d = bin 3
OUT_DIR = ROOT / "results"
FIG_DIR = ROOT / "results" / "figs"
NMDB_DIR = ROOT / "data" / "raw" / "nmdb"
USGS_DIR = ROOT / "data" / "raw" / "usgs"
CFG_FILE = ROOT / "config" / "stations.yaml"
SN_FILE = ROOT / "data" / "raw" / "sidc" / "sunspots.csv"
FIG_DIR.mkdir(parents=True, exist_ok=True)
SOLAR_CYCLES = {
21: ("1976-03-01", "1986-09-01"),
22: ("1986-09-01", "1996-08-01"),
23: ("1996-08-01", "2008-12-01"),
24: ("2008-12-01", "2019-12-31"),
}
# ---------------------------------------------------------------------------
# Shared utilities
# ---------------------------------------------------------------------------
def _station_names() -> list[str]:
with open(CFG_FILE) as fh:
return list(yaml.safe_load(fh)["stations"].keys())
def _bin_daily(daily: pd.Series, t0: pd.Timestamp, bin_days: int,
agg: str = "mean") -> pd.Series:
days = (daily.index - t0).days
bin_num = days // bin_days
bin_dates = t0 + pd.to_timedelta(bin_num * bin_days, unit="D")
g = daily.groupby(bin_dates)
return g.sum() if agg == "sum" else g.mean()
def _load_cr(study_start: str, study_end: str,
bin_days: int = BIN_DAYS,
min_stations: int = MIN_STATIONS) -> tuple[pd.Series, pd.DataFrame]:
"""Return (cr_index, station_daily_norm)."""
t0 = pd.Timestamp(study_start)
t1 = pd.Timestamp(study_end)
norm: dict[str, pd.Series] = {}
for stn in _station_names():
hourly = load_station(stn, t0.year, t1.year, NMDB_DIR)
if hourly.empty:
continue
daily = resample_daily(hourly, stn, coverage_threshold=COV_THRESH)[stn]
daily = daily.loc[study_start:study_end]
if daily.notna().sum() < 30:
continue
mu = daily.mean()
if not (np.isfinite(mu) and mu > 0):
continue
norm[stn] = daily / mu
if not norm:
raise RuntimeError("No NMDB data.")
mat = pd.DataFrame(norm)
n_valid = mat.notna().sum(axis=1)
global_daily = mat.mean(axis=1)
global_daily[n_valid < min_stations] = np.nan
cr = _bin_daily(global_daily, t0, bin_days)
cr.name = "cr_index"
log.info("CR (%d-d bins, min_stn=%d): %d bins, %d stations",
bin_days, min_stations, len(cr), len(norm))
return cr, mat
def _load_seismic_events(study_start: str, study_end: str,
min_mag: float = MIN_MAG) -> pd.DataFrame:
"""Return raw USGS event DataFrame with latitude, longitude, mag columns."""
t0 = pd.Timestamp(study_start)
t1 = pd.Timestamp(study_end)
ev = load_usgs(t0.year, t1.year, USGS_DIR)
ev = ev.loc[study_start:study_end]
ev = ev[ev["mag"] >= min_mag].copy()
log.info("Events M≥%.1f: %d in %s%s", min_mag, len(ev),
study_start, study_end)
return ev
def _energy_metric(events: pd.DataFrame, study_start: str, study_end: str,
bin_days: int, ref_index: pd.DatetimeIndex | None = None,
min_mag: float = MIN_MAG) -> pd.Series:
t0 = pd.Timestamp(study_start)
s = seismic_energy_per_bin(events, study_start, study_end, bin_days, t0,
min_mag=min_mag)
if ref_index is not None:
s = s.reindex(ref_index, fill_value=float(s.min()))
else:
s = s.fillna(float(s.min()))
return s
def _load_sunspots_binned(study_start: str, study_end: str,
bin_days: int = BIN_DAYS) -> pd.Series:
"""Parse the KSO comma-sep sunspot CSV → 5-day binned daily mean."""
df = pd.read_csv(SN_FILE, header=0)
df.columns = [c.strip() for c in df.columns]
df["date"] = pd.to_datetime(df["Date"].str.strip(), errors="coerce")
df = df.dropna(subset=["date"]).set_index("date")
sn = pd.to_numeric(df["Total"].astype(str).str.strip(), errors="coerce")
sn = sn.loc[study_start:study_end].rename("sunspot")
# Resample to daily (data is already monthly-ish — forward-fill)
daily_idx = pd.date_range(study_start, study_end, freq="D")
sn = sn.reindex(daily_idx).interpolate("linear").ffill().bfill()
t0 = pd.Timestamp(study_start)
return _bin_daily(sn, t0, bin_days)
def xcorr(x: np.ndarray, y: np.ndarray, lag_bins: np.ndarray) -> np.ndarray:
"""Pearson r(τ) for each lag bin; τ>0 means x leads y."""
N = len(x)
rs = np.full(len(lag_bins), np.nan)
for i, lag in enumerate(lag_bins):
if lag >= 0:
xa, ya = x[:N - lag], y[lag:]
else:
absl = -lag
xa, ya = x[absl:], y[:N - absl]
ok = np.isfinite(xa) & np.isfinite(ya)
n = ok.sum()
if n >= 10:
xo = xa[ok] - xa[ok].mean()
yo = ya[ok] - ya[ok].mean()
denom = np.sqrt((xo ** 2).sum() * (yo ** 2).sum())
if denom > 1e-12:
rs[i] = np.dot(xo, yo) / denom
return rs
# ---------------------------------------------------------------------------
# 3a — Block-bootstrap surrogates
# ---------------------------------------------------------------------------
def _circular_block_bootstrap(
x: np.ndarray, y: np.ndarray,
block_len: int,
n_surr: int,
lag_bins: np.ndarray,
seed: int = SEED,
) -> tuple[np.ndarray, np.ndarray]:
"""
Circular block bootstrap (CBB) null distribution.
Independently resample *x* and *y* with replacement using blocks of length
*block_len* (circular, so the series wraps). Returns arrays of shape
(n_surr,) containing the surrogate r(+15d) and peak |r| values.
Vectorised: all surrogates are built into a matrix (n_surr × N) and
the correlation is computed for all surrogates simultaneously per lag,
avoiding a 5000 × 401 = 2 M Python-loop iterations.
"""
rng = np.random.default_rng(seed)
N = len(x)
n_blocks = int(np.ceil(N / block_len))
n_lags = len(lag_bins)
# Build surrogate matrices (n_surr × N) — Python loop only over n_surr
log.info(" Building %d surrogate series (block_len=%d) …", n_surr, block_len)
xs_mat = np.empty((n_surr, N), dtype=np.float64)
ys_mat = np.empty((n_surr, N), dtype=np.float64)
for i in range(n_surr):
starts_x = rng.integers(0, N, size=n_blocks)
starts_y = rng.integers(0, N, size=n_blocks)
xs_mat[i] = np.concatenate([np.roll(x, -s)[:block_len] for s in starts_x])[:N]
ys_mat[i] = np.concatenate([np.roll(y, -s)[:block_len] for s in starts_y])[:N]
# Vectorised xcorr: loop over lags only (all surrogates in parallel)
log.info(" Vectorised xcorr over %d lags …", n_lags)
rs_mat = np.full((n_surr, n_lags), np.nan, dtype=np.float64)
for j, lag in enumerate(lag_bins):
if lag >= 0:
xa = xs_mat[:, :N - lag] if lag > 0 else xs_mat
ya = ys_mat[:, lag:] if lag > 0 else ys_mat
else:
absl = -lag
xa = xs_mat[:, absl:]
ya = ys_mat[:, :N - absl]
xm = xa - xa.mean(axis=1, keepdims=True)
ym = ya - ya.mean(axis=1, keepdims=True)
num = (xm * ym).sum(axis=1)
denom = np.sqrt((xm ** 2).sum(axis=1) * (ym ** 2).sum(axis=1))
valid = denom > 1e-12
rs_mat[valid, j] = num[valid] / denom[valid]
claim_idx = np.where(lag_bins == CLAIM_BIN)[0]
rs_15 = rs_mat[:, claim_idx[0]] if len(claim_idx) else np.full(n_surr, np.nan)
rs_pk = np.nanmax(np.abs(rs_mat), axis=1)
return rs_15, rs_pk
def run_3a(cr: pd.Series, sei: pd.Series) -> dict:
log.info("=== 3a: Block-bootstrap surrogates ===")
x = cr.values.copy()
y = sei.values.copy()
# Fill NaN with series mean for bootstrap (preserves length)
x = np.where(np.isfinite(x), x, np.nanmean(x))
y = np.where(np.isfinite(y), y, np.nanmean(y))
N = len(x)
# Block length ≈ 1 solar cycle (11 yr ≈ 4016 d ÷ 5 d/bin = 803 bins)
block_len = int(round(11 * 365.25 / BIN_DAYS))
log.info(" N=%d block_len=%d bins (≈%.1f yr) surrogates=5000",
N, block_len, block_len * BIN_DAYS / 365.25)
rs_15, rs_pk = _circular_block_bootstrap(x, y, block_len, 5000, LAG_BINS)
obs_rv = xcorr(x, y, LAG_BINS)
obs_15 = obs_rv[LAG_BINS == CLAIM_BIN][0]
obs_pk = np.nanmax(np.abs(obs_rv))
p_15 = float(np.mean(np.abs(rs_15) >= np.abs(obs_15)))
p_pk = float(np.mean(rs_pk >= obs_pk))
ci95_15 = (float(np.percentile(rs_15, 2.5)), float(np.percentile(rs_15, 97.5)))
log.info(" obs r(+15d)=%.4f block-bootstrap p(+15d)=%.4f p(peak)=%.4f",
obs_15, p_15, p_pk)
# Load IAAFT p-value for comparison
iaaft_raw = None
try:
with open(OUT_DIR / "detrended_results.json") as fh:
det = json.load(fh)
iaaft_raw = det["results"][0]["p_global_iaaft"]
except Exception:
pass
# Figure
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].hist(rs_15, bins=60, color="steelblue", alpha=0.7,
label="Block-bootstrap null")
axes[0].axvline(obs_15, color="red", lw=2, label=f"Observed r={obs_15:.3f}")
axes[0].axvline(ci95_15[0], color="grey", ls="--")
axes[0].axvline(ci95_15[1], color="grey", ls="--", label="95% CI")
axes[0].set_xlabel("r(+15 d)")
axes[0].set_title(f"Block bootstrap null\np(+15d) = {p_15:.3f}")
axes[0].legend(fontsize=8)
axes[1].hist(rs_pk, bins=60, color="darkorange", alpha=0.7,
label="Block-bootstrap null")
axes[1].axvline(obs_pk, color="red", lw=2, label=f"Observed peak |r|={obs_pk:.3f}")
axes[1].set_xlabel("Peak |r|")
axes[1].set_title(f"Peak |r| null\np(peak) = {p_pk:.3f}")
axes[1].legend(fontsize=8)
if iaaft_raw is not None:
axes[0].set_xlabel("r(+15 d)" + f"\n(IAAFT p_global={iaaft_raw:.4f})")
fig.tight_layout()
fig.savefig(FIG_DIR / "block_bootstrap_null.png", dpi=150, bbox_inches="tight")
plt.close(fig)
log.info("3a figure saved.")
return dict(
block_len_bins=block_len,
obs_r_15d=float(obs_15),
obs_peak_r=float(obs_pk),
p_block_15d=p_15,
p_block_peak=p_pk,
ci95_15d=list(ci95_15),
iaaft_p_global_raw=iaaft_raw,
interpretation=(
"p-value similar to IAAFT" if iaaft_raw is None or abs(p_15 - iaaft_raw) < 0.1
else "p-value changes materially vs IAAFT"
),
)
# ---------------------------------------------------------------------------
# 3b — Partial correlation controlling for sunspots (raw data)
# ---------------------------------------------------------------------------
def run_3b(cr: pd.Series, sei: pd.Series) -> dict:
log.info("=== 3b: Partial correlation (sunspot control) ===")
sn = _load_sunspots_binned(STUDY_START, STUDY_END)
# Align all three series
idx = cr.index.intersection(sei.index).intersection(sn.index)
x = cr.reindex(idx).values.astype(float)
y = sei.reindex(idx).values.astype(float)
z = sn.reindex(idx).values.astype(float)
ok = np.isfinite(x) & np.isfinite(y) & np.isfinite(z)
log.info(" Aligned N=%d, valid=%d", len(x), ok.sum())
# OLS: regress seismic on sunspot
z_ok = z[ok]; y_ok = y[ok]; x_ok = x[ok]
slope, intercept, *_ = scipy.stats.linregress(z_ok, y_ok)
y_resid = y_ok - (slope * z_ok + intercept)
log.info(" Sunspot regression on seismic: slope=%.4f intercept=%.4f", slope, intercept)
r_partial, pv = scipy.stats.pearsonr(x_ok, y_resid)
log.info(" Partial r(CR, Seismic|Sunspot) at zero lag = %.4f p=%.4e",
r_partial, pv)
# Full cross-correlation of CR vs seismic residual
x_full = np.full(len(idx), np.nan)
y_res_full = np.full(len(idx), np.nan)
x_full[ok] = x_ok
y_res_full[ok] = y_resid
rv_partial = xcorr(x_full, y_res_full, LAG_BINS)
rv_raw = xcorr(x, y, LAG_BINS)
r_partial_15 = rv_partial[LAG_BINS == CLAIM_BIN][0]
r_raw_15 = rv_raw[LAG_BINS == CLAIM_BIN][0]
peak_partial = float(np.nanmax(np.abs(rv_partial)))
log.info(" r(+15d) raw=%.4f partial=%.4f", r_raw_15, r_partial_15)
# Figure
fig, ax = plt.subplots(figsize=(9, 4))
lags_d = LAG_BINS * BIN_DAYS
ax.plot(lags_d, rv_raw, color="steelblue", alpha=0.7, label="Raw seismic")
ax.plot(lags_d, rv_partial, color="darkorange", lw=1.5,
label="Seismic residual (sunspot removed)")
ax.axhline(0, color="black", lw=0.6)
ax.axvline(15, color="grey", ls="--", lw=1.2, label="+15 d")
ax.set_xlabel("Lag τ (days)")
ax.set_ylabel("Pearson r")
ax.set_title(f"Partial correlation: CR vs seismic after sunspot regression\n"
f"r_raw(+15d)={r_raw_15:.3f} r_partial(+15d)={r_partial_15:.3f}")
ax.legend(fontsize=9)
fig.tight_layout()
fig.savefig(FIG_DIR / "partial_correlation.png", dpi=150, bbox_inches="tight")
plt.close(fig)
log.info("3b figure saved.")
drop_frac = (abs(r_raw_15) - abs(r_partial_15)) / max(abs(r_raw_15), 1e-9)
return dict(
sunspot_slope=float(slope),
r_raw_15d=float(r_raw_15),
r_partial_15d=float(r_partial_15),
drop_fraction_at_15d=float(drop_frac),
peak_r_partial=float(peak_partial),
interpretation=(
"Partial correlation near zero — solar-cycle confounding confirmed"
if abs(r_partial_15) < 0.05 else
"Partial correlation non-trivial — residual signal remains after sunspot control"
),
)
# ---------------------------------------------------------------------------
# 3c — Spectral coherence + mutual information
# ---------------------------------------------------------------------------
def _mi_knn(x: np.ndarray, y: np.ndarray, k: int = 5) -> float:
"""
Kraskov et al. (2004) kNN mutual information estimator (estimator 1).
Uses Chebyshev (L-inf) metric in joint space; marginal counts via
vectorised searchsorted O(N log N), no Python loop over points.
Requires finite values only.
"""
from scipy.special import digamma
N = len(x)
x = (x - x.mean()) / (x.std() + 1e-12)
y = (y - y.mean()) / (y.std() + 1e-12)
xy = np.column_stack([x, y])
# k-NN in joint space using Chebyshev (L-inf) metric
tree_xy = scipy.spatial.cKDTree(xy)
dists, _ = tree_xy.query(xy, k=k + 1, p=np.inf, workers=-1)
eps = dists[:, -1] # k-th neighbour Chebyshev distance
# Count marginal neighbours via sorted binary search — O(N log N), vectorised
xs = np.sort(x)
ys = np.sort(y)
nx = (np.searchsorted(xs, x + eps, side="right")
- np.searchsorted(xs, x - eps, side="left") - 1)
ny = (np.searchsorted(ys, y + eps, side="right")
- np.searchsorted(ys, y - eps, side="left") - 1)
nx = np.maximum(nx, 0)
ny = np.maximum(ny, 0)
mi = digamma(k) + digamma(N) - np.mean(digamma(nx + 1)) - np.mean(digamma(ny + 1))
return float(max(mi, 0.0))
def run_3c(cr: pd.Series, sei: pd.Series) -> dict:
log.info("=== 3c: Spectral coherence + mutual information ===")
rng = np.random.default_rng(SEED)
idx = cr.index.intersection(sei.index)
x = cr.reindex(idx).values.astype(float)
y = sei.reindex(idx).values.astype(float)
ok = np.isfinite(x) & np.isfinite(y)
xf, yf = x[ok], y[ok]
# --- Spectral coherence ---
# nperseg=2048 gives freq. resolution (1/5)/2048 = 0.036 cycles/yr,
# sufficient to resolve the solar-cycle band (0.080.115 cycles/yr).
# nperseg=512 only gives 0.143 cycles/yr — no bins fall in the SC band.
nperseg = 2048
fs = 1.0 / BIN_DAYS # cycles per day
f_d, Cxy = scipy.signal.coherence(xf, yf, fs=fs, nperseg=nperseg,
window="hann", noverlap=nperseg * 3 // 4)
f_yr = f_d * 365.25 # cycles per year
# Solar cycle band: 0.080.11 cycles/yr (912 year period)
sc_mask = (f_yr >= 0.08) & (f_yr <= 0.115)
coh_sc = float(np.mean(Cxy[sc_mask]))
log.info(" Mean coherence in solar-cycle band: %.4f", coh_sc)
# Significance: 95th percentile of coherence for white-noise pairs
noverlap_used = nperseg * 3 // 4
step = nperseg - noverlap_used
n_seg = max(1, (ok.sum() - nperseg) // step + 1)
coh_95 = 1 - 0.05 ** (1.0 / (n_seg - 1)) if n_seg > 1 else np.nan
log.info(" Coherence 95%% significance threshold (for %d segments): %.4f",
n_seg, coh_95)
# --- Mutual information ---
N = len(xf)
mi_lag0 = _mi_knn(xf, yf)
# MI at lag +15d (=+3 bins)
lag15 = CLAIM_BIN
xi15, yi15 = xf[:N - lag15], yf[lag15:]
ok15 = np.isfinite(xi15) & np.isfinite(yi15)
mi_lag15 = _mi_knn(xi15[ok15], yi15[ok15])
log.info(" MI(lag=0)=%.4f MI(lag=+15d)=%.4f", mi_lag0, mi_lag15)
# Shuffle null for MI (1000 permutations)
n_shuf = 1000
mi_null_0 = np.empty(n_shuf)
mi_null_15 = np.empty(n_shuf)
for i in range(n_shuf):
ys = rng.permutation(yf)
mi_null_0[i] = _mi_knn(xf, ys)
ys15 = rng.permutation(yf[lag15:])
mi_null_15[i] = _mi_knn(xf[:N - lag15][ok15], ys15[ok15])
p_mi_0 = float(np.mean(mi_null_0 >= mi_lag0))
p_mi_15 = float(np.mean(mi_null_15 >= mi_lag15))
log.info(" p(MI lag=0)=%.4f p(MI lag=+15d)=%.4f", p_mi_0, p_mi_15)
# Figure
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
# Coherence panel
ax = axes[0]
ax.plot(f_yr, Cxy, color="steelblue", lw=1, label="Coherence")
ax.axvspan(0.08, 0.115, alpha=0.15, color="orange", label="Solar-cycle band (0.080.115 yr⁻¹)")
if np.isfinite(coh_95):
ax.axhline(coh_95, color="red", ls="--", lw=1.2,
label=f"95% sig. ({coh_95:.3f}, K={n_seg} seg.)")
ax.set_xlim(0, 0.5)
ax.set_ylim(0, 1.05)
ax.set_xlabel("Frequency (cycles yr⁻¹)")
ax.set_ylabel("Magnitude-squared coherence")
coh_sc_str = f"{coh_sc:.3f}" if np.isfinite(coh_sc) else "N/A"
ax.set_title(f"Spectral coherence (nperseg={nperseg})\nMean coh. in SC band: {coh_sc_str}")
ax.legend(fontsize=8)
# MI panel
ax = axes[1]
ax.hist(mi_null_0, bins=40, color="steelblue", alpha=0.6, label="Shuffle null (lag=0)")
ax.hist(mi_null_15, bins=40, color="darkorange", alpha=0.6, label="Shuffle null (lag=+15d)")
ax.axvline(mi_lag0, color="steelblue", lw=2, ls="-", label=f"Obs MI(0)={mi_lag0:.3f}")
ax.axvline(mi_lag15, color="darkorange", lw=2, ls="--",
label=f"Obs MI(+15d)={mi_lag15:.3f}")
ax.set_xlabel("Mutual information (nats)")
ax.set_title(f"kNN mutual information\np(lag=0)={p_mi_0:.3f} p(lag=+15d)={p_mi_15:.3f}")
ax.legend(fontsize=7)
fig.tight_layout()
fig.savefig(FIG_DIR / "spectral_coherence.png", dpi=150, bbox_inches="tight")
plt.close(fig)
log.info("3c figure saved.")
return dict(
coherence_solar_cycle_band=coh_sc,
coherence_95pct_threshold=coh_95 if np.isfinite(coh_95) else None,
mi_lag0=mi_lag0,
mi_lag15d=mi_lag15,
p_mi_lag0=p_mi_0,
p_mi_lag15d=p_mi_15,
)
# ---------------------------------------------------------------------------
# 3d — Missing-data sensitivity
# ---------------------------------------------------------------------------
SOLAR_MAXIMA = [1979.7, 1989.6, 2000.3, 2014.2] # approximate decimal years
def _cr_nan_analysis(study_start: str, study_end: str,
min_stations: int) -> dict:
"""Return NaN stats and r(+15d) for the given station threshold."""
cr, _ = _load_cr(study_start, study_end, bin_days=BIN_DAYS,
min_stations=min_stations)
ev = _load_seismic_events(study_start, study_end)
sei = _energy_metric(ev, study_start, study_end, BIN_DAYS, cr.index)
nan_frac = float(cr.isna().mean())
# Are NaN bins concentrated near solar maxima?
is_nan = cr.isna()
bin_years = cr.index.year + cr.index.dayofyear / 365.25
# Flag years within ±1.5 yr of any solar maximum
near_max = np.zeros(len(cr), dtype=bool)
for sm in SOLAR_MAXIMA:
near_max |= np.abs(bin_years - sm) <= 1.5
nan_near = float(is_nan[near_max].mean())
nan_far = float(is_nan[~near_max].mean())
# r(+15d)
ok = np.isfinite(cr.values) & np.isfinite(sei.values)
x, y = cr.values[ok], sei.values[ok]
r15, _ = scipy.stats.pearsonr(x, y) # zero-lag as proxy; lag-3 below
# Actual lag-3
N = len(cr)
xa = cr.values[:N - CLAIM_BIN]; ya = sei.values[CLAIM_BIN:]
ok2 = np.isfinite(xa) & np.isfinite(ya)
r_15d, _ = scipy.stats.pearsonr(xa[ok2], ya[ok2])
return dict(
min_stations=min_stations,
nan_fraction=nan_frac,
nan_fraction_near_solar_max=nan_near,
nan_fraction_far_from_solar_max=nan_far,
clustering_ratio=nan_near / max(nan_far, 1e-9),
r_at_15d=float(r_15d),
)
def run_3d() -> dict:
log.info("=== 3d: Missing-data sensitivity ===")
results = []
for thr in (2, 3, 5):
log.info(" Station threshold = %d", thr)
res = _cr_nan_analysis(STUDY_START, STUDY_END, thr)
results.append(res)
log.info(" NaN=%.1f%% near-max=%.1f%% r(+15d)=%.4f",
100 * res["nan_fraction"],
100 * res["nan_fraction_near_solar_max"],
res["r_at_15d"])
return dict(station_threshold_sensitivity=results)
# ---------------------------------------------------------------------------
# 3e — Bin-size sensitivity
# ---------------------------------------------------------------------------
def _run_for_bin_size(bin_days: int) -> dict:
"""Load CR and seismic at *bin_days* resolution, compute r(τ)."""
cr, _ = _load_cr(STUDY_START, STUDY_END, bin_days=bin_days)
ev = _load_seismic_events(STUDY_START, STUDY_END)
sei = _energy_metric(ev, STUDY_START, STUDY_END, bin_days, cr.index)
# Lag range: ±1000 days in steps of bin_days
max_lag_bins = int(1000 / bin_days)
lbs = np.arange(-max_lag_bins, max_lag_bins + 1)
rv = xcorr(cr.values, sei.values, lbs)
# Find claimed lag bin (closest to +15d)
claim_bin = int(round(15 / bin_days))
r15 = rv[lbs == claim_bin][0] if np.any(lbs == claim_bin) else np.nan
peak_idx = np.nanargmax(np.abs(rv))
peak_r = rv[peak_idx]
peak_lag = int(lbs[peak_idx]) * bin_days # days
log.info(" %d-d bins: r(+%dd)=%.4f peak r=%.4f @ τ=%dd",
bin_days, claim_bin * bin_days, r15, peak_r, peak_lag)
return dict(
bin_days=bin_days,
r_at_claimed_lag=float(r15),
claimed_lag_days=claim_bin * bin_days,
peak_r=float(peak_r),
peak_lag_days=peak_lag,
lag_bins=lbs.tolist(),
r_values=rv.tolist(),
)
def run_3e() -> dict:
log.info("=== 3e: Bin-size sensitivity ===")
results = []
rv_by_bin = {}
for bd in (1, 5, 27):
r = _run_for_bin_size(bd)
results.append({k: v for k, v in r.items() if k not in ("lag_bins", "r_values")})
rv_by_bin[bd] = (r["lag_bins"], r["r_values"])
# Figure: 3-panel
fig, axes = plt.subplots(1, 3, figsize=(14, 4), sharey=False)
colours = ["steelblue", "darkorange", "seagreen"]
for ax, (bd, (lbs, rv)), col in zip(axes, rv_by_bin.items(), colours):
lags_d = np.array(lbs) * bd
rv = np.array(rv)
ax.plot(lags_d, rv, color=col, lw=0.8)
ax.axhline(0, color="black", lw=0.5)
ax.axvline(15, color="grey", ls="--", lw=1, label="+15 d")
closest = lbs[np.argmin(np.abs(np.array(lbs) - round(15 / bd)))]
pk_d = lbs[np.nanargmax(np.abs(rv))] * bd
ax.axvline(pk_d, color="red", ls=":", lw=1, label=f"Peak τ={pk_d}d")
ax.set_title(f"{bd}-day bins\nr(+15d≈{int(round(15/bd)*bd)}d)="
f"{rv[np.argmin(np.abs(np.array(lbs)-round(15/bd)))]:.3f}")
ax.set_xlabel("Lag (days)")
ax.set_ylabel("Pearson r")
ax.legend(fontsize=7)
fig.suptitle("Bin-size sensitivity: 1-day, 5-day, 27-day bins", fontsize=11)
fig.tight_layout()
fig.savefig(FIG_DIR / "bin_size_sensitivity.png", dpi=150, bbox_inches="tight")
plt.close(fig)
log.info("3e figure saved.")
return dict(bin_size_sensitivity=results)
# ---------------------------------------------------------------------------
# 3f — GardnerKnopoff declustering
# ---------------------------------------------------------------------------
def _gk_time_window(mag: float) -> float:
"""After-shock time window T(M) in days (Gardner & Knopoff 1974)."""
if mag < 6.5:
return 10 ** (0.5 * mag - 1.8)
else:
return 10 ** (0.46 * mag - 2.31)
def _gk_dist_window(mag: float) -> float:
"""After-shock distance window L(M) in km (Gardner & Knopoff 1974)."""
return 10 ** (0.1238 * mag + 0.983)
def _haversine_km(lat1: np.ndarray, lon1: np.ndarray,
lat2: float, lon2: float) -> np.ndarray:
"""Vectorised haversine distance in km."""
R = 6371.0
dlat = np.radians(lat2 - lat1)
dlon = np.radians(lon2 - lon1)
a = (np.sin(dlat / 2) ** 2 +
np.cos(np.radians(lat1)) * np.cos(np.radians(lat2)) *
np.sin(dlon / 2) ** 2)
return 2 * R * np.arcsin(np.sqrt(np.clip(a, 0, 1)))
def _gardner_knopoff_decluster(events: pd.DataFrame) -> pd.DataFrame:
"""
Remove aftershocks from *events* using the Gardner-Knopoff (1974) algorithm.
Returns the mainshock-only DataFrame. Uses forward-only time windows
(each mainshock's aftershock zone applies to all future events within T(M)).
"""
ev = events.dropna(subset=["latitude", "longitude", "mag"]).copy()
ev = ev.sort_index()
n = len(ev)
times = ev.index.values.astype("datetime64[ns]").astype(np.int64) / 1e9 / 86400 # days
lats = ev["latitude"].values
lons = ev["longitude"].values
mags = ev["mag"].values
is_as = np.zeros(n, dtype=bool)
log.info(" GK declustering: %d events …", n)
for i in range(n):
if is_as[i]:
continue
tw = _gk_time_window(mags[i])
dw = _gk_dist_window(mags[i])
# Forward window in time
t_end = times[i] + tw
j_lo = i + 1
# Find j_hi via binary search (times is sorted)
j_hi = np.searchsorted(times, t_end, side="right")
if j_lo >= j_hi:
continue
cands = np.arange(j_lo, j_hi)
cands = cands[~is_as[cands]] # skip already-flagged
if len(cands) == 0:
continue
dists = _haversine_km(lats[cands], lons[cands], lats[i], lons[i])
is_as[cands[dists <= dw]] = True
n_main = int((~is_as).sum())
n_as = int(is_as.sum())
log.info(" GK result: %d mainshocks %d aftershocks (%.1f%% removed)",
n_main, n_as, 100 * n_as / max(n, 1))
return ev[~is_as]
def run_3f(cr: pd.Series) -> dict:
log.info("=== 3f: GardnerKnopoff declustering ===")
events = _load_seismic_events(STUDY_START, STUDY_END, min_mag=MIN_MAG)
sei_full = _energy_metric(events, STUDY_START, STUDY_END, BIN_DAYS, cr.index)
mainshocks = _gardner_knopoff_decluster(events)
sei_decl = _energy_metric(mainshocks, STUDY_START, STUDY_END, BIN_DAYS, cr.index)
rv_full = xcorr(cr.values, sei_full.values, LAG_BINS)
rv_decl = xcorr(cr.values, sei_decl.values, LAG_BINS)
r15_full = float(rv_full[LAG_BINS == CLAIM_BIN][0])
r15_decl = float(rv_decl[LAG_BINS == CLAIM_BIN][0])
pk_full = float(np.nanmax(np.abs(rv_full)))
pk_decl = float(np.nanmax(np.abs(rv_decl)))
log.info(" r(+15d) full=%.4f declustered=%.4f", r15_full, r15_decl)
n_removed_frac = float(1 - len(mainshocks) / len(events))
# Figure
fig, ax = plt.subplots(figsize=(9, 4))
lags_d = LAG_BINS * BIN_DAYS
ax.plot(lags_d, rv_full, color="steelblue", alpha=0.8,
label=f"Full catalogue (n={len(events):,})")
ax.plot(lags_d, rv_decl, color="darkorange", lw=1.5,
label=f"Declustered / mainshocks only (n={len(mainshocks):,})")
ax.axhline(0, color="black", lw=0.5)
ax.axvline(15, color="grey", ls="--", lw=1.2, label="+15 d")
ax.set_xlabel("Lag τ (days)")
ax.set_ylabel("Pearson r")
ax.set_title(f"GardnerKnopoff declustering\n"
f"r(+15d): full={r15_full:.3f} declustered={r15_decl:.3f} "
f"({100*n_removed_frac:.0f}% removed)")
ax.legend(fontsize=9)
fig.tight_layout()
fig.savefig(FIG_DIR / "declustered_xcorr.png", dpi=150, bbox_inches="tight")
plt.close(fig)
log.info("3f figure saved.")
return dict(
n_events_full=len(events),
n_mainshocks=len(mainshocks),
fraction_removed=n_removed_frac,
r_15d_full=r15_full,
r_15d_declustered=r15_decl,
peak_r_full=pk_full,
peak_r_declustered=pk_decl,
interpretation=(
"Aftershock clustering is NOT a primary confound — result stable after GK declustering"
if abs(r15_full - r15_decl) < 0.03 else
"Result changes after GK declustering — aftershock contamination is a concern"
),
)
# ---------------------------------------------------------------------------
# 3g — Sub-period analysis (per solar cycle)
# ---------------------------------------------------------------------------
def run_3g(cr: pd.Series, sei: pd.Series) -> dict:
log.info("=== 3g: Sub-period analysis (per solar cycle) ===")
lag_range_bins = np.arange(-40, 41) # ±200 d in 5-d steps (short cycles)
fig, axes = plt.subplots(2, 2, figsize=(12, 8), sharey=True)
results = {}
for ax, (cycle_num, (t_start, t_end)) in zip(axes.flat, SOLAR_CYCLES.items()):
# Crop pre-aligned global CR/seismic series — avoids bin-date misalignment
cr_c = cr.loc[t_start:t_end]
sei_c = sei.loc[t_start:t_end]
if len(cr_c) < 40:
log.warning(" Cycle %d: insufficient data (%d bins)", cycle_num, len(cr_c))
ax.set_title(f"Cycle {cycle_num}: insufficient data")
results[f"cycle_{cycle_num}"] = None
continue
rv = xcorr(cr_c.values, sei_c.values, lag_range_bins)
if np.all(np.isnan(rv)):
log.warning(" Cycle %d: all-NaN xcorr — skipping", cycle_num)
ax.set_title(f"Cycle {cycle_num}: all-NaN")
results[f"cycle_{cycle_num}"] = None
continue
r15 = float(rv[lag_range_bins == CLAIM_BIN][0]) if np.any(lag_range_bins == CLAIM_BIN) else np.nan
pk_idx = np.nanargmax(np.abs(rv))
pk_r = float(rv[pk_idx])
pk_lag = int(lag_range_bins[pk_idx]) * BIN_DAYS
n_bins = len(cr_c)
log.info(" Cycle %d (%s%s): N=%d r(+15d)=%.4f peak=%.4f@%dd",
cycle_num, t_start, t_end, n_bins, r15, pk_r, pk_lag)
lags_d = lag_range_bins * BIN_DAYS
ax.plot(lags_d, rv, color="steelblue", lw=1.2)
ax.axhline(0, color="black", lw=0.5)
ax.axvline(15, color="grey", ls="--", lw=1, label="+15 d")
ax.axvline(pk_lag, color="red", ls=":", lw=1,
label=f"Peak τ={pk_lag}d r={pk_r:.3f}")
ax.set_title(f"Solar Cycle {cycle_num} ({t_start[:4]}{t_end[:4]})\n"
f"N={n_bins} bins r(+15d)={r15:.3f}")
ax.set_xlabel("Lag (days)")
ax.set_ylabel("Pearson r")
ax.legend(fontsize=7)
results[f"cycle_{cycle_num}"] = dict(
start=t_start, end=t_end,
n_bins=n_bins,
r_at_15d=r15,
peak_r=pk_r,
peak_lag_days=pk_lag,
)
fig.suptitle("Cross-correlation per solar cycle (19762019)", fontsize=11)
fig.tight_layout()
fig.savefig(FIG_DIR / "solar_cycle_xcorr.png", dpi=150, bbox_inches="tight")
plt.close(fig)
log.info("3g figure saved.")
r15_vals = [v["r_at_15d"] for v in results.values() if v is not None]
sign_consistent = all(r > 0 for r in r15_vals) or all(r < 0 for r in r15_vals)
return dict(
per_cycle=results,
r15d_range=[float(min(r15_vals)), float(max(r15_vals))],
sign_consistent_across_cycles=sign_consistent,
interpretation=(
"r(+15d) consistent in sign across all solar cycles"
if sign_consistent else
"r(+15d) sign INCONSISTENT across solar cycles — confirms solar-cycle artefact"
),
)
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
def main() -> None:
log.info("Loading base CR and seismic data …")
cr, _stn = _load_cr(STUDY_START, STUDY_END)
events = _load_seismic_events(STUDY_START, STUDY_END)
sei = _energy_metric(events, STUDY_START, STUDY_END, BIN_DAYS, cr.index)
out = {}
log.info("Running 3a …")
out["3a_block_bootstrap"] = run_3a(cr, sei)
log.info("Running 3b …")
out["3b_partial_correlation"] = run_3b(cr, sei)
log.info("Running 3c …")
out["3c_coherence_mi"] = run_3c(cr, sei)
log.info("Running 3d …")
out["3d_missing_data"] = run_3d()
log.info("Running 3e …")
out["3e_bin_size"] = run_3e()
log.info("Running 3f …")
out["3f_declustering"] = run_3f(cr)
log.info("Running 3g …")
out["3g_solar_cycles"] = run_3g(cr, sei)
# Save JSON
out_path = OUT_DIR / "additional_robustness.json"
with open(out_path, "w") as fh:
json.dump(out, fh, indent=2, default=str)
log.info("Results saved: %s", out_path)
# ── Summary printout ───────────────────────────────────────────────────
print("\n" + "=" * 70)
print(" ADDITIONAL ROBUSTNESS SUMMARY")
print("=" * 70)
r = out["3a_block_bootstrap"]
print(f" 3a Block bootstrap p(+15d)={r['p_block_15d']:.4f} "
f"p(peak)={r['p_block_peak']:.4f}")
r = out["3b_partial_correlation"]
print(f" 3b Partial corr r_raw(+15d)={r['r_raw_15d']:.4f} "
f"r_partial={r['r_partial_15d']:.4f}")
r = out["3c_coherence_mi"]
print(f" 3c Coherence SC-band={r['coherence_solar_cycle_band']:.4f} "
f"MI p(lag=0)={r['p_mi_lag0']:.3f} p(+15d)={r['p_mi_lag15d']:.3f}")
for res in out["3d_missing_data"]["station_threshold_sensitivity"]:
print(f" 3d min_stn={res['min_stations']} "
f"NaN={100*res['nan_fraction']:.1f}% r(+15d)={res['r_at_15d']:.4f}")
for res in out["3e_bin_size"]["bin_size_sensitivity"]:
print(f" 3e {res['bin_days']:2d}-d bins "
f"r(+{res['claimed_lag_days']}d)={res['r_at_claimed_lag']:.4f} "
f"peak={res['peak_r']:.4f}@{res['peak_lag_days']}d")
r = out["3f_declustering"]
print(f" 3f Declustering removed={100*r['fraction_removed']:.0f}% "
f"r_full={r['r_15d_full']:.4f} r_decl={r['r_15d_declustered']:.4f}")
r = out["3g_solar_cycles"]
print(f" 3g Solar cycles r(+15d) range={r['r15d_range']} "
f"sign_consistent={r['sign_consistent_across_cycles']}")
print("=" * 70)
if __name__ == "__main__":
main()