Skip to content

Commit 12f148e

Browse files
committed
Remove EnergyPlus mapping functions and tests.
1 parent b7cf7cf commit 12f148e

File tree

3 files changed

+1
-927
lines changed

3 files changed

+1
-927
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
@@ -779,73 +779,6 @@ def __init__(
779779
"mseg_out_break"]["energy"]["efficient-captured"] = \
780780
copy.deepcopy(self.handyvars.out_break_in)
781781

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

86818614
return rand_list
86828615

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

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)