# Writing Demo Scripts

## Primary tabs

Wiki home pageDemo scripts are invaluable for helping others learn OpenMx, and, during development, to test that the integrity of the program is maintained as well as to test new features.

Please include a style header that matches these guidelines when creating a demo:

1. Include the program name labeled with 'Program:'
2. Include the author name labeled with 'Author:'
3. Include the date in YYYY.MM.DD format and labeled with 'Date:'
4. Include the type of model being used in the demo and label it with 'ModelType:'
5. Include the type of data being used in the demo and label it with 'DataType:'
6. Include the substantive field being used in the demo and label it with 'Field:'
7. Include the purpose of the demo and label it with 'Purpose:'
8. Keep an ongoing revision history of the demo and label it with 'RevisionHistory:'

Here is an example of a style header:

# -----------------------------------------------------------------------------
# Program: ExampleDemo.R
# Author: Ross Gore
# Date: 2011.06.16
#
# ModelType: Model Type Suggestions
# DataType: Data Type Suggestions
# Field: Field Suggestions
#
# Purpose:
#      One Factor model to demonstrate style header for demos.
#
# RevisionHistory:
#      Ross Gore -- 2011.06.16 initial creation
# -----------------------------------------------------------------------------


1. Each major action in the source code should be followed by a comment describing it and followed by a line of "-"s up to column 80.
2. If additional detail is needed to describe minor actions within the block of source code then a comment should be inserted immediately following minor action and followed by a line of "-"s up to column 40.
3. If even further detail is needed then comments should be inserted on the same line as the source code following the item needing further explanation.

Here is an example of the standard setup of a demo along with the commenting style.

require(OpenMx)
# -----------------------------------------------------------------------------

data(myRawData)
# Prepare Data
# -----------------------------------------------------------------------------

myMxModel <- mxModel("ExampleDemoModel", type ="..."
mxPath(from="...") # this particular path is very important
# Added a path to my model
# -------------------------------------
) # close model
# Create an MxModel object
# -----------------------------------------------------------------------------

myMxModelFit <- mxRun(myMxModel)
# Fit model with mxRun
# -----------------------------------------------------------------------------

summary(myMxModelFit)
# Print a summary of the results
# -----------------------------------------------------------------------------


### How to write

Avoid using functions which will not work for all users/platforms. Things to avoid include:

source() Include the source in the demo so it is self-contained
setwd() use data() to avoid needing to set the current directory
(unless from a URL)
data(, package="OpenMx")
Undefined variables check that your script is not dependent on variables which it does not set. "rm(list = ls())" will remove all variables from your environment - a bit extreme but if your script still runs it is a good check that you are not using variables you don't set'

### Where to put demos

Demo scripts with the intention of teaching or sharing a technique can be added to the "/trunk/demos/" directory.
nb: When adding a file to this directory, please manually update the "00INDEX" file in this directory with the name of the file and a 1-line description of its purpose.

Test scripts with the intention of verifying OpenMx functionality can be added to the "/trunk/models/passing" or "/trunk/models/failing".

nb: Test scripts differ from other scripts in that they MUST verify that the results obtained are those returned in Mx 1.x using omxCheckCloseEnough() and related functions.

## Using omxCheckCloseEnough()

omxCloseEnough() simply compares the elements of two compatible arrays, returning TRUE if no pair of elements differ by more than epsilon (the maximum allowed difference)
omxCloseEnough() takes three arguments:

   omxCheckCloseEnough(a, b, epsilon = 10^(-15))

'a' and 'b' are numeric vectors or matrices, and 'epsilon' is the maximum allowed (absolute?) difference between the elements of 'a' and the elements of 'b'.

In usage, you would typically fill vector a with results from the results of an OpenMx mxRun() statement, while the elements of b will be hard-coded from a comparable Mx run. nb:

For convenience, you can run mx 1.x from OpenMx using the function omxOriginalMx(), which takes two arguments: 'mx.filename' is a string that is the path and name of the mx script to run (relative be found in the directory returned by getwd() ), and 'output.directory' similarly the relative path to the directory where output files will be written.

notes: 'mx' must appear somewhere in your \$PATH.
While you can use omxOriginalMx() to get the correct values for omxCloseEnough(). comment this code out in the demo, and hard code the results: We cannot assume that developers and users have installed Mx 1.X.