Commit c320dde
Address PR #346 CI review round 2: 2 P1s + 1 P2
**P1 #1 (Methodology): continuous_near_d_lower on mass-point samples**
When a user explicitly forced design="continuous_near_d_lower" on a
sample that actually satisfies the >2% modal-fraction mass-point
criterion, the downstream regressor shift (D - d_lower) would move the
support minimum to zero on the shifted scale. Phase 1c's mass-point
rejection guard only fires when d.min() > 0 (_validate_had_inputs), so
the silent coercion ran the nonparametric local-linear estimator on a
sample the paper (Section 3.2.4) requires to use the 2SLS branch,
producing the wrong estimand.
Fix: `HeterogeneousAdoptionDiD.fit()` now runs the modal-fraction
check on the ORIGINAL (unshifted) d_arr when the user explicitly
selects design="continuous_near_d_lower". If the fraction at d.min()
exceeds 2%, the fit raises ValueError pointing to design="mass_point"
or design="auto". design="auto" is unaffected (_detect_design already
correctly resolves such samples to mass_point).
**P1 #2 (Code Quality): first_treat_col validator not dtype-agnostic**
The previous validator called `.astype(np.float64)` and `int(v)` on
grouped first_treat values, which crashed on otherwise-supported
string-labelled two-period panels (period in {"A","B"}, first_treat
in {0, "B"}). Rewrote using `pd.isna()` for missingness and raw-value
set-membership against `{0, t_post}` with no numeric coercion.
**P2 (Maintainability): cluster-applied mass-point stored wrong vcov_type**
When cluster was supplied, `_fit_mass_point_2sls` unconditionally
switches to the CR1 cluster-robust sandwich, but the result object
stored the REQUESTED family ("hc1" or "classical") as `vcov_type`.
`summary()` rendered correctly via the cluster_name branch, but
`to_dict()` and downstream programmatic consumers saw the stale
requested label. Fixed: when cluster is supplied, `vcov_type` is
stored as `"cr1"` regardless of the requested family. Renamed the
local variable from `vcov_effective` to `vcov_requested` to separate
the input from the effective family. Updated the
`HeterogeneousAdoptionDiDResults.summary()` branch so the cluster
rendering still works with the new stored value.
**Tests added (+8 regression):**
- TestValidateHadPanel.test_first_treat_col_with_string_periods
- TestValidateHadPanel.test_first_treat_col_dtype_agnostic_rejects_invalid_string
- TestContinuousPathRejectsMassPoint (2 tests)
- TestMassPointClusterLabel (4 tests: cr1 stored when clustered, base
family when unclustered, classical+cluster collapses to cr1,
to_dict shows effective family)
Targeted regression: 126 HAD tests + 505 total across Phase 1 and
adjacent surfaces, all green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 8c38f07 commit c320dde
2 files changed
Lines changed: 174 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
189 | 189 | | |
190 | 190 | | |
191 | 191 | | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
196 | 201 | | |
197 | 202 | | |
198 | 203 | | |
| |||
269 | 274 | | |
270 | 275 | | |
271 | 276 | | |
272 | | - | |
273 | 277 | | |
| 278 | + | |
| 279 | + | |
274 | 280 | | |
| 281 | + | |
| 282 | + | |
275 | 283 | | |
276 | 284 | | |
277 | 285 | | |
| |||
476 | 484 | | |
477 | 485 | | |
478 | 486 | | |
479 | | - | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
480 | 491 | | |
481 | | - | |
482 | | - | |
| 492 | + | |
| 493 | + | |
483 | 494 | | |
484 | 495 | | |
485 | 496 | | |
486 | 497 | | |
487 | 498 | | |
488 | | - | |
| 499 | + | |
| 500 | + | |
489 | 501 | | |
490 | 502 | | |
491 | 503 | | |
492 | | - | |
| 504 | + | |
493 | 505 | | |
494 | 506 | | |
495 | 507 | | |
| |||
1042 | 1054 | | |
1043 | 1055 | | |
1044 | 1056 | | |
| 1057 | + | |
| 1058 | + | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
| 1062 | + | |
| 1063 | + | |
| 1064 | + | |
| 1065 | + | |
| 1066 | + | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + | |
| 1070 | + | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
| 1074 | + | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
| 1078 | + | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
1045 | 1085 | | |
1046 | 1086 | | |
1047 | 1087 | | |
| |||
1148 | 1188 | | |
1149 | 1189 | | |
1150 | 1190 | | |
1151 | | - | |
| 1191 | + | |
1152 | 1192 | | |
1153 | | - | |
1154 | | - | |
| 1193 | + | |
1155 | 1194 | | |
1156 | 1195 | | |
1157 | 1196 | | |
1158 | 1197 | | |
1159 | 1198 | | |
1160 | | - | |
| 1199 | + | |
1161 | 1200 | | |
1162 | 1201 | | |
1163 | 1202 | | |
1164 | 1203 | | |
1165 | | - | |
| 1204 | + | |
| 1205 | + | |
| 1206 | + | |
| 1207 | + | |
| 1208 | + | |
| 1209 | + | |
1166 | 1210 | | |
1167 | 1211 | | |
1168 | 1212 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1404 | 1404 | | |
1405 | 1405 | | |
1406 | 1406 | | |
| 1407 | + | |
| 1408 | + | |
| 1409 | + | |
| 1410 | + | |
| 1411 | + | |
| 1412 | + | |
| 1413 | + | |
| 1414 | + | |
| 1415 | + | |
| 1416 | + | |
| 1417 | + | |
| 1418 | + | |
| 1419 | + | |
| 1420 | + | |
| 1421 | + | |
| 1422 | + | |
| 1423 | + | |
| 1424 | + | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
| 1435 | + | |
| 1436 | + | |
| 1437 | + | |
| 1438 | + | |
| 1439 | + | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
| 1444 | + | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
| 1470 | + | |
| 1471 | + | |
| 1472 | + | |
| 1473 | + | |
| 1474 | + | |
| 1475 | + | |
| 1476 | + | |
| 1477 | + | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
0 commit comments