Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: python -m pip install --upgrade pip setuptools wheel openstudio oslg numpy
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not even sure this numpy pip call was at all required.

run: python -m pip install --upgrade pip setuptools wheel openstudio oslg
- name: Run unit tests
run: python -m unittest

Expand All @@ -37,6 +37,6 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: python -m pip install --upgrade pip setuptools wheel openstudio oslg numpty
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub Actions certainly didn't trip over this "numpty" typo.

run: python -m pip install --upgrade pip setuptools wheel openstudio oslg
- name: Run unit tests
run: python -m unittest
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "osut"
version = "0.6.0a2"
version = "0.6.0a3"
description = "OpenStudio SDK utilities for Python"
readme = "README.md"
requires-python = ">=3.2"
Expand Down
65 changes: 54 additions & 11 deletions src/osut/osut.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

import re
import math
import numpy
import collections
import openstudio
from oslg import oslg
Expand Down Expand Up @@ -257,6 +256,50 @@ def each_cons(it, n):
yield tuple(deq)


def clamp(value, minimum, maximum) -> float:
"""In-house alternative to Numpy's 'clip' (re: Ruby's 'clamp').

Args:
value (float):
A float-convertible value (to clip/clamp).
minimum (float):
Lower bound.
maximum (float):
Upper bound.

Returns:
float: Clamped value. Either value, min, max or '0' if invalid inputs.

"""
try:
value = float(value)
except:
try:
minimum = float(minimum)
return minimum
except:
try:
maximum = float(maximum)
return maximum
except:
return 0.0
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No logged warnings or errors if invalid input. Will ultimately return 0.0 if all three parameters can't be converted to floating point numbers.


try:
minimum = float(minimum)
except:
return value

try:
maximum = float(maximum)
except:
return value

if value < minimum: return minimum
if value > maximum: return maximum

return value


def genConstruction(model=None, specs=dict()):
"""Generates an OpenStudio multilayered construction, + materials if needed.

Expand Down Expand Up @@ -1950,7 +1993,7 @@ def minCoolScheduledSetpoint(zone=None):

if sched.to_ScheduleConstant():
sched = sched.to_ScheduleConstant().get()
minimum = scheduleConstantMinMax(sched)[:min]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yikes. Ruby leftover.

minimum = scheduleConstantMinMax(sched)["min"]

if minimum:
if res["spt"] is None or res["spt"] > minimum:
Expand Down Expand Up @@ -6215,8 +6258,8 @@ def addSubs(s=None, subs=[], clear=False, bound=False, realign=False, bfr=0.005)
cl2 = openstudio.model.WindowPropertyFrameAndDivider
cl3 = openstudio.model.ConstructionBase
v = int("".join(openstudio.openStudioVersion().split(".")))
min = 0.050 # minimum ratio value ( 5%)
max = 0.950 # maximum ratio value (95%)
mn = 0.050 # minimum ratio value ( 5%)
mx = 0.950 # maximum ratio value (95%)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yish. Thought I had purged out all min and max variables.

if isinstance(subs, dict): subs = [subs]

# --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- #
Expand Down Expand Up @@ -6471,7 +6514,7 @@ def addSubs(s=None, subs=[], clear=False, bound=False, realign=False, bfr=0.005)

m = "Reset '%s' height %.3fm (%s)" % (ide, sub["height"], mth)
oslg.log(CN.WRN, m)
sub["height"] = numpy.clip(sub["height"], glass, max_height)
sub["height"] = clamp(sub["height"], glass, max_height)
m = "Height '%s' reset to %.3fm (%s)" % (ide, sub["height"], mth)
oslg.log(CN.WRN, m)

Expand All @@ -6482,7 +6525,7 @@ def addSubs(s=None, subs=[], clear=False, bound=False, realign=False, bfr=0.005)

m = "Reset '%s' head %.3fm (%s)" % (ide, sub["head"], mth)
oslg.log(CN.WRN, m)
sub["head"] = numpy.clip(sub["head"], min_head, max_head)
sub["head"] = clamp(sub["head"], min_head, max_head)
m = "Head '%s' reset to %.3fm (%s)" % (ide, sub["head"], mth)
oslg.log(CN.WRN, m)

Expand All @@ -6493,7 +6536,7 @@ def addSubs(s=None, subs=[], clear=False, bound=False, realign=False, bfr=0.005)

m = "Reset '%s' sill %.3fm (%s)" % (ide, sub["sill"], mth)
oslg.log(CN.WRN, m)
sub["sill"] = numpy.clip(sub["sill"], min_sill, max_sill)
sub["sill"] = clamp(sub["sill"], min_sill, max_sill)
m = "Sill '%s reset to %.3fm (%s)" % (ide, sub["sill"], mth)
oslg.log(CN.WRN, m)

Expand Down Expand Up @@ -6621,7 +6664,7 @@ def addSubs(s=None, subs=[], clear=False, bound=False, realign=False, bfr=0.005)

m = "Reset '%s' width %.3fm (%s)" % (ide, sub["width"], mth)
oslg.log(CN.WRN, m)
sub["width"] = numpy.clip(sub["width"], glass, max_width)
sub["width"] = clamp(sub["width"], glass, max_width)
m = "Width '%s' reset to %.3fm ()%s)" % (ide, sub["width"], mth)
oslg.log(CN.WRN, m)

Expand Down Expand Up @@ -6676,10 +6719,10 @@ def addSubs(s=None, subs=[], clear=False, bound=False, realign=False, bfr=0.005)
continue

# Log/reset if "ratio" beyond min/max?
if sub["ratio"] < min and sub["ratio"] > max:
if sub["ratio"] < mn and sub["ratio"] > mx:
m = "Reset ratio %.3f (%s)" % (sub["ratio"], mth)
oslg.log(CN.WRN, m)
sub["ratio"] = numpy.clip(sub["ratio"], min, max)
sub["ratio"] = clamp(sub["ratio"], mn, mx)
m = "Ratio reset to %.3f (%s)" % (sub["ratio"], mth)
oslg.log(CN.WRN, m)

Expand Down Expand Up @@ -7411,7 +7454,7 @@ def addSkyLights(spaces=[], opts=dict) -> float:
if srr > 0.90:
oslg.log(CN.WRN, "SRR (%.2f) reset to 90% (%s)" % (srr, mth))

srr = numpy.clip(srr, 0.00, 0.10)
srr = clamp(srr, 0.00, 0.10)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar function call/arguments as Numpy's clip. Haven't added unit stress tests, yet all higher-level functions work as intended. Good enough for now.

else:
return oslg.hashkey("area", opts, "area", mth, CN.ERR, 0)

Expand Down