Skip to content

Commit 76e7030

Browse files
authored
Merge pull request #2361 from mayankchetan/of_io_update
Updates to openfast_io to match current dev branch API
2 parents b642fcd + cc4ba09 commit 76e7030

29 files changed

+6294
-10644
lines changed

.github/workflows/automated-dev-tests.yml

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,8 @@ jobs:
535535
- name: Run Interface / API tests
536536
working-directory: ${{runner.workspace}}/openfast/build
537537
run: |
538-
ctest -VV -L "cpp|python|fastlib"
538+
ctest -VV -L "cpp|python|fastlib" \
539+
-LE "openfast_io"
539540
- name: Failing test artifacts
540541
uses: actions/upload-artifact@v4
541542
if: failure()
@@ -601,6 +602,51 @@ jobs:
601602
!${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/UAE_VI
602603
!${{runner.workspace}}/openfast/build/reg_tests/glue-codes/openfast/WP_Baseline
603604
605+
rtest-openfast_io:
606+
runs-on: ubuntu-22.04
607+
needs: build-openfast-release
608+
steps:
609+
- name: Cache the workspace
610+
uses: actions/cache@v4
611+
with:
612+
path: ${{runner.workspace}}
613+
key: build-openfast-release-${{ github.sha }}
614+
- name: Setup Python
615+
uses: actions/setup-python@v5
616+
with:
617+
python-version: '3.11'
618+
- name: Install dependencies
619+
run: |
620+
pip install -r requirements.txt
621+
sudo apt-get update -y
622+
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
623+
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
624+
- name: Install openfast_io
625+
working-directory: ${{runner.workspace}}/openfast/openfast_io
626+
run: |
627+
pip install -e .
628+
- name: Configure Tests
629+
working-directory: ${{runner.workspace}}/openfast/build
630+
run: |
631+
cmake \
632+
-DPython_ROOT_DIR:STRING=${{env.pythonLocation}} \
633+
-DBUILD_TESTING:BOOL=ON \
634+
-DCTEST_PLOT_ERRORS:BOOL=ON \
635+
${GITHUB_WORKSPACE}
636+
cmake --build . --target regression_test_controllers
637+
- name: Run openfast_io tests
638+
working-directory: ${{runner.workspace}}/openfast/build
639+
run: |
640+
ctest -VV -j4 \
641+
-L openfast_io
642+
- name: Failing test artifacts
643+
uses: actions/upload-artifact@v4
644+
if: failure()
645+
with:
646+
name: rtest-openfast_io
647+
path: |
648+
${{runner.workspace}}/openfast/build/reg_tests/openfast_io
649+
604650
605651
rtest-OF-simulink:
606652
runs-on: ubuntu-22.04

.github/workflows/deploy.yml

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,75 @@ name: deploy
66

77
on:
88
workflow_dispatch:
9-
9+
1010
release:
1111
types:
1212
- released
1313

14+
1415
jobs:
15-
publish-to-pypi:
16+
publish-to-pypi-test:
1617
runs-on: ubuntu-latest
17-
permissions:
18-
id-token: write
19-
contents: read
20-
18+
if: github.event_name == 'workflow_dispatch'
2119
steps:
22-
- name: Checkout Repository
23-
uses: actions/checkout@v4
20+
- uses: actions/checkout@v3
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v4
24+
with:
25+
python-version: '3.12'
26+
cache: 'pip'
2427

25-
- name: Install Poetry
26-
uses: snok/install-poetry@v1.3.4
28+
- name: Install Hatch
29+
uses: pypa/hatch@install
2730

28-
- name: Build a binary wheel and a source tarball
29-
run: poetry build
30-
working-directory: openfast_python
31+
- name: Install dependencies
32+
run: pip install keyring[file]
3133

32-
- name: Publish package distributions to PyPI
33-
uses: pypa/gh-action-pypi-publish@v1.8.14
34+
- name: Build package
35+
run: hatch build
36+
working-directory: openfast_io
37+
38+
- name: Publish to PyPI test
39+
env:
40+
HATCH_INDEX_USER: __token__
41+
HATCH_INDEX_AUTH: ${{ secrets.PYPI_TEST_TOKEN }}
42+
run: hatch publish -r test
43+
working-directory: openfast_io
44+
45+
publish-to-pypi:
46+
runs-on: ubuntu-latest
47+
if: github.event_name == 'release'
48+
steps:
49+
- uses: actions/checkout@v3
50+
51+
- name: Set up Python
52+
uses: actions/setup-python@v4
3453
with:
35-
packages-dir: openfast_python/dist
54+
python-version: '3.12'
55+
cache: 'pip'
56+
57+
- name: Install Hatch
58+
uses: pypa/hatch@install
59+
60+
- name: Install dependencies
61+
run: pip install keyring[file]
62+
63+
- name: Build package
64+
run: hatch build
65+
working-directory: openfast_io
3666

67+
- name: Publish to PyPI
68+
env:
69+
HATCH_INDEX_USER: __token__
70+
HATCH_INDEX_AUTH: ${{ secrets.PYPI_TOKEN }}
71+
run: hatch publish
72+
working-directory: openfast_io
3773

3874
docker-build-and-push:
3975
runs-on: ubuntu-latest
40-
timeout-minutes: 300
76+
if: github.event_name == 'release'
77+
timeout-minutes: 500
4178
env:
4279
DOCKERFILE_PATH: share/docker/Dockerfile
4380
DOCKERHUB_REPOSITORY: nrel/openfast

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,7 @@ vs-build/
5858
#Simulink cache files
5959
varcache
6060
*.slxc
61+
62+
# Python cache files
63+
openfast_io/dist/
64+
openfast_io/openfast_io/_version.py

docs/source/install/index.rst

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,17 +217,29 @@ You can also build your own custom images using our `Dockerfile` or base your im
217217
Install the ``openfast_io`` python wrapper
218218
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
219219
The ``openfast_io`` python package is a wrapper comprising readers and writers for converting OpenFAST files to/from
220-
python objects. You can install it with:
220+
python objects.
221221

222-
.. code-block::
222+
To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment):
223+
224+
.. code-block:: bash
223225
224226
pip install openfast_io
225227
226-
or
228+
These instructions are for interaction directly with the `openfast_io` source code.
229+
230+
1. Follow this step only if you have not cloned the OpenFAST repo:
231+
232+
.. code-block:: bash
233+
234+
git clone https://github.com/OpenFAST/OpenFAST.git
235+
cd OpenFAST
227236
228-
.. code-block::
237+
2. Assuming you are within the OpenFAST directory:
238+
239+
.. code-block:: bash
229240
230-
poetry add openfast_io
241+
cd openfast_io
242+
pip install -e .
231243
232244
For more information and installation options, see the `OpenFAST Python readme <https://github.com/OpenFAST/openfast/blob/main/openfast_python/README.md>`_.
233245

