forked from OpenFAST/openfast_toolbox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bmodes_out_file.py
152 lines (130 loc) · 5.21 KB
/
bmodes_out_file.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"""
Input/output class for the BModes output files
"""
import numpy as np
import pandas as pd
import os
try:
from .file import File, WrongFormatError, BrokenFormatError
except:
File=dict
EmptyFileError = type('EmptyFileError', (Exception,),{})
WrongFormatError = type('WrongFormatError', (Exception,),{})
BrokenFormatError = type('BrokenFormatError', (Exception,),{})
class BModesOutFile(File):
"""
Read/write a BModes output file. The object behaves as a dictionary.
Main methods
------------
- read, write, toDataFrame, keys
Examples
--------
f = BModesOutFile('file.out')
print(f.keys())
print(f.toDataFrame().columns)
"""
@staticmethod
def defaultExtensions():
""" List of file extensions expected for this fileformat"""
return ['.out']
@staticmethod
def formatName():
""" Short string (~100 char) identifying the file format"""
return 'BModes output file'
def __init__(self, filename=None, **kwargs):
""" Class constructor. If a `filename` is given, the file is read. """
self.filename = filename
if filename:
self.read(**kwargs)
def read(self, filename=None, **kwargs):
""" Reads the file self.filename, or `filename` if provided """
# --- Standard tests and exceptions (generic code)
if filename:
self.filename = filename
if not self.filename:
raise Exception('No filename provided')
if not os.path.isfile(self.filename):
raise OSError(2,'File not found:',self.filename)
if os.stat(self.filename).st_size == 0:
raise EmptyFileError('File is empty:',self.filename)
# --- Calling (children) function to read
self._read(**kwargs)
def write(self, filename=None):
""" Rewrite object to file, or write object to `filename` if provided """
if filename:
self.filename = filename
if not self.filename:
raise Exception('No filename provided')
# Calling (children) function to write
self._write()
def _read(self):
""" Reads self.filename and stores data into self. Self is (or behaves like) a dictionary"""
# --- Example:
#self['data']=[]
#with open(self.filename, 'r', errors="surrogateescape") as f:
# for i, line in enumerate(f):
# self['data'].append(line)
with open(self.filename) as f:
self['frequencies'] = []
self['mode_shapes'] = []
row_string = f.readline()
if row_string.find('BModes')<0:
raise WrongFormatError('This file was not generated by BModes, "BModes" is not found on first line')
while row_string:
row_string = f.readline()
freq_id = row_string.find('freq = ')
if freq_id > 0:
self['frequencies'].append(float(row_string[freq_id+7:freq_id+19]))
f.readline()
f.readline()
f.readline()
data=[]
while True:
row_data = f.readline()
if len(row_data.strip())==0 or row_data.find('===')==0:
break
else:
data.append(row_data.split())
self['mode_shapes'].append(np.asarray(data).astype(float))
def _write(self):
""" Writes to self.filename"""
# --- Example:
#with open(self.filename,'w') as f:
# f.write(self.toString)
raise NotImplementedError()
def toDataFrame(self):
""" Returns object into one DataFrame, or a dictionary of DataFrames"""
dfs={}
cols =['span_loc','s-s disp','s-s slope','f-a disp','f-a slope','twist']
for iMode,mode in enumerate(self['mode_shapes']):
dfs['Mode_{}'.format(iMode+1)]= pd.DataFrame(data=mode,columns=cols)
return dfs
# --- Optional functions
def __repr__(self):
""" String that is written to screen when the user calls `print()` on the object.
Provide short and relevant information to save time for the user.
"""
s='<{} object>:\n'.format(type(self).__name__)
s+='|Main attributes:\n'
s+='| - filename: {}\n'.format(self.filename)
# --- Example printing some relevant information for user
s+='|Main keys:\n'
s+='| - frequencies: {}\n'.format(self['frequencies'])
s+='| - mode_shapes : {} shapes of shape {}x{}\n'.format(len(self['mode_shapes']), *self['mode_shapes'][0].shape)
s+='|Main methods:\n'
s+='| - read, write, toDataFrame, keys'
return s
def _get_modal_coefficients(x, y, deg=[2, 3, 4, 5, 6]):
# Normalize x input
xn = (x - x.min()) / (x.max() - x.min())
# Get coefficients to 6th order polynomial
p6 = np.polynomial.polynomial.polyfit(xn, y, deg)
return p6
def _identify(self):
""" identify modes"""
pass
if __name__ == '__main__':
f = BModesOutFile('tests/example_files/BModesOut.out')
df = f.toDataFrame()
print(f)
print(df)