3737CPS = "hf://policyengine/policyengine-us-data/cps_2023.h5"
3838POOLED_CPS = "hf://policyengine/policyengine-us-data/pooled_3_year_cps_2023.h5"
3939
40- check_against_api_v2 = (
41- os .environ .get ("GOOGLE_APPLICATION_CREDENTIALS" ) is not None
42- )
40+ use_api_v2 = os .environ .get ("GOOGLE_APPLICATION_CREDENTIALS" ) is not None
4341
44- if not check_against_api_v2 :
42+ if not use_api_v2 :
4543 logging .warn (
46- "Didn't find any GOOGLE_APPLICATION_CREDENTIALS, so will not check results for matches against APIv2."
44+ "Didn't find any GOOGLE_APPLICATION_CREDENTIALS, so will not use APIv2."
4745 )
4846
4947
5048class CalculateEconomySimulationJob (BaseJob ):
5149 def __init__ (self ):
5250 super ().__init__ ()
53- if check_against_api_v2 :
51+ if use_api_v2 :
5452 self .api_v2 = SimulationAPIv2 ()
5553
5654 def run (
@@ -152,7 +150,7 @@ def run(
152150 comment ("Computing baseline" )
153151
154152 # Kick off APIv2 job
155- if check_against_api_v2 :
153+ if use_api_v2 :
156154 input_data = {
157155 "country" : country_id ,
158156 "scope" : "macro" ,
@@ -162,51 +160,35 @@ def run(
162160 }
163161 execution = self .api_v2 .run (input_data )
164162
165- # Compute baseline economy
166- baseline_economy = self ._compute_economy (
167- country_id = country_id ,
168- region = region ,
169- dataset = dataset ,
170- time_period = time_period ,
171- options = options ,
172- policy_json = baseline_policy ,
173- )
174- comment ("Computing reform" )
175-
176- # Compute reform economy
177- reform_economy = self ._compute_economy (
178- country_id = country_id ,
179- region = region ,
180- dataset = dataset ,
181- time_period = time_period ,
182- options = options ,
183- policy_json = reform_policy ,
184- )
185-
186- baseline_economy = baseline_economy ["result" ]
187- reform_economy = reform_economy ["result" ]
188- comment ("Comparing baseline and reform" )
189- impact = compare_economic_outputs (
190- baseline_economy , reform_economy , country_id = country_id
191- )
163+ impact = self .api_v2 .wait_for_completion (execution )
164+ else :
165+ # Compute baseline economy
166+ baseline_economy = self ._compute_economy (
167+ country_id = country_id ,
168+ region = region ,
169+ dataset = dataset ,
170+ time_period = time_period ,
171+ options = options ,
172+ policy_json = baseline_policy ,
173+ )
174+ comment ("Computing reform" )
192175
193- # Wait for APIv2 job to complete
194- if check_against_api_v2 :
195- result = self .api_v2 .wait_for_completion (execution )
196- if result is None :
197- print ("APIv2 COMPARISON failed: result is not JSON." )
198- else :
199- try :
200- print (
201- f"APIv2 COMPARISON: match={ is_similar (result , json .loads (json .dumps (impact )))} "
202- )
203- except :
204- print ("APIv2 COMPARISON: ERROR COMPARING" , result )
176+ # Compute reform economy
177+ reform_economy = self ._compute_economy (
178+ country_id = country_id ,
179+ region = region ,
180+ dataset = dataset ,
181+ time_period = time_period ,
182+ options = options ,
183+ policy_json = reform_policy ,
184+ )
205185
206- if options .get ("apiv2" , False ):
207- # If the APIv2 job was successful, use its result
208- if result is not None :
209- impact = result
186+ baseline_economy = baseline_economy ["result" ]
187+ reform_economy = reform_economy ["result" ]
188+ comment ("Comparing baseline and reform" )
189+ impact = compare_economic_outputs (
190+ baseline_economy , reform_economy , country_id = country_id
191+ )
210192
211193 # Finally, update all reform impact rows with the same baseline and reform policy IDs
212194 reform_impacts_service .set_complete_reform_impact (
@@ -468,79 +450,6 @@ def _compute_cliff_impacts(self, simulation: Microsimulation) -> Dict:
468450 }
469451
470452
471- def is_similar (x , y , parent_name : str = "" ) -> bool :
472- if x is None or x == {}:
473- if y is None or y == {}:
474- return True
475- # Handle None values
476- if x is None or y is None :
477- equal = x is y
478- if not equal :
479- print (f"Not equal: { x } vs { y } in { parent_name } " )
480- return equal
481-
482- # Handle different types
483- if type (x ) != type (y ):
484- if float in ((type (x ), type (y ))) and int in ((type (x ), type (y ))):
485- pass
486- else :
487- print (f"Different types: { type (x )} vs { type (y )} in { parent_name } " )
488- return False
489-
490- # Handle numeric values
491- if isinstance (x , (int , float )):
492- close = (abs (y - x ) < 1e-2 ) or (abs (y - x ) / abs (x ) < 0.01 )
493- if not close :
494- print (f"Not close: { x } vs { y } in { parent_name } " )
495- return close
496-
497- # Handle boolean values
498- elif isinstance (x , bool ):
499- equal = x == y
500- if not equal :
501- print (f"Not equal: { x } vs { y } in { parent_name } " )
502- return equal
503-
504- # Handle string values
505- elif isinstance (x , str ):
506- equal = x == y
507- if not equal :
508- print (f"Not equal: { x } vs { y } in { parent_name } " )
509- return equal
510-
511- # Handle dictionaries
512- elif isinstance (x , dict ):
513- # Check for keys in both dictionaries
514- all_keys = set (x .keys ()) | set (y .keys ())
515- for k in all_keys :
516- if k not in x :
517- print (f"Key { k } missing in first dict in { parent_name } " )
518- return False
519- if k not in y :
520- print (f"Key { k } missing in second dict in { parent_name } " )
521- return False
522- if not is_similar (x [k ], y [k ], parent_name = parent_name + "/" + k ):
523- return False
524- return True
525-
526- # Handle lists
527- elif isinstance (x , list ):
528- if len (x ) != len (y ):
529- print (f"Different lengths: { len (x )} vs { len (y )} in { parent_name } " )
530- return False
531- return all (
532- is_similar (x [i ], y [i ], parent_name = parent_name + f"[{ i } ]" )
533- for i in range (len (x ))
534- )
535-
536- # Handle other types
537- else :
538- equal = x == y
539- if not equal :
540- print (f"Not equal: { x } vs { y } in { parent_name } " )
541- return equal
542-
543-
544453class SimulationAPIv2 :
545454 project : str
546455 location : str
0 commit comments