Skip to content

Commit 6b23ec1

Browse files
committed
Remove EnergyPlus mapping functions and tests.
1 parent 69af22f commit 6b23ec1

File tree

3 files changed

+1
-928
lines changed

3 files changed

+1
-928
lines changed

scout/ecm_prep.py

Lines changed: 1 addition & 276 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from pathlib import Path
2121
import argparse
2222
from scout.ecm_prep_args import ecm_args
23-
from scout.ecm_prep_vars import UsefulVars, UsefulInputFiles, EPlusMapDicts
23+
from scout.ecm_prep_vars import UsefulVars, UsefulInputFiles
2424
from scout.utils import JsonIO, PrintFormat as fmt
2525
from scout.config import LogConfig, FilePaths as fp
2626
import traceback
@@ -795,73 +795,6 @@ def __init__(
795795
"mseg_out_break"]["energy"]["efficient-captured"] = \
796796
copy.deepcopy(self.handyvars.out_break_in)
797797

798-
def fill_eplus(self, msegs, eplus_dir, eplus_coltypes,
799-
eplus_files, vintage_weights, base_cols):
800-
"""Fill in measure performance with EnergyPlus simulation results.
801-
802-
Note:
803-
Find the appropriate set of EnergyPlus simulation results for
804-
the current measure, and use the relative savings percentages
805-
in these results to determine the measure performance attribute.
806-
807-
Args:
808-
msegs (dict): Baseline microsegment stock/energy data to use in
809-
validating categorization of measure performance information.
810-
eplus_dir (string): Directory of EnergyPlus performance files.
811-
eplus_coltypes (list): Expected EnergyPlus variable data types.
812-
eplus_files (list): EnergyPlus performance file names.
813-
vintage_weights (dict): Square-footage-derived weighting factors
814-
for each EnergyPlus building vintage type.
815-
816-
Returns:
817-
Updated Measure energy_efficiency, energy_efficiency_source, and
818-
energy_efficiency_source attribute values.
819-
820-
Raises:
821-
ValueError: If EnergyPlus file is not matched to Measure
822-
definition or more than one EnergyPlus file matches the
823-
Measure definition.
824-
"""
825-
# Instantiate useful EnergyPlus-Scout mapping dicts
826-
handydicts = EPlusMapDicts()
827-
# Determine the relevant EnergyPlus building type name(s)
828-
bldg_type_names = []
829-
for x in self.bldg_type:
830-
bldg_type_names.extend(handydicts.bldgtype[x].keys())
831-
# Find all EnergyPlus files including the relevant building type
832-
# name(s)
833-
eplus_perf_in = [(eplus_dir / x) for x in eplus_files if any([
834-
y.lower() in x for y in bldg_type_names])]
835-
836-
# Import EnergyPlus input file as array and use it to fill a dict
837-
# of measure performance data
838-
if len(eplus_perf_in) > 0:
839-
# Assemble the EnergyPlus data into a record array
840-
eplus_perf_array = self.build_array(eplus_coltypes, eplus_perf_in)
841-
# Create a measure performance dictionary, zeroed out, to
842-
# be updated with data from EnergyPlus array
843-
perf_dict_empty = self.create_perf_dict(msegs)
844-
845-
# Update measure performance based on EnergyPlus data
846-
# (* Note: only update efficiency information for
847-
# secondary microsegments if applicable)
848-
if perf_dict_empty['secondary'] is not None:
849-
self.energy_efficiency = self.fill_perf_dict(
850-
perf_dict_empty, eplus_perf_array,
851-
vintage_weights, base_cols, eplus_bldg_types={})
852-
else:
853-
self.energy_efficiency = self.fill_perf_dict(
854-
perf_dict_empty['primary'], eplus_perf_array,
855-
vintage_weights, base_cols, eplus_bldg_types={})
856-
# Set the energy efficiency data source for the measure to
857-
# EnergyPlus and set to highest data quality rating
858-
self.energy_efficiency_source = 'EnergyPlus/OpenStudio'
859-
else:
860-
raise ValueError(
861-
"Failure to find relevant EPlus files for " +
862-
"Scout building type(s) " + str(self.bldg_type) +
863-
"in ECM '" + self.name + "'")
864-
865798
def fill_mkts(self, msegs, msegs_cpl, convert_data, tsv_data_init, opts,
866799
ctrb_ms_pkg_prep, tsv_data_nonfs):
867800
"""Fill in a measure's market microsegments using EIA baseline data.
@@ -8696,214 +8629,6 @@ def rand_list_gen(self, distrib_info, nsamples):
86968629

86978630
return rand_list
86988631

8699-
def fill_perf_dict(
8700-
self, perf_dict, eplus_perf_array, vintage_weights,
8701-
base_cols, eplus_bldg_types):
8702-
"""Fill an empty dict with updated measure performance information.
8703-
8704-
Note:
8705-
Use structured array data drawn from an EnergyPlus output file
8706-
and building type/vintage weighting data to fill a dictionary of
8707-
final measure performance information.
8708-
8709-
Args:
8710-
perf_dict (dict): Empty dictionary to fill with EnergyPlus-based
8711-
performance information broken down by climate zone, building
8712-
type/vintage, fuel type, and end use.
8713-
eplus_perf_array (numpy recarray): Structured array of EnergyPlus
8714-
energy savings information for the Measure.
8715-
vintage_weights (dict): Square-footage-derived weighting factors
8716-
for each EnergyPlus building vintage type.
8717-
eplus_bldg_types (dict): Scout-EnergyPlus building type mapping
8718-
data, including weighting factors needed to map multiple
8719-
EnergyPlus building types to a single Scout building type.
8720-
Drawn from EPlusMapDicts object's 'bldgtype' attribute.
8721-
8722-
Returns:
8723-
A measure performance dictionary filled with relative energy
8724-
savings values from an EnergyPlus simulation output file.
8725-
8726-
Raises:
8727-
KeyError: If an EnergyPlus category name cannot be mapped to the
8728-
input perf_dict keys.
8729-
ValueError: If weights used to map multiple EnergyPlus reference
8730-
building types to a single Scout building type do not sum to 1.
8731-
"""
8732-
# Instantiate useful EnergyPlus-Scout mapping dicts
8733-
handydicts = EPlusMapDicts()
8734-
8735-
# Set the header of the EnergyPlus input array (used when reducing
8736-
# columns of the array to the specific performance categories being
8737-
# updated below)
8738-
eplus_header = list(eplus_perf_array.dtype.names)
8739-
8740-
# Loop through zeroed out measure performance dictionary input and
8741-
# update the values with data from the EnergyPlus input array
8742-
for key, item in perf_dict.items():
8743-
# If current dict item is itself a dict, reduce EnergyPlus array
8744-
# based on the current dict key and proceed further down the dict
8745-
# levels
8746-
if isinstance(item, dict):
8747-
# Microsegment type level (no update to EnergyPlus array
8748-
# required)
8749-
if key in ['primary', 'secondary']:
8750-
updated_perf_array = eplus_perf_array
8751-
# Climate zone level
8752-
elif key in handydicts.czone.keys():
8753-
# Reduce EnergyPlus array to only rows with climate zone
8754-
# currently being updated in the performance dictionary
8755-
updated_perf_array = eplus_perf_array[numpy.where(
8756-
eplus_perf_array[
8757-
'climate_zone'] == handydicts.czone[key])].copy()
8758-
if len(updated_perf_array) == 0:
8759-
raise KeyError(
8760-
"EPlus climate zone name not found for ECM '" +
8761-
self.name + "'")
8762-
# Building type level
8763-
elif key in handydicts.bldgtype.keys():
8764-
# Determine relevant EnergyPlus building types for current
8765-
# Scout building type
8766-
eplus_bldg_types = handydicts.bldgtype[key]
8767-
if sum(eplus_bldg_types.values()) != 1:
8768-
raise ValueError(
8769-
"EPlus building type weights do not sum to 1 "
8770-
"for ECM '" + self.name + "'")
8771-
# Reduce EnergyPlus array to only rows with building type
8772-
# relevant to current Scout building type
8773-
updated_perf_array = eplus_perf_array[numpy.in1d(
8774-
eplus_perf_array['building_type'],
8775-
list(eplus_bldg_types.keys()))].copy()
8776-
if len(updated_perf_array) == 0:
8777-
raise KeyError(
8778-
"EPlus building type name not found for ECM '" +
8779-
self.name + "'")
8780-
# Fuel type level
8781-
elif key in handydicts.fuel.keys():
8782-
# Reduce EnergyPlus array to only columns with fuel type
8783-
# currently being updated in the performance dictionary,
8784-
# plus bldg. type/vintage, climate, and measure columns
8785-
colnames = base_cols + [
8786-
x for x in eplus_header if handydicts.fuel[key] in x]
8787-
if len(colnames) == len(base_cols):
8788-
raise KeyError(
8789-
"EPlus fuel type name not found for ECM '" +
8790-
self.name + "'")
8791-
updated_perf_array = eplus_perf_array[colnames].copy()
8792-
# End use level
8793-
elif key in handydicts.enduse.keys():
8794-
# Reduce EnergyPlus array to only columns with end use
8795-
# currently being updated in the performance dictionary,
8796-
# plus bldg. type/vintage, climate, and measure columns
8797-
colnames = base_cols + [
8798-
x for x in eplus_header if x in handydicts.enduse[
8799-
key]]
8800-
if len(colnames) == len(base_cols):
8801-
raise KeyError(
8802-
"EPlus end use name not found for ECM '" +
8803-
self.name + "'")
8804-
updated_perf_array = eplus_perf_array[colnames].copy()
8805-
else:
8806-
raise KeyError(
8807-
"Invalid performance dict key for ECM '" +
8808-
self.name + "'")
8809-
8810-
# Given updated EnergyPlus array, proceed further down the
8811-
# dict level hierarchy
8812-
self.fill_perf_dict(
8813-
item, updated_perf_array, vintage_weights,
8814-
base_cols, eplus_bldg_types)
8815-
else:
8816-
# Reduce EnergyPlus array to only rows with structure type
8817-
# currently being updated in the performance dictionary
8818-
# ('new' or 'retrofit')
8819-
if key in handydicts.structure_type.keys():
8820-
# A 'new' structure type will match only one of the
8821-
# EnergyPlus building vintage names
8822-
if key == "new":
8823-
updated_perf_array = eplus_perf_array[numpy.where(
8824-
eplus_perf_array['template'] ==
8825-
handydicts.structure_type['new'])].copy()
8826-
# A 'retrofit' structure type will match multiple
8827-
# EnergyPlus building vintage names
8828-
else:
8829-
updated_perf_array = eplus_perf_array[numpy.in1d(
8830-
eplus_perf_array['template'], list(
8831-
handydicts.structure_type[
8832-
'retrofit'].keys()))].copy()
8833-
if len(updated_perf_array) == 0 or \
8834-
(key == "new" and
8835-
len(numpy.unique(updated_perf_array[
8836-
'template'])) != 1 or key == "retrofit" and
8837-
len(numpy.unique(updated_perf_array[
8838-
'template'])) != len(
8839-
handydicts.structure_type["retrofit"].keys())):
8840-
raise ValueError(
8841-
"EPlus vintage name not found for ECM '" +
8842-
self.name + "'")
8843-
else:
8844-
raise KeyError(
8845-
"Invalid performance dict key for ECM '" +
8846-
self.name + "'")
8847-
8848-
# Separate filtered array into the rows representing measure
8849-
# consumption and those representing baseline consumption
8850-
updated_perf_array_m, updated_perf_array_b = [
8851-
updated_perf_array[updated_perf_array[
8852-
'measure'] != 'none'],
8853-
updated_perf_array[updated_perf_array[
8854-
'measure'] == 'none']]
8855-
# Ensure that a baseline consumption row exists for every
8856-
# measure consumption row retrieved
8857-
if len(updated_perf_array_m) != len(updated_perf_array_b):
8858-
raise ValueError(
8859-
"Lengths of ECM and baseline EPlus data arrays "
8860-
"are unequal for ECM '" + self.name + "'")
8861-
# Initialize total measure and baseline consumption values
8862-
val_m, val_b = (0 for n in range(2))
8863-
8864-
# Weight and combine the measure/baseline consumption values
8865-
# left in the EnergyPlus arrays; subtract total measure
8866-
# consumption from baseline consumption and divide by baseline
8867-
# consumption to reach relative savings value for the current
8868-
# dictionary branch
8869-
for ind in range(0, len(updated_perf_array_m)):
8870-
row_m, row_b = [
8871-
updated_perf_array_m[ind], updated_perf_array_b[ind]]
8872-
# Loop through remaining columns with consumption data
8873-
for n in eplus_header:
8874-
if row_m[n].dtype.char != 'S' and \
8875-
row_m[n].dtype.char != 'U':
8876-
# Find appropriate building type to weight
8877-
# consumption data points by
8878-
eplus_bldg_type_wt_row_m, \
8879-
eplus_bldg_type_wt_row_b = [
8880-
eplus_bldg_types[row_m['building_type']],
8881-
eplus_bldg_types[row_b['building_type']]]
8882-
# Weight consumption data points by factors for
8883-
# appropriate building type and vintage
8884-
row_m_val, row_b_val = [(
8885-
row_m[n] * eplus_bldg_type_wt_row_m *
8886-
vintage_weights[row_m['template'].copy()]),
8887-
(row_b[n] * eplus_bldg_type_wt_row_b *
8888-
vintage_weights[row_b['template'].copy()])]
8889-
# Add weighted measure consumption data point to
8890-
# total measure consumption
8891-
val_m += row_m_val
8892-
# Add weighted baseline consumption data point to
8893-
# total base consumption
8894-
val_b += row_b_val
8895-
# Find relative savings if total baseline use != zero
8896-
if val_b != 0:
8897-
end_key_val = (val_b - val_m) / val_b
8898-
else:
8899-
end_key_val = 0
8900-
8901-
# Update the current dictionary branch value to the final
8902-
# measure relative savings value derived above
8903-
perf_dict[key] = round(end_key_val, 3)
8904-
8905-
return perf_dict
8906-
89078632
def create_perf_dict(self, msegs):
89088633
"""Create dict to fill with updated measure performance information.
89098634

