Commit a17c8a0
Address PR #365 R11 P1: drop FPC pre-resolve on placebo + Case D effective-support guard
P1 #1 (FPC validator in SurveyDesign.resolve fires on placebo with
explicit psu):
The R10 fix gated the in-fit implicit-PSU FPC validator on
bootstrap/jackknife only, but ``SurveyDesign.resolve()`` itself
enforces ``FPC >= n_PSU`` design-validity (survey.py:349-368) before
``synthetic_did.fit()`` even sees the resolved object. So a placebo
fit with explicit ``psu`` and low ``fpc`` would still raise — same
parameter-interaction problem one layer earlier in resolution.
Fix: when ``variance_method == "placebo"`` and
``survey_design.fpc is not None``, construct an FPC-stripped copy of
the SurveyDesign (``dataclasses.replace(survey_design, fpc=None)``)
BEFORE calling ``_resolve_survey_for_fit``. Emit the FPC no-op
``UserWarning`` at the same time. The original ``survey_design``
object is preserved (caller's reference unchanged); the resolved
unit-level survey design carries no FPC on placebo, so the in-fit
validators (and the downstream FPC-related dispatch flags) all
correctly skip FPC handling.
The duplicate downstream FPC no-op warning (added in R8 keyed on
``resolved_survey_unit.fpc``) becomes unreachable on placebo and is
removed.
New regression
``test_placebo_low_fpc_with_explicit_psu_skips_resolve_validator``:
asserts (a) placebo with explicit psu + ``fpc < n_PSU`` succeeds
+ emits no-op warning, (b) SE matches the no-FPC fit at ``rel=1e-12``,
(c) bootstrap on the same low-FPC design still raises
``"FPC (2.0) is less than the number of PSUs"`` from
``SurveyDesign.resolve()`` — validator-skip is correctly variance-
method-gated.
P1 #2 (Case D missed effective single-support):
The Case D guard for placebo degeneracy keyed on raw control counts
(``n_c_h > n_t_h`` for at least one stratum). It missed the case
where ``n_c_h_positive < 2`` for every treated stratum: rows allow
multiple subsets, but every successful pseudo-treated mean reduces
to the unique positive-weight control's outcome (zero-weight
cohabitants contribute 0 to numerator and denominator, R11 P1).
The placebo null collapses to a single point and SE = FP noise.
Fix: extend the non-degeneracy invariant to require **both**
``n_c_h > n_t_h`` AND ``n_c_h_positive >= 2`` for at least one
treated stratum. The classical Case D shape (raw exact-count
``n_c_h == n_t_h``) and the new "effective single-support" shape
(positive-weight controls < 2 even with extra zero-weight rows) both
trigger Case D. Updated the Case D error message to enumerate
``n_c_positive`` alongside ``n_c`` / ``n_t`` per stratum.
New regression
``test_placebo_full_design_raises_on_effective_single_support``:
constructs a fixture with 1 treated unit + 1 positive-weight
control + 9 zero-weight controls in stratum 0; raw guards (B/C/E)
pass but Case D fires with the new "single distinct positive-mass
pseudo-treated mean" message.
Updated existing
``test_placebo_full_design_raises_on_exact_count_stratum`` regex
to match the new message (same Case D path, slightly different
wording).
REGISTRY §SyntheticDiD Case enumeration updated: Case D now
documents both the classical (``n_c == n_t``) and effective single-
support (``n_c_positive < 2``) shapes, with the combined non-
degeneracy invariant.
Verification: 98 passed (2 new regressions; existing Case B/C/E/D-
classical guards still fire on their fixtures).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 312f78f commit a17c8a0
3 files changed
Lines changed: 209 additions & 45 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
330 | 330 | | |
331 | 331 | | |
332 | 332 | | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
333 | 366 | | |
334 | | - | |
| 367 | + | |
335 | 368 | | |
336 | 369 | | |
337 | 370 | | |
| |||
822 | 855 | | |
823 | 856 | | |
824 | 857 | | |
825 | | - | |
826 | | - | |
827 | | - | |
828 | | - | |
829 | | - | |
830 | | - | |
831 | | - | |
832 | | - | |
833 | | - | |
834 | | - | |
835 | | - | |
836 | | - | |
837 | | - | |
838 | | - | |
839 | | - | |
840 | | - | |
841 | | - | |
842 | | - | |
843 | | - | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
844 | 863 | | |
845 | 864 | | |
846 | 865 | | |
| |||
929 | 948 | | |
930 | 949 | | |
931 | 950 | | |
932 | | - | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
933 | 967 | | |
934 | | - | |
935 | | - | |
936 | | - | |
937 | | - | |
938 | | - | |
939 | | - | |
940 | | - | |
941 | | - | |
942 | | - | |
943 | | - | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
944 | 983 | | |
945 | 984 | | |
946 | 985 | | |
| 986 | + | |
947 | 987 | | |
948 | 988 | | |
949 | 989 | | |
950 | 990 | | |
951 | 991 | | |
952 | | - | |
953 | | - | |
954 | | - | |
955 | | - | |
956 | | - | |
957 | | - | |
958 | | - | |
959 | | - | |
960 | | - | |
961 | | - | |
962 | | - | |
963 | | - | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
964 | 1005 | | |
965 | 1006 | | |
966 | 1007 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1589 | 1589 | | |
1590 | 1590 | | |
1591 | 1591 | | |
1592 | | - | |
| 1592 | + | |
1593 | 1593 | | |
1594 | 1594 | | |
1595 | 1595 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
841 | 841 | | |
842 | 842 | | |
843 | 843 | | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
844 | 891 | | |
845 | 892 | | |
846 | 893 | | |
| |||
897 | 944 | | |
898 | 945 | | |
899 | 946 | | |
900 | | - | |
| 947 | + | |
901 | 948 | | |
902 | 949 | | |
903 | 950 | | |
| |||
1031 | 1078 | | |
1032 | 1079 | | |
1033 | 1080 | | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
1034 | 1157 | | |
1035 | 1158 | | |
1036 | 1159 | | |
| |||
0 commit comments