Skip to content

Clean up experiments/: typos, annotations, and constants#796

Open
louismagowan wants to merge 10 commits intopymc-labs:mainfrom
louismagowan:refactor/lm-experiments
Open

Clean up experiments/: typos, annotations, and constants#796
louismagowan wants to merge 10 commits intopymc-labs:mainfrom
louismagowan:refactor/lm-experiments

Conversation

@louismagowan
Copy link
Copy Markdown
Contributor

@louismagowan louismagowan commented Mar 7, 2026

Summary

Purely mechanical cleanup of causalpy/experiments/ — no behavioural changes.
Closes: #795

  • Fix typos: "treament" → "treatment" (diff_in_diff), "trestment" → "treatment" (prepostnegd)
  • Fix **kwargs: dict → **kwargs: Any: 9 experiment files — dict is the wrong annotation for **kwargs values
  • Replace is False with not: idiomatic boolean checks in dummy-coded validation (3 files)
  • Fix misplaced docstring: DifferenceInDifferences.input_validation() had its docstring after the first executable line
  • Standardize expt_type to instance attribute: remove dead class attribute in InterruptedTimeSeries, move to init in PiecewiseITS
    • Extract LEGEND_FONT_SIZE to causalpy/experiments/constants.py (8 files)
    • Extract HDI_PROB to causalpy/utils.py, replace all hardcoded 0.94 defaults and 0.03/1 - 0.03 quantile bounds (10 files)

louismagowan and others added 7 commits March 7, 2026 18:07
- diff_in_diff.py: "treament" -> "treatment" in plot label
- prepostnegd.py: "trestment" -> "treatment" in comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ethods

`**kwargs: dict` is incorrect — it annotates each value as a dict,
not the collection. Every experiment except inverse_propensity_weighting
(which already used Any) is fixed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use idiomatic `if not func(...)` instead of `if func(...) is False`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The docstring was after the first executable line; move it to the
correct position immediately after the method signature.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- interrupted_time_series.py: remove dead class attribute (overwritten
  by self.expt_type in __init__)
- piecewise_its.py: move class attribute to self.expt_type in __init__
- Update test to check expt_type as instance attribute

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create a shared constants module and replace the per-file
`LEGEND_FONT_SIZE = 12` definitions in all 8 experiment files with
an import from `causalpy.experiments.constants`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add `HDI_PROB: float = 0.94` to `causalpy/utils.py` and replace all
hardcoded `0.94` parameter defaults and `0.03` / `1 - 0.03` quantile
bounds with expressions derived from HDI_PROB.

Updated files: utils.py, plot_utils.py, pymc_models.py, and 6
experiment modules (prepostnegd, regression_discontinuity,
regression_kink, interrupted_time_series, piecewise_its,
staggered_did, synthetic_control).

Test files and docstrings are intentionally left unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@read-the-docs-community
Copy link
Copy Markdown

read-the-docs-community bot commented Mar 7, 2026

Documentation build overview

📚 causalpy | 🛠️ Build #32121496 | 📁 Comparing 10214b4 against latest (1ee7322)

  🔍 Preview build  

