Subsections of Reference

API Reference

Technical reference for the shipped GeoSC interfaces.

Interface Hierarchy

Primary operational interface:

  • installed geosc CLI and compatibility geolift CLI

Programmatic interface:

  • GeoLiftAnalyzer
  • load_config
  • load_and_prepare_data
  • process_sparse_sc_results

Compatibility interfaces:

  • runme.py
  • recipes/

For the exact CLI command surface, see CLI Reference.

Installed CLI

Installed commands:

  • geosc power
  • geosc donors
  • geosc infer
  • geosc pipeline

Shared flags on all commands:

  • --config
  • --output-dir
  • --jobs
  • --use-gpu
  • --no-progress
  • --quiet

Infer-only flags:

  • --data
  • --create-plots
  • --no-create-plots

Pipeline-only flags:

  • --skip-power
  • --skip-donor
  • --only-inference
  • --report
  • --no-report

Pipeline config contract:

  • pipeline --config accepts one canonical stage YAML path
  • GeoSC resolves sibling canonical YAMLs from the same directory
  • there is no separate pipeline config schema

Core Classes

GeoLiftAnalyzer

Main orchestration class for causal inference analysis using SparseSC-backed estimation.

Initialization modes:

  1. File-based: config_path plus data_path
  2. Direct data: prepared outcomes_df plus unit_treatment_periods

File-based example with user-owned config and data paths:

from geolift import GeoLiftAnalyzer

analyzer = GeoLiftAnalyzer(
    config_path="/path/to/geolift_analysis_config.yaml",
    data_path="/path/to/input.csv",
)

Source-checkout example:

from geolift import GeoLiftAnalyzer

analyzer = GeoLiftAnalyzer(
    config_path="data-config/geolift_analysis_config.yaml",
    data_path="data-config/synthetic_geolift_multi.csv",
)

Direct-data example:

import pandas as pd
from geolift import GeoLiftAnalyzer

outcomes_df = pd.DataFrame(...)
unit_treatment_periods = pd.Series(...)

analyzer = GeoLiftAnalyzer(
    outcomes_df=outcomes_df,
    unit_treatment_periods=unit_treatment_periods,
    intervention_date="2023-06-01",
    config={
        "estimator": "sparsesc",
        "sparse_sc_model_type": "retrospective",
        "sparse_sc_max_n_pl": 1000,
        "sparse_sc_placebo_seed": 110011,
        "sparse_sc_level": 0.95,
    },
)

run_geolift_analysis()

Executes the full inference workflow and returns the compact top-level results dictionary.

Returned fields include:

  • schema_version
  • status
  • att
  • p_value
  • p_value_method
  • n_placebos
  • max_n_placebos
  • possible_placebos
  • p_value_placebo_mode
  • placebo_seed
  • ci_lower
  • ci_upper
  • ci
  • se
  • se_available
  • se_approx_from_ci
  • se_approx_available
  • se_approximation_method
  • significant
  • significance_available
  • assumption_status
  • assumption_required
  • assumption_checks_run
  • assumption_checks_completed

Detailed diagnostics remain on analyzer.diagnostics. Assumption validation is available on analyzer.assumption_validation and, when output_dir is set, in assumption_validation.json.

analyzer.diagnostics["inference"] records the estimator method, placebo mode, seed, requested placebo count, possible combinations, and effective placebo count. The seed is material only when the placebo mode is sampled.

For the 0.3.0 beta, these public wrapper semantics are release-certified by the statistical certification gate in scripts/verify_release_candidate.py. That gate covers SparseSC parity, deterministic effect recovery, timing/orientation, artifact parity, uncertainty and placebo metadata, donor design-stage semantics, power failure accounting, assumption-validator status metadata, and release-preflight schema regressions. It does not certify that a specific campaign satisfies causal-design assumptions.

run_analysis()

Primary convenience entry point that delegates to run_geolift_analysis(). Either method is valid on the shipped class.

plot_results(output_path: str | None = None) -> str

Generates and saves the uplift time-series plot. When output_path is omitted, the plot is written to <output_dir>/uplift_timeseries.png.

Utility Functions

load_and_prepare_data(...)

from geolift.data_handler import load_and_prepare_data

File-based data preparation helper used by the analyser path.

load_config(path)

from geolift.config_manager import load_config

Loads one YAML config file.

process_sparse_sc_results(sparse_sc_results, config)

from geolift.results_processor import process_sparse_sc_results

