Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComStock! #65

Merged
merged 80 commits into from May 20, 2020
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
fc4c041
Add todo noting use of unit specifications in commercial results.
rHorsey Jun 24, 2019
65e6329
Enable setting of OS_VERSION and OS_SHA through the yml.
rHorsey Jun 24, 2019
eda0f5a
Enable specification of the singularity image and path from the yml f…
rHorsey Jun 24, 2019
fbdbd76
Check singularity container download status code in case of 404, 501,…
rHorsey Jun 24, 2019
2990efe
Adding catch in run_batch to ensure that results are only ever overwr…
rHorsey Jun 24, 2019
5bcd369
Add support for custom (non-linked) gems in the singularity container…
rHorsey Jun 24, 2019
37cb2f9
Adding default commercial workflow generator.
rHorsey Jun 24, 2019
48b1873
Updates to the commercial sobol sampler.
rHorsey Jun 24, 2019
44f59cf
Additional updates to the commercial sobol sampler.
rHorsey Jun 24, 2019
0bc880c
Add support for precomputed buildstock.csv files as a sampling algori…
rHorsey Jun 24, 2019
c0a9bfe
merging master.
rHorsey Aug 26, 2019
b708915
Ensuring standard n_datapoint default interface of None.
rHorsey Aug 26, 2019
d4e48c4
Fix sampling inheritance preemption.
rHorsey Aug 27, 2019
39f7a29
Updates enabling through simulation.
Aug 27, 2019
f1fafb1
Updates to enable commercial apply-upgrade measure usage.
rHorsey Sep 27, 2019
850303d
Merging enable-com
rHorsey Sep 27, 2019
fa7f068
Merge remote-tracking branch 'origin/master' into enable-com
nmerket Oct 10, 2019
810a638
Adding in option of additional QAQC measure to Commercial workflow.
rHorsey Oct 21, 2019
95a0e06
Removing debugging sleep statement.
rHorsey Oct 21, 2019
fa16cef
Fix a botched merge in postprocessing.py.
rHorsey Oct 21, 2019
23a6efc
Update to qaqc enablement.
rHorsey Oct 22, 2019
c76b578
Adding simulation settings check into QAQC block.
rHorsey Oct 23, 2019
878fa75
making a return true explicit.
rHorsey Oct 23, 2019
721f4bb
Add preliminary ComStock postprocessing functions
Oct 30, 2019
0189471
Merge branch 'fix_ci' into enable-com
nmerket Nov 1, 2019
54cd807
Change os_version and os_sha from class constants to instance variables
asparke2 Jan 10, 2020
0b0c144
Provide clearer error message if docker daemon not running on Windows
asparke2 Jan 10, 2020
1dd308e
Avoid attempts to copy buildstock.csv files to current location
asparke2 Jan 10, 2020
9d88003
Modifies tests to use LocalDocker and HPCBatch instances to test inst…
asparke2 Jan 10, 2020
8c7c7f2
Modifies test again to avoid unrelated docker hub connection error
asparke2 Jan 10, 2020
4ddcf13
Fix style errors
asparke2 Jan 10, 2020
a79b2ea
Fix style and missing import references in postprocessing code; still…
asparke2 Jan 10, 2020
5142566
Small change to make default behavior more obvious.
rHorsey Jan 10, 2020
f3e88d0
Merge pull request #124 from NREL/fix_com_docker_4
rHorsey Jan 10, 2020
6d77611
Merge branch 'master' into enable-com
nmerket Feb 11, 2020
b034f82
fixing merge conflict goof
nmerket Feb 11, 2020
bd14ecd
add new sensitivity reporting measure
Mar 19, 2020
aafc455
forgot to change measure name
Mar 19, 2020
f27017f
Adding in support for configiration settings required for com.
rHorsey Mar 20, 2020
76bef02
Merge branch 'rHorsey/enable-com' into comstock-sensitivity
rHorsey Mar 20, 2020
120d159
Making sure weather_dir method is hit in sampling - removes a rare ra…
rHorsey Mar 30, 2020
d1db85e
add qoi measure to workflow_generator
Mar 30, 2020
a0c5628
Merge pull request #142 from NREL/comstock-sensitivity
rHorsey Mar 30, 2020
d2cd915
Fixing datetime specification error.
rHorsey Mar 31, 2020
517c59b
Initial merge of output refactor complete.
rHorsey Apr 14, 2020
5fb5dc7
Fixed several tests - sampler mock still needs fixing, will inquire w…
rHorsey Apr 14, 2020
1788a4e
Fixed test and made additional changes to support close-to-previous p…
rHorsey Apr 15, 2020
c061c26
Forgot to flake8
rHorsey Apr 15, 2020
b7b404c
Merge branch 'master' into enable-com
nmerket Apr 22, 2020
72bbd66
using docker_image property instead of function
nmerket Apr 22, 2020
c96a397
Merge branch 'master' into rHorsey/enable-com
rHorsey Apr 24, 2020
a0780fa
Fixing postprocessing bug.
rHorsey Apr 24, 2020
adf302e
Merge branch 'rHorsey/enable-com' of http://github.com/nrel/buildstoc…
rHorsey Apr 24, 2020
ed602bd
Adding seeds folder mount.
rHorsey Apr 24, 2020
ae62171
Try two updating to include seeds directory in mounts.
rHorsey Apr 24, 2020
34cb059
Fixing tests for local docker and upgrading schema to v0.2
rHorsey Apr 28, 2020
c5510d6
Forgot to add the v0.2 schema...
rHorsey Apr 28, 2020
8a6b4bc
Adding docker support to circle - maybe a bad idea...
rHorsey Apr 28, 2020
9abb0b7
Remove empty.osm seed dependency -- we do not need it.
May 6, 2020
da480c7
Forcing sampling_algorithm key to exist.
rHorsey May 6, 2020
d9e03b8
Removing the seeds mount from eagle.
rHorsey May 6, 2020
5f653eb
Updated documentation for 0.18 release - added changelog and migratio…
rHorsey May 8, 2020
4d6d5d7
Final doc updates.
rHorsey May 8, 2020
1fb08dd
Merge branch 'master' into rHorsey/enable-com
nmerket May 12, 2020
50e9f82
Merge branch 'master' into enable-com
nmerket May 12, 2020
36eb73c
Adding logic and tests to validate downselect schema requirements.
rHorsey May 14, 2020
3aba168
updating version
nmerket May 15, 2020
6ea0b75
precomputed sampling overhaul
nmerket May 18, 2020
ccbb7d3
fixing testing
nmerket May 18, 2020
49d4b88
style fixes
nmerket May 18, 2020
afbb416
more validation
nmerket May 18, 2020
1679fb4
moving precomputed sample validation
nmerket May 19, 2020
f8d3d67
fixing testing
nmerket May 19, 2020
69f7b51
Fixing style.
rHorsey May 19, 2020
588e590
fixing docker image for aws
nmerket May 19, 2020
bbc0cc6
Fixing weather files doc conflict.
rHorsey May 20, 2020
6928d6a
Final documentation updates for release 0.18
rHorsey May 20, 2020
d7702b5
Fix for comm update docs.
rHorsey May 20, 2020
744bae5
One last rst fix.
rHorsey May 20, 2020
37b56fd
Merge remote-tracking branch 'origin/master' into enable-com
nmerket May 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .circleci/config.yml
Expand Up @@ -4,6 +4,7 @@ jobs:
docker:
- image: continuumio/miniconda3
steps:
- setup_remote_docker
- checkout
- run:
name: Install buildstock
Expand Down
3 changes: 2 additions & 1 deletion .github/pull_request_template.md
Expand Up @@ -12,5 +12,6 @@ Not all may apply
- [ ] Tests exercising your feature/bug fix (check coverage report on CircleCI build -> Artifacts)
- [ ] All other unit tests passing
- [ ] Update validation for project config yaml file changes
- [ ] Update documentation
- [ ] Update existing documentation
- [ ] Run a small batch run to make sure it all works (local is fine, unless an Eagle specific feature)
- [ ] Add to the changelog_dev.rst file and propose migration text in the pull request
4 changes: 2 additions & 2 deletions buildstockbatch/__version__.py
@@ -1,8 +1,8 @@
__title__ = 'buildstock-batch'
__description__ = 'Executing BuildStock projects on batch infrastructure.'
__url__ = 'http://github.com/NREL/buildstockbatch'
__version__ = '0.17.1'
__schema_version__ = '0.1'
__version__ = '0.18'
__schema_version__ = '0.2'
__author__ = 'Noel Merket'
__author_email__ = 'noel.merket@nrel.gov'
__license__ = 'BSD-3'
Expand Down
10 changes: 5 additions & 5 deletions buildstockbatch/aws/aws.py
Expand Up @@ -1744,8 +1744,8 @@ def validate_project(project_file):
super(AwsBatch, AwsBatch).validate_project(project_file)
AwsBatch.validate_instance_types(project_file)

