Adding An Actor to Ptolemy II

Below are instructions for adding an actor to Ptolemy II and making it visible in Vergil.

Chapter 5, "Designing Actors," of the Volume 1: Introduction to Ptolemy II of the Ptolemy II Design Document at http://ptolemy.eecs.berkeley.edu/ptolemyII/designdoc.htm discusses how to design actors, but the design document does not discuss compiling the actor and adding it to Vergil. The reason for this omission is because we are hoping to eventually have a cleaner method for adding actors. The text below is a how-to guide for the current environment.

To add a director, see the tutorial at $PTII/doc/tutorial/index.htm.

Contents

Overview

Ptolemy II atomic actors are typically .java files that are compiled to .class files. Ptolemy II composite actors are typically .xml files. There are various ways to make both types of actors available, below is a list with pros and cons.
Instantiate Entity
An atomic or composite actor that has been compiled to a .class file or a composite actor that is contained in a .xml file may be instantiated from Vergil via Graph -> Instantiate Entity and used in the model.
Pros: Easy. Instantiate an actor and use it in the model. When the model is saved, the reference to the class is saved in the model.
Cons: Each time the modeler wants to use the actor, they must instantiate the actor, which means they need to know the name. The .class or .xml file must be present in the CLASSPATH of the JVM when the model is opened.
User Library via Save Actor in Library
Each user has a User Library, stored in $HOME/.ptolemy/UserLibrary.xml. The user library is visible at the bottom of the actor palette. Once a class has been instantiated, to add it to the User Library right click on the actor and select "Save Actor in Library"
Pros: The custom actor appears in the User Library, so it is easy to browse available custom actors.
Cons: The modeler has to import each actor by hand. This can be addressed by using "Import Library"
Import Library
In Vergil Graph -> Import Library will import a file that lists custom actors. This library can be saved in the User Library for more access in later Vergil sessions
Pros: An actor developer can create a file that lists custom actors and send it to a model builder.
Cons: The actor developer must also send a .jar file that includes the .class and/or .xml definitions of the custom actors.
Creating an Import Library Graphically
It is possible to create an library file graphically.
Pros: Same as Import Library. the library file can be created graphically instead of by hand.
Cons: Same as Import Library, the steps are non-intuitive.
Edit the configuration files
Ptolemy II reads configuration files from $PTII/ptolemy/configs. A custom configuration can be created in that directory and invoked using a command-line option to $PTII/bin/vergil or ptolemy.vergil.VergilApplication.
Pros: Creating a custom configuration gives the actor developer control over what actors are easily available to the model builder. In this way, it is possible to hide or remove little-used, confusing or unused actors.
Cons: This method requires editing configuration .xml and possibly a custom Ptolemy II distribution for use by model builders.

The steps for creating a custom actor and adding it to the configuration are covered below.

Creating a Custom Atomic Actor and compiling it

All of the methods above require a custom actor.

The steps below cover creating a custom Atomic actor, which is the most common type of custom actor. It is also possible to create a custom composite actor and use Actor Oriented Classes to make a custom composite actor, see
Edward A. Lee, Xiaojun Liu, Stephen Neuendorffer. Classes and Inheritance in Actor-Oriented Design, ACM Transactions on Embedded Computing Systems (TECS), 8(4):29-1, July 2009.
See also "Sharing Actors Across Models" in the "Using Vergil" chapter of
C. Brooks, E.A. Lee, X. Liu, S. Neuendorffer, Y. Zhao, H. Zheng (eds.), Heterogeneous Concurrent Modeling and Design in Java (Volume 1: Introduction to Ptolemy II), EECS Department, University of California, Berkeley, UCB/EECS-2008-28, April 1, 2008.

The first step to creating a custom atomic actor is to create a .java file and compile it, creating a .class file in the classpath.

Eclipse users should look at the Eclipse Notes page for "Instructions for adding an actor in Eclipse".

For this example, we are going to take the Ramp actor and change the default step from 1 to 2. The new actor will be called Ramp2.

The instructions below assume that you have installed the Java Development Kit (JDK), which includes the javac binary, that you have a make binary and other tools installed, that Ptolemy II has been installed, and that $PTII/configure and make have been run. For details about the installation process, see $PTII/doc/install.htm

Under Windows Server 2008 R2 with Java 7 and Cygwin, to do the setup, I did:

      export PTII=c:/Ptolemy/ptII9.0.devel
      cd "$PTII"
      ./configure
      make fast >& make.out
    

Configure and make usually generate a few warnings.

