Skip to content

Commit 891b039

Browse files
Move base plots from LadybugTools_Toolkit (#147)
2 parents ab59437 + cd52274 commit 891b039

17 files changed

+10928
-2
lines changed

.gitignore

+120-1
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,123 @@ Alligator/Alligator_REMOTE_9848.csproj
9898

9999
# User defined files #
100100
######################
101-
build.ps1
101+
build.ps1
102+
103+
# Testing files
104+
.dev/
105+
prototypes/
106+
107+
# PyInstaller
108+
# Usually these files are written by a python script from a template
109+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
110+
*.manifest
111+
*.spec
112+
113+
# Installer logs
114+
pip-log.txt
115+
pip-delete-this-directory.txt
116+
117+
# Unit test / coverage reports
118+
htmlcov/
119+
.tox/
120+
.nox/
121+
.coverage
122+
.coverage.*
123+
.cache
124+
nosetests.xml
125+
coverage.xml
126+
*.cover
127+
*.py,cover
128+
.hypothesis/
129+
.pytest_cache/
130+
cover/
131+
132+
# Translations
133+
*.mo
134+
*.pot
135+
136+
# Django stuff:
137+
*.log
138+
local_settings.py
139+
db.sqlite3
140+
db.sqlite3-journal
141+
142+
# Flask stuff:
143+
instance/
144+
.webassets-cache
145+
146+
# Scrapy stuff:
147+
.scrapy
148+
149+
# Sphinx documentation
150+
docs/_build/
151+
152+
# PyBuilder
153+
.pybuilder/
154+
target/
155+
156+
# Jupyter Notebook
157+
*.ipynb
158+
.ipynb_checkpoints
159+
160+
# IPython
161+
profile_default/
162+
ipython_config.py
163+
164+
# pyenv
165+
# For a library or package, you might want to ignore these files since the code is
166+
# intended to run in multiple environments; otherwise, check them in:
167+
# .python-version
168+
169+
# pipenv
170+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
171+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
172+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
173+
# install all needed dependencies.
174+
#Pipfile.lock
175+
176+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
177+
__pypackages__/
178+
179+
# Celery stuff
180+
celerybeat-schedule
181+
celerybeat.pid
182+
183+
# SageMath parsed files
184+
*.sage.py
185+
186+
# Environments
187+
.env
188+
.venv
189+
env/
190+
venv/
191+
ENV/
192+
env.bak/
193+
venv.bak/
194+
195+
# Spyder project settings
196+
.spyderproject
197+
.spyproject
198+
199+
# Rope project settings
200+
.ropeproject
201+
202+
# mkdocs documentation
203+
/site
204+
205+
# mypy
206+
.mypy_cache/
207+
.dmypy.json
208+
dmypy.json
209+
210+
# Pyre type checker
211+
.pyre/
212+
213+
# pytype static type analyzer
214+
.pytype/
215+
216+
# Cython debug symbols
217+
cython_debug/
218+
219+
# unignored files
220+
!example.sql

Python_Engine/Python/requirements.txt

+11-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
1-

1+
virtualenv
2+
jupyterlab
3+
black
4+
pylint
5+
pytest
6+
pytest-cov
7+
pytest-order
8+
case-converter
9+
numpy==1.26.4
10+
pandas==2.2.1
11+
matplotlib==3.8.3

Python_Engine/Python/run_tests.bat

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
SET PYTHON_EXE=C:\ProgramData\BHoM\Extensions\PythonEnvironments\Python_Toolkit\v3_10\python.exe
2+
SET TEST_DIR=C:\ProgramData\BHoM\Extensions\PythonCode\Python_Toolkit\tests
3+
4+
@REM C:\ProgramData\BHoM\Extensions\PythonEnvironments\Python_Toolkit\v3_10\python.exe -m pytest --cov-report term --cov-report html:cov_html --cov python_toolkit -v C:\ProgramData\BHoM\Extensions\PythonCode\Python_Toolkit\tests
5+
6+
"%PYTHON_EXE%" -m pytest --cov-report term --cov-report html:cov_html --cov python_toolkit -v "%TEST_DIR%"
7+
cmd /k
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from .timeseries import (
2+
validate_timeseries,
3+
timeseries_summary_monthly
4+
)
5+
from .cardinality import (
6+
cardinality,
7+
angle_from_cardinal,
8+
angle_from_north,
9+
angle_to_vector
10+
)
11+
from .decay_rate import (
12+
DecayMethod,
13+
proximity_decay,
14+
decay_rate_smoother
15+
)
16+
from .helpers import (
17+
sanitise_string,
18+
convert_keys_to_snake_case,
19+
remove_leap_days,
20+
timedelta_tostring,
21+
safe_filename
22+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import numpy as np
2+
3+
from ..bhom.analytics import bhom_analytics
4+
5+
@bhom_analytics()
6+
def cardinality(direction_angle: float, directions: int = 16):
7+
"""Returns the cardinal orientation of a given angle, where that angle is related to north at
8+
0 degrees.
9+
Args:
10+
direction_angle (float):
11+
The angle to north in degrees (+Ve is interpreted as clockwise from north at 0.0
12+
degrees).
13+
directions (int):
14+
The number of cardinal directions into which angles shall be binned (This value should
15+
be one of 4, 8, 16 or 32, and is centred about "north").
16+
Returns:
17+
int:
18+
The cardinal direction the angle represents.
19+
"""
20+
21+
if direction_angle > 360 or direction_angle < 0:
22+
raise ValueError(
23+
"The angle entered is beyond the normally expected range for an orientation in degrees."
24+
)
25+
26+
cardinal_directions = {
27+
4: ["N", "E", "S", "W"],
28+
8: ["N", "NE", "E", "SE", "S", "SW", "W", "NW"],
29+
16: [
30+
"N",
31+
"NNE",
32+
"NE",
33+
"ENE",
34+
"E",
35+
"ESE",
36+
"SE",
37+
"SSE",
38+
"S",
39+
"SSW",
40+
"SW",
41+
"WSW",
42+
"W",
43+
"WNW",
44+
"NW",
45+
"NNW",
46+
],
47+
32: [
48+
"N",
49+
"NbE",
50+
"NNE",
51+
"NEbN",
52+
"NE",
53+
"NEbE",
54+
"ENE",
55+
"EbN",
56+
"E",
57+
"EbS",
58+
"ESE",
59+
"SEbE",
60+
"SE",
61+
"SEbS",
62+
"SSE",
63+
"SbE",
64+
"S",
65+
"SbW",
66+
"SSW",
67+
"SWbS",
68+
"SW",
69+
"SWbW",
70+
"WSW",
71+
"WbS",
72+
"W",
73+
"WbN",
74+
"WNW",
75+
"NWbW",
76+
"NW",
77+
"NWbN",
78+
"NNW",
79+
"NbW",
80+
],
81+
}
82+
83+
if directions not in cardinal_directions:
84+
raise ValueError(
85+
f'The input "directions" must be one of {list(cardinal_directions.keys())}.'
86+
)
87+
88+
val = int((direction_angle / (360 / directions)) + 0.5)
89+
90+
arr = cardinal_directions[directions]
91+
92+
return arr[(val % directions)]
93+
94+
@bhom_analytics()
95+
def angle_from_cardinal(cardinal_direction: str) -> float:
96+
"""
97+
For a given cardinal direction, return the corresponding angle in degrees.
98+
99+
Args:
100+
cardinal_direction (str):
101+
The cardinal direction.
102+
Returns:
103+
float:
104+
The angle associated with the cardinal direction.
105+
"""
106+
cardinal_directions = [
107+
"N",
108+
"NbE",
109+
"NNE",
110+
"NEbN",
111+
"NE",
112+
"NEbE",
113+
"ENE",
114+
"EbN",
115+
"E",
116+
"EbS",
117+
"ESE",
118+
"SEbE",
119+
"SE",
120+
"SEbS",
121+
"SSE",
122+
"SbE",
123+
"S",
124+
"SbW",
125+
"SSW",
126+
"SWbS",
127+
"SW",
128+
"SWbW",
129+
"WSW",
130+
"WbS",
131+
"W",
132+
"WbN",
133+
"WNW",
134+
"NWbW",
135+
"NW",
136+
"NWbN",
137+
"NNW",
138+
"NbW",
139+
]
140+
if cardinal_direction not in cardinal_directions:
141+
raise ValueError(f"{cardinal_direction} is not a known cardinal_direction.")
142+
angles = np.arange(0, 360, 11.25)
143+
144+
lookup = dict(zip(cardinal_directions, angles))
145+
146+
return lookup[cardinal_direction]
147+
148+
def angle_from_north(vector: list[float]) -> float:
149+
"""For an X, Y vector, determine the clockwise angle to north at [0, 1].
150+
151+
Args:
152+
vector (list[float]):
153+
A vector of length 2.
154+
155+
Returns:
156+
float:
157+
The angle between vector and north in degrees clockwise from [0, 1].
158+
"""
159+
north = [0, 1]
160+
angle1 = np.arctan2(*north[::-1])
161+
angle2 = np.arctan2(*vector[::-1])
162+
return np.rad2deg((angle1 - angle2) % (2 * np.pi))
163+
164+
def angle_to_vector(clockwise_angle_from_north: float) -> list[float]:
165+
"""Return the X, Y vector from of an angle from north at 0-degrees.
166+
167+
Args:
168+
clockwise_angle_from_north (float):
169+
The angle from north in degrees clockwise from [0, 360], though
170+
any number can be input here for angles greater than a full circle.
171+
172+
Returns:
173+
list[float]:
174+
A vector of length 2.
175+
"""
176+
177+
clockwise_angle_from_north = np.radians(clockwise_angle_from_north)
178+
179+
return np.sin(clockwise_angle_from_north), np.cos(clockwise_angle_from_north)

0 commit comments

Comments
 (0)