Skip to content

Commit

Permalink
Improve error handling for REopt (#63)
Browse files Browse the repository at this point in the history
* update pre-commit hook versions

* bump minimum ruff version

* error handling if reopt is specified before being run

* update ruff settings in pyproject.toml

* replace `%` formatting with f-strings per ruffs recommendation

* different way of printing error message and quitting

* test for error message if no reopt data

* require opendssdirect.py ~= 0.8.0

* bump GHA versions
  • Loading branch information
vtnate authored May 3, 2024
1 parent bb3a23b commit e2c8d33
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 27 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install ditto-reader
run: pip install .[dev]
- name: Run pre-commit to confirm linting and formatting
# https://github.com/pre-commit/action
uses: pre-commit/[email protected].0
uses: pre-commit/[email protected].1
with:
extra_args: --all-files
- name: Run unit tests
Expand Down
20 changes: 7 additions & 13 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: check-ast
- id: check-added-large-files
Expand All @@ -20,20 +20,14 @@ repos:
- id: debug-statements
# - id: detect-aws-credentials
- id: detect-private-key
# - repo: meta
# hooks:
# - id: check-useless-excludes # Ensure the exclude syntax is correct
# - id: check-hooks-apply # Fails if a hook doesn't apply to any file
# Run the Ruff linter
# https://docs.astral.sh/ruff/integrations/#pre-commit
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
rev: v0.4.2
hooks:
# Run the linter
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
args: [--fix, --exit-non-zero-on-fix, --output-format=full]
types_or: [python, pyi, jupyter]
# Run the Ruff formatter
# https://docs.astral.sh/ruff/integrations/#pre-commit
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
hooks:
# Run the formatter
- id: ruff-format
types_or: [python, pyi, jupyter]
15 changes: 9 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ classifiers = [
]
dependencies = [
"ditto.py[opendss] ~= 0.2.4",
"opendssdirect.py ~= 0.8",
"opendssdirect.py ~= 0.8.0",
]

[project.optional-dependencies]
dev = [
"pytest ~= 7.4",
"pre-commit ~= 3.3",
"ruff ~= 0.1.6",
"ruff ~= 0.4.0",
]

# https://setuptools.pypa.io/en/latest/userguide/package_discovery.html
Expand All @@ -61,19 +61,22 @@ readme = {file = "README.md", content-type = "text/markdown"}
minversion = "6.0"
testpaths = "tests"

# https://github.com/charliermarsh/ruff
# https://docs.astral.sh/ruff/tutorial/#configuration
[tool.ruff]
fix = true # automatically fix problems if possible
select = ["RUF", "E", "F", "I", "UP", "N", "S", "BLE", "A", "C4", "T10", "ISC", "ICN", "PT",
line-length = 120

# https://docs.astral.sh/ruff/linter/#rule-selection
[tool.ruff.lint]
extend-select = ["RUF", "E", "F", "I", "UP", "N", "S", "BLE", "A", "C4", "T10", "ISC", "ICN", "PT",
"Q", "SIM", "TID", "ARG", "DTZ", "PD", "PGH", "PLC", "PLE", "PLR", "PLW", "PIE", "COM"] # Enable these rules
ignore = ["PLR0913", "PLR2004", "PLR0402", "COM812", "COM819", "SIM108", "ARG002", "ISC001"] # except for these specific errors
line-length = 120

# https://docs.astral.sh/ruff/settings/#format
[tool.ruff.format]
# quote-style = "double"

[tool.ruff.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101", "S607", "S603"] # assert statements are allowed in tests, and paths are safe
"update_licenses.py" = ["SIM115", "A002", "ARG001"]
"urbanopt_ditto_reader/reader/read.py" = ["PLR0912", "PLR0915"] # ignore complexity warnings in this file
Expand Down
28 changes: 28 additions & 0 deletions tests/urbanopt_ditto_reader/test_ditto_reader_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,34 @@ def test_upgrade_transformers(capfd):
# This text is printed by ditto.consistency.fix_undersized_transformers


def test_graceful_error_if_no_reopt(capfd):
reopt_optimization_file = (
Path(__file__).parent.parent.parent
/ "example"
/ "run"
/ "baseline_scenario"
/ "1"
/ "feature_reports"
/ "feature_optimization.csv"
)
assert reopt_optimization_file.exists() is False
subprocess.run(
[
"ditto_reader_cli",
"run-opendss",
"--config",
"example_config.json",
"--upgrade",
"--reopt",
],
cwd=examples_dir,
check=True,
)
captured = capfd.readouterr()
assert "not found" in captured.out
# This text is printed by ditto.consistency.fix_undersized_transformers


# REopt data for testing not present in this repo as of 2023-04-05
# def test_use_reopt(capfd):
# subprocess.run(
Expand Down
12 changes: 9 additions & 3 deletions urbanopt_ditto_reader/reader/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@
OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************************
"""

import json
import os
from datetime import datetime
from pathlib import Path

from ditto.models.base import Unicode
from ditto.models.feeder_metadata import Feeder_metadata
Expand Down Expand Up @@ -510,11 +512,15 @@ def parse_loads(self, model, **kwargs):
load.nominal_voltage = model["urbanopt-feeder"].nominal_voltage

# load the power draw of the buildings from the energy sim results
load_path = os.path.join(self.load_folder, id_value, "feature_reports")
load_path = Path(self.load_folder) / id_value / "feature_reports"
load_multiplier = 1000
if os.path.exists(load_path): # We've found the load data
if load_path.is_dir(): # We've found the load data
if self.use_reopt:
rep_csv = os.path.join(load_path, "feature_optimization.csv")
rep_csv = load_path / "feature_optimization.csv"
if not rep_csv.is_file():
print("feature_optimization.csv not found. Please run REopt post-processing first.")
# TODO: Get the test to read this text appropriately from inside the SystemExit()
raise SystemExit()
report_mtx = self._read_csv(rep_csv)
header_row = report_mtx.pop(0)
load_col_i = header_row.index("REopt:Electricity:Load:Total(kw)")
Expand Down
6 changes: 3 additions & 3 deletions urbanopt_ditto_reader/urbanopt_ditto_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,13 +466,13 @@ def run(self, master_file):

# write the collected results into CSV files
for element, result_values in voltage_df_dic.items():
res_path = os.path.join(features_path, "%s.csv" % element.replace("_", "-"))
res_path = Path(features_path) / f"{element.replace('_', '-')}.csv"
self._write_csv(result_values, res_path)
for element, result_values in line_df_dic.items():
res_path = os.path.join(lines_path, "%s.csv" % element.replace(":", ""))
res_path = Path(lines_path) / f"{element.replace(':', '')}.csv"
self._write_csv(result_values, res_path)
for element, result_values in transformer_df_dic.items():
res_path = os.path.join(trans_path, "%s.csv" % element.replace(":", ""))
res_path = Path(trans_path) / f"{element.replace(':', '')}.csv"
self._write_csv(result_values, res_path)

@staticmethod
Expand Down

0 comments on commit e2c8d33

Please sign in to comment.