Show files changed (199 files in total): 📝 66 modified | ➕ 0 added | ➖ 133 deleted
File Status
404.html 📝 modified
genindex.html 📝 modified
index.html 📝 modified
py-modindex.html 📝 modified
_modules/index.html 📝 modified
api/index.html 📝 modified
knowledgebase/custom_pymc_models.html ➖ deleted
knowledgebase/design_notation.html 📝 modified
knowledgebase/index.html 📝 modified
notebooks/ancova_pymc.html 📝 modified
notebooks/did_pymc.html 📝 modified
notebooks/did_pymc_banks.html 📝 modified
notebooks/did_skl.html 📝 modified
notebooks/geolift1.html 📝 modified
notebooks/index.html 📝 modified
notebooks/inv_prop_latent.html 📝 modified
notebooks/inv_prop_pymc.html 📝 modified
notebooks/its_covid.html 📝 modified
notebooks/its_lift_test.html 📝 modified
notebooks/its_post_intervention_analysis.html 📝 modified
notebooks/its_pymc.html 📝 modified
notebooks/its_pymc_comparative.html 📝 modified
notebooks/its_skl.html 📝 modified
notebooks/multi_cell_geolift.html 📝 modified
notebooks/piecewise_its_pymc.html 📝 modified
notebooks/pipeline_workflow.html ➖ deleted
notebooks/rd_donut_pymc.html 📝 modified
notebooks/rd_pymc.html 📝 modified
notebooks/rd_pymc_drinking.html 📝 modified
notebooks/rd_skl.html 📝 modified
notebooks/rd_skl_drinking.html 📝 modified
notebooks/report_demo.html ➖ deleted
notebooks/rkink_pymc.html 📝 modified
notebooks/sc_pymc.html 📝 modified
notebooks/sc_pymc_brexit.html 📝 modified
notebooks/sc_skl.html 📝 modified
notebooks/sensitivity_checks.html ➖ deleted
notebooks/staggered_did_pymc.html 📝 modified
_modules/causalpy/pipeline.html ➖ deleted
_modules/causalpy/pymc_models.html 📝 modified
api/generated/causalpy.checks.bandwidth.BandwidthSensitivity.init.html ➖ deleted
api/generated/causalpy.checks.bandwidth.BandwidthSensitivity.html ➖ deleted
api/generated/causalpy.checks.bandwidth.BandwidthSensitivity.run.html ➖ deleted
api/generated/causalpy.checks.bandwidth.BandwidthSensitivity.validate.html ➖ deleted
api/generated/causalpy.checks.bandwidth.html ➖ deleted
api/generated/causalpy.checks.base.Check.init.html ➖ deleted
api/generated/causalpy.checks.base.Check.html ➖ deleted
api/generated/causalpy.checks.base.Check.run.html ➖ deleted
api/generated/causalpy.checks.base.Check.validate.html ➖ deleted
api/generated/causalpy.checks.base.CheckResult.init.html ➖ deleted
api/generated/causalpy.checks.base.CheckResult.html ➖ deleted
api/generated/causalpy.checks.base.clone_model.html ➖ deleted
api/generated/causalpy.checks.base.html ➖ deleted
api/generated/causalpy.checks.convex_hull.ConvexHullCheck.init.html ➖ deleted
api/generated/causalpy.checks.convex_hull.ConvexHullCheck.html ➖ deleted
api/generated/causalpy.checks.convex_hull.ConvexHullCheck.run.html ➖ deleted
api/generated/causalpy.checks.convex_hull.ConvexHullCheck.validate.html ➖ deleted
api/generated/causalpy.checks.convex_hull.html ➖ deleted
api/generated/causalpy.checks.html ➖ deleted
api/generated/causalpy.checks.leave_one_out.LeaveOneOut.init.html ➖ deleted
api/generated/causalpy.checks.leave_one_out.LeaveOneOut.html ➖ deleted
api/generated/causalpy.checks.leave_one_out.LeaveOneOut.run.html ➖ deleted
api/generated/causalpy.checks.leave_one_out.LeaveOneOut.validate.html ➖ deleted
api/generated/causalpy.checks.leave_one_out.html ➖ deleted
api/generated/causalpy.checks.mccrary.McCraryDensityTest.init.html ➖ deleted
api/generated/causalpy.checks.mccrary.McCraryDensityTest.html ➖ deleted
api/generated/causalpy.checks.mccrary.McCraryDensityTest.run.html ➖ deleted
api/generated/causalpy.checks.mccrary.McCraryDensityTest.validate.html ➖ deleted
api/generated/causalpy.checks.mccrary.html ➖ deleted
api/generated/causalpy.checks.persistence.PersistenceCheck.init.html ➖ deleted
api/generated/causalpy.checks.persistence.PersistenceCheck.html ➖ deleted
api/generated/causalpy.checks.persistence.PersistenceCheck.run.html ➖ deleted
api/generated/causalpy.checks.persistence.PersistenceCheck.validate.html ➖ deleted
api/generated/causalpy.checks.persistence.html ➖ deleted
api/generated/causalpy.checks.placebo_in_space.PlaceboInSpace.init.html ➖ deleted
api/generated/causalpy.checks.placebo_in_space.PlaceboInSpace.html ➖ deleted
api/generated/causalpy.checks.placebo_in_space.PlaceboInSpace.run.html ➖ deleted
api/generated/causalpy.checks.placebo_in_space.PlaceboInSpace.validate.html ➖ deleted
api/generated/causalpy.checks.placebo_in_space.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.AssuranceResult.init.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.AssuranceResult.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.PlaceboFoldResult.init.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.PlaceboFoldResult.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.PlaceboInTime.init.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.PlaceboInTime.bayesian_rope_decision.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.PlaceboInTime.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.PlaceboInTime.run.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.PlaceboInTime.validate.html ➖ deleted
api/generated/causalpy.checks.placebo_in_time.html ➖ deleted
api/generated/causalpy.checks.pre_treatment_placebo.PreTreatmentPlaceboCheck.init.html ➖ deleted
api/generated/causalpy.checks.pre_treatment_placebo.PreTreatmentPlaceboCheck.html ➖ deleted
api/generated/causalpy.checks.pre_treatment_placebo.PreTreatmentPlaceboCheck.run.html ➖ deleted
api/generated/causalpy.checks.pre_treatment_placebo.PreTreatmentPlaceboCheck.validate.html ➖ deleted
api/generated/causalpy.checks.pre_treatment_placebo.html ➖ deleted
api/generated/causalpy.checks.prior_sensitivity.PriorSensitivity.init.html ➖ deleted
api/generated/causalpy.checks.prior_sensitivity.PriorSensitivity.html ➖ deleted
api/generated/causalpy.checks.prior_sensitivity.PriorSensitivity.run.html ➖ deleted
api/generated/causalpy.checks.prior_sensitivity.PriorSensitivity.validate.html ➖ deleted
api/generated/causalpy.checks.prior_sensitivity.html ➖ deleted
api/generated/causalpy.experiments.base.BaseExperiment.generate_report.html ➖ deleted
api/generated/causalpy.experiments.base.BaseExperiment.html 📝 modified
api/generated/causalpy.experiments.base.BaseExperiment.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.diff_in_diff.DifferenceInDifferences.init.html 📝 modified
api/generated/causalpy.experiments.diff_in_diff.DifferenceInDifferences.generate_report.html ➖ deleted
api/generated/causalpy.experiments.diff_in_diff.DifferenceInDifferences.html 📝 modified
api/generated/causalpy.experiments.diff_in_diff.DifferenceInDifferences.input_validation.html 📝 modified
api/generated/causalpy.experiments.diff_in_diff.DifferenceInDifferences.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.instrumental_variable.InstrumentalVariable.init.html 📝 modified
api/generated/causalpy.experiments.instrumental_variable.InstrumentalVariable.generate_report.html ➖ deleted
api/generated/causalpy.experiments.instrumental_variable.InstrumentalVariable.html 📝 modified
api/generated/causalpy.experiments.instrumental_variable.InstrumentalVariable.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.interrupted_time_series.InterruptedTimeSeries.init.html 📝 modified
api/generated/causalpy.experiments.interrupted_time_series.InterruptedTimeSeries.generate_report.html ➖ deleted
api/generated/causalpy.experiments.interrupted_time_series.InterruptedTimeSeries.html 📝 modified
api/generated/causalpy.experiments.interrupted_time_series.InterruptedTimeSeries.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.inverse_propensity_weighting.InversePropensityWeighting.generate_report.html ➖ deleted
api/generated/causalpy.experiments.inverse_propensity_weighting.InversePropensityWeighting.html 📝 modified
api/generated/causalpy.experiments.inverse_propensity_weighting.InversePropensityWeighting.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.piecewise_its.PiecewiseITS.init.html 📝 modified
api/generated/causalpy.experiments.piecewise_its.PiecewiseITS.generate_report.html ➖ deleted
api/generated/causalpy.experiments.piecewise_its.PiecewiseITS.html 📝 modified
api/generated/causalpy.experiments.piecewise_its.PiecewiseITS.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.prepostnegd.PrePostNEGD.init.html 📝 modified
api/generated/causalpy.experiments.prepostnegd.PrePostNEGD.generate_report.html ➖ deleted
api/generated/causalpy.experiments.prepostnegd.PrePostNEGD.html 📝 modified
api/generated/causalpy.experiments.prepostnegd.PrePostNEGD.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.regression_discontinuity.RegressionDiscontinuity.init.html 📝 modified
api/generated/causalpy.experiments.regression_discontinuity.RegressionDiscontinuity.generate_report.html ➖ deleted
api/generated/causalpy.experiments.regression_discontinuity.RegressionDiscontinuity.html 📝 modified
api/generated/causalpy.experiments.regression_discontinuity.RegressionDiscontinuity.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.regression_kink.RegressionKink.init.html 📝 modified
api/generated/causalpy.experiments.regression_kink.RegressionKink.generate_report.html ➖ deleted
api/generated/causalpy.experiments.regression_kink.RegressionKink.html 📝 modified
api/generated/causalpy.experiments.regression_kink.RegressionKink.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.staggered_did.StaggeredDifferenceInDifferences.init.html 📝 modified
api/generated/causalpy.experiments.staggered_did.StaggeredDifferenceInDifferences.generate_report.html ➖ deleted
api/generated/causalpy.experiments.staggered_did.StaggeredDifferenceInDifferences.html 📝 modified
api/generated/causalpy.experiments.staggered_did.StaggeredDifferenceInDifferences.set_maketables_options.html ➖ deleted
api/generated/causalpy.experiments.synthetic_control.SyntheticControl.init.html 📝 modified
api/generated/causalpy.experiments.synthetic_control.SyntheticControl.generate_report.html ➖ deleted
api/generated/causalpy.experiments.synthetic_control.SyntheticControl.html 📝 modified
api/generated/causalpy.experiments.synthetic_control.SyntheticControl.set_maketables_options.html ➖ deleted
api/generated/causalpy.pipeline.Pipeline.init.html ➖ deleted
api/generated/causalpy.pipeline.Pipeline.html ➖ deleted
api/generated/causalpy.pipeline.Pipeline.run.html ➖ deleted
api/generated/causalpy.pipeline.PipelineContext.init.html ➖ deleted
api/generated/causalpy.pipeline.PipelineContext.html ➖ deleted
api/generated/causalpy.pipeline.PipelineResult.init.html ➖ deleted
api/generated/causalpy.pipeline.PipelineResult.from_context.html ➖ deleted
api/generated/causalpy.pipeline.PipelineResult.html ➖ deleted
api/generated/causalpy.pipeline.Step.init.html ➖ deleted
api/generated/causalpy.pipeline.Step.html ➖ deleted
api/generated/causalpy.pipeline.Step.run.html ➖ deleted
api/generated/causalpy.pipeline.Step.validate.html ➖ deleted
api/generated/causalpy.pipeline.html ➖ deleted
api/generated/causalpy.steps.estimate_effect.EstimateEffect.init.html ➖ deleted
api/generated/causalpy.steps.estimate_effect.EstimateEffect.html ➖ deleted
api/generated/causalpy.steps.estimate_effect.EstimateEffect.run.html ➖ deleted
api/generated/causalpy.steps.estimate_effect.EstimateEffect.validate.html ➖ deleted
api/generated/causalpy.steps.estimate_effect.html ➖ deleted
api/generated/causalpy.steps.html ➖ deleted
api/generated/causalpy.steps.report.GenerateReport.init.html ➖ deleted
api/generated/causalpy.steps.report.GenerateReport.html ➖ deleted
api/generated/causalpy.steps.report.GenerateReport.run.html ➖ deleted
api/generated/causalpy.steps.report.GenerateReport.validate.html ➖ deleted
api/generated/causalpy.steps.report.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivityAnalysis.init.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivityAnalysis.default_for.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivityAnalysis.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivityAnalysis.run.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivityAnalysis.validate.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivitySummary.init.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivitySummary.from_results.html ➖ deleted
api/generated/causalpy.steps.sensitivity.SensitivitySummary.html ➖ deleted
api/generated/causalpy.steps.sensitivity.html ➖ deleted
api/generated/causalpy.steps.sensitivity.register_default_check.html ➖ deleted
_modules/causalpy/checks/bandwidth.html ➖ deleted
_modules/causalpy/checks/base.html ➖ deleted
_modules/causalpy/checks/convex_hull.html ➖ deleted
_modules/causalpy/checks/leave_one_out.html ➖ deleted
_modules/causalpy/checks/mccrary.html ➖ deleted
_modules/causalpy/checks/persistence.html ➖ deleted
_modules/causalpy/checks/placebo_in_space.html ➖ deleted
_modules/causalpy/checks/placebo_in_time.html ➖ deleted
_modules/causalpy/checks/pre_treatment_placebo.html ➖ deleted
_modules/causalpy/checks/prior_sensitivity.html ➖ deleted
_modules/causalpy/experiments/base.html 📝 modified
_modules/causalpy/experiments/diff_in_diff.html 📝 modified
_modules/causalpy/experiments/instrumental_variable.html 📝 modified
_modules/causalpy/experiments/interrupted_time_series.html 📝 modified
_modules/causalpy/experiments/piecewise_its.html 📝 modified
_modules/causalpy/experiments/prepostnegd.html 📝 modified
_modules/causalpy/experiments/regression_discontinuity.html 📝 modified
_modules/causalpy/experiments/regression_kink.html 📝 modified
_modules/causalpy/experiments/staggered_did.html 📝 modified
_modules/causalpy/experiments/synthetic_control.html 📝 modified
_modules/causalpy/steps/estimate_effect.html ➖ deleted
_modules/causalpy/steps/report.html ➖ deleted
_modules/causalpy/steps/sensitivity.html ➖ deleted

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 7, 2026