Transforms SparseSC outputs into the compact top-level results plus the richer diagnostics payload.

Output Artifacts

Inference outputs:

  • geolift_results.json
  • geolift_diagnostics.json
  • data_validation.json
  • assumption_validation.json
  • uplift_timeseries.png when plot generation is enabled

Power outputs:

  • power_analysis_results.csv
  • power_curves.png

Power CSV rows include reproducibility and failure fields such as random_seed, n_failed, failure_rate, valid, dgp_rank, and requested_max_n_pl, possible_placebos, effective_max_n_pl, dgp_backend, and generation_backend.

Donor outputs:

  • donor_eval_results.csv
  • donor_pool_quality.json
  • donor_map_*.png

Pipeline reports:

  • geolift_pipeline_report.md
  • geolift_pipeline_report.html

Compatibility Surfaces

runme.py and the scripts in recipes/ remain available for compatibility. They are not the primary documented interface.

Migration map:

  • source-checkout: python runme.py -> geosc pipeline --config data-config/geolift_analysis_config.yaml
  • source-checkout: python recipes/power_calculator_sparsesc.py ... -> geosc power ...
  • source-checkout: python recipes/donor_evaluator.py ... -> geosc donors ...
  • source-checkout: python recipes/geolift_multi_cell.py ... -> geosc infer ...

CLI Reference

Canonical reference for the installed geosc command surface. The legacy geolift command remains available as a compatibility alias during the beta.

Examples below use source-tree config paths such as data-config/... when that helps illustrate the shipped demo workflow. Built wheel and sdist installs do not include data-config/; packaged users should supply their own YAML config paths.

Top-Level Command

geosc --help

Installed subcommands:

  • geosc power
  • geosc donors
  • geosc infer
  • geosc pipeline

Shared Flags

All commands accept:

  • --config CONFIG
  • --output-dir OUTPUT_DIR
  • --jobs JOBS
  • --use-gpu
  • --no-progress
  • --quiet

Semantics:

  • --config points to the YAML configuration file for the command
  • --output-dir overrides the configured output directory for stage commands
  • --jobs overrides n_jobs
  • --use-gpu is meaningful for power analysis
  • --no-progress disables progress output
  • --quiet reduces non-critical output without hiding errors

geosc power

Source-checkout example:

geosc power --config data-config/power_analysis_config.yaml --use-gpu --jobs -1

Purpose:

  • run GeoSC power-analysis workflows through the installed CLI

Typical outputs:

  • power_analysis_results.csv
  • power_curves.png

power_analysis_results.csv includes failure_rate and valid; invalid rows should not be used for recommendations.

geosc donors

Source-checkout example:

geosc donors --config data-config/donor_eval_config.yaml --jobs -1

Purpose:

  • run donor-evaluation workflows through the installed CLI

Typical outputs:

  • donor_eval_results.csv
  • donor_pool_quality.json
  • donor_map_*.png

geosc infer

Packaged-install example:

geosc infer --config /path/to/geolift_analysis_config.yaml --create-plots

Source-checkout example:

geosc infer --config data-config/geolift_analysis_config.yaml --create-plots

Infer-only flags:

  • --data DATA
  • --create-plots
  • --no-create-plots

Semantics:

  • --data overrides the CSV path defined in YAML
  • --create-plots forces plot generation
  • --no-create-plots disables plot generation

Typical outputs:

  • geolift_results.json
  • geolift_diagnostics.json
  • uplift_timeseries.png when plots are enabled

geosc pipeline

Packaged-install example:

geosc pipeline --config /path/to/geolift_analysis_config.yaml

Source-checkout example:

geosc pipeline --config data-config/geolift_analysis_config.yaml

Pipeline-only flags:

  • --skip-power
  • --skip-donor
  • --only-inference
  • --report
  • --no-report

Pipeline config contract:

  • --config is an anchor to one canonical stage YAML file
  • in a source checkout, GeoSC resolves sibling canonical YAMLs from the same directory:
    • power_analysis_config.yaml
    • donor_eval_config.yaml
    • geolift_analysis_config.yaml
  • there is no pipeline --stage
  • there is no separate pipeline config schema

Stage-selection semantics:

  • --skip-power skips power analysis
  • --skip-donor skips donor evaluation
  • --only-inference skips both earlier stages

Report semantics:

  • reports are generated by default
  • --report forces report generation explicitly
  • --no-report suppresses report generation

Output-root semantics:

