# Author: Simon-Pierre Boucher — contact@spboucher.ai """Paths and global constants for the WP10 pipeline. All paths are relative to the repository root, so the pipeline runs on any machine after cloning. Override the root with the ``WP10_ROOT`` environment variable if the scripts are launched from elsewhere. """ import os from pathlib import Path ROOT = Path(os.environ.get("WP10_ROOT", Path(__file__).resolve().parents[2])) RAW_PARQUET = ROOT / "data" / "raw" / "transactions_700k_avec_registre_foncier.parquet" PROCESSED = ROOT / "data" / "processed" ANALYSIS_PARQUET = PROCESSED / "analysis.parquet" FIGURES = ROOT / "figures" RESULTS = ROOT / "results" REPRODUCED = RESULTS / "reproduced" TABLES = RESULTS / "tables" # ---------------------------------------------------------------- sample # Residential CUBF use codes kept in the estimation sample # 1000 Logement | 1100 Chalet ou maison de villégiature | 1211 Maison mobile # 1990 Autres immeubles résidentiels RESIDENTIAL_CUBF = {"1000", "1100", "1211", "1990"} MATCH_MAX_DIST_M = 50.0 # roll–transaction geocoding distance ceiling MATCH_MIN_SCORE = 150.0 # matcher confidence floor (max attainable: 220) PRICE_MIN = 50_000 # source feed already truncates below 50k RATIO_TRIM = (0.01, 0.99) # symmetric trim on the assessment ratio, by roll vintage CELL_MIN_OBS = 20 # minimum sales per municipality×roll×year cell (FE cells) MUNI_MIN_SALES = 100 # minimum sales for municipality-level IAAO statistics # ---------------------------------------------------------------- inference SEED_BOOT = 20260809 # bootstrap seed (IAAO confidence intervals) N_BOOT = 500 # bootstrap replications QUANTILES = [0.10, 0.25, 0.50, 0.75, 0.90] # quantile-regression grid # IAAO (2013) acceptable ranges, quoted in the paper's tables IAAO_COD_MAX_SF = 15.0 # single-family, heterogeneous areas IAAO_PRD_RANGE = (0.98, 1.03) IAAO_PRB_RANGE = (-0.05, 0.05) # Ten largest markets reported individually in the IAAO table BIG_CITIES = ["Montréal", "Québec", "Laval", "Gatineau", "Longueuil", "Lévis", "Sherbrooke", "Saguenay", "Trois-Rivières", "Terrebonne"] def ensure_dirs() -> None: """Create every output directory the pipeline writes to.""" for p in (PROCESSED, FIGURES, REPRODUCED, TABLES): p.mkdir(parents=True, exist_ok=True)