scout/ecm_prep_vars.py

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,90 +1699,3 @@ def get_suffix(arg):
16991699
f"tsv_carbon-{opts.alt_regions.lower()}-MidCase.json")
17001700
self.ss_data_nonfs, self.tsv_cost_data_nonfs, \
17011701
self.tsv_carbon_data_nonfs = (None for n in range(3))
1702-
1703-
1704-
class EPlusMapDicts(object):
1705-
"""Class of dicts used to map Scout measure definitions to EnergyPlus.
1706-
1707-
Attributes:
1708-
czone (dict): Scout-EnergyPlus climate zone mapping.
1709-
bldgtype (dict): Scout-EnergyPlus building type mapping. Shown are
1710-
the EnergyPlus commercial reference building names that correspond
1711-
to each AEO commercial building type, and the weights needed in
1712-
some cases to map multiple EnergyPlus reference building types to
1713-
a single AEO type. See 'convert_data' JSON for more details.
1714-
fuel (dict): Scout-EnergyPlus fuel type mapping.
1715-
enduse (dict): Scout-EnergyPlus end use mapping.
1716-
structure_type (dict): Scout-EnergyPlus structure type mapping.
1717-
"""
1718-
1719-
def __init__(self):
1720-
self.czone = {
1721-
"sub arctic": "BA-SubArctic",
1722-
"very cold": "BA-VeryCold",
1723-
"cold": "BA-Cold",
1724-
"marine": "BA-Marine",
1725-
"mixed humid": "BA-MixedHumid",
1726-
"mixed dry": "BA-MixedDry",
1727-
"hot dry": "BA-HotDry",
1728-
"hot humid": "BA-HotHumid"}
1729-
self.bldgtype = {
1730-
"assembly": {
1731-
"Hospital": 1},
1732-
"education": {
1733-
"PrimarySchool": 0.26,
1734-
"SecondarySchool": 0.74},
1735-
"food sales": {
1736-
"Supermarket": 1},
1737-
"food service": {
1738-
"QuickServiceRestaurant": 0.31,
1739-
"FullServiceRestaurant": 0.69},
1740-
"health care": None,
1741-
"lodging": {
1742-
"SmallHotel": 0.26,
1743-
"LargeHotel": 0.74},
1744-
"large office": {
1745-
"LargeOfficeDetailed": 0.9,
1746-
"MediumOfficeDetailed": 0.1},
1747-
"small office": {
1748-
"SmallOffice": 0.12,
1749-
"OutpatientHealthcare": 0.88},
1750-
"mercantile/service": {
1751-
"RetailStandalone": 0.53,
1752-
"RetailStripmall": 0.47},
1753-
"warehouse": {
1754-
"Warehouse": 1},
1755-
"other": None,
1756-
"unspecified": None}
1757-
self.fuel = {
1758-
'electricity': 'electricity',
1759-
'natural gas': 'gas',
1760-
'distillate': 'other_fuel'}
1761-
self.enduse = {
1762-
'heating': [
1763-
'heating_electricity', 'heat_recovery_electricity',
1764-
'humidification_electricity', 'pump_electricity',
1765-
'heating_gas', 'heating_other_fuel'],
1766-
'cooling': [
1767-
'cooling_electricity', 'pump_electricity',
1768-
'heat_rejection_electricity'],
1769-
'water heating': [
1770-
'service_water_heating_electricity',
1771-
'service_water_heating_gas',
1772-
'service_water_heating_other_fuel'],
1773-
'ventilation': ['fan_electricity'],
1774-
'cooking': [
1775-
'interior_equipment_gas', 'interior_equipment_other_fuel'],
1776-
'lighting': ['interior_lighting_electricity'],
1777-
'refrigeration': ['refrigeration_electricity'],
1778-
'PCs': ['interior_equipment_electricity'],
1779-
'non-PC office equipment': ['interior_equipment_electricity'],
1780-
'MELs': ['interior_equipment_electricity']}
1781-
# Note: assumed year range for each structure vintage shown in lists
1782-
self.structure_type = {
1783-
"new": '90.1-2013',
1784-
"retrofit": {
1785-
'90.1-2004': [2004, 2009],
1786-
'90.1-2010': [2010, 2012],
1787-
'DOE Ref 1980-2004': [1980, 2003],
1788-
'DOE Ref Pre-1980': [0, 1979]}}

0 commit comments

Comments
 (0)