Codecov Report

❌ Patch coverage is 93.75000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.79%. Comparing base (5e8db5c) to head (10214b4).
⚠️ Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
causalpy/experiments/interrupted_time_series.py 66.66% 0 Missing and 1 partial ⚠️
causalpy/experiments/regression_kink.py 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #796      +/-   ##
==========================================
+ Coverage   92.42%   93.79%   +1.37%     
==========================================
  Files          52       78      +26     
  Lines        9230    11883    +2653     
  Branches      562      696     +134     
==========================================
+ Hits         8531    11146    +2615     
- Misses        527      545      +18     
- Partials      172      192      +20     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…nd UP038

- Move HDI_PROB after all imports in utils.py to avoid E402
- Sort `from causalpy.experiments.constants` alphabetically with other causalpy imports
- Wrap long quantile lines for ruff format compliance
- Fix pre-existing UP038: use `X | Y` instead of `(X, Y)` in isinstance
- Restore `from typing import Any, Literal` in regression_discontinuity.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@louismagowan
Copy link
Copy Markdown
Contributor Author

@drbenvincent

Copy link
Copy Markdown
Collaborator

@juanitorduz juanitorduz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @louismagowan ! This looks great. I just let a minor question :)

Copy link
Copy Markdown
Collaborator

@drbenvincent drbenvincent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the cleanup — this is thorough and well-structured. All CI green, coverage maintained. A couple of things to address:

1. Hardcoded "94%" label strings should derive from HDI_PROB

The quantile computations now correctly use HDI_PROB, but the display labels are still hardcoded as "94%". This means the constant extraction is half-done — if someone changes HDI_PROB, the math updates but the labels would be wrong.

Locations:

  • pymc_models.py:420"94% HDI [...]"
  • utils.py:111r"$CI_{94\%}$"
  • regression_kink.py:279r"$CI_{94\%}$"
  • regression_discontinuity.py:338r"$CI_{94\%}$"
  • prepostnegd.py:219r"$CI_{94%}$" (also note: missing \ before %, unlike the other files)

These should derive from the constant, e.g. f"{HDI_PROB*100:.0f}% HDI" and rf"$CI_{{{HDI_PROB*100:.0f}\%}}$".

2. Agree with @juanitorduz — move HDI_PROB into constants.py

Having constants split across experiments/constants.py (for LEGEND_FONT_SIZE) and utils.py (for HDI_PROB) is a bit scattered. Since HDI_PROB is used outside experiments/ too (utils.py, plot_utils.py, pymc_models.py), a top-level causalpy/constants.py might be the cleanest home for both constants. That way there's one obvious place to look.

@drbenvincent
Copy link
Copy Markdown
Collaborator

Just following up on this @louismagowan. Do you think you'd be able to make the updates? Then we can merge :)

…e CI labels from HDI_PROB

- Create causalpy/constants.py as single home for shared constants
- Delete causalpy/experiments/constants.py (now unused)
- Update all imports across 10 files to use causalpy.constants directly
- Fix 5 hardcoded "94%" label strings to derive from HDI_PROB (pymc_models,
  utils, regression_kink, regression_discontinuity, prepostnegd); also fix
  missing backslash before % in prepostnegd CI string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@louismagowan
Copy link
Copy Markdown
Contributor Author

@drbenvincent - how's it look now? Everything resolved? ☺️

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clean up typos, incorrect annotations, and duplicated constants in experiments/

3 participants