Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
finesse
pykat
Commits
c87e25eb
Commit
c87e25eb
authored
Dec 05, 2013
by
Andreas Freise
Browse files
Merge branch 'master' of gitmaster.atlas.aei.uni-hannover.de:pykat/pykat
parents
2b0d2775
d9f9af21
Changes
7
Hide whitespace changes
Inline
Side-by-side
bin/test_parser.py
View file @
c87e25eb
...
...
@@ -14,7 +14,6 @@ ad ad1 0 n2
kat
=
finesse
.
kat
(
kat_code
=
code
)
kat
.
add
(
xaxis
(
"lin"
,
[
0
,
360
],
kat
.
m2
,
kat
.
m2
.
phi
,
1000
))
kat
.
add
(
xaxis
(
"lin"
,
[
0
,
360
],
kat
.
m2
,
kat
.
m2
.
phi
,
1000
))
r
=
kat
.
run
(
printerr
=
1
)
...
...
bin/test_plot.py
View file @
c87e25eb
...
...
@@ -23,9 +23,9 @@ kat.parseCommands(code)
kat
.
add
(
cavity
(
'cav1'
,
'm1'
,
'n3'
,
'm2'
,
'n4'
))
kat
.
add
(
photodiode
(
'pd_cav'
,
'n4'
,[]
))
kat
.
add
(
photodiode
(
'pd_ref'
,
'n2'
,[]
))
kat
.
add
(
photodiode
(
'pd_trs'
,
'n5'
,[]
))
kat
.
add
(
photodiode
(
'pd_cav'
,
'n4'
))
kat
.
add
(
photodiode
(
'pd_ref'
,
'n2'
))
kat
.
add
(
photodiode
(
'pd_trs'
,
'n5'
))
kat
.
add
(
xaxis
(
"lin"
,
[
0
,
360
],
kat
.
m2
,
kat
.
m2
.
phi
,
100
))
...
...
pykat/commands.py
View file @
c87e25eb
...
...
@@ -11,6 +11,9 @@ from components import *
from
structs
import
*
class
Command
(
object
):
def
__init__
(
self
):
self
.
tag
=
None
def
getFinesseText
(
self
):
""" Base class for individual finesse optical components """
raise
NotImplementedError
(
"This function is not implemented"
)
...
...
pykat/components.py
View file @
c87e25eb
...
...
@@ -5,6 +5,7 @@ Created on Mon Jan 28 11:10:01 2013
@author: Daniel
"""
import
exceptions
import
pykat.exceptions
as
pkex
import
pykat
from
pykat.node_network
import
*
from
pykat.exceptions
import
*
...
...
@@ -14,60 +15,102 @@ import pykat.gui.graphics
from
pykat.gui.graphics
import
*
from
pykat.SIfloat
import
*
next_component_id
=
1
class
NodeGaussSetter
:
def
__init__
(
self
,
component
,
node
):
if
not
isinstance
(
component
,
Component
):
raise
pkex
.
BasePyKatException
(
"Value passed is not a Component"
)
if
not
isinstance
(
node
,
Node
):
raise
pkex
.
BasePyKatException
(
"Value passed is not a Node"
)
self
.
_comp
=
component
self
.
_node
=
node
class
Component
(
object
)
:
def
__init__
(
self
,
name
):
self
.
__name
=
name
self
.
_svgItem
=
None
self
.
_nodes
=
[]
self
.
_nodes
=
None
self
.
_requested_node_names
=
[]
self
.
_kat
=
None
self
.
tag
=
None
# store a unique ID for this component
global
next_component_id
self
.
__id
=
next_component_id
next_component_id
+=
1
def
_on_kat_add
(
self
,
kat
):
"""
Called when this component has been added to a kat object
Called when this component has been added to a kat object.
kat is the finesse.kat object which it now belongs to and
node_array is an array specific to this object which contains
references to the nodes that are attached to it.
"""
if
self
.
_kat
!=
None
:
raise
pkex
.
BasePyKatException
(
"Component has already been added to a finesse.kat object"
)
self
.
_kat
=
kat
for
node_name
in
self
.
_requested_node_names
:
self
.
_addNode
(
node_name
)
kat
.
nodes
.
registerComponentNodes
(
self
,
self
.
_requested_node_names
,
self
.
__on_node_change
)
def
__on_node_change
(
self
):
# need to update the node gauss parameter setter members
#self.__update_node_setters()
return
def
__update_node_setters
(
self
):
# check if any node setters have already been added. If so we
# need to remove them. This function should get called if the nodes
# are updated, either by some function call or the GUI
key_rm
=
[
k
for
k
in
self
.
__dict__
if
k
.
startswith
(
"__nodesetter_"
,
0
,
13
)]
# now we have a list of which to remove
for
key
in
key_rm
:
ns
=
self
.
__dict__
[
key
]
detattr
(
self
,
'__nodesetter_'
+
ns
.
_node
.
name
)
delattr
(
self
.
__class__
,
ns
.
_node
.
name
)
for
node
in
self
.
nodes
:
self
.
__add_node_setter
(
NodeGaussSetter
(
self
,
node
))
def
__add_node_setter
(
self
,
ns
):
if
not
isinstance
(
ns
,
NodeGaussSetter
):
raise
exceptions
.
ValueError
(
"Argument is not of type NodeGaussSetter"
)
name
=
ns
.
__class__
.
__name__
fget
=
lambda
self
:
self
.
__get_node_setter
(
name
)
setattr
(
self
.
__class__
,
name
,
property
(
fget
))
setattr
(
self
,
'__nodesetter_'
+
name
,
ns
)
def
__get_node_setter
(
self
,
name
):
return
getattr
(
self
,
'__nodesetter_'
+
name
)
@
staticmethod
def
parseFinesseText
(
text
):
raise
NotImplementedError
(
"This function is not implemented"
)
def
setAttr
(
name
,
value
):
raise
NotImplementedError
(
"This function is not implemented"
)
def
getFinesseText
(
self
):
""" Base class for individual finesse optical components """
raise
NotImplementedError
(
"This function is not implemented"
)
def
getQGraphicsItem
(
self
):
return
None
def
_addNode
(
self
,
name
):
""" Adds a node in sequential order to the component, i.e. add them
n1, n2, n3, n4... etc. by the name of the node"""
n
=
self
.
_kat
.
nodes
.
createNode
(
name
)
if
n
==
None
:
raise
exceptions
.
RuntimeError
(
"createNode did not return a node for '{0}'"
.
format
(
name
))
else
:
n
.
connect
(
self
)
self
.
_nodes
.
append
(
n
)
return
n
def
getNodes
(
self
):
""" Returns a copy of the nodes the component has """
return
self
.
_nodes
[:]
def
__getname
(
self
):
return
self
.
__name
name
=
property
(
__getname
)
@
property
def
nodes
(
self
):
return
self
.
_kat
.
nodes
.
getComponentNodes
(
self
)
@
property
def
name
(
self
):
return
self
.
__name
@
property
def
id
(
self
):
return
self
.
__id
class
Param
(
float
):
def
__new__
(
self
,
name
,
value
):
...
...
@@ -97,7 +140,7 @@ class mirror(Component):
self
.
__ybeta
=
float
(
ybeta
)
@
property
def
r_ap
(
self
):
return
Param
(
'r_ap'
,
self
.
__
mass
)
def
r_ap
(
self
):
return
Param
(
'r_ap'
,
self
.
__
r_ap
)
@
r_ap
.
setter
def
r_ap
(
self
,
value
):
self
.
__aperture
=
float
(
value
)
...
...
@@ -169,14 +212,10 @@ class mirror(Component):
def
getFinesseText
(
self
):
rtn
=
[]
nodes
=
self
.
getNodes
()
if
len
(
nodes
)
!=
2
:
raise
exceptions
.
RuntimeError
(
"Not enough nodes for mirror"
)
rtn
.
append
(
'm {0} {1} {2} {3} {4} {5}'
.
format
(
self
.
name
,
self
.
__R
,
self
.
__T
,
self
.
__phi
,
nodes
[
0
].
name
,
nodes
[
1
].
name
))
self
.
nodes
[
0
].
name
,
self
.
nodes
[
1
].
name
))
if
self
.
r_ap
!=
0
:
rtn
.
append
(
"attr {0} r_ap {1}"
.
format
(
self
.
name
,
self
.
__r_ap
))
if
self
.
mass
!=
0
:
rtn
.
append
(
"attr {0} mass {1}"
.
format
(
self
.
name
,
self
.
__mass
))
...
...
@@ -189,8 +228,7 @@ class mirror(Component):
def
getQGraphicsItem
(
self
):
if
self
.
_svgItem
==
None
:
nodes
=
self
.
getNodes
()
self
.
_svgItem
=
pykat
.
gui
.
graphics
.
ComponentQGraphicsItem
(
":/resources/mirror_flat.svg"
,
self
,[(
-
4
,
15
,
nodes
[
0
]),
(
14
,
15
,
nodes
[
1
])])
self
.
_svgItem
=
pykat
.
gui
.
graphics
.
ComponentQGraphicsItem
(
":/resources/mirror_flat.svg"
,
self
,[(
-
4
,
15
,
self
.
nodes
[
0
]),
(
14
,
15
,
self
.
nodes
[
1
])])
return
self
.
_svgItem
...
...
@@ -232,12 +270,10 @@ class space(Component):
raise
exceptions
.
RuntimeError
(
"Space Finesse code format incorrect '{0}'"
.
format
(
text
))
def
getFinesseText
(
self
):
nodes
=
self
.
getNodes
()
if
self
.
__n
==
1
:
return
's {0} {1} {2} {3}'
.
format
(
self
.
name
,
self
.
__L
,
nodes
[
0
].
name
,
nodes
[
1
].
name
)
return
's {0} {1} {2} {3}'
.
format
(
self
.
name
,
self
.
__L
,
self
.
nodes
[
0
].
name
,
self
.
nodes
[
1
].
name
)
else
:
return
's {0} {1} {2} {3} {4}'
.
format
(
self
.
name
,
self
.
__L
,
self
.
__n
,
nodes
[
0
].
name
,
nodes
[
1
].
name
)
return
's {0} {1} {2} {3} {4}'
.
format
(
self
.
name
,
self
.
__L
,
self
.
__n
,
self
.
nodes
[
0
].
name
,
self
.
nodes
[
1
].
name
)
def
getQGraphicsItem
(
self
):
if
self
.
_QItem
==
None
:
...
...
@@ -245,19 +281,19 @@ class space(Component):
return
self
.
_QItem
def
changeNode
(
self
,
node_old
,
node_new
):
'''
Called when a space's node has been connected
to another components node
'''
node_new
.
connect
(
self
)
node_old
.
disconnect
(
self
)
if
self
.
_nodes
[
0
]
==
node_old
:
self
.
_nodes
[
0
]
=
node_new
if
self
.
_nodes
[
1
]
==
node_old
:
self
.
_nodes
[
1
]
=
node_new
#
def changeNode(self, node_old, node_new):
#
'''
#
Called when a space's node has been connected
#
to another components node
#
'''
#
node_new.connect(self)
#
node_old.disconnect(self)
#
if self._nodes[0] == node_old:
#
self._nodes[0] = node_new
#
if self._nodes[1] == node_old:
#
self._nodes[1] = node_new
f
class
laser
(
Component
):
...
...
@@ -302,15 +338,11 @@ class laser(Component):
raise
exceptions
.
FinesseParse
(
"Laser Finesse code format incorrect '{0}'"
.
format
(
text
))
def
getFinesseText
(
self
):
nodes
=
self
.
getNodes
()
return
'l {0} {1} {2} {3} {4}'
.
format
(
self
.
name
,
self
.
__power
,
self
.
__f_offset
,
self
.
__phase
,
nodes
[
0
].
name
)
return
'l {0} {1} {2} {3} {4}'
.
format
(
self
.
name
,
self
.
__power
,
self
.
__f_offset
,
self
.
__phase
,
self
.
nodes
[
0
].
name
)
def
getQGraphicsItem
(
self
):
if
self
.
_svgItem
==
None
:
nodes
=
self
.
getNodes
()
self
.
_svgItem
=
pykat
.
gui
.
graphics
.
ComponentQGraphicsItem
(
":/resources/laser.svg"
,
self
,[(
65
,
25
,
nodes
[
0
])])
self
.
_svgItem
=
pykat
.
gui
.
graphics
.
ComponentQGraphicsItem
(
":/resources/laser.svg"
,
self
,
[(
65
,
25
,
self
.
nodes
[
0
])])
return
self
.
_svgItem
pykat/detectors.py
View file @
c87e25eb
...
...
@@ -18,6 +18,8 @@ class Detector(object) :
self
.
_kat
=
None
self
.
noplot
=
False
self
.
enabled
=
True
self
.
tag
=
None
self
.
__node
=
None
if
node
.
find
(
'*'
):
self
.
_alternate_beam
=
True
...
...
@@ -26,7 +28,7 @@ class Detector(object) :
self
.
__requested_node
=
node
def
_on_kat_add
(
self
,
kat
):
self
.
_node
=
kat
.
nodes
.
createNode
(
self
.
__requested_node
)
self
.
_
_
node
=
kat
.
nodes
.
createNode
(
self
.
__requested_node
)
@
staticmethod
def
parseFinesseText
(
text
):
...
...
@@ -39,8 +41,8 @@ class Detector(object) :
def
getQGraphicsItem
(
self
):
return
None
def
getNodes
(
self
):
return
[
self
.
_node
]
@
property
def
node
(
self
):
return
self
.
_
_
node
def
__getname
(
self
):
return
self
.
__name
...
...
@@ -85,7 +87,7 @@ class photodiode(Detector):
self
.
values
[
key
]
=
SIfloat
(
value
)
def
__init__
(
self
,
name
,
node
,
senstype
,
num_demods
,
demods
):
def
__init__
(
self
,
name
,
node
,
senstype
=
None
,
num_demods
=
0
,
demods
=
[]
):
Detector
.
__init__
(
self
,
name
,
node
)
if
num_demods
>
2
:
raise
NotImplementedError
(
"pd with more than two demodulations not implemented yet"
)
...
...
@@ -93,10 +95,10 @@ class photodiode(Detector):
self
.
senstype
=
senstype
# every second element into f (starting at 1)
self
.
f
(
demods
[::
2
])
print
self
.
f
[
1
]
# every second element into phi (starting at 2)
self
.
phi
([
1
,
2
])
print
self
.
phi
[
1
]
for
i
in
demods
[
1
::
2
]:
self
.
phi
.
append
(
i
)
...
...
@@ -147,9 +149,9 @@ class photodiode(Detector):
rtn
=
[]
if
self
.
_alternate_beam
:
rtn
.
append
(
"pd {0} {1}"
.
format
(
self
.
name
,
self
.
_
node
.
name
))
rtn
.
append
(
"pd {0} {1}"
.
format
(
self
.
name
,
self
.
node
.
name
))
else
:
rtn
.
append
(
"pd {0} {1}*"
.
format
(
self
.
name
,
self
.
_
node
.
name
))
rtn
.
append
(
"pd {0} {1}*"
.
format
(
self
.
name
,
self
.
node
.
name
))
if
self
.
noplot
:
rtn
.
append
(
"noplot {0}"
.
format
(
self
.
name
))
...
...
@@ -160,7 +162,7 @@ class photodiode(Detector):
def
getQGraphicsItem
(
self
):
if
self
.
_svgItem
==
None
:
self
.
_svgItem
=
ComponentQGraphicsItem
(
":/resources/photodiode_red.svg"
,
self
,[(
-
5
,
11
,
self
.
_
node
)])
self
.
_svgItem
=
ComponentQGraphicsItem
(
":/resources/photodiode_red.svg"
,
self
,[(
-
5
,
11
,
self
.
node
)])
return
self
.
_svgItem
pykat/finesse.py
View file @
c87e25eb
...
...
@@ -43,7 +43,8 @@ from pykat.commands import Command, xaxis
from
pykat.gui.gui
import
pyKatGUI
NO_GUI
=
False
NO_BLOCK
=
"NO_BLOCK"
class
katRun
(
object
):
def
__init__
(
self
):
self
.
runDateTime
=
datetime
.
datetime
.
now
()
...
...
@@ -54,12 +55,9 @@ class katRun(object):
self
.
katScript
=
None
self
.
katVersion
=
None
def
saveKatRun
(
self
,
run
,
filename
):
if
not
isinstance
(
run
,
katRun
):
raise
BasePyKatException
(
"run object must be a katRun type"
)
def
saveKatRun
(
self
,
filename
):
with
open
(
filename
,
'w'
)
as
outfile
:
pickle
.
dump
(
run
,
outfile
,
pickle
.
HIGHEST_PROTOCOL
)
pickle
.
dump
(
self
,
outfile
)
@
staticmethod
def
loadKatRun
(
filename
):
...
...
@@ -67,11 +65,21 @@ class katRun(object):
return
pickle
.
load
(
infile
)
class
Block
:
def
__init__
(
self
,
name
):
self
.
__name
=
name
self
.
contents
=
[]
# List of objects and strings of finesse code
self
.
enabled
=
True
@
property
def
name
(
self
):
return
self
.
__name
class
kat
(
object
):
def
__init__
(
self
,
kat_file
=
None
,
kat_code
=
None
,
katdir
=
""
,
katname
=
""
,
tempdir
=
None
,
tempname
=
None
):
self
.
scene
=
None
# scene object for GUI
self
.
__blocks
=
{}
# dictionary of blocks that are used
self
.
__components
=
{}
# dictionary of optical components
self
.
__detectors
=
{}
# dictionary of detectors
self
.
__commands
=
{}
# dictionary of commands
...
...
@@ -83,7 +91,9 @@ class kat(object):
self
.
__tempdir
=
tempdir
self
.
__tempname
=
tempname
self
.
pykatgui
=
None
# Various
# Various options for running finesse, typicaly the commands with just 1 input
# and have no name attached to them.
self
.
__phase
=
None
self
.
__maxtem
=
None
self
.
__noxaxis
=
None
...
...
@@ -128,10 +138,14 @@ class kat(object):
def
parseCommands
(
self
,
commands
):
blockComment
=
False
self
.
__currentTag
=
""
self
.
__currentTag
=
NO_BLOCK
if
not
(
NO_BLOCK
in
self
.
__blocks
):
self
.
__blocks
[
NO_BLOCK
]
=
Block
(
NO_BLOCK
)
commands
=
self
.
remove_comments
(
commands
)
for
line
in
commands
.
split
(
"
\n
"
):
#for line in commands:
if
len
(
line
.
strip
())
>=
2
:
...
...
@@ -142,11 +156,19 @@ class kat(object):
if
values
[
0
]
==
"%%%"
:
if
values
[
1
]
==
"FTblock"
:
newTag
=
values
[
2
]
if
newTag
!=
self
.
__currentTag
and
self
.
__currentTag
:
if
self
.
__currentTag
!=
None
and
newTag
!=
self
.
__currentTag
:
warnings
.
warn
(
"found block {0} before block {1} ended"
.
format
(
newTag
,
self
.
__currentTag
))
if
newTag
in
self
.
__blocks
:
raise
pkex
.
BasePyKatException
(
"Block `{0}` has already been read"
)
self
.
__blocks
[
newTag
]
=
Block
(
newTag
)
# create new list to store all references to components in block
self
.
__currentTag
=
newTag
if
values
[
1
]
==
"FTend"
:
self
.
__currentTag
=
""
self
.
__currentTag
=
NO_BLOCK
continue
#warnings.warn("current tag {0}".format(self.__currentTag))
...
...
@@ -163,21 +185,26 @@ class kat(object):
continue
first
=
line
.
split
(
" "
,
1
)[
0
]
obj
=
None
if
(
first
==
"m"
):
self
.
add
(
pykat
.
components
.
mirror
.
parseFinesseText
(
line
)
)
obj
=
pykat
.
components
.
mirror
.
parseFinesseText
(
line
)
elif
(
first
==
"s"
):
self
.
add
(
pykat
.
components
.
space
.
parseFinesseText
(
line
)
)
obj
=
pykat
.
components
.
space
.
parseFinesseText
(
line
)
elif
(
first
==
"l"
):
self
.
add
(
pykat
.
components
.
laser
.
parseFinesseText
(
line
))
elif
(
first
==
"xaxis"
or
first
==
"x2axis"
or
first
==
"xaxis*"
or
first
==
"x2axis*"
):
self
.
add
(
pykat
.
commands
.
xaxis
.
parseFinesseText
(
line
))
#elif(first[0:2] == "pd"):
#self.add(pykat.detectors.photodiode.parseFinesseText(line))
obj
=
pykat
.
components
.
laser
.
parseFinesseText
(
line
)
elif
(
first
==
"xaxis"
or
first
==
"x2axis"
or
first
==
"xaxis*"
or
first
==
"x2axis*"
):
obj
=
pykat
.
commands
.
xaxis
.
parseFinesseText
(
line
)
else
:
print
"Parsing `{0}` into pykat object not implemented yet, added as extra line."
.
format
(
line
)
self
.
__extra_lines
.
append
(
line
+
"
\n
"
)
self
.
__currentTag
=
""
obj
=
line
# manually add the line to the block contents
self
.
__blocks
[
self
.
__currentTag
].
contents
.
append
(
line
)
if
not
isinstance
(
obj
,
str
):
self
.
add
(
obj
)
self
.
__currentTag
=
NO_BLOCK
def
run
(
self
,
printout
=
1
,
printerr
=
1
,
save_output
=
False
,
save_kat
=
False
,
kat_name
=
None
)
:
"""
...
...
@@ -314,10 +341,11 @@ class kat(object):
print
fe
def
add
(
self
,
obj
)
:
print
type
(
obj
)
def
add
(
self
,
obj
):
try
:
obj
.
tag
=
self
.
__currentTag
self
.
__blocks
[
self
.
__currentTag
].
contents
.
append
(
obj
)
if
isinstance
(
obj
,
Component
):
if
obj
.
name
in
self
.
__components
:
...
...
@@ -378,37 +406,28 @@ class kat(object):
out
=
[]
for
key
in
self
.
__
components
:
txt
=
self
.
__
components
[
key
].
getFinesseText
()
for
key
in
self
.
__
blocks
:
objs
=
self
.
__
blocks
[
key
].
contents
if
txt
!=
None
:
if
isinstance
(
txt
,
list
):
for
t
in
txt
:
out
.
append
(
t
+
"
\n
"
)
else
:
out
.
append
(
txt
+
"
\n
"
)
for
key
in
self
.
__detectors
:
txt
=
self
.
__detectors
[
key
].
getFinesseText
()
out
.
append
(
"%%% FTblock "
+
key
+
"
\n
"
)
if
txt
!=
None
:
if
isinstance
(
txt
,
list
):
for
t
in
txt
:
out
.
append
(
t
+
"
\n
"
)
else
:
out
.
append
(
txt
+
"
\n
"
)
for
obj
in
objs
:
if
isinstance
(
obj
,
str
):
out
.
append
(
obj
+
'
\n
'
)
elif
isinstance
(
obj
,
Component
)
or
isinstance
(
obj
,
Detector
)
or
isinstance
(
obj
,
Command
):
txt
=
obj
.
getFinesseText
()
if
txt
!=
None
:
if
isinstance
(
txt
,
list
):
for
t
in
txt
:
out
.
append
(
t
+
"
\n
"
)
else
:
out
.
append
(
txt
+
"
\n
"
)
out
.
append
(
"%%% FTend "
+
key
+
"
\n
"
)
if
self
.
noxaxis
!=
None
and
self
.
noxaxis
==
True
:
out
.
append
(
"noxaxis
\n
"
)
for
key
in
self
.
__commands
:
if
self
.
noxaxis
==
None
or
(
self
.
noxaxis
==
True
and
isinstance
(
self
.
__commands
[
key
],
xaxis
)):
txt
=
self
.
__commands
[
key
].
getFinesseText
()
if
txt
!=
None
:
if
isinstance
(
txt
,
list
):
for
t
in
txt
:
out
.
append
(
t
+
"
\n
"
)
else
:
out
.
append
(
txt
+
"
\n
"
)
# now loop through all the nodes and get any gauss commands
for
key
in
self
.
nodes
.
getNodes
():
...
...
@@ -422,14 +441,7 @@ class kat(object):
if
self
.
phase
!=
None
:
out
.
append
(
"phase {0}
\n
"
.
format
(
self
.
phase
))
if
self
.
maxtem
!=
None
:
out
.
append
(
"maxtem {0}
\n
"
.
format
(
self
.
maxtem
))
# There maybe extra lines we want to include in the kat
# script which aren't parseable into components, detectors
# or commands. Typically when something hasn't been fully
# supported yet. So bung these extra lines on at the end
for
lines
in
self
.
__extra_lines
:
out
.
append
(
lines
)
# ensure we don't do any plotting. That should be handled
# by user themselves
out
.
append
(
"gnuterm no
\n
"
)
...
...
pykat/node_network.py
View file @
c87e25eb
...
...
@@ -12,51 +12,99 @@ from pykat.detectors import Detector
class
NodeNetwork
(
object
):
def
__init__
(
self
,
kat
):
self
.
_nodes
=
{}
self
.
_
_
nodes
=
{}
self
.
__kat
=
kat
self
.
__nodeComponents
=
{}
# dictionary of tuples containing which components are connected to a node
self
.
__componentNodes
=
{}
# dictionary of tuples containing which nodes are connected to a given component
self
.
__componentCallback
=
{}
self
.
__node_id
=
1
def
registerComponentNodes
(
self
,
comp
,
node_names
,
change_callback
):
"""
For a given component we create some nodes or get existing ones and
attach them to this component. Also specify a callback function that
is called whenever the nodes attached to this component are changed
, e.g. connected, disconnected, name change, etc.
"""
if
not
isinstance
(
comp
,
Component
):
raise
exceptions
.
ValueError
(
"comp argument is not of type Component"
)
if
comp
.
id
in
self
.
__componentNodes
:
raise
pkex
.
BasePyKatException
(
"Component has already been registered"
)
list
=
[]
for
name
in
node_names
:
n
=
self
.
createNode
(
name
)
self
.
connectNodeToComp
(
n
,
comp
,
do_callback
=
False
)
list
.
append
(
n
)
self
.
__componentNodes
[
comp
.
id
]
=
tuple
(
list
)
self
.
__componentCallback
[
comp
.
id
]
=
change_callback
change_callback
()
def
connectNodeToComp
(
self
,
node
,
comp
,
do_callback
=
True
):
if
node
.
id
in
self
.
__nodeComponents
:
comps
=
self
.
__nodeComponents
[
node
.
id
]
else
:
comps
=
()
if
len
(
comps
)
>=
2
:
raise
pkex
.
BasePyKatException
(
"Node is already connected to 2 components"
)
l
=
list
(
comps
)
l
.
append
(
comp
)
self
.
__nodeComponents
[
node
.
id
]
=
tuple
(
l
)
if
do_callback
:
self
.
__componentCallback
[
comp
.
id
]()
def
createN