Creating a Package: Adding a Model
Follow these steps to add a model (i.e. calculations) to a Package.
While models can be written in just about any programming language, this article demonstrates the concepts using a script written in the R Programming Language.
Step 1 - Add a Transformer to your Configuration File
Although the helloworld Package created in the previous article is a complete Package, it does not yet do any model calculations and so is not yet runnable in SyncroSim. To make the Package runnable we must first add at least one Transformer element to the Package.
Transformers are the executable units of a SyncroSim Package - in other words, the calculations associated with your Package. Each Package has a special entry point called a Primary Transformer; there is only ever one Primary Transformer per Package. You can think of the Primary Transformer as your Package's overall "model". Each Primary Transformer can optionally then refer to any number of additional Transformers (i.e. "sub-models" within your overall model).
In the example below we will add a single Primary Transformer to the helloworld Package; this Transformer will take the form of an R or Python script.
As is the case in all of the helloworld examples, the package.xml file below has been formatted for demonstration purposes. Most real Packages use more typical XML formatting to save vertical space. For example, each attribute for an element normally appears on the same line.
Here is the new package.xml file:
<?xml version="1.0" encoding="utf-8"?> <package name="helloworld" displayName="Hello World Package" version="1.0.0"> <transformers> <transformer name="Primary" isPrimary="True" programName="Rscript" programArguments="model.R"/> </transformers> <layouts> <layout name="coreforms_LibraryDatafeeds"> <item name="core_Rconfig"/> </layout> </layouts> </package>
Notice that we have added to our previous example new <transformers> and <layouts> (plural) elements as a children of the <package> element.
The <transformers> element contains all of the Transformers within the Package. In this simple example we have specified our transformer as a single <transformer> (singular) child element with the following attributes:
- name specifies the internal name of the Transformer.
- isPrimary="True" to indicate that this is the Package's Primary Transformer.
- programName="Rscript" or "python" to specify the name of the external program to execute when the Transformer is invoked; the keyword Rscript indicates that we wish to run an R script, while the keyword python indicates that we wish to run a Python script.
- programArguments="model.R" or "model.py" to specify a string to pass to the external program as the command-line argument: in this case we specify model.R as the name of our R Script, or model.py as the name of our Python script.
The <layouts> element specifies items to include on the SyncroSim user interface. Here we say that we want a built-in SyncroSim Core form (named core_RConfig or core_PyConfig) to be displayed as part of the Library Datafeeds (named coreforms_LibraryDatafeeds). This form will allow users to control the location of their R or Python program executable.
The example XML configuration file above assumes your Transformer calls an R Script. Because R is used so frequently with SyncroSim, entering the keyword RScript for the externalProgramName argument allows SyncroSim to try to find your R installation automatically, and/or to specify it directly on the SyncroSim user interface using the built-in core_Rconfig form.
Replace your existing package.xml file in the helloworld subfolder (from the previous article) with the text above.
Step 2 - Create the Model Script
Of course the model.R file does not exist yet. You must create it and add it to the Package. Below is a very simple example script in R that multiplies two numbers together and saves the results to a file:
x <- 5.0 # Set first model input a <- 2 # Set second model input y <- a * x # Calculate output # Save output to file write.csv(y, file = "c:/temp/helloworld.csv", row.names=F)
The example model.R script above assumes you are using c:\temp as your working folder for this tutorial. If you are using a different folder then you will need to modify the last line of this example accordingly.
Save the text above to a file called model.R in your helloworld subfolder (from the previous article)
Step 3 - Rebuild the Package
Next use the Package Manager to rebuild the Package (see Step 4 in the Building a Package article).
Step 4 - Run the Model
You are now ready to run your model from SyncroSim.
- Start SyncroSim
- Create a new Library based on the helloworld Package
- Check your executable location - click on helloworld Library in the Library Explorer, and then select Library Properties from the File menu. Then select the R Configuration or Python Configuration tab to check and/or set the location of your R or Python Program Executable. Note that if you installed R in its default location then SyncroSim will have found it automatically (shown as Default), in which case you can leave this screen blank.
- Run the Scenario - click on the auto-generated New Scenario in the Library Explorer, and then select Run from the Scenario menu.
Your Scenario should run without error; the results of your run can be found in the CSV file (e.g. c:\temp\helloworld.csv) generated by your script above.
You can optionally run your R or Python script interactively (i.e. line by line) from within SyncroSim; this can be very helpful for testing and debugging a new script.
Using an IDE
To run your script interactively from an Integrated Development Environment (IDE) such as R Studio or Spyder, return to the R Configuration or Python Configuration tab (under File | Library Properties menu) and select the button beside Run using IDE. In the filepath, point to the IDE program executable (e.g. by default for RStudio this would be C:\Program Files\RStudio\bin\rstudio.exe); this ensures SyncroSim opens the IDE each time your model is run. You can then run your R or Python script line-by-line as you would normally in your IDE.
- Define data associated with the inputs and outputs of your model