scspill 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. scspill-0.1.0/LICENSE +21 -0
  2. scspill-0.1.0/PKG-INFO +151 -0
  3. scspill-0.1.0/README.md +116 -0
  4. scspill-0.1.0/pyproject.toml +136 -0
  5. scspill-0.1.0/scspill/__init__.py +82 -0
  6. scspill-0.1.0/scspill/config_models.py +589 -0
  7. scspill-0.1.0/scspill/data/__init__.py +286 -0
  8. scspill-0.1.0/scspill/data/files/california_W_matrix.csv +39 -0
  9. scspill-0.1.0/scspill/data/files/california_panel.csv +1210 -0
  10. scspill-0.1.0/scspill/data/files/california_w_vector.csv +39 -0
  11. scspill-0.1.0/scspill/data/files/sudan_W_matrix.csv +34 -0
  12. scspill-0.1.0/scspill/data/files/sudan_panel.csv +545 -0
  13. scspill-0.1.0/scspill/data/files/sudan_w_vector.csv +34 -0
  14. scspill-0.1.0/scspill/estimators/__init__.py +1 -0
  15. scspill-0.1.0/scspill/estimators/scspill.py +222 -0
  16. scspill-0.1.0/scspill/exceptions.py +25 -0
  17. scspill-0.1.0/scspill/py.typed +0 -0
  18. scspill-0.1.0/scspill/simulate/__init__.py +33 -0
  19. scspill-0.1.0/scspill/simulate/dgp.py +302 -0
  20. scspill-0.1.0/scspill/simulate/runner.py +309 -0
  21. scspill-0.1.0/scspill/simulate/summary.py +198 -0
  22. scspill-0.1.0/scspill/utils/__init__.py +1 -0
  23. scspill-0.1.0/scspill/utils/datautils.py +55 -0
  24. scspill-0.1.0/scspill/utils/effectutils.py +58 -0
  25. scspill-0.1.0/scspill/utils/fitutils.py +44 -0
  26. scspill-0.1.0/scspill/utils/plotting.py +410 -0
  27. scspill-0.1.0/scspill/utils/results_helpers.py +256 -0
  28. scspill-0.1.0/scspill/utils/scspill_helpers/__init__.py +6 -0
  29. scspill-0.1.0/scspill/utils/scspill_helpers/_kernels.py +514 -0
  30. scspill-0.1.0/scspill/utils/scspill_helpers/config.py +177 -0
  31. scspill-0.1.0/scspill/utils/scspill_helpers/diagnostics.py +196 -0
  32. scspill-0.1.0/scspill/utils/scspill_helpers/effects.py +385 -0
  33. scspill-0.1.0/scspill/utils/scspill_helpers/inference.py +64 -0
  34. scspill-0.1.0/scspill/utils/scspill_helpers/numba_kernels.py +81 -0
  35. scspill-0.1.0/scspill/utils/scspill_helpers/pipeline.py +140 -0
  36. scspill-0.1.0/scspill/utils/scspill_helpers/plotter.py +258 -0
  37. scspill-0.1.0/scspill/utils/scspill_helpers/sampler_alpha.py +125 -0
  38. scspill-0.1.0/scspill/utils/scspill_helpers/sampler_sar.py +565 -0
  39. scspill-0.1.0/scspill/utils/scspill_helpers/scm_baseline.py +131 -0
  40. scspill-0.1.0/scspill/utils/scspill_helpers/setup.py +280 -0
  41. scspill-0.1.0/scspill/utils/scspill_helpers/structures.py +452 -0
  42. scspill-0.1.0/scspill/validation/__init__.py +52 -0
  43. scspill-0.1.0/scspill/validation/geweke.py +374 -0
  44. scspill-0.1.0/scspill/validation/kernels.py +440 -0
  45. scspill-0.1.0/scspill/validation/plotter.py +102 -0
  46. scspill-0.1.0/scspill/validation/robustness.py +467 -0
  47. scspill-0.1.0/scspill/validation/structures.py +108 -0
  48. scspill-0.1.0/scspill.egg-info/PKG-INFO +151 -0
  49. scspill-0.1.0/scspill.egg-info/SOURCES.txt +51 -0
  50. scspill-0.1.0/scspill.egg-info/dependency_links.txt +1 -0
  51. scspill-0.1.0/scspill.egg-info/requires.txt +12 -0
  52. scspill-0.1.0/scspill.egg-info/top_level.txt +1 -0
  53. scspill-0.1.0/setup.cfg +4 -0