geosc pipeline \
  --config data-config/geolift_analysis_config.yaml \
  --output-dir results/campaign_a

This preserves the legacy stage/report layout under the supplied root:

  • results/campaign_a/multicell_power_analysis/
  • results/campaign_a/multicell_donor_eval/
  • results/campaign_a/multicell_geolift_analysis/
  • results/campaign_a/geolift_pipeline_report.md
  • results/campaign_a/geolift_pipeline_report.html

Migration From Legacy Entry Points

Legacy source-checkout command Preferred command
python runme.py geosc pipeline --config data-config/geolift_analysis_config.yaml
python recipes/power_calculator_sparsesc.py --config data-config/power_analysis_config.yaml --use-gpu --jobs -1 geosc power --config data-config/power_analysis_config.yaml --use-gpu --jobs -1
python recipes/donor_evaluator.py --config data-config/donor_eval_config.yaml geosc donors --config data-config/donor_eval_config.yaml
python recipes/geolift_multi_cell.py --config data-config/geolift_analysis_config.yaml geosc infer --config data-config/geolift_analysis_config.yaml

runme.py remains available as a compatibility wrapper. recipes/ remain available for migration and legacy stage-specific workflows.

Configuration Reference

GeoSC uses flat YAML keys for its configuration.

The example below reflects the supported YAML shape. The data-config/ directory is a source-tree example asset, not a packaged runtime asset, so built wheel and sdist installs should replace those demo paths with user-owned config and data paths.

Inference Config Parameters

Below are the standard configuration keys used in geolift_analysis_config.yaml:

schema_version: "1.0"
data_path: "data-config/synthetic_geolift_multi.csv"
location_col_name: "location"
date_col_name: "date"
date_format: "%d/%m/%Y"
duplicate_policy: "error"
missing_outcome_policy: "error"
outcome_col_name: "Y"
treatment_unit_ids: [501, 502, 503]
intervention_date_str: "01/03/2023"
estimator: "sparsesc"
cooldown_periods: 0
# measurement_start_date_str: "08/03/2023"  # Optional; must agree with cooldown_periods if set.
covariate_col_names: ["covariate_1", "covariate_2"]
sparse_sc_model_type: "retrospective"
sparse_sc_fast_estimation: true
sparse_sc_level: 0.95
sparse_sc_return_ci: true
sparse_sc_max_n_pl: 1000
sparse_sc_placebo_seed: 110011
min_pre_treatment_periods: 12
min_post_treatment_periods: 1
run_assumption_checks: false
require_assumption_checks: false
fail_on_assumption_error: true
parallel_trends_method: "regression"
spillover_method: "correlation"
assumption_alpha: 0.05
output_dir: "outputs/multicell_geolift_analysis"
create_plots: true

Cooldown And Measurement Window

cooldown_periods excludes an initial post-launch transition window from effect measurement. It defaults to 0, which preserves the existing behavior where the measurement window starts on intervention_date_str.

Cooldown counts observed data periods, not calendar days. For daily data, cooldown_periods: 7 excludes seven daily observations. For weekly data, cooldown_periods: 2 excludes two weekly observations.

When cooldown is positive:

  • pre-treatment fit uses dates before intervention_date_str;
  • cooldown dates are excluded from the estimator-facing panel;
  • measurement post-periods start at the resolved measurement start date;
  • min_post_treatment_periods is checked after cooldown exclusion.

You may supply measurement_start_date_str explicitly, but if it is supplied with cooldown_periods, both settings must resolve to the same observed period. Positive cooldown shortens the measurement window and can reduce power.

sparse_sc_T0 and sparse_sc_T1 are SparseSC history-length settings. They are not cooldown controls.

All file-based and direct-data panels are canonicalised before validation. Date labels become a sorted, timezone-naive DatetimeIndex; malformed or timezone-aware labels, duplicate periods after parsing, and treatment dates absent from the outcome panel are rejected rather than coerced.

Estimator Identity

estimator: "sparsesc" is the only supported estimator selector and is also the default when the key is omitted. Historical values sdid, sc, did, and regsynth all executed this same SparseSC path; they are now rejected because their names implied implementations that were not present. Replace any such value with estimator: "sparsesc".

SparseSC Runtime Keys

