1515import sys
1616from pathlib import Path
1717
18+
1819# IMPORTANT: Parse --backend and set environment variable BEFORE importing diff_diff
1920def _get_backend_from_args ():
2021 """Parse --backend argument without importing diff_diff."""
@@ -23,6 +24,7 @@ def _get_backend_from_args():
2324 args , _ = parser .parse_known_args ()
2425 return args .backend
2526
27+
2628_requested_backend = _get_backend_from_args ()
2729if _requested_backend in ("python" , "rust" ):
2830 os .environ ["DIFF_DIFF_BACKEND" ] = _requested_backend
@@ -38,14 +40,14 @@ def _get_backend_from_args():
3840
3941
4042def parse_args ():
41- parser = argparse .ArgumentParser (
42- description = "Benchmark WooldridgeDiD (ETWFE) estimator"
43- )
43+ parser = argparse .ArgumentParser (description = "Benchmark WooldridgeDiD (ETWFE) estimator" )
4444 parser .add_argument ("--data" , required = True , help = "Path to input CSV data (mpdta format)" )
4545 parser .add_argument ("--output" , required = True , help = "Path to output JSON results" )
4646 parser .add_argument (
47- "--backend" , default = "auto" , choices = ["auto" , "python" , "rust" ],
48- help = "Backend to use: auto (default), python (pure Python), rust (Rust backend)"
47+ "--backend" ,
48+ default = "auto" ,
49+ choices = ["auto" , "python" , "rust" ],
50+ help = "Backend to use: auto (default), python (pure Python), rust (Rust backend)" ,
4951 )
5052 return parser .parse_args ()
5153
@@ -91,31 +93,35 @@ def main():
9193 # Format ATT(g,t) effects
9294 gt_effects_out = []
9395 for (g , t ), cell in sorted (results .group_time_effects .items ()):
94- gt_effects_out .append ({
95- "cohort" : int (g ),
96- "time" : int (t ),
97- "att" : float (cell ["att" ]),
98- "se" : float (cell ["se" ]),
99- })
96+ gt_effects_out .append (
97+ {
98+ "cohort" : int (g ),
99+ "time" : int (t ),
100+ "att" : float (cell ["att" ]),
101+ "se" : float (cell ["se" ]),
102+ }
103+ )
100104
101105 # Format event study effects
102106 es_effects = []
103107 if results .event_study_effects :
104108 for rel_t , effect_data in sorted (results .event_study_effects .items ()):
105- es_effects .append ({
106- "event_time" : int (rel_t ),
107- "att" : float (effect_data ["att" ]),
108- "se" : float (effect_data ["se" ]),
109- })
109+ es_effects .append (
110+ {
111+ "event_time" : int (rel_t ),
112+ "att" : float (effect_data ["att" ]),
113+ "se" : float (effect_data ["se" ]),
114+ }
115+ )
110116
111117 output = {
112118 "estimator" : "diff_diff.WooldridgeDiD" ,
113119 "method" : "ols" ,
114120 "control_group" : "not_yet_treated" ,
115121 "backend" : actual_backend ,
116122 # Overall ATT
117- "overall_att" : float (results .overall_att ),
118- "overall_se" : float (results .overall_se ),
123+ "overall_att" : float (results .att ),
124+ "overall_se" : float (results .se ),
119125 # Group-time ATT(g,t)
120126 "group_time_effects" : gt_effects_out ,
121127 # Event study
@@ -140,7 +146,7 @@ def main():
140146 with open (output_path , "w" ) as f :
141147 json .dump (output , f , indent = 2 )
142148
143- print (f"Overall ATT: { results .overall_att :.6f} (SE: { results .overall_se :.6f} )" )
149+ print (f"Overall ATT: { results .att :.6f} (SE: { results .se :.6f} )" )
144150 print (f"Completed in { total_time :.3f} seconds" )
145151 return output
146152
0 commit comments