scspill-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Carlos Mendez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
scspill-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.4
2
+ Name: scspill
3
+ Version: 0.1.0
4
+ Summary: Bayesian spatial-spillover synthetic control (Sakaguchi & Tagawa) for causal inference on panel data.
5
+ Author-email: Carlos Mendez <carlosmendez777@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/quarcs-lab/scspill
8
+ Project-URL: Documentation, https://quarcs-lab.github.io/scspill/
9
+ Project-URL: Repository, https://github.com/quarcs-lab/scspill
10
+ Project-URL: Issues, https://github.com/quarcs-lab/scspill/issues
11
+ Keywords: synthetic control,spillover effects,spatial econometrics,bayesian inference,causal inference,panel data,MCMC
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: pandas>=2.0
25
+ Requires-Dist: numpy>=1.26
26
+ Requires-Dist: scipy>=1.11
27
+ Requires-Dist: matplotlib>=3.8
28
+ Requires-Dist: pydantic>=2.0
29
+ Requires-Dist: threadpoolctl>=3.6.0
30
+ Provides-Extra: numba
31
+ Requires-Dist: numba>=0.60; extra == "numba"
32
+ Provides-Extra: all
33
+ Requires-Dist: scspill[numba]; extra == "all"
34
+ Dynamic: license-file
35
+
36
+ <p align="center">
37
+ <img src="https://raw.githubusercontent.com/quarcs-lab/scspill/main/docs/images/hero-v2.png" alt="scspill — Bayesian synthetic control with spillovers" width="85%">
38
+ </p>
39
+
40
+ # scspill
41
+
42
+ [![CI](https://github.com/quarcs-lab/scspill/actions/workflows/ci.yml/badge.svg)](https://github.com/quarcs-lab/scspill/actions/workflows/ci.yml)
43
+ [![Docs](https://img.shields.io/badge/docs-quarcs--lab.github.io%2Fscspill-blue)](https://quarcs-lab.github.io/scspill/)
44
+ [![PyPI](https://img.shields.io/pypi/v/scspill.svg)](https://pypi.org/project/scspill/)
45
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/scspill/)
46
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
47
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
48
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/quarcs-lab/scspill/blob/main/notebooks/california.ipynb)
49
+
50
+ Synthetic control when the treatment leaks. **scspill** is a Python
51
+ implementation of the Bayesian spatial-spillover synthetic control of
52
+ Sakaguchi & Tagawa (*Identification and Bayesian Inference for Synthetic
53
+ Control Methods with Spillover Effects*, The Econometrics Journal): it
54
+ relaxes SUTVA by letting the treatment spill over to the donor pool through
55
+ a spatial-autoregressive channel with user-supplied weights, and estimates
56
+ both the treatment effect on the treated unit and the spillover effect
57
+ received by every donor — with full Bayesian uncertainty.
58
+
59
+ The estimator follows the
60
+ [mlsynth](https://github.com/jgreathouse9/mlsynth) architecture (a pydantic
61
+ config in, a standardized results object out) so the two libraries compose
62
+ naturally; the documentation site follows
63
+ [geometrics](https://github.com/quarcs-lab/geometrics).
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install scspill # NumPy/SciPy sampler backend
69
+ pip install "scspill[numba]" # + JIT-compiled samplers (~10x faster)
70
+ pip install "scspill @ git+https://github.com/quarcs-lab/scspill.git" # latest
71
+ ```
72
+
73
+ Python 3.10+.
74
+
75
+ ## At a glance
76
+
77
+ ```python
78
+ from scspill import SCSPILL
79
+ from scspill.data import load_california
80
+
81
+ panel = load_california() # Prop 99 panel + rook-contiguity weights
82
+ result = SCSPILL(
83
+ {**panel.config_kwargs(), "m_iter": 20_000, "burn": 10_000, "seed": 42}
84
+ ).fit()
85
+
86
+ result.att, result.att_ci # treatment effect on California + 95% CrI
87
+ result.rho_hat, result.rho_ci # spillover intensity posterior
88
+ result.spillover_panel["Nevada"] # the effect received by Nevada, per year
89
+ result.diagnostics() # ESS / R-hat / MCSE per chain
90
+ result.plot(kind="panel") # counterfactual | effect | top spillovers
91
+ ```
92
+
93
+ ## What's inside
94
+
95
+ | Subpackage | What it does | Docs |
96
+ |---|---|---|
97
+ | `scspill` | `SCSPILL(config).fit()` — the two-step Bayesian sampler (horseshoe synthetic weights, SAR spillover block, adaptive Metropolis for the spillover intensity) and the identification formulas | [Get started](https://quarcs-lab.github.io/scspill/get-started.html) |
98
+ | `scspill.validation` | The Geweke (2004) joint distribution test of the sampler, prior-sensitivity grids, prior predictive checks | [Validation](https://quarcs-lab.github.io/scspill/articles/validation.html) |
99
+ | `scspill.simulate` | The paper's Monte Carlo engine: rook-lattice SAR DGP, SCM/BSCM/SCSPILL comparison, the Tables 1–2 grid | [Simulation study](https://quarcs-lab.github.io/scspill/articles/simulation-study.html) |
100
+ | `scspill.data` | The bundled California Prop 99 and Sudan secession case studies | [Datasets](https://quarcs-lab.github.io/scspill/articles/datasets.html) |
101
+
102
+ ## Validated against the R replication package
103
+
104
+ The Python port is cross-validated against the authors' R replication
105
+ package (`python benchmarks/run_benchmarks.py --all --report`): California
106
+ and Sudan posteriors against the frozen R credible intervals, the Monte
107
+ Carlo grid against the paper's frozen Tables 1–2, prior predictive
108
+ statistics to three decimals, and the samplers against the Geweke joint
109
+ distribution test. The defaults are *paper-correct*: several documented bugs
110
+ of the reference implementation (a covariate memory-layout mismatch, a
111
+ missing horseshoe prior, alpha-frozen credible intervals, two incoherent
112
+ factor-block conditionals) are fixed here, each with an escape hatch or a
113
+ benchmark quantifying the difference — see the
114
+ [method article](https://quarcs-lab.github.io/scspill/articles/method.html).
115
+
116
+ ## Documentation
117
+
118
+ Full documentation, executed tutorials, and the API reference live at
119
+ **<https://quarcs-lab.github.io/scspill/>**. Machine-readable entry points
120
+ for AI agents: [`llms.txt`](https://quarcs-lab.github.io/scspill/llms.txt)
121
+ and [`llms-full.txt`](https://quarcs-lab.github.io/scspill/llms-full.txt).
122
+
123
+ ## Development
124
+
125
+ ```bash
126
+ git clone https://github.com/quarcs-lab/scspill && cd scspill
127
+ uv sync --all-extras --group dev --group docs
128
+ make test # pytest (fast tier; `make test-slow` for the long tier)
129
+ make lint # ruff check + format
130
+ make typecheck # mypy
131
+ make docs # quartodoc build -> quarto render -> llms.txt
132
+ ```
133
+
134
+ ## Citing
135
+
136
+ If you use scspill, please cite the methodological article and the software
137
+ (see `CITATION.cff`):
138
+
139
+ > Sakaguchi, S., & Tagawa, H. Identification and Bayesian Inference for
140
+ > Synthetic Control Methods with Spillover Effects. *The Econometrics
141
+ > Journal*.
142
+
143
+ ## Acknowledgments
144
+
145
+ The method and reference implementation are by Shosei Sakaguchi and Hayato
146
+ Tagawa. The estimator architecture follows Jared Greathouse's mlsynth; the
147
+ documentation stack follows the QuaRCS-lab geometrics package.
148
+
149
+ ## License
150
+
151
+ MIT
@@ -0,0 +1,116 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/quarcs-lab/scspill/main/docs/images/hero-v2.png" alt="scspill — Bayesian synthetic control with spillovers" width="85%">
3
+ </p>
4
+
5
+ # scspill
6
+
7
+ [![CI](https://github.com/quarcs-lab/scspill/actions/workflows/ci.yml/badge.svg)](https://github.com/quarcs-lab/scspill/actions/workflows/ci.yml)
8
+ [![Docs](https://img.shields.io/badge/docs-quarcs--lab.github.io%2Fscspill-blue)](https://quarcs-lab.github.io/scspill/)
9
+ [![PyPI](https://img.shields.io/pypi/v/scspill.svg)](https://pypi.org/project/scspill/)
10
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/scspill/)
11
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
12
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
13
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/quarcs-lab/scspill/blob/main/notebooks/california.ipynb)
14
+
15
+ Synthetic control when the treatment leaks. **scspill** is a Python
16
+ implementation of the Bayesian spatial-spillover synthetic control of
17
+ Sakaguchi & Tagawa (*Identification and Bayesian Inference for Synthetic
18
+ Control Methods with Spillover Effects*, The Econometrics Journal): it
19
+ relaxes SUTVA by letting the treatment spill over to the donor pool through
20
+ a spatial-autoregressive channel with user-supplied weights, and estimates
21
+ both the treatment effect on the treated unit and the spillover effect
22
+ received by every donor — with full Bayesian uncertainty.
23
+
24
+ The estimator follows the
25
+ [mlsynth](https://github.com/jgreathouse9/mlsynth) architecture (a pydantic
26
+ config in, a standardized results object out) so the two libraries compose
27
+ naturally; the documentation site follows
28
+ [geometrics](https://github.com/quarcs-lab/geometrics).
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install scspill # NumPy/SciPy sampler backend
34
+ pip install "scspill[numba]" # + JIT-compiled samplers (~10x faster)
35
+ pip install "scspill @ git+https://github.com/quarcs-lab/scspill.git" # latest
36
+ ```
37
+
38
+ Python 3.10+.
39
+
40
+ ## At a glance
41
+
42
+ ```python
43
+ from scspill import SCSPILL
44
+ from scspill.data import load_california
45
+
46
+ panel = load_california() # Prop 99 panel + rook-contiguity weights
47
+ result = SCSPILL(
48
+ {**panel.config_kwargs(), "m_iter": 20_000, "burn": 10_000, "seed": 42}
49
+ ).fit()
50
+
51
+ result.att, result.att_ci # treatment effect on California + 95% CrI
52
+ result.rho_hat, result.rho_ci # spillover intensity posterior
53
+ result.spillover_panel["Nevada"] # the effect received by Nevada, per year
54
+ result.diagnostics() # ESS / R-hat / MCSE per chain
55
+ result.plot(kind="panel") # counterfactual | effect | top spillovers
56
+ ```
57
+
58
+ ## What's inside
59
+
60
+ | Subpackage | What it does | Docs |
61
+ |---|---|---|
62
+ | `scspill` | `SCSPILL(config).fit()` — the two-step Bayesian sampler (horseshoe synthetic weights, SAR spillover block, adaptive Metropolis for the spillover intensity) and the identification formulas | [Get started](https://quarcs-lab.github.io/scspill/get-started.html) |
63
+ | `scspill.validation` | The Geweke (2004) joint distribution test of the sampler, prior-sensitivity grids, prior predictive checks | [Validation](https://quarcs-lab.github.io/scspill/articles/validation.html) |
64
+ | `scspill.simulate` | The paper's Monte Carlo engine: rook-lattice SAR DGP, SCM/BSCM/SCSPILL comparison, the Tables 1–2 grid | [Simulation study](https://quarcs-lab.github.io/scspill/articles/simulation-study.html) |
65
+ | `scspill.data` | The bundled California Prop 99 and Sudan secession case studies | [Datasets](https://quarcs-lab.github.io/scspill/articles/datasets.html) |
66
+
67
+ ## Validated against the R replication package
68
+
69
+ The Python port is cross-validated against the authors' R replication
70
+ package (`python benchmarks/run_benchmarks.py --all --report`): California
71
+ and Sudan posteriors against the frozen R credible intervals, the Monte
72
+ Carlo grid against the paper's frozen Tables 1–2, prior predictive
73
+ statistics to three decimals, and the samplers against the Geweke joint
74
+ distribution test. The defaults are *paper-correct*: several documented bugs
75
+ of the reference implementation (a covariate memory-layout mismatch, a
76
+ missing horseshoe prior, alpha-frozen credible intervals, two incoherent
77
+ factor-block conditionals) are fixed here, each with an escape hatch or a
78
+ benchmark quantifying the difference — see the
79
+ [method article](https://quarcs-lab.github.io/scspill/articles/method.html).
80
+
81
+ ## Documentation
82
+
83
+ Full documentation, executed tutorials, and the API reference live at
84
+ **<https://quarcs-lab.github.io/scspill/>**. Machine-readable entry points
85
+ for AI agents: [`llms.txt`](https://quarcs-lab.github.io/scspill/llms.txt)
86
+ and [`llms-full.txt`](https://quarcs-lab.github.io/scspill/llms-full.txt).
87
+
88
+ ## Development
89
+
90
+ ```bash
91
+ git clone https://github.com/quarcs-lab/scspill && cd scspill
92
+ uv sync --all-extras --group dev --group docs
93
+ make test # pytest (fast tier; `make test-slow` for the long tier)
94
+ make lint # ruff check + format
95
+ make typecheck # mypy
96
+ make docs # quartodoc build -> quarto render -> llms.txt
97
+ ```
98
+
99
+ ## Citing
100
+
101
+ If you use scspill, please cite the methodological article and the software
102
+ (see `CITATION.cff`):
103
+
104
+ > Sakaguchi, S., & Tagawa, H. Identification and Bayesian Inference for
105
+ > Synthetic Control Methods with Spillover Effects. *The Econometrics
106
+ > Journal*.
107
+
108
+ ## Acknowledgments
109
+
110
+ The method and reference implementation are by Shosei Sakaguchi and Hayato
111
+ Tagawa. The estimator architecture follows Jared Greathouse's mlsynth; the
112
+ documentation stack follows the QuaRCS-lab geometrics package.
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,136 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "scspill"
7
+ version = "0.1.0"
8
+ description = "Bayesian spatial-spillover synthetic control (Sakaguchi & Tagawa) for causal inference on panel data."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Carlos Mendez", email = "carlosmendez777@gmail.com" }]
14
+ keywords = [
15
+ "synthetic control",
16
+ "spillover effects",
17
+ "spatial econometrics",
18
+ "bayesian inference",
19
+ "causal inference",
20
+ "panel data",
21
+ "MCMC",
22
+ ]
23
+ classifiers = [
24
+ "Development Status :: 3 - Alpha",
25
+ "Intended Audience :: Science/Research",
26
+ "Programming Language :: Python :: 3",
27
+ "Programming Language :: Python :: 3.10",
28
+ "Programming Language :: Python :: 3.11",
29
+ "Programming Language :: Python :: 3.12",
30
+ "Programming Language :: Python :: 3.13",
31
+ "Topic :: Scientific/Engineering",
32
+ "Topic :: Scientific/Engineering :: Mathematics",
33
+ ]
34
+ dependencies = [
35
+ "pandas>=2.0",
36
+ "numpy>=1.26",
37
+ "scipy>=1.11",
38
+ "matplotlib>=3.8",
39
+ "pydantic>=2.0",
40
+ "threadpoolctl>=3.6.0",
41
+ ]
42
+
43
+ [project.optional-dependencies]
44
+ # JIT-accelerated Gibbs/SAR kernels. Optional because numba wheels can lag new
45
+ # Python releases; the pure-NumPy path is always available.
46
+ numba = ["numba>=0.60"]
47
+ all = ["scspill[numba]"]
48
+
49
+ [project.urls]
50
+ Homepage = "https://github.com/quarcs-lab/scspill"
51
+ Documentation = "https://quarcs-lab.github.io/scspill/"
52
+ Repository = "https://github.com/quarcs-lab/scspill"
53
+ Issues = "https://github.com/quarcs-lab/scspill/issues"
54
+
55
+ [dependency-groups]
56
+ dev = [
57
+ "pytest>=8",
58
+ "pytest-cov>=5",
59
+ "pytest-xdist>=3",
60
+ "ruff>=0.6",
61
+ "mypy>=1.10",
62
+ "pandas-stubs",
63
+ ]
64
+ docs = [
65
+ "quartodoc>=0.11",
66
+ "griffe<1",
67
+ "jupyter",
68
+ "nbformat>=5.9",
69
+ ]
70
+
71
+ # ---------------------------------------------------------------------------
72
+ # Packaging: flat layout, in-package tests excluded from the wheel (mlsynth
73
+ # convention), bundled case-study CSVs shipped as package data.
74
+ # ---------------------------------------------------------------------------
75
+ [tool.setuptools.packages.find]
76
+ include = ["scspill*"]
77
+ exclude = ["scspill.tests*"]
78
+
79
+ [tool.setuptools.package-data]
80
+ scspill = ["py.typed"]
81
+ "scspill.data" = ["files/*.csv"]
82
+
83
+ # ---------------------------------------------------------------------------
84
+ # Tooling
85
+ # ---------------------------------------------------------------------------
86
+ [tool.ruff]
87
+ line-length = 100
88
+ target-version = "py310"
89
+ src = ["scspill"]
90
+
91
+ [tool.ruff.lint]
92
+ select = ["E", "F", "W", "I", "UP", "B", "SIM", "D", "RUF"]
93
+ ignore = [
94
+ "D100", "D104", "D105", "D107", # module/package/magic/__init__ docstrings
95
+ "D106", # pydantic `class Config` blocks need no docstring
96
+ "E501", # line length handled by the formatter
97
+ ]
98
+ # Greek symbols appear in scientific prose and labels: alpha donor weights,
99
+ # rho spillover intensity, tau treatment effect, sigma error scale.
100
+ allowed-confusables = ["α", "ρ", "τ", "σ", "β", "γ", "η", "ξ", "ω", "φ", "ψ", "λ", "−"]
101
+
102
+ [tool.ruff.lint.pydocstyle]
103
+ convention = "numpy"
104
+
105
+ [tool.ruff.lint.per-file-ignores]
106
+ "scspill/tests/*" = ["D"]
107
+ "docs/*" = ["D"]
108
+ "tools/*" = ["D"]
109
+ "benchmarks/*" = ["D"]
110
+ # json_encoders in the pydantic Config blocks (mlsynth-inherited surface).
111
+ "scspill/config_models.py" = ["RUF012"]
112
+
113
+ [tool.mypy]
114
+ python_version = "3.12"
115
+ warn_unused_configs = true
116
+ ignore_missing_imports = true
117
+ files = ["scspill"]
118
+ exclude = ["scspill/tests"]
119
+
120
+ [tool.pytest.ini_options]
121
+ minversion = "8.0"
122
+ addopts = "--strict-markers --strict-config"
123
+ testpaths = ["scspill/tests"]
124
+ markers = [
125
+ "slow: long-running tests (full-length MCMC chains, large Monte-Carlo designs)",
126
+ ]
127
+ filterwarnings = ["ignore::DeprecationWarning"]
128
+
129
+ [tool.coverage.run]
130
+ source = ["scspill"]
131
+ branch = true
132
+ omit = ["scspill/tests/*"]
133
+
134
+ [tool.coverage.report]
135
+ show_missing = true
136
+ exclude_lines = ["pragma: no cover", "raise NotImplementedError", "if TYPE_CHECKING:"]
@@ -0,0 +1,82 @@
1
+ """scspill: Bayesian spatial-spillover synthetic control.
2
+
3
+ Implements:
4
+
5
+ Sakaguchi, S., & Tagawa, H. "Identification and Bayesian Inference for
6
+ Synthetic Control Methods with Spillover Effects." The Econometrics
7
+ Journal.
8
+
9
+ A synthetic control method that relaxes SUTVA: spillovers from the treated
10
+ unit to the donor pool are modeled through a spatial-autoregressive (SAR)
11
+ structure with user-supplied spatial weights, and both the treatment effect on
12
+ the treated and the spillover effect received by every control unit are
13
+ identified from the synthetic-control weights ``alpha``, the spillover
14
+ intensity ``rho``, and the weights ``(w, W)``. Estimation is a two-step
15
+ Bayesian sampler: a horseshoe Gibbs sampler for ``alpha`` on the
16
+ pre-treatment fit, then a SAR block (latent AR(1) factors, covariates, and a
17
+ random-walk Metropolis step for ``rho``) conditional on the posterior mean of
18
+ ``alpha``.
19
+
20
+ Public API::
21
+
22
+ from scspill import SCSPILL, SCSPILLConfig
23
+
24
+ result = SCSPILL(config).fit() # -> SCSPILLResults
25
+
26
+ plus the companion subpackages :mod:`scspill.validation` (Geweke joint
27
+ distribution test, prior sensitivity, prior predictive checks),
28
+ :mod:`scspill.simulate` (the paper's Monte Carlo engine), and
29
+ :mod:`scspill.data` (the bundled California Proposition 99 and Sudan
30
+ secession case studies).
31
+ """
32
+
33
+ from importlib.metadata import PackageNotFoundError, version
34
+
35
+ try: # pragma: no cover - fallback exercised only in odd install states
36
+ __version__ = version("scspill")
37
+ except PackageNotFoundError: # pragma: no cover
38
+ __version__ = "0.0.0.dev0"
39
+
40
+ from scspill.exceptions import (
41
+ ScspillConfigError,
42
+ ScspillDataError,
43
+ ScspillError,
44
+ ScspillEstimationError,
45
+ ScspillPlottingError,
46
+ )
47
+
48
+ __all__ = [
49
+ "SCSPILL",
50
+ "SCSPILLConfig",
51
+ "SCSPILLResults",
52
+ "ScspillConfigError",
53
+ "ScspillDataError",
54
+ "ScspillError",
55
+ "ScspillEstimationError",
56
+ "ScspillPlottingError",
57
+ "__version__",
58
+ ]
59
+
60
+ # Lazy exports (PEP 562): the estimator stack imports pandas/pydantic/scipy,
61
+ # so defer those imports until first attribute access for fast cold starts.
62
+ _LAZY_EXPORTS = {
63
+ "SCSPILL": ("scspill.estimators.scspill", "SCSPILL"),
64
+ "SCSPILLConfig": ("scspill.utils.scspill_helpers.config", "SCSPILLConfig"),
65
+ "SCSPILLResults": ("scspill.utils.scspill_helpers.structures", "SCSPILLResults"),
66
+ }
67
+
68
+
69
+ def __getattr__(name: str):
70
+ """Resolve lazily exported public names (PEP 562)."""
71
+ target = _LAZY_EXPORTS.get(name)
72
+ if target is not None:
73
+ import importlib
74
+
75
+ module_path, attr = target
76
+ return getattr(importlib.import_module(module_path), attr)
77
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
78
+
79
+
80
+ def __dir__():
81
+ """Include lazy exports in ``dir(scspill)``."""
82
+ return sorted(set(globals()) | set(_LAZY_EXPORTS))