Based on the requirement of the demand allocation module, it seems better to encapsulate the demand allocation algorithm into a class object rather than creating individual functions as the number of arguments keep on increasing in every subsequent function.
The major idea behind the demand allocation class is to encapsulate the various attributes: the collection of dataframes being merged, the collection of geodataframes being disaggregated with the original ba_county_map (mapping of service territories with the counties), the attributes dictionary which keeps track of uniform and constant features. I will define the class structure below: with pointers on how I want to define each function and attribute. Please tell me if there are new functions which should be added, or something that is not clear. @ezwelty, @zaneselvans
class DemandSpaceTimeSeries:
def __init__(self):
# Initialize the service territory timeseries dataframe
self.pa_demand_df = pudl_out.demand_hourly_pa_ferc714()
# Initialize the county-demand mapping geodataframe
ferc714_out = pudl.output.ferc714.Respondents(pudl_out)
self.ba_county_map = ferc714_out.georef_counties()
# List of dataframes which will be merged with the county-demand mapping geodataframe
# Each dataframe will add new attributes to the timeseries dataframe, thus it needs to have common keys
self._join_df_list = []
# List of geodataframes which will be disaggregated with the county-demand mapping layer
# Each geodataframe will add new attributes to the timeseries dataframe (needs to have geometry column)
self._sjoin_gdf_list = []
# Dictionary to keep track of columns in all dataframes on constant and uniform attributes
self.attributes = dict()
return
def add_df(self, df, uniform_list):
## 1. drop geometry column, if exists
## 2. check df common columns with ba county map are superset of ba_county_map
## 3. check df common columns indexable and no duplicates()
## 4. check attribute collision
## 5. add to list
## 6. add columns to attribute dict
return
def add_gdf(self, gdf_list, uniform_list):
## 1. check no common columns except geometry (otherwise column names)
## 2. add to list
## 3. add columns to attribute dict
return
def del_df(self, index):
## remove df by list index
## update attributes
return
def del_gdf(self, index):
## remove gdf by list index
## update attributes
return
def get_df(self):
## return list of dataframes
return
def get_gdf(self):
## return list of geodataframes
return
def _annual_demand_space_time(self, reporting_year):
## 1. return clean version of pa_time_series | ba_county_map for 1 year
## 2. Done for one reporting year every time as the mapping changes every year
return
def _allocate_demand_annual(self, reporting_year, allocators, aggregators):
## 1. allocate demand for an individual reporting year
## 2. Done for one reporting year every time as the mapping changes every year
## 3. return timeseries, geometries
return
def allocate_demand(self, start_year, end_year, allocators, aggregators, localize):
## 1. run _allocate_demand_annual for each year
## 2. stitch all demand allocations together in one dataframe,
## 3. Provide new geometries for every year with aggregator columns, reporting_year together
## 3. All the allocations and aggregations done in utc_datetime. After the aggregation, the timeseries
## can be localized based on centroid of each of the aggregated geometry positions
return
Based on the requirement of the demand allocation module, it seems better to encapsulate the demand allocation algorithm into a class object rather than creating individual functions as the number of arguments keep on increasing in every subsequent function.
The major idea behind the demand allocation class is to encapsulate the various attributes: the collection of dataframes being merged, the collection of geodataframes being disaggregated with the original
ba_county_map
(mapping of service territories with the counties), the attributes dictionary which keeps track ofuniform
andconstant
features. I will define the class structure below: with pointers on how I want to define each function and attribute. Please tell me if there are new functions which should be added, or something that is not clear. @ezwelty, @zaneselvans