An alternative is to use Apache Ant. Under Mac OS X 10.7, first install Ant, then download the Ptolemy II development tree:

      cd
      svn co https://source.eecs.berkeley.edu/svn/chess/ptII/trunk ptII
      cd ptII
      export PTII=`pwd`
      cp build.default.xml build.xml
      ant
    

Below are the steps necessary to create the .java file for an actor and compile it:

  1. Create the new .java file that implements your actor:
    1. In this case, we are just copying a Ramp.java to Ramp2.java
      	      cd $PTII/ptolemy/actor/lib	
      	      cp -p Ramp.java Ramp2.java
      	    
      Note that if we had copied our java code from a different directory, we would also have to change the package statement (usually near line 31) in the java code. This is good to keep in mind since there is no error message to clue you in to this particular error.

    2. Edit Ramp2.java and
      • Change:
        		  public class Ramp extends SequenceSource {
        		
        to:
        		  public class Ramp2 extends SequenceSource {
        		
      • Change:
        		  public Ramp(CompositeEntity container, String name)
        		  throws NameDuplicationException, IllegalActionException  {
        		
        to:
        		  public Ramp2(CompositeEntity container, String name)
        		  throws NameDuplicationException, IllegalActionException  {
        		
      • Change:
        		  step.setExpression("1");
        		
        to:
        		  step.setExpression("2");
        		
      • Change:
        		  Ramp newObject = (Ramp)super.clone(workspace);
        		
        to:
        		  Ramp2 newObject = (Ramp2)super.clone(workspace);
        		
  2. If you are using make to build Ptolemy II, then the makefiles need to be updated.
    If you are using ant, then there is no need to update the makefiles for this example.
    make users: Edit the $PTII/ptolemy/actor/lib/makefile and add Ramp2.java to the value of JSRCS. A good place for this is just after the Ramp.java \ line:
    	  Quantizer.java \
    	  Ramp.java \
    	  RandomSource.java \
    	
    	  Quantizer.java \
    	  Ramp.java \
    	  Ramp2.java \
    	  RandomSource.java \
    	
    Note that there is a TAB character before Ramp2.java.
    This step is not strictly necessary, but it is good programming practice to put all source files in the makefile. Another reason we add it to the makefile is so that our new actor will be included in the lib.jar file.
  3. make users: Run make in the $PTII/ptolemy/actor/lib directory (which is where you should already be). make will descend into the subdirectories and compile any needed files and eventually run
    	  rm -f `basename Ramp2.java .java`.class
    	  CLASSPATH="../../.." "/cygdrive/c/j2sdk1.4.2_06/bin/javac" -g -O Ramp2.java
    	
    and Ramp2.class will be produced.
    ant users: Run
    	  cd $PTII
    	  ant
    	

At this point, a class file at $PTII/ptolemy/actor/lib/Ramp2.class will have been created.

Below is a discussion of various ways to use that actor.

Instantiate Entity

To instantiate an entity, follow these steps
  1. Start up Vergil and do File -> New -> Graph Editor
  2. In Vergil, select Graph -> Instantiate Entity
  3. In the Instantiate Entity window, edit the Class name field and replace its contents with ptolemy.actor.lib.Ramp2
    Leave the Location (URL) field blank
    Hit OK
  4. The Ramp2 icon will appear.
  5. To test the Ramp2 actor:
    1. Click on Actors -> sinks -> GenericSinks and drag a Display actor over to the main canvas.
    2. Connect the two actors by left clicking on the output of the ramp2 actor and dragging over to the input of the Display actor.
    3. Select Directors -> SDF and drag the SDF director over to the right window.
    4. Select View -> Run and change the number of iterations from 0 to 10, then hit the Run button.
    5. You should see the numbers from 0 to 18 in the display.

Pros: Easy. Instantiate an actor and use it in the model. When the model is saved, the reference to the class is saved in the model.

Cons: Each time the modeler wants to use the actor, they must instantiate the actor, which means they need to know the name. The .class or .xml file must be present in the CLASSPATH of the JVM when the model is opened.

A few notes about Instantiate Entity:

Composite Actors can also be instantiated in this way. For example ptolemy.actor.lib.Sinewave is an Actor Oriented Class definition of a composite actor.

The Graph -> Instantiate Attribute menu choice is used to instantiate Ptolemy Attributes such as parameters or Directors.

User Library via Save Actor in Library

Each user has a User Library, stored in $HOME/.ptolemy/UserLibrary.xml.

In Vergil, the user library is visible at the bottom of the actor palette on the left. Once a class has been instantiated, to add it to the User Library right click on the actor and select "Save Actor in Library"

Pros: The custom actor appears in the User Library, so it is easy to browse available custom actors.

Cons: The modeler has to import each actor by hand. This can be addressed by using "Import Library"

The UserLibrary can be opened and organized just like a regular composite actor or a ptolemy.moml.EntityLibrary can be used to provide a tree structure within the User Library.
To add hierarchy to the User Library:

  1. In a Vergil graph editor, right click on UserLibrary and select Open for Editing
  2. Instantiate an Entity Library by doing Graph -> Instantiate Entity and then changing the Class name field to ptolemy.moml.EntityLibrary and hitting OK
  3. Optional: Change the name of the newly created EntityLibrary by right clicking on it
  4. Open a new graph editor (File -> New -> Graph Editor) and click on the UserLibrary to see the new Entity Library
  5. Right click on the new Entity Library and select Open for Editing to add actors

Import Library

Ptolemy II uses .xml files that list one or more actors. An actor developer can provide such a file to model developers.

  1. Create a file named myactors.xml with the contents below:
    <?xml version="1.0" standalone="no"?>
      <!DOCTYPE class PUBLIC "-//UC Berkeley//DTD MoML 1//EN"
      "http://ptolemy.eecs.berkeley.edu/xml/dtd/MoML_1.dtd">
    <class name="MyActors" extends="ptolemy.moml.EntityLibrary">
        <configure>
    	<group>
                <entity name="Ramp2" class="ptolemy.actor.lib.Ramp2"/>
            </group>
        </configure>
    </class>
    	  
  2. Start up vergil, do File -> New -> Graph Editor
  3. Import myactors.xml with Graph -> Import Library
  4. In the left hand actor pane, "MyActors" will appear at the bottom
Currently, to add these files to the User Library, one must drag each in from the imported library into the User Library.
  1. Import MyActors as above.
  2. In the left hand actor pane, right click on the UserLibrary and select Open for Editing.
  3. A new window will appear with UserLibrary.xml in the title bar. In that window open the MyActors palette and drag the Ramp2 actor into the main pane. This will add the Ramp2 actor to UserLibrary.

FIXME: It would be nice if we could import the library directly into the User Library.

Pros: An actor developer can create a file that lists custom actors and send it to a model builder.

Cons: The actor developer must also send a .jar file that includes the .class and/or .xml definitions of the custom actors.

Creating an Import Library Graphically

It is possible to create an library file graphically instead of by hand as above in Import Library.

  1. Follow the same procedure as above to create an EntityLibrary within the UserLibrary.
    1. In a Vergil graph editor, right click on UserLibrary and select Open for Editing.
    2. Instantiate an Entity Library by doing Graph -> Instantiate Entity and then changing the Class name field to ptolemy.moml.EntityLibrary and hitting OK.
  2. Right click on the newly created EntityLibrary and select Convert To Class. A blue border will be added, signifying that EntityLibrary is now an actor-oriented class.
  3. Right click on the EntityLibrary Class and select Open Actor. The contents of the EntityLibrary class will open in a new window.
  4. In the EntityLibrary Class window, drag in or instantiate actors.
  5. In the EntityLibrary Class window, select File -> Save As. When the Save Submodel? window pops up, check the "Save Submodel only" box, hit ok and save the file.
  6. The saved file may now be import as per the Import Library procedure above.

Pros: Same as Import Library, the library file can be created graphically instead of by hand.

Cons: Same as Import Library, the steps are non-intuitive.

Editing the configuration files

Ptolemy II reads configuration files from $PTII/ptolemy/configs. A custom configuration can be created in that directory and invoked using a command-line option to $PTII/bin/vergil or ptolemy.vergil.VergilApplication.

  1. There are many ways to make a custom actor permanently available. One way is to edit the Ptolemy II configuration. This method is best if only one person is using Ptolemy II. A downside is that an update of Ptolemy II will require readding the actor.
    An upside is that it is easy.
    Edit $PTII/ptolemy/actor/lib/sequencesources.xml and add Ramp2 just after the lines for Ramp
    Change:
    <entity name="Ramp" class="ptolemy.actor.lib.Ramp">
        <doc>Create a sequence of tokens with increasing value</doc>
    </entity>
    
    <entity name="Sinewave" class="ptolemy.actor.lib.Sinewave"/>
    	
    To:
    <entity name="Ramp" class="ptolemy.actor.lib.Ramp">
        <doc>Create a sequence of tokens with increasing value</doc>
    </entity>
    
    <entity name="Ramp2" class="ptolemy.actor.lib.Ramp2">
        <doc>Create a sequence of tokens with increasing value 2</doc>
    </entity>
    
    
    <entity name="Sinewave" class="ptolemy.actor.lib.Sinewave"/>
    	
  2. Start up Vergil and click on File -> New -> Graph Editor
  3. In the Graph Editor window, click on Actors -> Sources -> SequenceSources

Pros: Creating a custom configuration gives the actor developer control over what actors are easily available to the model builder. In this way, it is possible to hide or remove little-used, confusing or unused actors.

Cons: This method requires editing configuration .xml and possibly a custom Ptolemy II distribution for use by model builders.

Adding a new palette

To add a new set of actors, we first create a .xml file that lists the actor. In this case, the file is called $PTII/ptolemy/actor/lib/myactors.xml, and it contains one actor, Ramp2:

<?xml version="1.0" standalone="no"?>
  <!DOCTYPE plot PUBLIC "-//UC Berkeley//DTD MoML 1//EN"
  "http://ptolemy.eecs.berkeley.edu/xml/dtd/MoML_1.dtd">
<entity name="myactors" class="ptolemy.moml.EntityLibrary">
    <configure>
        <?moml
           <group>
               <doc>My Actors</doc>
               <entity name="Ramp2" class="ptolemy.actor.lib.Ramp2">
                   <doc>Create a sequence of tokens with increasing value of 2</doc>
               </entity>
           </group>
         ?>
    </configure>
</entity>
    

Note that the xml involving the Ramp2 actor is inside a <configure>...<configure> block, which prevents the actor from being instantiated until the file is viewed in the actor palette.

Below we discuss two ways of adding the configuration:

  1. Adding a palette to the user configuration
    Easier to do, works with the Windows installer version, makes your new palette visible in all configurations
  2. Adding a palette to the default configuration Adding a palette to the default configuration
    Harder to do, but useful for developers

Adding a palette to the user configuration

When vergil starts up, it opens the user library, which is located at $HOME/.ptolemyII/UserLibrary.

Under Windows 7, $HOME might be found at c:/Users/yourlogin, so the UserLibrary.xml file would be at c:/Users/yourlogin/.ptolemyII/UserLibrary.xml

Edit UserLibrary.xml and change:

      <entity name="UserLibrary" class="ptolemy.moml.EntityLibrary"/>
    

to:

      <entity name="UserLibrary" class="ptolemy.moml.EntityLibrary">
      <group>
      <input source="ptolemy/actor/lib/myactors.xml"/>
      </group>
      </entity>
    

Note that you must remove the slash in the first line:

      <entity name="UserLibrary" class="ptolemy.moml.EntityLibrary"/>
    

becomes:

      <entity name="UserLibrary" class="ptolemy.moml.EntityLibrary">
    

After changing UserLibrary.xml, restart vergil and the myactors sub-palette will appear under UserLibrary.

Adding a palette to the default configuration

The palette on the left side of the Graph editor lists the utilities, directors and actors available for use in Vergil.

The palette and menus are determined by configuration files.

The default configuration for $PTII/bin/vergil is located at $PTII/ptolemy/configs/full/configuration.xml. (For further information about how the configuration is specified, see the VergilApplication class documentation.)

$PTII/ptolemy/configs/full/configuration.xml. includes $PTII/ptolemy/configs/defaultFullConfiguration.xml. Eventually, we include $PTII/ptolemy/configs/basicActorLibrary.xml.

We want to add our new palette, myactors.xml, to the actor library palette so we will add myactors.xml to $PTII/ptolemy/configs/basicActorLibrary.xml. Note that we want our new palette to be a sub pallet of the actor library palette, just as the sources palette is. The input statements below do not cause the palette named by the source parameter to be a sub palette. Sub-paletting is caused by the entity statement in the 4th line of your myactors.xml file.

In ptolemy/configs/basicActorLibrary.xml we change

      <input source="ptolemy/actor/lib/sources.xml"/>
    

to:

      <input source="ptolemy/actor/lib/myactors.xml"/>
      <input source="ptolemy/actor/lib/sources.xml"/>
    

Then restart vergil, and your myactors sub-palette will appear under 'actor library'.

Adding to the Java Classpath

We consider two cases where you would like to make a custom actor available:

  1. If your custom actor has is based on a .java file, then the user must make your custom actor's .class file visible to the Ptolemy II runtime.
  2. If your custom actor is defined in a .xml or .moml file, then the user must make your custom actor's .xml or .moml file visible to the Ptolemy II runtime.

Both situations involve the user making files visible to the Ptolemy II runtime by placing files in a location where the Ptolemy II runtime will find the files. In Java, this is know as "Adding a file to the classpath.". For details about the classpath, see the Java Tutorial PATH and CLASSPATH page

A few things to keep in mind about the Java classpath:

Ptolemy II is available on several platforms and can be built in various ways. Below is a list of possibilities:

Installed from the Windows Installer, invoked using vergil.exe

The Windows vergil.exe is what gets invoked with the user installs Ptolemy II via the Windows installer and then invokes Ptolemy via the Windows Start Menu.

The vergil.exe binary is created using launch4j. When the installer is being built, a list of directories in which to search are passed to launch4j and then encoded in vergil.exe. A list of these directories may be found in $PTII/bin/mkl4j.

As of May, 2012, the directories that are searched by vergil.exe:

%HOMEPATH%/.ptolemyII
Any .class files in this directory or any subdirectories
%HOMEPATH%/.ptolemyII/*
Any .jar or .JAR files in this directory
%HOME%/.ptolemyII
Any .class files in this directory or any subdirectories
%HOME%/.ptolemyII/*
Any .jar or .JAR files in this directory
contrib/contrib.jar
The contrib/contrib.jar file in the directory where vergil.exe is invoked. Typically, this is c:\Ptolemy\ptIIN.M, here N.M is the release number.
$ROOT
The directory where vergil.exe is invoked. Typically, this is c:\Ptolemy\ptIIN.M, here N.M is the release number.
other jar files . . .
Other jar files in the Ptolemy II release

Under Windows %HOMEPATH% is set to various locations depending on the version of Windows, see http://www.askvg.com/list-of-environment-variables-in-windows-xp-vista-and-7/. Under Windows 7, %HOMEPATH% is typically C:\Users\username.

Under Windows %HOME% is not set by default, but since some Cygwin applications use it, %HOME% may be set in your environment.

So, under Windows when invoking vergil.exe if you have .class files, then adding them to either %HOMEPATH%/.ptolemyII or %HOME%/.ptolemyII or to the location where Ptolemy is installed is a good bet.

If you have .jar files, then place them in either %HOMEPATH%/.ptolemyII or %HOME%/.ptolemyII or replace contrib.jar with your jar file.

Built using ./configure or Ant, invoked using $PTII/bin/vergil.bat

The $PTII/bin/vergil.bat DOS batch file is created by running make in $PTII/bin. The vergil.bat file looks in the directories listed for vergil.exe.

Built using ./configure or Ant, invoked using $PTII/bin/vergil

The $PTII/bin/vergil shell script is a symbolic link to $PTII/bin/ptinvoke. The $PTII/bin/ptinvoke script is created from the $PTII/bin/ptinvoke.in, which is in turn created by running configure in $PTII.

To update $PTII/bin/vergil:

      cd $PTII
      ./configure
      cd $PTII/bin
      make
    

The $PTII/bin/vergil shell script can be run from any platform where Ptolemy II has been built from sources. The Windows installer does not include a working $PTII/bin/vergil file.

The $PTII/bin/vergil script searches from the same directories as vergil.exe above, except %HOMEPATH%/.ptolemyII and %HOMEPATH/.ptolemyII/* are not searched.

Macintosh, invoked using $PTII/bin/Vergil.app

Under Mac OS X, the $PTII/bin/Vergil.app script is created by invoking $PTII/bin/makeapp, which is a symbolic link to $PTII/bin/ptinvoke. The $PTII/bin/ptinvoke script is created from the $PTII/bin/ptinvoke.in, which is in turn created by running configure in $PTII.

To update $PTII/bin/Vergil.app:

      cd $PTII
      ./configure
      cd $PTII/bin
      make
    

$PTII/bin/Vergil.app is a directory that is contains bin/Vergil.app/Contents/Info.plist which is the file that is created by running $PTII/bin/makeapp.

Unfortunately, Mac OS X Java 1.6.0_31-b04-415-11M3635 does not seem to support Java wildcard paths like $HOME/.ptolemyII/*. The workaround is to open $PTII/bin/Vergil.app/Contents/Info.plist with an editor and add the .jar files by hand.

Conclusion

In the above, we have shown various ways of including user defined custom actors in Ptolemy II.