-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from danyoungday/time
Added timeline
- Loading branch information
Showing
26 changed files
with
952 additions
and
538 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
""" | ||
Timeline component. | ||
""" | ||
from collections import defaultdict | ||
|
||
import numpy as np | ||
from dash import html | ||
import yaml | ||
|
||
from enroadspy import load_input_specs | ||
|
||
|
||
class TimelineComponent(): | ||
""" | ||
Component handling generation of a timeline of actions taken. | ||
""" | ||
def __init__(self, actions: list[str]): | ||
self.actions = [a for a in actions] | ||
|
||
# Pre-compute timeline actions for later when we show actions | ||
with open("app/timeline.yaml", "r", encoding="utf-8") as f: | ||
self.timeline = yaml.load(f, Loader=yaml.FullLoader) | ||
self.timeline_actions = [] | ||
for action, details in self.timeline.items(): | ||
self.timeline_actions.append(action) | ||
for d in details.values(): | ||
self.timeline_actions.append(d) | ||
|
||
self.input_specs = load_input_specs() | ||
|
||
def _create_timeline_events(self, | ||
action: str, | ||
details: dict, | ||
context_actions_dict: dict[str, float]) -> dict[int, str]: | ||
""" | ||
Creates 0 or more timeline events for a given action. | ||
We have to manually handle electric standard being active and if this is the final carbon tax as they rely on | ||
other actions. | ||
We also manually handle if the action is a different type of bioenergy | ||
Returns a dict with the year as the key and the event as the value. | ||
""" | ||
# Electric standard needs to be active | ||
if action == "_electric_standard_target" and not context_actions_dict["_electric_standard_active"]: | ||
return {} | ||
# If we're doing subsidy by feedstock ignore the default bio subsidy | ||
if action == "_source_subsidy_delivered_bio_boe" and context_actions_dict["_use_subsidies_by_feedstock"]: | ||
return {} | ||
# If we're not doing subsidy by feedstock ignore the specific feedstock subsidies | ||
if action in ["_wood_feedstock_subsidy_boe", "_crop_feedstock_subsidy_boe", "_other_feedstock_subsidy_boe"] \ | ||
and not context_actions_dict["_use_subsidies_by_feedstock"]: | ||
return {} | ||
|
||
events = {} | ||
row = self.input_specs[self.input_specs["varId"] == action].iloc[0] | ||
name = row["varName"] | ||
decimal = np.ceil(-1 * np.log10(row["step"])).astype(int) | ||
value = context_actions_dict[action] | ||
|
||
start_year = context_actions_dict[details["start"]] | ||
|
||
# Carbon price phasing start date needs to be after previous carbon price phase end date | ||
if action == "_carbon_tax_final_target": | ||
initial_end = context_actions_dict["_carbon_tax_phase_1_start"] + \ | ||
context_actions_dict["_carbon_tax_time_to_achieve_initial_target"] | ||
if start_year < initial_end: | ||
start_year = initial_end | ||
|
||
# Compute the stop year from the length if necessary | ||
if "stop" in details or "length" in details: | ||
stop_year = context_actions_dict[details["stop"]] if "stop" in details else start_year + \ | ||
context_actions_dict[details["length"]] | ||
if start_year < stop_year: | ||
events[int(start_year)] = f"start {name}: {value:.{decimal}f}" | ||
events[int(stop_year)] = f"end {name}" | ||
else: | ||
events[int(start_year)] = f"{name}: {value:.{decimal}f}" | ||
|
||
return events | ||
|
||
def create_timeline_div(self, context_actions_dict: dict[str, float]) -> html.Div: | ||
""" | ||
Creates a nice timeline of actions taken as well as the initial actions taken. | ||
""" | ||
# Generate initial actions | ||
children = [html.H3("Initial Actions")] | ||
for action in context_actions_dict: | ||
if action not in self.timeline_actions and action in self.actions: | ||
input_spec = self.input_specs[self.input_specs["varId"] == action].iloc[0] | ||
val = context_actions_dict[action] | ||
if input_spec["kind"] == "slider": | ||
formatting = input_spec["format"] | ||
val_formatted = f"{val:{formatting}}" | ||
else: | ||
val_formatted = "on" if val else "off" | ||
children.append(html.P(f"{input_spec['varName']}: {val_formatted}")) | ||
|
||
# Generate timeline | ||
timeline = defaultdict(list) | ||
for action, details in self.timeline.items(): | ||
if action in context_actions_dict: | ||
events = self._create_timeline_events(action, details, context_actions_dict) | ||
for year, event in events.items(): | ||
timeline[year].append(event) | ||
|
||
# Sort the timeline by year so that we can display it in order | ||
children.append(html.H3("Timeline")) | ||
for year in sorted(timeline.keys()): | ||
children.append(html.H4(str(year))) | ||
for event in timeline[year]: | ||
children.append(html.P(event)) | ||
|
||
return html.Div(children) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
_source_subsidy_delivered_coal_tce: | ||
type: subsidy | ||
start: _source_subsidy_start_time_delivered_coal | ||
stop: _source_subsidy_stop_time_delivered_coal | ||
_no_new_coal: | ||
type: no_new | ||
start: _year_of_no_new_capacity_coal | ||
_utilization_adjustment_factor_delivered_coal: | ||
type: adjustment | ||
start: _utilization_policy_start_time_delivered_coal | ||
stop: _utilization_policy_stop_time_delivered_coal | ||
_source_subsidy_delivered_oil_boe: | ||
type: subsidy | ||
start: _source_subsidy_start_time_delivered_oil | ||
stop: _source_subsidy_stop_time_delivered_oil | ||
_no_new_oil: | ||
type: no_new | ||
start: _year_of_no_new_capacity_oil | ||
_utilization_adjustment_factor_delivered_oil: | ||
type: adjustment | ||
start: _utilization_policy_start_time_delivered_oil | ||
stop: _utilization_policy_stop_time_delivered_oil | ||
_source_subsidy_delivered_gas_mcf: | ||
type: subsidy | ||
start: _source_subsidy_start_time_delivered_gas | ||
stop: _source_subsidy_stop_time_delivered_gas | ||
_no_new_gas: | ||
type: no_new | ||
start: _year_of_no_new_capacity_gas | ||
_utilization_adjustment_factor_delivered_gas: | ||
type: adjustment | ||
start: _utilization_policy_start_time_delivered_gas | ||
stop: _utilization_policy_stop_time_delivered_gas | ||
_source_subsidy_renewables_kwh: | ||
type: subsidy | ||
start: _source_subsidy_start_time_renewables | ||
stop: _source_subsidy_stop_time_renewables | ||
_source_subsidy_delivered_bio_boe: | ||
type: subsidy | ||
start: _source_subsidy_start_time_delivered_bio | ||
stop: _source_subsidy_stop_time_delivered_bio | ||
_wood_feedstock_subsidy_boe: | ||
type: bio | ||
start: _source_subsidy_start_time_delivered_bio | ||
stop: _source_subsidy_stop_time_delivered_bio | ||
_crop_feedstock_subsidy_boe: | ||
type: bio | ||
start: _source_subsidy_start_time_delivered_bio | ||
stop: _source_subsidy_stop_time_delivered_bio | ||
_other_feedstock_subsidy_boe: | ||
type: bio | ||
start: _source_subsidy_start_time_delivered_bio | ||
stop: _source_subsidy_stop_time_delivered_bio | ||
_no_new_bio: | ||
type: no_new | ||
start: _year_of_no_new_capacity_bio | ||
_source_subsidy_nuclear_kwh: | ||
type: subsidy | ||
start: _source_subsidy_start_time_nuclear | ||
stop: _source_subsidy_stop_time_nuclear | ||
_carbon_tax_initial_target: | ||
type: carbon_tax | ||
start: _carbon_tax_phase_1_start | ||
length: _carbon_tax_time_to_achieve_initial_target | ||
_carbon_tax_final_target: | ||
type: carbon_tax | ||
start: _carbon_tax_phase_3_start | ||
length: _carbon_tax_time_to_achieve_final_target | ||
# Note: we need to see if electric_standard_active is true for this | ||
_electric_standard_target: | ||
start: _electric_standard_start_year | ||
length: _electric_standard_target_time | ||
_emissions_performance_standard: | ||
start: _performance_standard_time | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.