Contents
- MODEL_plotWindow.py
- EXPORT_LaTeX.py
- EXPORT_Mfile.py
- SIM_pause.py
- SIM_reset.py
- SIM_startResume.py
MODEL_plotWindow.py 1/6
[top][prev][next]
import DataSet
import Plotter
# We assume for the time being there is only a single Plot block
# should really pass a reference to this Plot block
# "data" could then be attached to this block
# currently "data" is attached to the parent and
# thus there can only be one Plot block
def plotWindow(block):
model = block.rootNode
# titles contains names of blocks connected to the Plot block
titles = []
for in_connect in block.in_connections_:
plotted_block = in_connect.in_connections_[0]
plotted_var_name = plotted_block.block_name.getValue()
if plotted_var_name == "":
print "ignoring unnamed blocks"
else:
titles.append(plotted_var_name)
if not ("data" in dir(model)):
model.data = DataSet.DataSet(source = 'simulator', titles = titles)
gFrame = Plotter.GraphWindow(block.parent, [model.data])
gFrame.title("Plot")
EXPORT_LaTeX.py 2/6
[top][prev][next]
def exportLaTeX(parentApp, model):
# parentApp is the "parent" application object
# It is visible from all buttons, nodes, ...
# Hence, it can be used to store "global" information in.
# model is a hypergraph structure consisting of
# connected "nodes". The nodes in the data structure
# are both CBD nodes and CBD links
# The "model" node has attributes corresponding to the
# global "model attributes" such as model_name and simul_t_init
# Node attributes can be accessed directly as attributes
# They are AToM3 entities however and thus need .getValue()
# to access their value, e.g., model.model_name.getValue()
#
print "\nmodel.model_name"
print model.model_name.getValue()
# Note how simul_t_init is a float
print "model.simul_t_init"
print model.simul_t_init.getValue()
# model.listNodes is a dictionary
# Its keys are the names of all 'nodes' in the model
#
print "nmodel.listNodes"
print model.listNodes
print ""
# model.listNodes.keys() gives us the keys only"
print "model.listNodes.keys()"
print model.listNodes.keys()
print ""
# Keys can be used to access the list of all nodes
# of a particular type directly, for example
print "model.listNodes['Block']"
print model.listNodes["Block"]
print ""
# We can thus iterate over all "Block" nodes
print "Iterating over all 'Block' nodes"
print ""
for node in model.listNodes["Block"]:
print " Node "+str(node)+":"
# Node attributes can be accessed directly as attributes
# They are AToM3 entities however and thus need .getValue()
# to access their value, e.g., node.block_name.getValue()
print ""
print " node name: "+node.block_name.getValue()
print " node value Python type: "+str(type(node.block_out_value.getValue()))
print " node value: "+str(node.block_out_value.getValue())
# It is possible to change node attributes
print " Adding 'X' to node block_name attribute"
node.block_name.setValue(node.block_name.getValue()+"X")
print " node name is now: "+node.block_name.getValue()
# Update the model display to reflect change
node.graphObject_.ModifyAttribute("block_name", node.block_name.toString())
print " Adding '1.0' to node block_out_value attribute"
node.block_out_value.setValue(node.block_out_value.getValue()+1.0)
print " Constant node block_out_value is now: "+str(node.block_out_value.getValue())
# Update the model display to reflect change
node.graphObject_.ModifyAttribute("block_out_value", node.block_out_value.toString())
# We can access any node's
# in_connections_ and out_connections_ lists
# Note how a link is also a node in the model!
print ""
print " Iterating over all links out of node:"
print ""
for link in node.out_connections_:
print " link: "+str(link)
for node in link.out_connections_:
print " node: "+str(node)
# We can find out a node's type
print " node type: "+node.getClass()
# Not be be confused with the node's block_type attribute
# block_type only makes sense for Block nodes,
# so we need to test for that
if node.getClass() == "Block":
blockType = node.block_type.getValue()
print " node's block_type attribute (enum): "+str(blockType)
# An object of enum type is a tuple consisting of
# a list of unique enum names and an index into that
# list indicating which of the
# For example, for an Integrator block, the block_type enum
# is (['Generic', 'Negator', 'Inverter', 'Adder', 'Product',
# 'Delay', 'Integrator', 'Derivative', 'Constant', 'Time'], 6)
# To find out the string representation of the block_type,
# the second element of the tuple (6) is used as an index
# into the first element of the typle ['Generic', ... ]
blockTypeString = blockType[0][blockType[1]]
print " node's block_type attribute (enum): "+blockTypeString
# Some connections are "named ports"
# Rather than using in_connections_ or out_connections_,
# we can access them directly by their port name
if blockTypeString == "Integrator":
print " This is an 'Integrator' block"
print " Its block_IC_port (InitialCondition) port is connected to:"
print node.block_IC_port
print ""
# Note how many blocks have a port called "block_output_port"
EXPORT_Mfile.py 3/6
[top][prev][next]
def exportMfile(parentApp, model):
print "exporting to M-file"
SIM_pause.py 4/6
[top][prev][next]
def pause(parentApp, model):
# currently, this really halts the simulation rather than pausing
# (so Resume doesn't work)
if "generatorThread" in dir(model):
model.generatorThread.stop()
else:
print "\nWarning: no simulation to pause"
print "\n ignoring request\n"
SIM_reset.py 5/6
[top][prev][next]
def reset(parentApp, model):
if "data" in dir(model):
model.data.clear()
else:
print "\nWarning: no simulator to reset"
print "\n ignoring request\n"
SIM_startResume.py 6/6
[top][prev][next]
import threading
from time import sleep
from math import sin, cos, pi
class Generator:
""" This class generates data.
In our example, each generated data-item is a tuple with three
elements.
"""
def __init__(self, dataSet):
""" dataSet: DataSet
"""
self.running = 0 # generate data iff true
self.dataSet = dataSet # DataSet object to which data-items are added
def addDataItems(self):
self.running = 1
# Generate 100 data items:
for i in range(100):
t = i/25.
x = sin(2*pi*t)/5
y = cos(2*pi*t)/5
# Build a data-item with the values, and send them to the plotter:
self.sendPlotter( {'t':t, 'x':x, 'y':y} )
sleep(0.1) # pause to make it look as if some real calculation is
# happening (to emulate a real simulator at work)
# running will be set to 0 by stop() called from another thread
if not self.running:
break
def stop(self):
self.running = 0
def sendPlotter(self, names_values_dict):
""" The keys in the dictionnary "names_values_dict" are matched with
the entries in "self.dataSet.titles" to know what entry correspond
to what index in the data-item.
"""
titles = self.dataSet.titles # ordered titles
temp_data = [None]*len(titles)
for name in names_values_dict.keys():
try:
i = titles.index(name)
except ValueError:
pass # THIS SHOULDN'T HAPPEND
temp_data[i] = names_values_dict[name]
# data-item ordered : add it to dataSet
# (this will trigger updating the appropriate trajectory plots in the GUI)
self.dataSet.append( temp_data )
class GeneratorThread(threading.Thread):
def __init__(self, generatorObject):
""" generatorObject is a Generator instance. """
self.theThread = None
self.generatorObject = generatorObject
def start(self):
""" Start generating data-items. """
# if (has been stopped) or (is finished)...
if self.theThread == None or not(self.theThread.isAlive()):
# Empty the DataSet
self.generatorObject.dataSet.clear()
# Create the thread
self.theThread = \
threading.Thread(target=self.generatorObject.addDataItems)
# Start the thread
self.theThread.start()
def stop(self):
""" Stop data-items from being generated. """
self.generatorObject.stop() # stop the generator
if self.theThread != None:
self.theThread.join() # wait until the thread terminates
self.theThread = None
def startResume(parentApp, model):
# currently, this only (re-)starts, no resume
if "data" in dir(model):
model.generator = Generator(model.data)
model.generatorThread = GeneratorThread(model.generator)
model.generatorThread.start()
else:
print "\nWarning: need to set up data element (in plot window) first\n"
Generated by GNU enscript 1.6.1.