GeoSC validates keys that start with sparse_sc_ so misspellings fail before the adapter falls back to defaults. Supported SparseSC runtime keys are:

  • sparse_sc_model_type
  • sparse_sc_fast_estimation
  • sparse_sc_return_ci
  • sparse_sc_T0
  • sparse_sc_T1
  • sparse_sc_max_n_pl
  • sparse_sc_placebo_seed
  • sparse_sc_level
  • sparse_sc_lasso_max_iter
  • sparse_sc_lasso_tol
  • sparse_sc_cv_folds
  • sparse_sc_scoring
  • sparse_sc_gcv_mode

sparse_sc_placebo_seed defaults to 110011 and must be a non-negative integer. It controls only the sampled-placebo branch used when sparse_sc_max_n_pl caps the feasible placebo combinations. Exhaustive enumeration is unchanged. Results persist the seed, placebo mode, requested count, possible count, and effective count so sampled inference can be replayed.

Existing non-prefixed lasso options such as lasso_selection, lasso_fit_intercept, and lasso_normalize keep their legacy behavior and are not part of the sparse_sc_* allowlist.

Data Contract Policies

Inference defaults are fail-closed:

  • duplicate_policy: "error" rejects duplicate location-date rows. Use "mean" or "sum" only when that aggregation is statistically intended.
  • missing_outcome_policy: "error" rejects incomplete outcome panels. Explicit alternatives are "drop_unit", "drop_period", and "impute_with_report".

Every inference run writes data_validation.json next to the result artifacts. Review it before interpreting lift. The artifact includes raw outcome value checks plus separate input-panel and model-panel quality summaries, so missing values hidden by explicit duplicate aggregation remain auditable.

Inference also writes geolift_results.json with schema_version and status. Treat ok as “the configured contract completed”, not as a proof of causal validity. Treat partial as “estimate available but interpretation metadata incomplete”, and treat failed as unusable for decision-making.

Assumption Gates

  • run_assumption_checks: false skips the parallel-trends diagnostic and advisory interference screen, but still writes assumption_validation.json with overall_status: "skipped".
  • require_assumption_checks: true makes only the gate-eligible parallel-trends diagnostic a hard result gate. A failed gate marks geolift_results.json as status: "failed".
  • fail_on_assumption_error: true treats parallel-trends validator exceptions as failed gates when checks are run. An interference-screen exception is recorded as indeterminate and remains advisory.
  • parallel_trends_method supports "placebo", "regression", and "visual".
  • spillover_method supports "correlation", "change", and "visual" for the advisory interference screen.

The interference screen reports signal, no_signal, or indeterminate and adds a result caveat where appropriate; it never changes result status or significance. Neither a signal nor no signal identifies treatment exposure or proves the presence or absence of spillover. A future hard interference gate would need a pre-specified exposure, network, or geographical-interference design; GeoSC does not implement one.

Power Config Parameters

Power analysis accepts the demo keys in data-config/power_analysis_config.yaml, including:

random_seed: 12345
alpha: 0.05
n_simulations: 300
sparse_sc_max_n_pl: 100
power_dgp_rank: null
power_dgp_max_rank: 5
power_failure_rate_threshold: 0.2
effect_pattern: "constant"
use_gpu: false

random_seed makes repeated runs with the same config reproducible. Each power_analysis_results.csv row records n_failed, failure_rate, valid, random_seed, simulation_seed, dgp_rank, dgp_explained_var, requested_max_n_pl, possible_placebos, effective_max_n_pl, dgp_backend, generation_backend, seeded_reproducibility_mode, and effect_pattern. Rows with valid: false exceeded the configured failure tolerance or had no successful simulations. power_failure_rate_threshold must be a finite number in [0, 1]; non-finite values are rejected at construction. When random_seed is set, GPU DGP estimation and GPU post-period generation are disabled so seeded CPU simulation draws are reproducible. The shipped demo config sets use_gpu: false to match this seeded reproducibility default.

The factor-model DGP supports SVD extraction only. power_dgp_rank controls the number of SVD factors, and power_dgp_max_rank caps automatic rank selection. GeoSC estimates VAR(1) dynamics on the selected factor series and stores the transition, intercept, innovation covariance, and initial factor distribution in the DGP metadata used for simulation. Automatic rank selection applies an additional effective cap so the selected rank is estimable by the VAR(1) regression on short pre-period panels. Explicit power_dgp_rank values that cannot support VAR(1) estimation fail with an actionable error instead of silently switching DGP families. Unsupported extraction methods such as pca are rejected rather than treated as aliases.

