How-To Guides
Task-oriented guides for running GeoSC workflows from the installed CLI or Python.
Task-oriented guides for running GeoSC workflows from the installed CLI or Python.
Selecting the right control (donor) pool is critical for Synthetic Control methods. This guide shows how to evaluate potential donors.
Packaged-install example:
Source-checkout example with the shipped demo config:
Built wheel and sdist installs do not include data-config/, so packaged users
should provide their own YAML path.
donor_eval_results.csv: Ranks potential donor regions based on correlation, RMSE, MAPE, and DTW (Dynamic Time Warping) against the treatment unit(s) during the pre-treatment period. Includes quality band, warning flags, per-treatment rank, and normalized recommendation weight.donor_pool_quality.json: Summarizes recommended donor-pool quality and concentration.donor_map_*.png: Visualizations mapping the geographical distribution and quality of the donors (if shapefiles are configured).selected_weight is a design-stage recommendation weight, not the final
SparseSC donor weight used during treatment-effect estimation.
For geography setup, including UK postcode area and postcode district examples, see How to Use Shapemaps.
This guide explains how to use GeoSC to evaluate test strength before running an experiment.
Use the power command to simulate experiments with known treatment effects and calculate the statistical power:
Packaged-install example:
Source-checkout example with the shipped demo config:
--config: Path to the YAML configuration file.--use-gpu: (Optional) Accelerates computation using compatible GPUs.--jobs -1: Uses all available CPU cores for parallel processing.Built wheel and sdist installs do not include data-config/, so packaged users
should provide their own YAML path.
power_analysis_results.csv: Detailed grid of simulated lifts, sample sizes, power, Monte Carlo uncertainty, simulation failures, seed, DGP rank, feasible placebo support, and SparseSC/backend parameters.power_curves.png: Visualization of the power curve across different minimal detectable effects (MDE).Rows with valid: false exceeded the configured simulation failure tolerance or
had no successful simulations. Do not use those rows for feasibility decisions.
Seeded runs use CPU generation for reproducible simulation draws, so the shipped
demo config sets use_gpu: false.
The factor-model power DGP is estimated from pre-treatment outcomes with SVD. GeoSC then estimates VAR(1) dynamics on the extracted factor series and uses those temporal parameters when simulating post-treatment periods. This preserves shared cross-sectional movement through the factor loadings and lag-1 temporal dependence through the VAR(1) transition and innovation covariance.
Covariance matrices are symmetrized and regularized with a small diagonal floor
when needed. If VAR(1) dynamics or factor draws cannot be estimated safely,
power analysis fails with an actionable error instead of silently switching to a
diagonal-covariance DGP. Legacy direct calls to the generator without VAR(1)
metadata still use independent factor draws from the supplied F_mean and
F_cov.
Current VAR(1) post-period generation runs on CPU so seeded and unseeded power simulations preserve the same temporal contract. GPU acceleration may still be used for eligible DGP estimation, but generated post-period panels from the VAR(1) DGP are produced by NumPy.
The power calculator fails fast at construction with a ValueError if the
design has no treatment units, or if there are fewer control units than
treatment units. In that case placebo inference is infeasible and no power
analysis is run.
plot_power_curves filters rows where valid is false out of the decision
plots (logging the number of excluded rows), and skips plot creation entirely
if no valid rows remain. Inspect power_analysis_results.csv directly to see
why rows were marked invalid (high failure_rate, zero n_successful, etc.).
When random_seed is set, repeated runs of the same config produce identical
power_analysis_results.csv content (excluding timestamp/path metadata), in
both sequential and parallel modes. This is covered by both unit and CLI
integration tests.
This guide explains how to measure lift (the actual causal effect) post-experiment using SparseSC.
Packaged-install example:
Source-checkout example with the shipped demo config:
--data: (Optional) Override the CSV path specified in the YAML.--create-plots / --no-create-plots: Toggle generation of visualization artifacts.Built wheel and sdist installs do not include data-config/, so packaged users
should provide their own YAML path.
geolift_results.json: Top-level statistical results including status, ATT, p-value, and confidence interval metadata.geolift_diagnostics.json: Schema-shaped diagnostic metrics for the synthetic control fit. Raw synthetic-control frames and raw weight matrices are not persisted.data_validation.json: Input contract report covering duplicate rows, raw outcome value checks, input/model panel missingness, finite-value checks, and any explicit handling policy.assumption_validation.json: Gate-eligible parallel-trends diagnostic and
advisory interference-screen report, or a skipped-status artifact when
checks are disabled.uplift_timeseries.png: Visual comparison of the treatment unit vs. the synthetic control over time.Check status before interpreting lift. A partial result means the estimator
returned some core quantities but uncertainty fields are incomplete. A failed
result causes the CLI to exit non-zero.
Also check assumption_status: skipped means interpretability checks were not
run; fail or error means the causal interpretation needs review even if the
effect estimate exists.
This guide explains how to orchestrate the full GeoSC workflow using the
installed geosc pipeline command.
Packaged-install example:
Source-checkout example with the shipped demo configs:
--config must point to one canonical stage YAML filepipeline_config.yamldata-config/; packaged users
should supply their own YAML path insteadYou can run partial pipelines by skipping specific stages:
--skip-power: Skips the power analysis stage--skip-donor: Skips the donor evaluation stage--only-inference: Runs only the final inference stageControl report generation with:
--report (enabled by default)--no-reportSpecify where results should be saved:
This will generate the following structure:
results/campaign_a/multicell_power_analysis/results/campaign_a/multicell_donor_eval/results/campaign_a/multicell_geolift_analysis/results/campaign_a/geolift_pipeline_report.mdresults/campaign_a/geolift_pipeline_report.htmlFor a source-tree walkthrough using the shipped demo configs, start with Quick Start.
GeoSC donor maps use shapemap_file to read a GeoPandas-compatible vector
file and shapemap_id_column to choose the geography ID used for joins. The
values in that ID column must match the unit IDs used in your experiment data,
such as DMA IDs, postcode districts, postcode areas, or another market key.
Built wheel and sdist installs do not include the repository-local shapemap/
directory. Packaged users should provide map files from their own runtime
environment.
GeoSC can read formats supported by GeoPandas, including GeoJSON, TopoJSON, Shapefile, and GeoPackage inputs when the local geospatial stack supports them.
Repository-local shapemap examples are available for common markets:
shapemap/uk/postcode_areas_approx_2026.geojsonshapemap/uk/postcode_districts_approx_2026.geojsonshapemap/us/dma_legacy_normalized.geojsonshapemap/fr/nuts3_2024.geojsonshapemap/de/nuts3_2024.geojsonshapemap/<uk|us|fr|de>/meta_commuting_zones.geojsonThese are source-checkout assets. They are not included in built wheel or sdist artifacts.
Meta Commuting Zones are also available as optional geographies for Meta-aligned study design. They are commuting/economic zones, not Meta ad-targeting boundaries.
For UK production workflows, postcode district is often the practical market geography:
The input data must use the same IDs as the shapemap:
Use scripts/prepare_uk_postcode_shapemap.py from a source checkout to
normalize licensed or user-supplied postcode polygon data:
The generated file exposes:
id: postcode district, such as SW1A, M1, or BT7name: display name, defaulting to the same value as idcountry: UKgeography_level: postcode_districtgeometry: dissolved polygon geometryThe repository includes an approximate version built from ONSPD live postcode centroids:
Validate the generated file before using it in donor evaluation:
For broader UK markets, use postcode areas:
Prepare the map with:
Do not commit or distribute postcode geometry unless the source license permits
that use. The repository records shapemap provenance policy in
shapemap/README.md and shapemap/manifest.yaml.
For UK data:
If donor maps do not highlight treatment or donor units:
shapemap_id_columngeopandas.read_filescripts/validate_shapemap.py reports missing expected IDs, duplicate IDs,
blank IDs, null or empty geometry, invalid geometry, row counts, unique ID
counts, and the detected CRS.
While the CLI is the preferred operational path, the Python API supports programmatic control and direct-data initialization without CSV/YAML files.
Packaged-install example:
Source-checkout example with the shipped demo configs: