From bb43039209bf41c7b2594911ee1c6318100f3383 Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Tue, 21 Apr 2020 15:47:37 -0700 Subject: [PATCH 1/2] feat: compare Grid equality --- powersimdata/input/grid.py | 73 +++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/powersimdata/input/grid.py b/powersimdata/input/grid.py index 592478fa8..a9099455f 100644 --- a/powersimdata/input/grid.py +++ b/powersimdata/input/grid.py @@ -4,7 +4,7 @@ from powersimdata.input.usa_tamu_model import TAMU from powersimdata.input.mat_reader import REISEMATReader from powersimdata.input.grid_fields \ - import Branch, Bus, DCLine, GenCost, Plant, Storage, Sub + import AbstractGridField, Branch, Bus, DCLine, GenCost, Plant, Storage, Sub class Grid(object): @@ -117,6 +117,77 @@ def __getitem__(self, field_name): except KeyError as e: print(e) + def __eq__(self, other): + """Used when 'self == other' is evaluated. + :param object other: other object to be compared against. + :return: (*bool*). + """ + def _univ_eq(ref, test): + """Check for {boolean, dataframe, or column data} equality. + :param object ref: one object to be tested (order does not matter). + :param object test: another object to be tested. + :raises AssertionError: if no equality can be confirmed. + """ + try: + test_eq = ref == test + if isinstance(test_eq, (bool, dict)): + assert test_eq + else: + assert test_eq.all().all() + except ValueError: + assert set(ref.columns) == set(test.columns) + for col in ref.columns: + assert (ref[col] == test[col]).all() + + if not isinstance(other, Grid): + err_msg = 'Unable to compare Grid & %s' % type(other).__name__ + raise NotImplementedError(err_msg) + assert self.fields.keys() == other.fields.keys() + assert self.transform.keys() == other.transform.keys() + # Check all AbstractGridField attributes + try: + for k, v in self.fields.items(): + if isinstance(v, GenCost): + # Comparing 'after' will fail if one Grid was linearized + self_data = self.fields[k].data['before'] + other_data = other.fields[k].data['before'] + _univ_eq(self_data, other_data) + elif isinstance(v, Storage): + self_storage_num = len(self.fields[k].data['gencost']) + other_storage_num = len(other.fields[k].data['gencost']) + if self_storage_num == 0: + assert other_storage_num == 0 + continue + # These are dicts, so we need to go one level deeper + self_keys = self.fields[k].data.keys() + other_keys = other.fields[k].data.keys() + assert self_keys == other_keys + for subkey in self_keys: + self_data = self.fields[k].data[subkey] + other_data = other.fields[k].data[subkey] + _univ_eq(self_data, other_data) + elif isinstance(v, Bus): + # MOST changes BUS_TYPE for buses with DC Lines attached + self_df = self.fields[k].data.drop('type', axis=1) + other_df = other.fields[k].data.drop('type', axis=1) + _univ_eq(self_df, other_df) + elif isinstance(v, Plant): + # REISE does some modifications to Plant data + excluded_cols = ['status', 'Pmin', 'ramp_10', 'ramp_30'] + self_df = self.fields[k].data.drop(excluded_cols, axis=1) + other_df = other.fields[k].data.drop(excluded_cols, axis=1) + _univ_eq(self_df, other_df) + elif isinstance(v, AbstractGridField): + _univ_eq(self.fields[k].data, other.fields[k].data) + else: + _univ_eq(self.fields[k], other.fields[k]) + # Check the transform attributes + for k, v in self.transform.items(): + _univ_eq(self.transform[k], other.transform[k]) + except: + return False + return True + def get_type2color(): """Defines generator type to generator color mapping. Used for plotting. From 32d8c636c8e0d0feb6298c3fffe838aa7de887c9 Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Tue, 21 Apr 2020 19:14:04 -0700 Subject: [PATCH 2/2] fix: transposed loss_zone and baseKV in col_name_bus --- powersimdata/input/mat_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powersimdata/input/mat_reader.py b/powersimdata/input/mat_reader.py index 0423a51e3..ecce41f6d 100644 --- a/powersimdata/input/mat_reader.py +++ b/powersimdata/input/mat_reader.py @@ -208,7 +208,7 @@ def column_name_provider(): 'name', 'interconnect_sub_id', 'lat', 'lon', 'interconnect'] col_name_bus = [ 'bus_id', 'type', 'Pd', 'Qd', 'Gs', 'Bs', 'zone_id', 'Vm', 'Va', - 'loss_zone', 'baseKV', 'Vmax', 'Vmin', 'lam_P', 'lam_Q', 'mu_Vmax', + 'baseKV', 'loss_zone', 'Vmax', 'Vmin', 'lam_P', 'lam_Q', 'mu_Vmax', 'mu_Vmin'] col_name_bus2sub = ['sub_id', 'interconnect'] col_name_branch = [