Generated post-period panels use the VAR(1) temporal parameters whenever they are present. Covariance matrices are symmetrized and regularized with a small diagonal floor; invalid factor dynamics or failed factor draws raise errors instead of falling back to diagonal covariance. Because the current GPU path does not implement the VAR(1) generator contract, post-period generation for estimator-produced power DGPs is reported as cpu_numpy_generator even when GPU SVD estimation was requested and available. Power values are Monte Carlo estimates, not guarantees; compare them with power_ci_lower, power_ci_upper, n_simulations, and failure_rate.

If a power-analysis design has fewer control units than treatment units the calculator now fails fast at construction with a ValueError rather than forwarding an infeasible placebo count to SparseSC. plot_power_curves filters rows with valid: false out of the decision plots (logging the count of excluded rows) and skips plot creation entirely when no valid rows remain.

Donor Config Parameters

Donor evaluation accepts donor_dominance_threshold in addition to the existing metric thresholds. donor_eval_results.csv includes rank, quality_band, warning_flags, and selected_weight. selected_weight is a normalized recommendation weight within the ranked donor set; it is not a fitted SparseSC weight. The stage also writes versioned donor_pool_quality.json with threshold settings, warning-flag counts, selected-weight concentration, effective donor count, and by-treatment quality summaries.

The maintained artifact contract is enforced by release preflight and described in the output sections of API Reference, Interpreting Results, and the stage-specific how-to guides.

Shapemap Keys

Donor maps use:

shapemap_file: "/path/to/markets.geojson"
shapemap_id_column: "id"

shapemap_file may point to any GeoPandas-readable vector file. The configured shapemap_id_column must contain IDs that exactly match the treatment and donor unit IDs in the analysis data. For UK production workflows, postcode district IDs such as SW1A or postcode area IDs such as SW can be used when the data and shapemap are both normalized to the same geography. See How to Use Shapemaps for examples.

Release Certification Boundary

scripts/verify_release_candidate.py includes a named statistical certification gate for the 0.3.0 beta. The gate runs the maintained wrapper tests for SparseSC parity, effect recovery, treatment timing and orientation, artifact parity, result uncertainty and placebo semantics, donor semantics, power semantics, assumption-validator metadata, and release-preflight schema regressions.

Passing the gate means the tested GeoSC wrapper contract is intact for the declared SparseSC operational surface. It does not prove donor exchangeability, absence of spillovers, correct campaign timing, outcome suitability, credible power DGP assumptions, or acceptable placebo p-value granularity for a specific measurement decision.

Vendored Dependencies Policy

This project vendors parts of third-party libraries to ensure stability, provenance, and reproducibility of core methods.

SparseSC (Microsoft)

  • Source: https://github.com/microsoft/SparseSC
  • Vendored Path: src/sparsesc/
  • Pinned upstream commit: 3b4d2ebd87b41fc8e0ec3e97fcb2be1b689275c0
  • Status: src/sparsesc/ is a governed integration fork of Microsoft’s SparseSC.
  • Technical provenance: See src/sparsesc/PROVENANCE.md for upstream commit, local modifications, coupling notes, and update procedure.
  • Change Policy: Modifications to src/sparsesc/ must be documented in src/sparsesc/PROVENANCE.md with rationale and verification impact.
  • Tooling: Excluded from formatting, linting, and typing checks (see pyproject.toml).
  • Release certification: GeoSC validates the first-party wrapper boundary around vendored SparseSC through the statistical certification gate in scripts/verify_release_candidate.py. The gate checks adapter/result parity, effect recovery, timing/orientation, artifact schemas, uncertainty and placebo metadata, and related advisory diagnostics. It does not treat passing wrapper tests as proof that a specific campaign satisfies SparseSC’s causal design assumptions.
  • Known cleanup candidate: src/sparsesc/utils/AzureBatch/ remains part of the governed vendored SparseSC fork. Removing or pruning it requires a separate SparseSC provenance-backed phase with documented rationale, verification impact, and an update to src/sparsesc/PROVENANCE.md.

synthdid (if retained)

  • Vendored Path: src/synthdid/
  • Status: Not used by the primary GeoLiftAnalyzer workflow.
  • Recommendation: Either remove it entirely, or expose it behind a stable adapter interface and document its usage with tests.
  • Tooling: Excluded from formatting, linting, and typing checks.

Update Procedure

  1. Keep a file-local provenance record for each vendored dependency.
  2. Verify unit, integration, and performance tests pass after a refresh.
  3. Update pyproject.toml exclusion lists only if vendored paths change.
  4. Document any intentional local modifications in the dependency-specific provenance file.