Project object model
cabledyn.project describes a complete CableDyn model as a graph of plain Python objects.
It is the model layer of the planned graphical front end and is also usable from scripts. It
has no GUI-toolkit dependency.
The package is under development: its classes and the project-file schema may change before they are used by a released front end.
Design
- Objects and properties
Every object is a
ModelObjectwith a stableuid, aname, aparentand typed properties declared with descriptors (Quantity,Integer,Choice,Vec3,Ref,Children,Strategy, …). Quantities are stored in SI units (angles in degrees, as in the deck); non-finite numbers are refused. Each property has a role:physics(written to the deck),construction(library and construction data such as a chain grade or a floater’s hydrodynamic database; not written today),appearance(for the 3D views; never written),derivedormeta.ModelObject.properties()lists the descriptors, which carry label, group, unit dimension, limits and documentation for editors. A value whose meaning changes with its sign in the deck is split: the axial damping is either a damping in N s or a dimensionless damping ratio (AxialModel).- Identity and ownership
Every object has one owner and a uid that is unique in its project: inserting an object whose uid is already used, or making an object own one of its owners, is refused.
ModelObject.from_dict()gives a copy fresh uids by default; passwithin=projectso the copy keeps its references to the project’s objects (paste).- References, renaming and removal
Objects refer to each other by reference, never by name or deck id, so renaming cannot break a link. Removing a referenced object either fails with
ObjectInUseErroror cascades (plan_removal()): a referrer whose required reference is lost is removed with it (ModelObject.required_references(), which can depend on the referrer’s state, such as a body rod’s body), an optional reference is cleared, and a line left without sections is removed. Weak references, such as group memberships, never block a removal and are cleared.Project.used_by()answers “used by” questions.- Events and commands
A change publishes
PropertyChanged,ReferenceChanged,ChildAdded,ChildRemovedorChildMovedon the object and on every ancestor, so one subscription on theProjectsees the whole model. Interactive edits areCommandobjects pushed onto aCommandStack, which provides undo, redo, merging of drags, grouping (CommandStack.macro()) and a clean (saved) marker. Undo restores the project’sto_dict()exactly. A change listener must not push, undo or redo while a command is being applied; the stack refuses it.- Validation
Three layers (
validate_project()): property checks with the numeric limits shared with the deck reader (cabledyn.project.schema), object invariants (references resolve, lines have sections, arc locations lie on the line, names the deck needs are unique), and the native deck rules, applied by writing the deck and reading it withcabledyn.DeckFile. A deck error is mapped back to the object whose row failed. No deck rule is restated in the object model.- Units
UnitSystemholds the display unit chosen for eachDimension; values are converted only for display.cabledyn.project.units.parse_quantity()reads text such as"1.2 MN".- Floaters
The object model uses the term floater:
Floaterbodies,FloaterPoint, the sharedFloaterTypelibrary entry, and the motion sourcesFloaterMotionRecordandFloaterRAO. The deck keeps its ownVesselkeywords (Vesselpoints and bodies,vesselMotion,vesselRAO,vesselRef), which the deck adapters map. Thehydrodynamicsproperty ofFloaterTypeis the slot for a hydrodynamic database: new database kinds register asHydroDatabasesubclasses.
Deck adapters and the project file
DeckReader reads a deck through cabledyn.DeckModel and builds the object
graph; DeckWriter builds a fresh DeckModel and renders it. Deck ids,
keyword spellings, the order and descriptions of OPTIONS rows are kept as hints, so a
deck read and written back gives exactly DeckModel.load(deck).to_text(). Comments and
column alignment of the original file are not kept. OPTIONS rows the model does not type are
kept verbatim as ExtraOption objects. An extra row that sets a typed option (a duplicate
kept from a deck, for example) never overrides the typed property: the writer places it before
the typed row, and validation warns about it. The writer returns an IdMap between
objects and deck ids.
from cabledyn.project import CommandStack, DeckReader, DeckWriter, ProjectStore
from cabledyn.project.commands import SetProperty
project = DeckReader.read("examples/lazy_wave_buoyancy_modules.dat")
stack = CommandStack()
stack.push(SetProperty(project.lines[0].sections[0], "length", 120.0))
stack.undo()
ProjectStore.save(project, "lazy_wave.cdproj")
text = DeckWriter(project).to_text()
ProjectStore writes a .cdproj zip archive (or an unzipped folder) with
project.json (the whole graph, physics and appearance, as strict JSON with a schema
version), model.dat, assets/ and results.json. model.dat is written only when
the project passes every validation layer. Its relative side-file paths (motion, bathymetry,
WaterKin and Syrope files) are rewritten to resolve from the project folder (a folder project)
or from the folder that holds the archive (a zip project), and side files that cannot be found
are listed in project.json. Each file is replaced atomically. Objects, properties and
references the reader does not understand are kept and written back unchanged.
Extending the model
A new object kind is a ModelObject subclass registered with model_type():
from cabledyn.project import HydroDatabase, model_type
from cabledyn.project.descriptors import FilePath
@model_type("myplugin.hydro.tabulated")
class TabulatedDatabase(HydroDatabase):
"""Hydrodynamic coefficients read from a table."""
table = FilePath()
API reference
Base classes, descriptors and events
- class cabledyn.project.ModelObject(name='', /, **values)
Base class of every object in a CableDyn project.
- Parameters:
name (str) – Object name, shown in the browser. Names need not be unique, except where the deck needs it (line and rod type names).
**values (object) – Initial property values, by property name.
- Raises:
AttributeError – If a keyword is not a settable property of the class.
Notes
Assigning a property (
line.outputs = "pt") validates its type and publishes a change event, but is not undoable. Interactive edits go throughcabledyn.project.commandsand aCommandStack.- type_key = 'object'
Stable type key in project files (set by
model_type()).
- type_label = 'Object'
Human-readable class name for the GUI.
- abstract = True
Set
abstract = Truein a class body to mark that class (not its subclasses) abstract; read it withis_abstract().
- classmethod is_abstract()
Whether this class itself is abstract (not offered as a strategy option).
- classmethod properties()
Return the property descriptors, base-class properties first.
- classmethod get_property(name)
Return the descriptor called
name.- Raises:
KeyError – If the class has no such property.
- property uid
Stable unique identifier (32 hexadecimal characters).
- property parent
The owning object, or
Nonefor a root or a detached object.
- property slot
Name of the parent’s property that owns this object.
- label()
Return a short description such as
Line 'Mooring 1'.
- root()
Return the top-most ancestor (the project, when attached).
- get_value(name)
Return the value of property
name.
- set_value(name, value)
Set property
name(as attribute assignment does).
- children()
Yield the directly owned sub-objects, in property order.
- walk()
Yield this object and every owned descendant, depth first.
- references()
Return the outgoing references as
(property name, target)pairs.
- required_references()
Return the names of the references this object cannot do without now.
A cascading removal that takes the target of one of them removes this object too. The base returns the
Refproperties declaredrequired; subclasses add conditional ones.
- emit(event)
Publish
eventon this object’s hub and on every ancestor’s hub.
- invariants()
Return the layer-2 issues of this object (structural invariants).
Subclasses extend this; the base checks references and collection sizes declared by the descriptors.
- validate(*, recursive=False)
Return the layer-1 and layer-2 issues of this object.
- Parameters:
recursive (bool) – Also validate every owned descendant.
- Returns:
Property-check issues (layer 1), then reference and invariant issues (layer 2).
- Return type:
list[Issue]
- to_dict(ctx=None)
Return the JSON-compatible form of this object and its descendants.
References are written as the target’s uid. Raw values kept from a project file (see
SerialContext) are written back unchanged.- Raises:
TypeError – If the class is not registered with
model_type()(it would be read back as another class).
- classmethod from_dict(data, *, fresh_uids=True, within=None)
Rebuild an object (and its descendants) written by
to_dict().The copy gets new uids by default, so it can be pasted next to the original. References to objects outside
dataare kept raw (seeSerialContext).- Parameters:
data (dict) – The dictionary.
fresh_uids (bool) – Give the rebuilt objects new uids;
Falsekeeps the stored ones.within (ModelObject | None) – The graph the copy will join (normally the project): references to its objects resolve, so a pasted line keeps its end points.
- Returns:
The rebuilt object.
- Return type:
- Raises:
TypeError – If
datadoes not describe aclsobject.
- class cabledyn.project.ObjectCollection(owner, name, item_type)
An ordered list of objects owned by one model object.
The collection is the value of a
Childrenproperty. Inserting an object makes the owner its parent; removing it clears the parent. Every change publishesChildAdded,ChildRemoved, orChildMovedon the owner. An object can belong to one collection at a time.- Parameters:
owner (ModelObject) – The owning object.
name (str) – The property name of the collection on
owner.item_type (type) – The class every item must be an instance of.
- property owner
The owning object.
- property name
The collection’s property name on its owner.
- property item_type
The class of the items.
- index(item)
Return the position of
item(identity, not equality).- Raises:
ValueError – If
itemis not in the collection.
- find(name)
Return the first item called
name(case-insensitive), orNone.
- by_uid(uid)
Return the item with
uid, orNone.
- insert(index, item)
Insert
itembeforeindex(clamped to the collection).- Raises:
TypeError – If
itemhas the wrong type.ValueError – If
itemalready has a parent, would own its own owner, or brings a uid the project already uses.
- append(item)
Append
itemand return it.
- extend(items)
Append several items in order.
- remove(item)
Remove
itemand return its former position.- Raises:
ValueError – If
itemis not in the collection.
- move(item, index)
Move
itemto positionindex(clamped).
- clear()
Remove every item, last first.
- cabledyn.project.model_type(key)
Class decorator registering a model class under a stable type key.
- Parameters:
key (str) – Stable key written to project files, for example
"line".- Returns:
The decorator; it returns the class unchanged.
- Return type:
Callable
Examples
>>> from cabledyn.project import ModelObject, Quantity, model_type >>> @model_type("example.marker") ... class Marker(ModelObject): ... height = Quantity(default=1.0) >>> Marker("m1").height 1.0
- class cabledyn.project.TypeRegistry
Maps stable type keys to model classes (and back).
The project file stores each object’s key; a plugin registers new object kinds here (see
model_type()).- register(key, cls)
Register
clsunderkey.- Raises:
ValueError – If
keyis taken by another class.
- unregister(key)
Remove the class registered under
key(no-op if none).
- get(key)
Return the class registered under
key.- Raises:
UnknownTypeError – If no class is registered under
key.
- keys()
Return the registered keys, sorted.
- subclasses_of(base)
Return the registered concrete classes that are
baseor derive from it.
- exception cabledyn.project.UnknownTypeError
A type key is not registered.
- class cabledyn.project.SerialContext(*, fresh_uids=False, within=None)
State of one project-file read or write.
It maps uids to rebuilt objects, defers references until every object exists, and collects objects of unknown type (kept verbatim), duplicate uids and warnings.
Values this version cannot use (an unknown property, a value a property refuses, a reference to an object that is not rebuilt, a sub-object of unknown type) are kept raw on the object and written back unchanged by
ModelObject.to_dict()until the property is assigned.- Parameters:
fresh_uids (bool) – Give rebuilt objects new uids (for copy and paste) instead of the stored ones. References inside the rebuilt data still resolve.
within (ModelObject | None) – An existing object graph (the project a copy is pasted into); references to its objects resolve to them.
- warn(message)
Record a warning.
- build(data, *, owner=None, slot=None, index=None)
Rebuild one object from its dictionary, or keep it verbatim if unknown.
- Returns:
The object, or
Nonefor an unknown type (recorded inunknown).- Return type:
ModelObject | None
- defer(obj, prop, data)
Resolve a reference once every object exists.
- lookup(uid)
Return the rebuilt object with
uid.- Raises:
KeyError – If no rebuilt object has
uid.
- resolve()
Resolve every deferred reference; dangling ones become warnings.
- class cabledyn.project.Role(*values)
What a property describes, and whether the deck writer reads it.
- PHYSICS = 'physics'
Solver input, written to the deck.
- CONSTRUCTION = 'construction'
Construction or library data (chain grade, rope construction, floater hydrodynamics); not written to the deck today.
- APPEARANCE = 'appearance'
Cosmetic data for the 3D views; never written to the deck.
- DERIVED = 'derived'
Computed, read-only, shown for information.
- META = 'meta'
Identity and bookkeeping (name, description, tags, GUI data).
- class cabledyn.project.Property(default, *, role=Role.PHYSICS, group='', label='', doc='', read_only=False)
Base class of every property descriptor.
- Parameters:
default (object) – Value of a new object.
role (Role) – Physics, construction, appearance, derived, or meta.
group (str) – Property-panel group, for example
"Hydrodynamics".label (str) – Display label; derived from the attribute name when empty.
doc (str) – One-sentence description for tooltips and generated documentation.
read_only (bool) – Shown but not editable in the property panel.
- coerce(value)
Return
valueconverted to the stored type.- Raises:
TypeError – If
valuehas the wrong type.ValueError – If
valuecannot be stored at all (for example a bad choice).
- check(obj, value)
Return the layer-1 issues of
value(finiteness and limits).
- describe()
Return a JSON-compatible description, for documentation and editors.
- class cabledyn.project.Quantity(dimension=Dimension(key='dimensionless', label='Dimensionless', si='-'), default=0.0, *, minimum=None, maximum=None, limit=None, **kwargs)
A real number with a physical dimension, stored in SI units (angles in degrees).
- Parameters:
dimension (Dimension) – What the value measures.
default (float) – Value of a new object.
minimum (float | None) – Inclusive bounds checked by validation layer 1.
maximum (float | None) – Inclusive bounds checked by validation layer 1.
limit (str | None) – Key of a shared deck limit (
cabledyn.project.schema.DECK_LIMITS).**kwargs – Role, group, label, doc, read_only (see
Property).
- class cabledyn.project.OptionalQuantity(dimension=Dimension(key='dimensionless', label='Dimensionless', si='-'), default=None, *, minimum=None, maximum=None, limit=None, **kwargs)
A
Quantitythat may be unset (None).Parameters are those of
Quantity; the default isNone.
- class cabledyn.project.Integer(default=0, *, minimum=None, maximum=None, limit=None, **kwargs)
An integer.
- Parameters:
default (int) – Value of a new object.
minimum (int | None) – Inclusive bounds.
maximum (int | None) – Inclusive bounds.
limit (str | None) – Key of a shared deck limit.
**kwargs – See
Property.
- class cabledyn.project.OptionalInteger(default=None, *, minimum=None, maximum=None, limit=None, **kwargs)
An
Integerthat may be unset (None).
- class cabledyn.project.Bool(default=False, **kwargs)
A Boolean flag.
- class cabledyn.project.OptionalBool(default=None, **kwargs)
A Boolean flag that may be unset (
None: the native default applies).
- class cabledyn.project.Choice(choices, default='', **kwargs)
One of a fixed set of strings.
- Parameters:
choices (Sequence[str]) – The admissible values.
default (str) – Value of a new object; the first choice when empty.
**kwargs – See
Property.
- class cabledyn.project.Text(default='', *, multiline=False, **kwargs)
A free-text string (single line unless
multiline).
- class cabledyn.project.OptionalText(default=None, **kwargs)
A string that may be unset (
None).
- class cabledyn.project.FilePath(default=None, **kwargs)
A file path, relative to the project’s deck folder or absolute; may be unset.
- class cabledyn.project.TextList(default=(), **kwargs)
An ordered tuple of strings (for example tags).
- class cabledyn.project.Colour(default='#808080', **kwargs)
An sRGB colour written
#rrggbb; an appearance property by default.
- class cabledyn.project.OptionalColour(default=None, **kwargs)
A
Colourthat may be unset (None: inherit).
- class cabledyn.project.Vector(dimension=Dimension(key='dimensionless', label='Dimensionless', si='-'), default=(0.0,), *, lengths=(1, 3), limit=None, **kwargs)
A tuple of real numbers of one dimension, with admissible lengths.
Used for deck fields that take one or several values (
a|b|c), such as a body’s drag areas.
- class cabledyn.project.Vec3(dimension=Dimension(key='dimensionless', label='Dimensionless', si='-'), default=(0.0, 0.0, 0.0), *, limit=None, **kwargs)
A three-component vector
(x, y, z)of one dimension.
- class cabledyn.project.OptionalVec3(dimension=Dimension(key='dimensionless', label='Dimensionless', si='-'), default=None, *, limit=None, **kwargs)
A
Vec3that may be unset (None).
- class cabledyn.project.JsonValue(default=None, **kwargs)
Opaque JSON-compatible data (GUI layouts, plot specifications, …).
The value must be JSON data (dictionaries with string keys, lists, strings, finite numbers, Booleans,
None); it is copied on assignment and never written to a deck.
- class cabledyn.project.Ref(target, *, required=True, weak=False, **kwargs)
A reference to another object of the model (not to a name or an id).
Renaming the target never breaks the reference. Removing a referenced object either fails or cascades (see
cabledyn.project.commands.RemoveObject): a referrer whoserequiredreference loses its target is removed with it, and an optional reference is cleared.- Parameters:
target (type) – The class (or common base class) of admissible targets.
required (bool) – A missing target is an error (validation layer 2). An object can make a reference required conditionally with
ModelObject.required_references().weak (bool) – A bookkeeping reference (for example a group membership): it never blocks a removal, is cleared when its target goes, and is left out of “used by”.
**kwargs – See
Property.
- class cabledyn.project.RefList(target, *, min_items=0, weak=False, **kwargs)
An ordered tuple of references to other objects.
- class cabledyn.project.Child(base, factory=None, **kwargs)
One owned sub-object, created with the owner and replaceable as a whole.
- Parameters:
base (type) – Class of the sub-object (subclasses are admissible).
factory (Callable[[], ModelObject] | None) – Creates the default sub-object;
baseitself whenNone.**kwargs – See
Property.
- class cabledyn.project.Strategy(base, factory=None, **kwargs)
A polymorphic sub-object such as an axial model or a wave model.
Any registered subclass of
basecan be swapped in (seecabledyn.project.commands.ReplaceStrategy);options()lists them for an editor.- options()
Return the registered concrete classes admissible here.
- class cabledyn.project.Children(item_type, *, min_items=0, **kwargs)
An owned, ordered, observable collection of sub-objects.
The collection itself cannot be replaced; insert, remove, and move items through it (or through commands, for undo).
- Parameters:
item_type (type) – Class of the items.
min_items (int) – Fewest items; a cascading removal that leaves fewer removes the owner.
**kwargs – See
Property.
- class cabledyn.project.EventHub
A list of listeners called synchronously, in subscription order.
- class cabledyn.project.Subscription(hub, listener)
Handle returned by
EventHub.subscribe(); callcancel()to stop.- cancel()
Stop delivering events to the listener (idempotent).
- class cabledyn.project.Event(source)
Base class of every model event.
- source
The object whose state changed.
- Type:
- class cabledyn.project.PropertyChanged(source, name, old, new)
A value property (number, text, choice, child object) changed.
- name
Property name.
- Type:
str
- old, new
Previous and new value.
- Type:
object
- class cabledyn.project.ReferenceChanged(source, name, old, new)
A reference property (
ReforRefList) now points elsewhere.- name
Property name.
- Type:
str
- old, new
Previous and new target (an object, a tuple of objects, or
None).- Type:
object
- class cabledyn.project.ChildAdded(source, collection, child, index)
An object was inserted into a child collection of
source.- child
The inserted object.
- Type:
- index
Its position.
- Type:
int
- class cabledyn.project.ChildRemoved(source, collection, child, index)
An object was removed from a child collection of
source.- collection
Name of the collection.
- Type:
str
- child
The removed object.
- Type:
- index
Its former position.
- Type:
int
Project and model objects
- class cabledyn.project.Project(name='', /, **values)
A CableDyn model: environment, settings, libraries, objects and GUI data.
Examples
>>> from cabledyn.project import ( ... FixedPoint, FloaterPoint, GenericLineType, Line, Project, Section) >>> project = Project("Single chain") >>> chain = project.line_types.append(GenericLineType("chain", diameter=0.252)) >>> fairlead = project.points.append(FloaterPoint("fairlead", position=(0, 0, -14))) >>> anchor = project.points.append(FixedPoint("anchor", position=(400, 0, -50))) >>> line = project.lines.append(Line("mooring", end_a=fairlead, end_b=anchor)) >>> _ = line.sections.append(Section(line_type=chain, length=410.0, segments=41)) >>> line.length 410.0
- find(uid)
Return the object with
uidanywhere in the project, orNone.
- objects_of(kind)
Yield every object of class
kindin the project, depth first.
- used_by(obj)
Return the objects (and property names) that refer to
objor its descendants.Referrers inside
objitself are not listed.
- class cabledyn.project.Environment(name='', /, **values)
Water, gravity, waves and current.
- class cabledyn.project.WaveModel(name='', /, **values)
Base class of the wave models (the deck’s
wavesandwavetrainrows).
- class cabledyn.project.NoWaves(name='', /, **values)
Still water.
- class cabledyn.project.RegularWave(name='', /, **values)
A regular wave: linear (Airy) or nonlinear stream-function theory.
- class cabledyn.project.JonswapWave(name='', /, **values)
A JONSWAP sea state.
- class cabledyn.project.SpectrumWave(name='', /, **values)
A two-parameter spectral sea state (Pierson-Moskowitz family, Torsethaugen).
- class cabledyn.project.OchiHubbleWave(name='', /, **values)
A two-peak Ochi-Hubble sea state.
- class cabledyn.project.MultiTrainSea(name='', /, **values)
A sea made of several wave trains (swell and wind sea, for example).
- class cabledyn.project.WaveTrain(name='', /, **values)
One wave train of a multi-train sea (one deck
wavetrainrow).
- class cabledyn.project.CurrentModel(name='', /, **values)
Base class of the current models (the deck’s
currentrow).
- class cabledyn.project.NoCurrent(name='', /, **values)
No current.
- class cabledyn.project.UniformCurrent(name='', /, **values)
A depth-uniform current.
- class cabledyn.project.ProfileCurrent(name='', /, **values)
A current varying linearly between two depths.
- class cabledyn.project.Seabed(name='', /, **values)
Base class of the seabed descriptions; holds the contact properties.
- class cabledyn.project.FlatSeabed(name='', /, **values)
A horizontal seabed at the environment’s water depth.
- class cabledyn.project.BathymetrySeabed(name='', /, **values)
A seabed from a structured x/y/depth bathymetry file.
- class cabledyn.project.MotionSource(name='', /, **values)
Base class of the prescribed-motion sources of a standalone run.
The deck keywords
motionFile,vesselMotion,vesselRAOandvesselRefmap toMotionFile,FloaterMotionRecord,FloaterRAOandreference.
- class cabledyn.project.NoMotion(name='', /, **values)
No prescribed motion.
- class cabledyn.project.MotionFile(name='', /, **values)
Point, rod-end and body motion from a time-series file.
- class cabledyn.project.FloaterMotionRecord(name='', /, **values)
A 6-DOF floater record moving every floater-borne point rigidly.
- class cabledyn.project.FloaterRAO(name='', /, **values)
Floater motion as the RAO response to the waves.
- class cabledyn.project.AnalysisSettings(name='', /, **values)
Run, statics, dynamics, modal and compatibility options.
- class cabledyn.project.ExtraOption(name='', /, **values)
An
OPTIONSrow kept verbatim (keyword, value tokens, description).
- class cabledyn.project.LineType(name='', /, **values)
Base class of the line types (one deck
LINE TYPESrow each).
- class cabledyn.project.GenericLineType(name='', /, **values)
A line type given only by its physics (the form a deck import produces).
- class cabledyn.project.ChainType(name='', /, **values)
Mooring chain.
- class cabledyn.project.WireRopeType(name='', /, **values)
Steel wire rope.
- class cabledyn.project.FibreRopeType(name='', /, **values)
Synthetic fibre rope.
- class cabledyn.project.CableType(name='', /, **values)
Power or umbilical cable.
- class cabledyn.project.AxialModel(name='', /, **values)
Base class of the axial (tension-strain) models of a line type.
The deck’s
BAcolumn holds an axial damping in N s, or a negative value meaning a damping ratio. The two meanings have different units, so the model keeps them apart:damping_modechoosesdamping(damping, N s) orratio(damping_ratio, dimensionless, written as its negative).dynamic_dampingis the optional second valueBdof a two-spring model.
- class cabledyn.project.LinearAxial(name='', /, **values)
Linear-elastic axial stiffness EA.
- class cabledyn.project.ViscoelasticAxial(name='', /, **values)
Two-spring viscoelastic stiffness:
Es|EdorEs|alphaMBL|vbeta.
- class cabledyn.project.SyropeAxial(name='', /, **values)
Syrope working-curve stiffness with a tension-dependent fast spring.
- class cabledyn.project.BendingModel(name='', /, **values)
Bending, shear and torsion data of a line type (the finite-EI columns).
- class cabledyn.project.RodType(name='', /, **values)
A rod type (one deck
ROD TYPESrow).
- class cabledyn.project.FloaterType(name='', /, **values)
A shared description of a floater (hull), referenced by
Floaterobjects.The physical description and the hydrodynamic database are construction data: the deck holds each floater as a prescribed-motion or rigid body row, so none of this is written to the deck today.
- class cabledyn.project.HydroDatabase(name='', /, **values)
Base class of a floater type’s hydrodynamic database.
This is the extension point for a time-domain floater solver: a database kind (added mass, radiation damping and retardation functions, first-order excitation and RAOs, second-order drift, hydrostatics, wind and current load coefficients, imported from a radiation-diffraction tool) registers as a subclass with
cabledyn.project.model_type(). Today floaters move by prescribed motion or as rigid bodies, and no database is written to the deck.
- class cabledyn.project.NoHydroDatabase(name='', /, **values)
No hydrodynamic database.
- class cabledyn.project.HydroDatabaseFile(name='', /, **values)
A reference to a hydrodynamic database file produced by another tool.
- class cabledyn.project.Body(name='', /, **values)
Base class of the bodies: pose, mass properties and hydrodynamics.
The deck has two
BODIESrow layouts. The CableDyn layout carries the hydrostatic restoring terms and three optional inertias; the MoorDyn layout carries a centre of gravity and multi-valued drag and added-mass entries.row_formatrecords which one the body uses.
- class cabledyn.project.Rigid6Body(name='', /, **values)
A free six-degree-of-freedom rigid body (deck
Rigid6, MoorDynFree).
- class cabledyn.project.Point3Body(name='', /, **values)
A three-degree-of-freedom point body (deck
Point3).
- class cabledyn.project.Floater(name='', /, **values)
A floater moved by the coupling host or by the prescribed motion.
The deck body types
CoupledandVesselmap tokind"coupled"and"floater"; the solver moves both kinds alike.
- class cabledyn.project.Turbine(name='', /, **values)
A FAST.Farm turbine of a standalone farm deck (
TURBINESrow).
- class cabledyn.project.Rod(name='', /, **values)
A rod (one deck
RODSrow).attachmentcoupledandfloatercorrespond to the deck typesCoupledandVessel;bodyandbody_pinnedneedbody, and the end positions are then in body axes.- endpoint(end)
Return the endpoint object of
end("A"or"B").
- class cabledyn.project.LineEndTarget(name='', /, **values)
Base class of everything a line end can attach to.
- class cabledyn.project.RodEndpoint(name='', /, **values)
End A or End B of a rod; owned by the rod, never removed on its own.
- class cabledyn.project.Point(name='', /, **values)
Base class of the points: position and lumped hydrodynamic properties.
- class cabledyn.project.FixedPoint(name='', /, **values)
A point fixed in space, such as an anchor (deck
Fixed).
- class cabledyn.project.FloaterPoint(name='', /, **values)
A point moved with the floater (deck
CoupledorVessel).
- class cabledyn.project.FreePoint(name='', /, **values)
A free point solved for (deck
Free).
- class cabledyn.project.ConnectPoint(name='', /, **values)
A free connection point joining several lines (deck
Connect).
- class cabledyn.project.TurbinePoint(name='', /, **values)
A point carried by a FAST.Farm turbine (deck
Turbine<J>/T<J>).The point refers to its
Turbineobject, so it follows a renumbered turbine and is removed with it. In a coupled farm deck without aTURBINEStable the turbine is known only by its number, given inturbine_numberinstead. The position is relative to the turbine’s reference.
- class cabledyn.project.BodyPoint(name='', /, **values)
A point fixed to a body; the position is in body axes (deck
Body<N>).
- class cabledyn.project.RodPoint(name='', /, **values)
A point at a rod end (deck
Rod<N>A/Rod<N>B).
- class cabledyn.project.Line(name='', /, **values)
A line from End A (fairlead side) to End B (anchor side).
One deck
LINESrow with its ordered sections.- property length
Total unstretched length, the sum of the section lengths.
- property segment_count
Total number of elements.
- class cabledyn.project.Section(name='', /, **values)
A length of one line type (one deck
SECTIONSrow), from End A.
- class cabledyn.project.EndConnection(name='', /, **values)
The bending (and optional torsion) boundary at one end of a finite-EI line.
One deck
END CONNECTIONSrow.rotationstiffnessusesrotational_stiffness;pinnedandrigidare the deck keywords.torsionnonewrites the six-column row.
- class cabledyn.project.Attachment(name='', /, **values)
Base class of discrete items on a finite-EI line (deck
ATTACHMENTS).The location is an arc length from End A, or a series
arc_length,arc_length + pitch, … up tolast_arc_length.- is_series()
Whether the attachment is a series of identical items.
- locations()
Return the arc length of every item (one value for a single item).
- class cabledyn.project.BuoyancyModule(name='', /, **values)
A buoyancy module (or a series of them).
- class cabledyn.project.ClumpWeight(name='', /, **values)
A clump weight (or a series of them).
- class cabledyn.project.LineAncillary(name='', /, **values)
Base class of line ancillaries drawn over an arc-length range.
Ancillaries are cosmetic: the stiffness and mass they add are modelled with sections and attachments. They have no deck rows.
- class cabledyn.project.BendStiffener(name='', /, **values)
A conical bend stiffener at a hang-off.
- class cabledyn.project.BendRestrictor(name='', /, **values)
Interlocking vertebrae limiting the bend radius.
- class cabledyn.project.TouchdownProtection(name='', /, **values)
Half-shell protection sleeves over the touchdown zone.
- class cabledyn.project.EquivalentBuoyancy(name='', /, **values)
A line type given by its net submerged weight (smeared buoyancy).
One deck
EQUIVALENT BUOYANCYrow; it rewrites the referenced type.
- class cabledyn.project.SyropeIC(name='', /, **values)
The prior load history of Syrope lines (one deck
SYROPE ICrow).
- class cabledyn.project.Failure(name='', /, **values)
Lines detaching from a point at a time or tension (one deck
FAILURErow).
- class cabledyn.project.Control(name='', /, **values)
Lines whose length follows a coupling-host control channel (deck
CONTROL).
- class cabledyn.project.ExternalLoad(name='', /, **values)
A constant force and damping on a rigid body (deck
EXTERNAL LOADS).
- class cabledyn.project.OutputRequest(name='', /, **values)
The requested output channels (the deck’s
OUTPUTSlist).
- class cabledyn.project.Channel(name='', /, **values)
Base class of a requested output channel.
- class cabledyn.project.ObjectChannel(name='', /, **values)
A channel of one object, such as a line’s fairlead tension.
The deck name is
quantity+ the target’s deck id +qualifier(FairTen+1;Ten+2+N5). The channel follows its target when the target is renumbered and is removed with it.
- class cabledyn.project.NamedChannel(name='', /, **values)
A channel given by its literal deck name.
Appearance and GUI data
- class cabledyn.project.LineAppearance(name='', /, **values)
Base class of the surface descriptions of a line type.
- class cabledyn.project.PlainLineAppearance(name='', /, **values)
A smooth tube in the line type’s colour.
- class cabledyn.project.ChainAppearance(name='', /, **values)
Chain links generated from the nominal diameter and link proportions.
- class cabledyn.project.WireRopeAppearance(name='', /, **values)
Helical strands, optionally under a polymer sheath.
- class cabledyn.project.FibreRopeAppearance(name='', /, **values)
A braided jacket with optional marker stripes.
- class cabledyn.project.CableAppearance(name='', /, **values)
A served power-cable exterior with stripes, marker bands and an optional cutaway.
- class cabledyn.project.ModuleGeometry(name='', /, **values)
The shape of a buoyancy module (two half-shells around the line).
- class cabledyn.project.MeshAsset(name='', /, **values)
A 3D mesh drawn for a body or a floater type (glTF first; OBJ, STL).
- class cabledyn.project.EnvironmentAppearance(name='', /, **values)
Sea, sky and underwater look of the presentation view.
- class cabledyn.project.SeabedAppearance(name='', /, **values)
Seabed texture and colouring of the presentation view.
- class cabledyn.project.StudioData(name='', /, **values)
Everything the GUI stores in a project besides the model itself.
- unit_system()
Return the project’s display units.
- set_unit_system(system)
Store display-unit choices (not an undoable command).
- class cabledyn.project.Group(name='', /, **values)
A user group of objects in the model browser.
- class cabledyn.project.CameraBookmark(name='', /, **values)
A saved camera of a 3D view.
Commands and references
- class cabledyn.project.CommandStack(limit=0)
Undo and redo history of commands.
- Parameters:
limit (int) – Most commands kept (oldest dropped first);
0keeps all.
- property index
Number of applied commands in the history.
- property can_undo
Whether there is a command to undo.
- property can_redo
Whether there is a command to redo.
- property is_clean
Whether the state equals the last
set_clean()(for example a save).
- commands()
Return the recorded commands, oldest first.
- subscribe(listener)
Call
listenerafter every stack change; returns an unsubscribe function.
- push(command)
Apply
commandand record it (inside a macro: add it to the macro).- Raises:
RuntimeError – If called while a command is being applied (from a change listener).
Exception – Whatever the command raises; nothing is recorded then.
- undo()
Revert the last applied command (no-op if none).
- redo()
Re-apply the next undone command (no-op if none).
- set_clean()
Mark the current state as saved.
- clear()
Forget the history (the model is unchanged).
- macro(text)
Group the commands pushed in a
withblock into one undo step.If the block raises, the commands pushed in it are undone and the error propagates.
- Parameters:
text (str) – Menu text of the group.
- class cabledyn.project.StackChanged(action, command)
Published by
CommandStackafter every change of its state.- action
"push","merge","undo","redo","clean", or"clear".- Type:
str
- class cabledyn.project.Command
Base class of an undoable change.
Subclasses implement
do()andundo();do()is called again for a redo and must give the same result.- text
Description for the Edit menu (“Set length of Section”).
- Type:
str
- do()
Apply the change.
- undo()
Revert the change.
- merge_with(other)
Absorb
other(already applied) into this command, if compatible.- Returns:
Whether
otherwas absorbed; the stack then discards it.- Return type:
bool
- affected()
Return the objects the command changes.
- class cabledyn.project.SetProperty(obj, name, value, *, merge=False, text=None)
Set one property of one object.
- Parameters:
obj (ModelObject) – The object.
name (str) – Property name.
value (object) – New value (SI units); checked against the property type at once.
merge (bool) – Merge with an immediately following mergeable
SetPropertyof the same object and property (one undo step for a drag).text (str | None) – Menu text; generated when
None.
- Raises:
KeyError – If the object has no such property.
TypeError, ValueError – If the value does not fit the property.
AttributeError – If the property is read-only or a collection.
- class cabledyn.project.ReplaceStrategy(obj, name, new, *, copy_common=True)
Replace a strategy sub-object (axial model, wave model, seabed, …).
Values of properties the old and new classes share are copied to the new object unless
copy_commonis false.- Parameters:
obj (ModelObject) – The owner.
new (ModelObject | type) – The new sub-object, or a class to instantiate.
copy_common (bool) – Copy shared property values from the current sub-object.
- class cabledyn.project.Reconnect(line, end, target)
Attach one end of a line to another point or rod end.
- Parameters:
line (Line) – The line.
end (str) –
"A"or"B".target (LineEndTarget) – The new attachment.
- class cabledyn.project.AddObject(collection, obj, index=None)
Insert a new object into a collection.
- Parameters:
collection (ObjectCollection) – The target collection, for example
project.points.obj (ModelObject) – The new object (without a parent).
index (int | None) – Position; appended when
None.
- class cabledyn.project.RemoveObject(root, objects, *, cascade=False)
Remove objects, refusing or cascading when they are still referred to.
The cascade (see
cabledyn.project.references) is worked out when the command is first applied and captured, so undo restores every removed dependant and every cleared reference.- Parameters:
root (ModelObject) – The object graph, normally the project.
objects (ModelObject | Sequence[ModelObject]) – The object(s) to remove.
cascade (bool) – Remove or update dependants instead of refusing.
- Raises:
ObjectInUseError – When applied without
cascadeto a referenced object.
- class cabledyn.project.MoveInCollection(obj, index)
Move an object to another position within its collection.
- Parameters:
obj (ModelObject) – The object.
index (int) – New position.
- class cabledyn.project.MacroCommand(text, commands=())
Several commands applied and undone as one.
If a command fails while the macro is applied, the commands already applied are undone and the error is raised.
- Parameters:
text (str) – Menu text.
commands (Sequence[Command]) – The commands, in order.
- class cabledyn.project.SplitSection(section, at)
Split a section in two at an arc length within it.
The elements are shared in proportion to the lengths (at least one each).
- Parameters:
section (Section) – The section; it must belong to a line.
at (float) – Distance from the section’s start, in m, strictly inside it.
- Raises:
ValueError – If
atis not inside the section or the section has one element.
- class cabledyn.project.ApplyLibraryItem(obj, values, text=None)
Set several properties of an object from a library entry.
- Parameters:
obj (ModelObject) – The object, typically a line type.
values (Mapping[str, object]) – Property values by name (SI units).
text (str | None) – Menu text.
- class cabledyn.project.ImportDeck(project, source, *, replace_environment=True)
Add the objects of a deck (or of another project) to a project.
Libraries, objects and rows are appended; the environment, seabed, motion and settings of the imported model (and its option spellings and order) replace the project’s when
replace_environmentis true. Name clashes of line or rod types are left for validation to report. The objects move out ofsourcewhen the command is first applied.- Parameters:
project (Project) – The receiving project.
source (Project) – A project built by
DeckReader.replace_environment (bool) – Also take the environment, seabed, motion, settings and option hints.
- cabledyn.project.plan_removal(root, targets, *, cascade=False)
Work out the cascade of removing
targetsfromroot.- Parameters:
root (ModelObject) – The object graph (normally the project).
targets (list[ModelObject]) – Objects to remove; each must sit in a collection.
cascade (bool) – Allow dependants to be removed or updated; otherwise refuse when anything outside the targets refers to them.
- Returns:
The objects to remove and the references to update.
- Return type:
- Raises:
ValueError – If a target is not held in a collection.
ObjectInUseError – If
cascadeis false and a target is still referred to.
- cabledyn.project.referrers(root, obj, *, include_weak=False)
Return
(referrer, property name)pairs that point intoobj.- Parameters:
root (ModelObject) – The object graph to search (normally the project).
obj (ModelObject) – The referenced object; references to its descendants count too.
include_weak (bool) – Also list weak (bookkeeping) references such as group memberships.
- Returns:
Referrers outside
obj, in model order, each property once.- Return type:
list[tuple[ModelObject, str]]
- class cabledyn.project.RemovalPlan(removed=<factory>, reference_updates=<factory>)
What removing objects does to the model.
- removed
Objects to take out of their collections (none inside another).
- Type:
list[ModelObject]
- reference_updates
(object, property, old value, new value)for surviving referrers.- Type:
list[tuple[ModelObject, str, Any, Any]]
- exception cabledyn.project.ObjectInUseError(message, found)
An object cannot be removed without cascading: other objects refer to it.
- referrers
The referring objects and property names.
- Type:
tuple[tuple[ModelObject, str], …]
Validation and units
- cabledyn.project.validate_project(project, *, deck=True)
Validate a project with every layer.
- class cabledyn.project.Issue(severity, message, obj=None, prop=None, layer=1)
One validation finding, attached to an object and optionally a property.
- message
Human-readable message.
- Type:
str
- obj
The object concerned, or
Nonefor a model-wide finding.- Type:
ModelObject | None
- prop
The property concerned, if any.
- Type:
str | None
- layer
1property checks,2object invariants,3native deck rules.- Type:
int
- property is_error
Whether the issue is an error.
- class cabledyn.project.Severity(*values)
How serious an
Issueis.- ERROR = 'error'
The model cannot be written as a valid deck, or is inconsistent.
- WARNING = 'warning'
The model is valid but probably not what was meant.
- INFO = 'info'
A note, for example an option kept verbatim.
- class cabledyn.project.UnitSystem(choices=None)
Display-unit preferences: one unit per dimension (SI where unset).
- Parameters:
choices (Mapping[str, str] | None) – Dimension key to unit symbol.
- Raises:
UnitError – If a dimension or unit is unknown, or a unit measures another dimension.
- classmethod si()
Return SI display units for every dimension.
- classmethod engineering()
Return offshore-engineering display units (kN, t, kN m^2, …).
- set(dimension, symbol)
Choose the display unit of a dimension.
- Parameters:
dimension (str) – Dimension key, for example
"force".symbol (str) – Unit symbol of that dimension.
- unit_for(dimension)
Return the display unit chosen for
dimension.
- to_display(value, dimension)
Convert an SI value to the display unit of
dimension.
- from_display(value, dimension)
Convert a value in the display unit of
dimensionto SI.
- format(value, dimension, digits=6)
Format an SI value in its display unit, for example
'850 m'.- Parameters:
value (float) – SI value.
dimension (Dimension) – Its dimension.
digits (int) – Significant digits.
- Returns:
Number and unit symbol (no symbol for dimensionless values).
- Return type:
str
- to_dict()
Return the non-SI choices, for a project file.
- dimensions()
Return the dimension keys with a non-SI choice.
- class cabledyn.project.Dimension(key, label, si)
A physical dimension and its SI unit symbol.
- key
Stable identifier, used in project files and preferences.
- Type:
str
- label
Human-readable name.
- Type:
str
- si
Symbol of the unit in which values are stored (SI; degrees for angles).
- Type:
str
- class cabledyn.project.Unit(symbol, dimension, scale)
A display unit:
si_value = value * scale.- symbol
Unit symbol. A symbol may measure several dimensions (
N/mis a force per length or a stiffness); thenunit()needs the dimension.- Type:
str
- scale
SI value of one unit.
- Type:
float
- to_si(value)
Convert a value in this unit to SI.
- from_si(value)
Convert an SI value to this unit.
- exception cabledyn.project.UnitError
A unit is unknown or does not measure the expected dimension.
- cabledyn.project.units.convert(value, source, target, dimension=None)
Convert
valuefrom unitsourceto unittarget.- Parameters:
value (float) – Value in
sourceunits.source (str) – Unit symbols of the same dimension.
target (str) – Unit symbols of the same dimension.
dimension (Dimension | None) – The dimension, needed only for shared symbols such as
N/m.
- Returns:
Value in
targetunits.- Return type:
float
- Raises:
UnitError – If a unit is unknown or the dimensions differ.
- cabledyn.project.units.parse_quantity(text, dimension, default_unit=None)
Parse text such as
"850 m"or"1.2 MN"into an SI value.- Parameters:
text (str) – A number optionally followed by a unit symbol.
dimension (Dimension) – The expected dimension.
default_unit (str | None) – Unit of a bare number; SI when
None.
- Returns:
The SI value.
- Return type:
float
- Raises:
UnitError – If the text is not a number with a unit of
dimension.
- cabledyn.project.units.unit(symbol, dimension=None)
Return the unit with
symbol.- Parameters:
symbol (str) – Unit symbol, for example
"kN".dimension (Dimension | None) – The dimension it must measure; needed only when the symbol is shared by several dimensions (
N/m: force per length or stiffness).
- Returns:
The unit.
- Return type:
- Raises:
UnitError – If the symbol is unknown, does not measure
dimension, or is ambiguous without one.
- cabledyn.project.units.units_for(dimension)
Return the units that measure
dimension, SI unit first.
- class cabledyn.project.schema.DeckLimit(minimum=None, maximum=None, absolute=False, exclusive_minimum=False)
An admissible range of one deck field.
- minimum, maximum
Inclusive bounds, or
Nonefor no bound.- Type:
float | None
- absolute
Apply the bounds to the magnitude of the value.
- Type:
bool
- exclusive_minimum
The minimum itself is not admissible.
- Type:
bool
- violation(value)
Return a message if
valueis outside the range, elseNone.
- cabledyn.project.schema.deck_limit(key)
Return the shared limit
key.- Parameters:
key (str) – A key of
DECK_LIMITS.- Returns:
The limit.
- Return type:
- Raises:
KeyError – If the key is unknown.
- cabledyn.project.schema.DECK_LIMITS
Shared limits by key, each taken from the native deck reader’s constant.
Adapters
- class cabledyn.project.DeckReader
Build a
Projectfrom a CableDyn deck.Examples
>>> from cabledyn.project import DeckReader >>> project = DeckReader.read("examples/spread_3line_chain.dat")
- classmethod read(path, *, caller_driven=False)
Read and validate a deck file.
- Parameters:
path (str | os.PathLike) – Deck file.
caller_driven (bool) – Validate for the OpenFAST coupling instead of the standalone driver.
- Returns:
The project.
- Return type:
- Raises:
DeckFormatError – If the deck violates the native deck contract.
- class cabledyn.project.DeckWriter(project)
Write a
Projectas a CableDyn deck.Relative side-file paths resolve from the folder of the project’s
deck_path; with nodeck_paththey resolve from the working folder (ProjectStoreanchors them at the project file). Points, lines, bodies and rods keep their deck ids where they can; external loads are numbered 1, 2, … in collection order, as the deck requires.- Parameters:
project (Project) – The project. Only
physicsproperties are written.
Examples
>>> from cabledyn.project import DeckReader, DeckWriter >>> project = DeckReader.read("examples/spread_3line_chain.dat") >>> text = DeckWriter(project).to_text()
- to_model()
Build a fresh
DeckModelfrom the project.- Returns:
The deck model and the id map.
- Return type:
- Raises:
DeckExportError – If an object cannot be expressed as a deck row (a missing reference, a bad value);
objnames it.
- to_text(*, validate=True)
Return the canonical deck text of the project.
- Parameters:
validate (bool) – Check the text with the native deck rules (
cabledyn.DeckFile).- Raises:
DeckExportError – If an object cannot be written.
DeckFormatError – If
validateis true and the deck violates the native rules.
- write(path, *, overwrite=False)
Validate the project and write it as a deck file.
Relative ancillary paths are rebased to the target folder (see
cabledyn.DeckModel.save()).- Returns:
The written file.
- Return type:
pathlib.Path
- class cabledyn.project.IdMap(keys=<factory>, objects=<factory>, rows=<factory>)
Correspondence between objects and deck ids, names and text rows.
- keys
Object uid to
(kind, deck id or name); kinds areline_type,rod_type,body,rod,turbine,point,lineandexternal_load.- Type:
dict[str, tuple[str, int | str]]
- objects
The reverse mapping (names in lower case).
- Type:
dict[tuple[str, int | str], ModelObject]
- rows
Zero-based line number of the written deck text to the object that produced the row (filled by
DeckWriter.to_text()).- Type:
dict[int, ModelObject]
- add(obj, kind, key)
Record that
objis written askindkey.
- deck_id(obj)
Return the deck id (or name) of
obj, orNone.
- object_for(kind, key)
Return the object written as
kindkey(names case-insensitive).
- object_at_row(line)
Return the object behind zero-based deck text line
line, if any.
- exception cabledyn.project.DeckExportError(message, obj=None)
The project cannot be written as a deck.
- obj
The object that could not be written, if known.
- Type:
ModelObject | None
- class cabledyn.project.ProjectStore
Save and load
.cdprojproject files.- static to_json(project, base=None)
Return the
project.jsondocument ofproject.Objects of unknown type are put back at their place in their collection.
- Parameters:
project (Project) – The project.
base (str | os.PathLike | None) – Folder that holds the project file;
deck_pathis stored relative to it when possible.
- Returns:
JSON-compatible data.
- Return type:
dict
- static from_json(data, base=None)
Rebuild a project from a
project.jsondocument.- Parameters:
data (object) – The parsed document.
base (str | os.PathLike | None) – Folder that holds the project file (resolves a relative
deck_path).
- Raises:
ProjectFormatError – If the document is not a project, is from a newer schema, or uses one uid for several objects.
- classmethod save(project, path, *, folder=False, overwrite=False)
Write
projectto a project file.Each file is written to a temporary name and then moved into place, so an interrupted save leaves the previous file intact.
- Parameters:
project (Project) – The project.
path (str | os.PathLike) – Target, normally ending in
.cdproj.folder (bool) – Write an unzipped folder instead of a zip archive.
overwrite (bool) – Replace an existing file or folder contents.
- Returns:
The written path.
- Return type:
pathlib.Path
- Raises:
FileExistsError – If
pathexists andoverwriteis false.
- classmethod load(path)
Read a project file (zip archive or folder).
- Returns:
The project;
Project.load_warningslists anything kept but not understood.- Return type:
- Raises:
FileNotFoundError – If
pathdoes not exist.ProjectFormatError – If the file is not a readable project.
- exception cabledyn.project.ProjectFormatError
A project file is not a readable CableDyn project, or is from a newer release.
Modules
Every public name above is importable from cabledyn.project; the classes are defined in
these modules.