Skip to content

Commit 7a8fa15

Browse files
committed
Baseline simulation created before simulation modifier is applied
1 parent 041fd88 commit 7a8fa15

2 files changed

Lines changed: 20 additions & 40 deletions

File tree

changelog_entry.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- bump: minor
2+
changes:
3+
fixed:
4+
- Baseline simulation created before simulation modifier is applied.

policyengine_uk/simulation.py

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ def __init__(
8080
self.invalidated_caches = set()
8181
self.debug: bool = False
8282
self.trace: bool = trace
83-
self.tracer: SimpleTracer = (
84-
SimpleTracer() if not trace else FullTracer()
85-
)
83+
self.tracer: SimpleTracer = SimpleTracer() if not trace else FullTracer()
8684
self.opt_out_cache: bool = False
8785
self.max_spiral_loops: int = 10
8886
self.memory_config = None
@@ -125,10 +123,6 @@ def __init__(
125123
self.move_values("capital_gains", "capital_gains_before_response")
126124
self.move_values("employment_income", "employment_income_before_lsr")
127125

128-
if scenario is not None:
129-
if scenario.simulation_modifier is not None:
130-
scenario.simulation_modifier(self)
131-
132126
if scenario is not None:
133127
self.baseline = Simulation(
134128
scenario=None,
@@ -139,6 +133,10 @@ def __init__(
139133
else:
140134
self.baseline = self.clone()
141135

136+
if scenario is not None:
137+
if scenario.simulation_modifier is not None:
138+
scenario.simulation_modifier(self)
139+
142140
self.calculated_periods = []
143141

144142
def reset_calculations(self):
@@ -157,9 +155,7 @@ def apply_parameter_changes(self, changes: dict):
157155
self.tax_benefit_system.reset_parameters()
158156

159157
for parameter in changes:
160-
p: Parameter = self.tax_benefit_system.parameters.get_child(
161-
parameter
162-
)
158+
p: Parameter = self.tax_benefit_system.parameters.get_child(parameter)
163159
if isinstance(changes[parameter], dict):
164160
# Time-period specific changes
165161
for time_period in changes[parameter]:
@@ -178,9 +174,7 @@ def build_from_situation(self, situation: Dict) -> None:
178174
Args:
179175
situation: Dictionary describing household composition and characteristics
180176
"""
181-
self.build_from_populations(
182-
self.tax_benefit_system.instantiate_entities()
183-
)
177+
self.build_from_populations(self.tax_benefit_system.instantiate_entities())
184178
from policyengine_core.simulations.simulation_builder import (
185179
SimulationBuilder,
186180
) # Import here to avoid circular dependency
@@ -204,9 +198,7 @@ def build_from_url(self, url: str) -> None:
204198
ValueError: If URL is not a HuggingFace URL
205199
"""
206200
if "hf://" not in url:
207-
raise ValueError(
208-
f"Non-HuggingFace URLs are currently not supported."
209-
)
201+
raise ValueError(f"Non-HuggingFace URLs are currently not supported.")
210202

211203
# Parse HuggingFace URL components
212204
owner, repo, filename = url.split("/")[-3:]
@@ -284,9 +276,7 @@ def build_from_dataset(self, dataset: Dataset) -> None:
284276
Args:
285277
dataset: PolicyEngine Dataset object containing simulation data
286278
"""
287-
data: Dict[str, Dict[str, Union[float, int, str]]] = (
288-
dataset.load_dataset()
289-
)
279+
data: Dict[str, Dict[str, Union[float, int, str]]] = dataset.load_dataset()
290280

291281
first_variable = data[list(data.keys())[0]]
292282
first_time_period = list(first_variable.keys())[0]
@@ -315,9 +305,7 @@ def get_first_array(variable_name: str) -> np.ndarray:
315305
for time_period in data[variable]:
316306
if variable not in self.tax_benefit_system.variables:
317307
continue
318-
self.set_input(
319-
variable, time_period, data[variable][time_period]
320-
)
308+
self.set_input(variable, time_period, data[variable][time_period])
321309

322310
# Now convert to the new UKSingleYearDataset
323311
self.input_variables = self.get_known_variables()
@@ -330,9 +318,7 @@ def get_first_array(variable_name: str) -> np.ndarray:
330318
self.build_from_multi_year_dataset(multi_year_dataset)
331319
self.dataset = multi_year_dataset
332320

333-
def build_from_single_year_dataset(
334-
self, dataset: UKSingleYearDataset
335-
) -> None:
321+
def build_from_single_year_dataset(self, dataset: UKSingleYearDataset) -> None:
336322
"""Build simulation from a single-year UK dataset.
337323
338324
Args:
@@ -343,9 +329,7 @@ def build_from_single_year_dataset(
343329
self.build_from_multi_year_dataset(dataset)
344330
self.dataset = dataset
345331

346-
def build_from_multi_year_dataset(
347-
self, dataset: UKMultiYearDataset
348-
) -> None:
332+
def build_from_multi_year_dataset(self, dataset: UKMultiYearDataset) -> None:
349333
"""Build simulation from a multi-year UK dataset.
350334
351335
Args:
@@ -506,9 +490,7 @@ def get_variable_dependencies(self, variable_name: str, depth: int = 1):
506490
trace=True,
507491
)
508492
self._example_simulation.calculate("hbai_household_net_income")
509-
for (
510-
variable
511-
) in self._example_simulation.tax_benefit_system.variables:
493+
for variable in self._example_simulation.tax_benefit_system.variables:
512494
try:
513495
dependencies = get_variable_dependencies(
514496
variable, self._example_simulation
@@ -529,9 +511,7 @@ def get_variable_dependencies(self, variable_name: str, depth: int = 1):
529511
all_dependencies = set(dependencies)
530512
for dep in dependencies:
531513
try:
532-
sub_dependencies = self.get_variable_dependencies(
533-
dep, depth - 1
534-
)
514+
sub_dependencies = self.get_variable_dependencies(dep, depth - 1)
535515
all_dependencies.update(sub_dependencies)
536516
except ValueError:
537517
continue
@@ -562,13 +542,9 @@ def compare(
562542
df_self = self.calculate_dataframe(variables, period=period)
563543
df_other = other.calculate_dataframe(variables, period=period)
564544

565-
df_combined = pd.concat(
566-
[df_self, df_other], axis=1, keys=["self", "other"]
567-
)
545+
df_combined = pd.concat([df_self, df_other], axis=1, keys=["self", "other"])
568546
# Reset columns, then order by variable name first then self/other
569-
df_combined.columns = [
570-
f"{var}_{entity}" for entity, var in df_combined.columns
571-
]
547+
df_combined.columns = [f"{var}_{entity}" for entity, var in df_combined.columns]
572548
# Add change where applicable (numeric only)
573549
for variable in variables:
574550
self_col = f"{variable}_self"

0 commit comments

Comments
 (0)