openfast_io/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# OpenFAST python readers/writers
2+
3+
This package is a python wrapper comprising readers and writers for converting OpenFAST files to/from python objects. It
4+
was originally written for [WEIS](https://github.com/WISDEM/WEIS/tree/77a878d7989b8c1d07d2244135ccd308a193a924/weis/aeroelasticse) and has been ported over to OpenFAST to make it more widely accessible.
5+
6+
## Installation
7+
Installation with [Anaconda](https://www.anaconda.com) is the recommended approach because of the ability to create self-contained environments suitable for testing and analysis.
8+
9+
### Installation as a "library"
10+
11+
To use `openfast_io` as a library for incorporation into other scripts or tools, it is available via (assuming that you have already setup your python environment):
12+
13+
```shell
14+
pip install openfast_io
15+
```
16+
17+
### Installation as an editable library
18+
19+
These instructions are for interaction directly with the `openfast_io` source code.
20+
21+
0. Follow this step only if you have not cloned the OpenFAST repo.
22+
```shell
23+
git clone https://github.com/OpenFAST/OpenFAST.git
24+
cd OpenFAST
25+
```
26+
27+
1. Assuming you are within the OpenFAST directory.
28+
```shell
29+
cd openfast_io
30+
pip install -e .
31+
```
32+
33+
2. To test `openfast_io`, OpenFAST must be compiled within the build folder, then run:
34+
35+
```shell
36+
cd tests
37+
pytest test_of_io_pytest.py
38+
```
39+
40+
### Extra options
41+
[ROSCO](https://github.com/NREL/ROSCO) can be installed as an optional dependency. Run either
42+
```shell
43+
pip install openfast_io[rosco]
44+
```
45+
46+
## Development and testing
47+
To contribute to the development of `openfast_io`, install additioal depemndancies using:
48+
49+
```shell
50+
pip install -e ".[all]"
51+
```

openfast_python/openfast_io/FAST_linearization_reader.py renamed to openfast_io/openfast_io/FAST_linearization_reader.py

File renamed without changes.

openfast_python/openfast_io/FAST_output_reader.py renamed to openfast_io/openfast_io/FAST_output_reader.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,15 @@ def toDataFrame(self):
103103
return df
104104

105105

106-
def load_ascii_output(filename):
106+
def load_ascii_output(filename, headerLines = 8, descriptionLine = 4, attributeLine = 6, unitLine = 7, delimiter = None):
107107
with open(filename) as f:
108108
info = {}
109109
info['name'] = os.path.splitext(os.path.basename(filename))[0]
110-
header = [f.readline() for _ in range(8)]
111-
info['description'] = header[4].strip()
112-
info['attribute_names'] = header[6].split()
113-
info['attribute_units'] = [unit[1:-1] for unit in header[7].split()] #removing "()"
114-
data = np.array([line.split() for line in f.readlines()], dtype=float)
110+
header = [f.readline() for _ in range(headerLines)]
111+
info['description'] = header[descriptionLine].strip()
112+
info['attribute_names'] = header[attributeLine].strip().split(delimiter)
113+
info['attribute_units'] = [unit[1:-1] for unit in header[unitLine].strip().split(delimiter)] #removing "()"
114+
data = np.array([line.split(delimiter) for line in f.readlines()], dtype=float)
115115
return data, info
116116

117117
def load_binary_output(filename):
@@ -211,16 +211,20 @@ def fread(fid, n, type):
211211

212212

213213
if __name__=="__main__":
214-
d,i = load_binary_output('Test18.T1.outb')
215-
types = []
216-
for j in range(39):
217-
types.append('f8')
218-
print(type(i['attribute_names']))
219214

220-
print(np.dtype({'names':tuple(i['attribute_names']), 'formats': tuple(types) }))
221-
print(type(d))
222-
print(np.array(d,dtype=np.dtype({'names':tuple(i['attribute_names']), 'formats': tuple(types) })))
215+
from openfast_io.FileTools import check_rtest_cloned
216+
217+
parent_dir = os.path.dirname( os.path.dirname( os.path.dirname( os.path.realpath(__file__) ) ) ) + os.sep
218+
219+
of_outputfile = os.path.join(parent_dir, 'reg_tests', 'r-test', 'glue-codes',
220+
'openfast', '5MW_Land_BD_DLL_WTurb', '5MW_Land_BD_DLL_WTurb.outb')
223221

222+
check_rtest_cloned(of_outputfile)
223+
224+
d,i,p = load_binary_output(of_outputfile)
225+
226+
print(tuple(i['attribute_names']))
227+
print(type(d))
224228
print(i)
225229
print(len(i['attribute_names']))
226230
print(np.shape(d))

0 commit comments

Comments
 (0)