mbe-shipyard / sysml.py Goto Github PK
View Code? Open in Web Editor NEWA Python package for the Systems Modeling Language (SysML) for Model-based Systems Engineering (MBSE) applications
License: Apache License 2.0
A Python package for the Systems Modeling Language (SysML) for Model-based Systems Engineering (MBSE) applications
License: Apache License 2.0
Implement attributes, constructors, and methods for Interaction()
class.
Parameters should include lifelines, messages, interaction uses.
Features to consider:
__call__()
method that returns a generator, such that Interaction
objects are callable and iterable.Refactor ModelElement
and its subclasses to use static type checking using mypy. Unit tests may need to be rewritten to accommodate differences in TypeError messages
Import SysML model from xmi file.
Should only install for the uncommented versions in .travis.yml.
See https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires
This is most likely an issue related to mypy.
Implement attributes, constructors, and methods for StateMachine()
class.
The last commit is was more than a year ago, is this project still maintained or have you find a better alternative ?
This issue entails writing classes for the following model elements in element.py
:
package
block
constraintBlock
activity
interaction
stateMachine
requirement
dependency
Note: modelLibrary
, view
, and profile
are currently omitted, as they're outside the namespacing scope of the SysML.py package.
i.e., Model class needs to be redesigned such that only one instance can be created.
Implementation should be accompanied by unit tests.
Implement attributes, constructors, and methods for Package()
class.
A module for making API calls to OpenMBEE's Model Management System (mms).
this might be as simple as uncommenting L13 or it may require some refactoring.
Need a way for __repr__()
in ModelElement
, to return a short or long formatted string element depending on whether it was called from within a dict(), or directly on the object itself. e.g.,
>>> bar1
name: bar name 1
stereotype: «block»
parts: []
references: []
values: []
constraints: []
flows: []
multiplicity: []
uuid: a14fdf5e-b4d7-11e8-8170-089e0132c719
>>> foo
name: foo name
stereotype: «block»
parts:
'bar1' : «block» bar name 1
'bar2' : «block» bar name 2
references: []
values: []
constraints: []
flows: []
multiplicity: []
uuid: c7aec630-b4b7-11e8-8170-089e0132c719
A __repr__()
decorator seems to make the most sense.
This issue is an enhancement for #3 and entails implementing instance methods for generating objects that can be passed to a plotting package (such as plotly matplotlib, bokeh) for generating the 9 SysML diagrams.
Diagrams are generated as "diagram objects" using generators in the form of instance methods via the Model() class, using the SysML diagram acronyms.
e.g.,
import sysml
# creates a model object from yaml file
model = sysml.import_yaml('deathstar_plans.yaml')
# generates an block definition diagram for package, 'Structure'
bdd = model['Structure'].bdd()
someplottingpackage.somegraphgenerator(bdd)
someplottingpackage.show()
# generates an internal block diagram object for 'block AA23'
ibd = model['Structure']['block AA23'].ibd()
someplottingpackage.somegraphgenerator(ibd)
someplottingpackage.show()
# generates an activity diagram object for 'order 66'
act = model['Behavior']['order 66'].act()
someplottingpackage.somegraphgenerator(act)
someplottingpackage.show()
# generates a state machine diagram object for 'statemachine 327'
stm = model['Behavior']['statemachine 327'].stm()
someplottingpackage.somegraphgenerator(stm)
someplottingpackage.show()
# generates a sequence diagram object for package, 'Behavior'
sd = model['Behavior'].sd()
someplottingpackage.somegraphgenerator(sd)
someplottingpackage.show()
# generates a use case diagram object for package, 'Behavior'
ud = model['Behavior'].ud()
someplottingpackage.somegraphgenerator(ud)
someplottingpackage.show()
# generates a requirements diagram object for package, 'Requirements'
req = model['Requirements'].req()
someplottingpackage.somegraphgenerator(req)
someplottingpackage.show()
# generates a parametric diagram object for 'block AA23'
par = model['Parametrics']['block AA23'].par()
someplottingpackage.somegraphgenerator(req)
someplottingpackage.show()
# generates a package diagram object for package, 'Structure'
pkg = model['Structure'].pkg()
someplottingpackage.somegraphgenerator(pkg)
someplottingpackage.show()
This would take in 3 arguments upon instantiation:
source
- a.k.a., "supplier" model element
target
- a.k.a., "client" model element
relationType
- For constructing dependency stereotype. Options: "trace", "derive", "refine", "satisfy", and "verify".
For installations via pip
to specify dependencies needed to run package.
See https://packaging.python.org/guides/distributing-packages-using-setuptools/#install-requires
Implement attributes, constructors, and methods for Requirement()
class.
It would be useful to be able to save a SysML model as XML for import into other modeling tools.
To be included as an instance method in the Model
class. This function entails exporting a Model
object (and its contents within) to a YAML file.
This issue should be worked on concurrently with #7 and accompanied by unit tests.
For MVP purposes, will settle for using PyYaml's dump()
method and built-in python object constructor for serializing/deserializing Model
objects
This would be a method, isValid()
, called from a Model
object, for performing requirements validation. isValid()
would recursively check if all requirements, or its derived requirements, contained in the model are satisfied by a Block
instance, and verified by an Interaction
instance.
e.g.,
import sysml
model = sysml.import_yaml('deathstar_plans.yaml') # import system model
model.isValid() # returns boolean
isValid()
can return the following:
True
- requirements are both satisfied and verified.
False
- requirements are satisfied or verified, but not both.
raise Exception
- requirements are over-satisfied or over-verified by multiple model elements.
This task entails creating a lightweight YAML template for SysML data serialization for initial standalone PyPI release. Currently using firesat.yaml as a draft template, but a more complete profile may resemble the TMT-SysML-Model or architecting-spacecraft-model This may be revised/replaced later with a JSON template.
Note: a complimentary YAML schema shall be produced for syntactic validation of the SysML model.
Implement attributes, constructors, and methods for Activity()
class.
Implement attributes, constructors, and methods for Model()
class.
This issue is used for outlining the design and scope of the initial package release onto PyPI.
System model creation is done using a composite design pattern, whereby model elements are instantiated then subsumed by a Model
object or model elements within a Model
object. See "class diagram" tab of SysML.py UML for a structural breakdown of the working design pattern implementation.
The long term vision is to provide automation support for two primary use cases:
See "use case diagram" tab of SysML.py UML
sysml/system.py
- This module contains the Model()
class for creating Model
objects that serve as a central namespace for subclasses of ModelElements
(see #3). Methods should also be callable from Model
objects (see #12, #15, & #25 #6). Module should also contain a function for deserializing Model
objects (see #7)
sysml/element.py
- This module contains the core language of SysML for creating subclasses of ModelElement
objects (s.a., Package
, Block
, ConstraintBlock
, Activity
, Interaction
, StateMachine
, and Requirement
). These objects are intended to be subsumed by Model
objects (see #11).
The following illustrates an example workflow, using the traditional pillars of SysML (i.e., structure, behavior, and requirements) in conjuction with two new pillars: analysis and verification & validation...
(See test_model.py for most up-to-date profile of unittests)
>>> import sysml
# Create a model object that will also serve as the root directory for all other model elements
>>> model = sysml.Model()
Structure
# Create a package, labeled 'Structure' within model which will serve as namespace for the system structure
>>> struct_pkg = sysml.Package('Structure')
>>> model.add(struct_pkg)
# Model and Package objects can be thought of as a dict-like container for returning model elements
>>> model['Structure'] # should return a package object with str, «package» Structure
# model elements use python-ic dict-like setters for adding other model elements
>>> starship = sysml.Block('Constitution-class starship')
>>> model['Structure'].add(starship)
>>> model['Structure']['Constitution-class starship'] # should return a block object with str, «block» Constitution-class starship
# Block elements have attributs, such as parts, for storing subcomponents
>>> saucer_sec = sysml.Block('Primary Hull')
>>> engineering_sec = sysml.Block('Secondary Hull')
>>> model['structure']['constitution-class starship'].parts['saucer section'] = saucer_sec
>>> model['structure']['constitution-class starship'].parts['engineering'] = engineering_sec
# Parts added to a block element are dictionary-callable via the 'parts' attribute
>>> model['structure']['Constitution-class starship'].parts['Primary Hull'] # should return a block object with str, «block» Primary Hull
>>> model['structure']['Constitution-class starship'].parts['Engineering Hull'] # should return a block object with str, «block» Engineering Hull
Requirements
# Create a package, labeled 'Requirements', within model which will serve as namespace for the system requirements
>>> req_package = sysml.Package('Requirements')
>>> model.add(req_package)
# Define two requirement elements, passing in a string name and text field as its constructor arguments
>>> top_req = sysml.Requirement('Top-level', 'A constitution-class starship shall provide a 5-year mission capability to explore strange new worlds, to seek out new life and new civilizations, and to boldly go where no one has gone before.')
>>> func_req = sysml.Requirement('Functional', 'A constitution-class starship shall be able to travel at warp 8 or higher')
>>> model['Requirements'].add(top_req)
>>> model['Requirements'].add(func_req)
# Define a dependency relationship, of stereotype «derive», between two requirements
>>> deriveReq1 = sysml.DeriveReqt(top_req, func_req)
>>> model['Requirements'].add(deriveReq1)
Behavior (WIP)
# Create a package, labeled 'Behavior', within model which will serve as namespace for the system behavior
>>> behavior_pkg = sysml.Package('Behavior')
>>> model.add(behavior_pkg)
>>> warpdrive_testcase = sysml.TestCase('Warp drive operation')
>>> model['Behavior'].add(warpdrive_testcase)
Analysis (WIP)
# Create a package, labeled 'Analysis', within model which will serve as namespace for the system analysis
>>> analysis_pkg = sysml.Package('Analysis')
>>> warpfieldsim_interaction = sysml.TestCase('Warp field simulation') # Create a test case for verifying one or more system requirements allocated to it.
>>> model.add(analysis_pkg)
>>> model['Analysis'].add(warpfieldsim_interaction)
# A dependency relationship, of stereotype «trace», can be defined to relate the analysis test case to the behavioral test case
>>> warpdrive_operation = sysml.Activity('Warp drive operation')
>>> dependency2 = sysml.Dependency(warpfieldsim, warpdrive_operation, 'trace')
Verification & Validation (WIP)
>>> warpdrive = sysml.Block('class-7 warp drive')
>>> model['Structure']['Constitution-class starship'].part['warpdrive'] = warpdrive
# Define a dependency relationship, of stereotype «satisfy», to relate a structural element to one or more of its corresponding requirements that it satisfies
>>> satisfy1 = sysml.Satisfy(func_req, warpdrive)
>>> model['Requirements'].add(satisfy1)
# Define a dependency relationship, of stereotype «verify», to relate a test case to one or more of its corresponding requirements that it verifies
>>> verify1 = sysml.Verify(functional_req, warpfieldsim_interaction)
>>> model['Requirements'].add(verify1)
# Perform validation on system model, using built-in validation method, or generate a requirements traceability matrix (RTM)
>>> model.isValid() # returns True if all requirements are satisfied by a block and verified by a test case
>>> model.rtm() # generates an RTM
Additional features being considered in the development pipeline include, but not limited to:
This method would be called from a Model
object for generating a Requirements Traceability Matrix (likely using pandas).
Integration/support for OpenMDAO.
Need to design a standardized format for return element in __repr__()
for model element objects.
e.g.,
>>> import sysml
>>> b = sysml.Block()
>>> print(b)
<???>
In the above example, the print()
function will call the __repr__()
dunder method for a sysml.element.Block
object. What should the print()
function return?
Users may want to implement custom stereotypes in their model. In usage, this may entail users having to write a custom class that inherits from the Block
type or using a factory object from library code that creates class definitions.
Things to consider
profile
template that users can replicate/modify for convenient reconstruction of user-defined class definitions for custom stereotypesHi,
I noticed this project a few years ago. I just cloned the codes and successfully installed on my computer. I tried to run system.py under sysml folder but I got error. I posed in following.
D:\Python38\Scripts\python.exe E:/WorkspaceCode/sysmlpy/sysml/system.py
Traceback (most recent call last):
File "E:/WorkspaceCode/sysmlpy/sysml/system.py", line 5, in
from sysml import *
File "", line 259, in load_module
File "D:\Python38\lib\site-packages\sysml-0.1.0-py3.8.egg\sysml_init_.py", line 1, in
from sysml.elements import *
ModuleNotFoundError: No module named 'sysml.elements'
Process finished with exit code 1
Would you mind to tell me how to solve it? Thank you very much.
BTW, my environment: Windows 10 Professional, Python 3.8 64-bit.
Best,
Zhentao Lu
Open to alternative implementation strategies, but this issue should, in essence, check if both objects referenced in both "supplier" and "client" attributes of a Dependency
object exist in the Package
object, or Package
objects recursively therein, when passed through a Package
objects add() method.
e.g.,
>>> timemachine = sysml.Package('time machine')
>>> req = sysml.Requirement('top requirement', 'make time travel possible')
>>> fluxcapacitor = sysml.Block('flux capacitor')
>>> timemachine.add(Dependency(req, fluxcapacitor))
The above would raise an AttributeError
, because neither timetravel
nor fluxcapacitor
are defined in timemachine
Working example:
>>> timemachine = sysml.Package('time machine')
>>> req = sysml.Requirement('top requirement', 'make time travel possible')
>>> fluxcapacitor = sysml.Block('flux capacitor')
>>> timemachine.add(req)
>>> timemachine.add(fluxcapacitor)
>>> timemachine.add(Dependency(req, fluxcapacitor))
Prior to creating an instance of a Block()
, the constructor should check whether dictionary values to be added in the self.values
attribute are of type int
or float
, or an instance of pint's UnitRegistry()
.
e.g.,
model['Requirement'].add_block(value={'missionDuration': 5*ureg('year')})
The ValueType
class (in parametrics.py
module) should inherit the UnitRegistry
behavior from pint and astropy and still be a subclass of ModelElement
. ValueType
can be implemented as either a decorated class or subclass that inherits from both UnitRegistry
objects/classes.
e.g.,
>>> kesselrun = 12*ValueType('parsecs')
>>> kesselrun
<ValueType(12, 'parsec')>
>>> kesselrun.magnitude
12
>>> str(kesselrun.units)
'parsec'
>>> kesselrun.to('lightyear')
<ValueType(39.138799173399406, 'light_year')>
>>> 2*kesselrun
<ValueType(24, 'parsec')>
>>> type(kesselrun)
ValueType
>>> isinstance(kesselrun, ModelElement)
True
Additional unit tests welcome.
Implement attributes, constructors, and methods for Block()
class.
Attributes:
parts
- dictionary of blocks that are owned/contained within the block instance.values
- dictionary of value properties that are of type int
or float
, or has attribute 'unit' (thus, can be a UnitRegistry from pint
package)references
- dictionary of reference properties (WIP)flows
- dictionary of flow properties (WIP)constraints
- dictionary of constraint properties that are of type Constraint
uuid
- universally unique idmultiplicity
- intMethods:
add_part()
remove_part()
add_value()
remove_value()
add_reference()
remove_reference()
add_flow()
remove_flow()
add_constraint()
remove_constraint()
Implement attributes, constructors, and methods for ConstraintBlock()
class.
This epic entails implementing 3 types of getters and setters for self._elements
& self._relationships
in model()
for all valid model elements (see #11):
getitem() & setitem() dictionary-like getter and setter. e.g.,
import sysml
model = sysml.Model()
warpcore = sysml.block('warp core')
model['block-1'] = sysml.block('dilithium crystals'),
model['block-2'] = sysml.block('antimatter')
model['block-3'] = warpcore
model['block-1'] # should return object with repr «block» 'dilithium crystals'`
model['reference-1'] = {'source': 'block-3', 'target': 'block-1', 'relationshipType':'reference'}
model['reference-1'] # should return object with repr «block» 'reference-1'`
@property
& @property.setter
decorators for attribute-like getter and setter. e.g.,
import sysml
model = sysml.Model()
model.elements = {'block-1': sysml.block('dilithium crystals'), 'block-2': sysml.block('antimatter'), 'block-3': sysml.block('warp core')}
model['block-1'] # should return object with repr «block» 'dilithium crystals'`
model.relationships = {'reference-1': {'source': 'block-3', 'target': 'block-1', 'relationshipType':'reference'}, 'reference-2': {'source': 'block-3', 'target': 'block-2', 'relationshipType':'reference'}}
model['reference-1'] # should return object with repr «block» 'reference-1'`
Note: the above will overwrite all existing model elements and relationships in self._elements
and self._relationships
, respectively.
instance methods e.g.,
import sysml
model = sysml.Model()
block1 = sysml.block('dilithium crystals')
block2 = sysml.block('antimatter')
block3 = sysml.block('warp core')
model.add_element(block1, block2, block3) # should also work with model.add_element(sysml.block('dilithium crystals'), sysml.block('antimatter'), sysml.block('warp core'))
model['block-1'] # should return object with repr «block» 'dilithium crystals'`
model.add_relationships({'source':'block-3', 'target':'block-1', 'relationshipType':'reference'}, {'source':'block-3', 'target':'block-2', 'relationshipType':'reference'})
model['reference-1'] # should return object with repr «block» 'reference-1'`
Note: the above method should internally assign a string key for each element added to model.
Stereotype objects should only fall under the category of model element or relationship for all of the above methods.
Parser for serializing/deserializing model objects, using pickling.
To be included in the parser.py
module. This function entails importing a Model
object from a YAML file.
This issue should be worked on concurrently with #6 and accompanied by unit tests.
For MVP purposes, will settle for using PyYaml's dump()
method and built-in python object constructor for serializing/deserializing Model
objects
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.