@classmethod
def docker_image(cls):
@property
def docker_image(self):
return 'nrel/buildstockbatch'

@property
Expand All @@ -1754,7 +1754,7 @@ def weather_dir(self):

@property
def container_repo(self):
repo_name = self.docker_image()
repo_name = self.docker_image
repos = self.ecr.describe_repositories()
repo = None
for repo in repos['repositories']:
Expand All @@ -1775,7 +1775,7 @@ def build_image(self):
logger.debug('Building docker image')
self.docker_client.images.build(
path=str(root_path),
tag=self.docker_image(),
tag=self.docker_image,
rm=True
)

Expand All @@ -1794,7 +1794,7 @@ def push_image(self):
registry=registry_url
)
logger.debug(resp)
image = self.docker_client.images.get(self.docker_image())
image = self.docker_client.images.get(self.docker_image)
image.tag(repo_url, tag=self.job_identifier)
last_status = None
for x in self.docker_client.images.push(repo_url, tag=self.job_identifier, stream=True):
Expand Down
140 changes: 69 additions & 71 deletions buildstockbatch/base.py
Expand Up @@ -50,8 +50,8 @@ class ValidationError(Exception):

class BuildStockBatchBase(object):

OS_VERSION = '2.9.1'
OS_SHA = '3472e8b799'
DEFAULT_OS_VERSION = '2.9.1'
DEFAULT_OS_SHA = '3472e8b799'
LOGO = '''
_ __ _ __, _ __
( / ) o // /( _/_ / ( / ) _/_ /
Expand All @@ -63,39 +63,40 @@ class BuildStockBatchBase(object):

def __init__(self, project_filename):
self.project_filename = os.path.abspath(project_filename)
with open(self.project_filename, 'r') as f:
self.cfg = yaml.load(f, Loader=yaml.SafeLoader)
if 'stock_type' not in self.cfg.keys():
raise KeyError('Key `stock_type` not specified in project file `{}`'.format(project_filename))
elif (self.stock_type != 'residential') & (self.stock_type != 'commercial'):
raise KeyError('Key `{}` for value `stock_type` not recognized in `{}`'.format(self.cfg['stock_type'],
project_filename))
if 'buildstock_csv' in self.cfg['baseline']:
buildstock_csv = self.path_rel_to_projectfile(self.cfg['baseline']['buildstock_csv'])
if not os.path.exists(buildstock_csv):
raise FileNotFoundError('The buildstock.csv file does not exist at {}'.format(buildstock_csv))
df = pd.read_csv(buildstock_csv)
n_datapoints = self.cfg['baseline'].get('n_datapoints', df.shape[0])
self.cfg['baseline']['n_datapoints'] = n_datapoints
if n_datapoints != df.shape[0]:
raise RuntimeError(
'A buildstock_csv was provided, so n_datapoints for sampling should not be provided or should be '
'equal to the number of rows in the buildstock.csv file. Remove or comment out '
'baseline->n_datapoints from your project file.'
)

# Load project file to self.cfg
self.cfg = self.get_project_configuration(project_filename)

self.buildstock_dir = self.cfg['buildstock_directory']
if not os.path.isdir(self.buildstock_dir):
raise FileNotFoundError(f'buildstock_directory = {self.buildstock_dir} is not a directory.')
self.project_dir = os.path.join(self.buildstock_dir, self.cfg['project_directory'])
if not os.path.isdir(self.project_dir):
raise FileNotFoundError(f'project_directory = {self.project_dir} is not a directory.')

# To be set in subclasses
self.sampler = None

def path_rel_to_projectfile(self, x):
# Load in OS_VERSION and OS_SHA arguments if they exist in the YAML,
# otherwise use defaults specified here.
self.os_version = self.cfg.get('os_version', self.DEFAULT_OS_VERSION)
self.os_sha = self.cfg.get('os_sha', self.DEFAULT_OS_SHA)
logger.debug(f"Using OpenStudio version: {self.os_version} with SHA: {self.os_sha}")

@staticmethod
def path_rel_to_file(startfile, x):
if os.path.isabs(x):
return os.path.abspath(x)
else:
return os.path.abspath(os.path.join(os.path.dirname(self.project_filename), x))
return os.path.abspath(os.path.join(os.path.dirname(startfile), x))

def path_rel_to_projectfile(self, x):
return self.path_rel_to_file(self.project_filename, x)

def _get_weather_files(self):
if 'weather_files_path' in self.cfg:
logger.debug('Copying weather files')
weather_file_path = self.path_rel_to_projectfile(self.cfg['weather_files_path'])
weather_file_path = self.cfg['weather_files_path']
with zipfile.ZipFile(weather_file_path, 'r') as zf:
logger.debug('Extracting weather files to: {}'.format(self.weather_dir))
zf.extractall(self.weather_dir)
Expand All @@ -119,22 +120,6 @@ def stock_type(self):
def weather_dir(self):
raise NotImplementedError

@property
def buildstock_dir(self):
d = self.path_rel_to_projectfile(self.cfg['buildstock_directory'])
# logger.debug('buildstock_dir = {}'.format(d))
assert(os.path.isdir(d))
return d

@property
def project_dir(self):
d = os.path.abspath(
os.path.join(self.buildstock_dir, self.cfg['project_directory'])
)
# logger.debug('project_dir = {}'.format(d))
assert(os.path.isdir(d))
return d

@property
def results_dir(self):
raise NotImplementedError
Expand All @@ -151,25 +136,7 @@ def skip_baseline_sims(self):
def run_sampling(self, n_datapoints=None):
if n_datapoints is None:
n_datapoints = self.cfg['baseline']['n_datapoints']
if 'buildstock_csv' in self.cfg['baseline']:
logger.debug("Reusing the buildstock_csv")
buildstock_csv = self.path_rel_to_projectfile(self.cfg['baseline']['buildstock_csv'])
destination_filename = self.sampler.csv_path
if destination_filename != buildstock_csv:
if os.path.exists(destination_filename):
logger.info("Removing {!r} before copying {!r} to that location."
.format(destination_filename, buildstock_csv))
os.remove(destination_filename)
shutil.copy(
buildstock_csv,
destination_filename
)
return destination_filename
else:
logger.debug("Running fresh sampling")
buildstock_csv_filename = self.sampler.run_sampling(n_datapoints)
logger.debug("Sampling completed")
return buildstock_csv_filename
return self.sampler.run_sampling(n_datapoints)

def run_batch(self):
raise NotImplementedError
Expand Down Expand Up @@ -279,7 +246,7 @@ def cleanup_sim_dir(sim_dir, dest_fs, simout_ts_dir, upgrade_id, building_id):
# and copy it to the results directory
timeseries_filepath = os.path.join(sim_dir, 'run', 'enduse_timeseries.csv')
if os.path.isfile(timeseries_filepath):
tsdf = pd.read_csv(timeseries_filepath, parse_dates=['Time'])
tsdf = pd.read_csv(timeseries_filepath, parse_dates=[0])
postprocessing.write_dataframe_as_parquet(
tsdf,
dest_fs,
Expand All @@ -304,22 +271,33 @@ def cleanup_sim_dir(sim_dir, dest_fs, simout_ts_dir, upgrade_id, building_id):
def validate_project(project_file):
assert(BuildStockBatchBase.validate_project_schema(project_file))
assert(BuildStockBatchBase.validate_misc_constraints(project_file))
assert(BuildStockBatchBase.validate_xor_schema_keys(project_file))
assert(BuildStockBatchBase.validate_xor_nor_schema_keys(project_file))
assert(BuildStockBatchBase.validate_precomputed_sample(project_file))
assert(BuildStockBatchBase.validate_reference_scenario(project_file))
assert(BuildStockBatchBase.validate_measures_and_arguments(project_file))
assert(BuildStockBatchBase.validate_options_lookup(project_file))
assert(BuildStockBatchBase.validate_measure_references(project_file))
assert(BuildStockBatchBase.validate_options_lookup(project_file))
logger.info('Base Validation Successful')
return True

@staticmethod
def get_project_configuration(project_file):
@classmethod
def get_project_configuration(cls, project_file):
try:
with open(project_file) as f:
cfg = yaml.load(f, Loader=yaml.SafeLoader)
except FileNotFoundError as err:
logger.error('Failed to load input yaml for validation')
raise err

# Set absolute paths
cfg['buildstock_directory'] = cls.path_rel_to_file(project_file, cfg['buildstock_directory'])
if 'precomputed_sample' in cfg.get('baseline', {}):
cfg['baseline']['precomputed_sample'] = \
cls.path_rel_to_file(project_file, cfg['baseline']['precomputed_sample'])
if 'weather_files_path' in cfg:
cfg['weather_files_path'] = cls.path_rel_to_file(project_file, cfg['weather_files_path'])

return cfg

@staticmethod
Expand All @@ -346,28 +324,48 @@ def validate_project_schema(project_file):
def validate_misc_constraints(project_file):
# validate other miscellaneous constraints
cfg = BuildStockBatchBase.get_project_configuration(project_file)
if 'buildstock_csv' in cfg['baseline']:
if 'precomputed_sample' in cfg['baseline']:
rHorsey marked this conversation as resolved.
Show resolved Hide resolved
if cfg.get('downselect', {'resample': False}).get('resample', True):
raise ValidationError("Downselect with resampling cannot be used when using buildstock_csv. \n"
"Please set resample: False in downselect, or do not use buildstock_csv.")
raise ValidationError("Downselect with resampling cannot be used when using precomputed buildstock_csv."
"\nPlease set resample: False in downselect or use a different sampler.")

if cfg.get('postprocessing', {}).get('aggregate_timeseries', False):
logger.warning('aggregate_timeseries has been deprecated and will be removed in a future version.')

return True

@staticmethod
def validate_xor_schema_keys(project_file):
def validate_xor_nor_schema_keys(project_file):
cfg = BuildStockBatchBase.get_project_configuration(project_file)
major, minor = cfg.get('version', __schema_version__).split('.')
if int(major) >= 0:
if int(minor) >= 0:
# xor
if ('weather_files_url' in cfg.keys()) is \
('weather_files_path' in cfg.keys()):
raise ValidationError('Both/neither weather_files_url and weather_files_path found in yaml root')
if ('n_datapoints' in cfg['baseline'].keys()) is \
('buildstock_csv' in cfg['baseline'].keys()):
raise ValidationError('Both/neither n_datapoints and buildstock_csv found in yaml baseline key')

# No precomputed sample key unless using precomputed sampling
if cfg['baseline']['sampling_algorithm'] != 'precomputed' and 'precomputed_sample' in cfg['baseline']:
raise ValidationError(
'baseline.precomputed_sample is not allowed unless '
'baseline.sampling_algorithm = "precomputed".'
)
return True

@staticmethod
def validate_precomputed_sample(project_file):
cfg = BuildStockBatchBase.get_project_configuration(project_file)
if 'precomputed_sample' in cfg['baseline']:
buildstock_csv = cfg['baseline']['precomputed_sample']
if not os.path.exists(buildstock_csv):
raise FileNotFoundError(buildstock_csv)
buildstock_df = pd.read_csv(buildstock_csv)
if buildstock_df.shape[0] != cfg['baseline']['n_datapoints']:
raise RuntimeError(
f'`n_datapoints` does not match the number of rows in {buildstock_csv}. '
f'Please set `n_datapoints` to {buildstock_df.shape[0]}'
)
return True

@staticmethod
Expand Down