Skip to content

Commit 6ea0335

Browse files
committed
Allow !include tag in ontology yaml
-- yaml loader added a constructor function in helpers.py to allow !inlcude tag - !include <yaml filename> will then input the contents of that file into the main yaml when reading it in -- small update to project.addMooring() to allow input of a subsystem in lieu of a design dictionary -- small bug fix in project.addMooring()
1 parent 54f31dd commit 6ea0335

File tree

2 files changed

+75
-13
lines changed

2 files changed

+75
-13
lines changed

famodel/helpers.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,64 @@ def unitVector(r):
6767
return r/L
6868

6969

70+
def loadYAML(filename):
71+
'''
72+
Loads a YAML file, allowing !include <filename> to include another yaml
73+
in the file.
74+
75+
Parameters
76+
----------
77+
filename : str
78+
Filename (including path if needed) of main yaml file to load
79+
80+
Returns
81+
-------
82+
info : dict
83+
Dictionary loaded from yaml
84+
85+
'''
86+
87+
with open(filename) as file:
88+
loader = yaml.FullLoader
89+
loader.add_constructor('!include',yamlInclude)
90+
project = yaml.load(file, Loader=loader)
91+
if not project:
92+
raise Exception(f'File {file} does not exist or cannot be read. Please check filename.')
93+
94+
return(project)
7095

96+
def yamlInclude(loader, node):
97+
'''
98+
Custom constructor that allows !include tag to include another yaml in
99+
the main yaml
100+
101+
Parameters
102+
----------
103+
loader : YAML loader object
104+
node : YAML node
105+
YAML node for include
106+
107+
Returns
108+
-------
109+
None.
110+
111+
'''
112+
# pull out f
113+
file_to_include = loader.construct_scalar(node)
114+
# pull out absolute path of file
115+
# if os.path.isabs(file_to_include):
116+
# included_yaml = file_to_include
117+
# else:
118+
# dir =
119+
included_yaml = os.path.abspath(file_to_include)
120+
try:
121+
with open(included_yaml) as file:
122+
return(yaml.load(file,Loader=loader.__class__))
123+
except FileNotFoundError:
124+
raise FileNotFoundError(f"Included file {included_yaml} not found")
125+
except Exception as err:
126+
raise Exception(f"Error ocurred while loading included file {included_yaml}: {err}")
127+
71128

72129
# ----- Cable routing support functions -----
73130

famodel/project.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
# Import select required helper functions
3535
from famodel.helpers import (check_headings, head_adjust, getCableDD, getDynamicCables,
3636
getMoorings, getAnchors, getFromDict, cleanDataTypes,
37-
getStaticCables, getCableDesign,m2nm)
37+
getStaticCables, getCableDesign,m2nm, loadYAML)
3838

3939

4040
class Project():
@@ -129,7 +129,7 @@ def __init__(self, lon=0, lat=0, file=None, depth=202,raft=1):
129129

130130

131131

132-
def load(self, info,raft=1):
132+
def load(self, info, raft=True):
133133
'''
134134
Load a full set of project information from a dictionary or
135135
YAML file. This calls other methods for each part of it.
@@ -141,10 +141,12 @@ def load(self, info,raft=1):
141141
'''
142142
# standard function to load dict if input is yaml
143143
if isinstance(info,str):
144-
with open(info) as file:
145-
project = yaml.load(file, Loader=yaml.FullLoader)
146-
if not project:
147-
raise Exception(f'File {file} does not exist or cannot be read. Please check filename.')
144+
145+
# with open(info) as file:
146+
# project = yaml.load(file, Loader=yaml.FullLoader)
147+
# if not project:
148+
# raise Exception(f'File {file} does not exist or cannot be read. Please check filename.')
149+
project = loadYAML(info)
148150
else:
149151
project = info
150152

@@ -161,7 +163,7 @@ def load(self, info,raft=1):
161163

162164
# ----- Design loading/processing methods -----
163165

164-
def loadDesign(self, d, raft=1):
166+
def loadDesign(self, d, raft=True):
165167
'''Load design information from a dictionary or YAML file
166168
(specified by input). This should be the design portion of
167169
the floating wind array ontology.'''
@@ -1485,7 +1487,8 @@ def addPlatform(self,r=[0,0,0], id=None, phi=0, entity='',
14851487
def addMooring(self, id=None, endA=None, endB=None, heading=0, dd={},
14861488
section_types=[], section_lengths=[],
14871489
connectors=[], span=0, shared=0, reposition=False, adjuster=None,
1488-
method = 'horizontal', target = None, i_line = 0):
1490+
method = 'horizontal', target = None, i_line = 0, subsystem=None):
1491+
14891492
'''
14901493
Function to create a mooring object and save in mooringList
14911494
Optionally does the following:
@@ -1552,7 +1555,7 @@ def addMooring(self, id=None, endA=None, endB=None, heading=0, dd={},
15521555
else:
15531556
id = 'moor'+str(len(self.mooringList))
15541557

1555-
if not dd:
1558+
if not dd and len(section_types) > 0:
15561559
sections = [{'type':section_types[i],'L':section_lengths[i]} for i in range(len(section_types))]
15571560
if len(connectors) == 0 and len(sections) != 0:
15581561
connectors = [{}]*len(sections)+1
@@ -1563,21 +1566,23 @@ def addMooring(self, id=None, endA=None, endB=None, heading=0, dd={},
15631566
'rad_fair':self.platformList[id_part[0]].rFair if id_part else 0,
15641567
'z_fair':self.platformList[id_part[0]].zFair if id_part else 0}
15651568

1566-
mooring = Mooring(dd=dd, id=id) # create mooring object
1569+
mooring = Mooring(dd=dd, id=id, subsystem=subsystem) # create mooring object
15671570

15681571
#calculate target pretension or horizontal tension if none provided
15691572
if adjuster != None and target == None:
1570-
targetdd = deepcopy(dd)
1573+
targetdd = deepcopy(mooring.dd)
15711574
targetdd['zAnchor'] = self.depth
1572-
mooring.createSubsystem(dd)
1575+
mooring.createSubsystem()
15731576

15741577
if method == 'horizontal':
15751578
mooring.target = np.linalg.norm(mooring.ss.fB_L[:2])
15761579
elif method =='pretension':
15771580
mooring.target = np.linalg.norm(mooring.ss.fB_L)
15781581
else:
15791582
raise Exception('Invalid adjustment method. Must be pretension or horizontal')
1580-
1583+
else:
1584+
mooring.target = target
1585+
15811586
# update shared prop if needed
15821587
if len(id_part)==2 and shared<1:
15831588
shared = 1

0 commit comments

Comments
 (0)