Creating a Package: Defining Data
Follow these steps to specify the inputs and outputs for a Package.
In the previous article we added a Transformer to the helloworld Package, but there is still one thing missing: we have not yet specified the format of the data that goes in to and out of this Package; as a result we cannot yet manage the data within SyncroSim.
Step 1 - Add Inputs and Outputs to the XML Configuration File
To provide the Transformer with model inputs and outputs, in this example we will add two Datafeeds to our existing XML configuration file for the helloworld Package: one for inputs (i.e. values of x and a in our R or Python Scripts) and one for outputs (i.e. calculated values of y). Here is the revised 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">
<datafeeds>
<!--Model Inputs-->
<datafeed name="InputDatafeed" displayName="Inputs" dataScope="Scenario">
<datasheets>
<datasheet name="InputDatasheet">
<columns>
<column name="InputDatasheetID" dataType="Integer" isPrimary="True"/>
<column name="ScenarioID" dataType="Integer"/>
<column name="x" dataType="Double" displayName="Value for x"/>
<column name="a" dataType="Integer" displayName="Value for a"/>
</columns>
</datasheet>
</datasheets>
</datafeed>
<!--Model Outputs-->
<datafeed name="OutputDatafeed"
displayName="Outputs"
dataScope="Scenario">
<datasheets>
<datasheet name="OutputDatasheet">
<columns>
<column name="OutputDatasheetID" dataType="Integer" isPrimary="True"/>
<column name="ScenarioID" dataType="Integer"/>
<column name="y" dataType="Double" displayName="Value for y"/>
</columns>
</datasheet>
</datasheets>
</datafeed>
</datafeeds>
</transformer>
</transformers>
<layouts>
<!--Library Datafeeds Layout-->
<layout name="coreforms_LibraryDatafeeds">
<item name="core_Rconfig"/>
</layout>
<!--Scenario Datafeeds Layout-->
<layout name="coreforms_ScenarioDatafeeds">
<item name="InputDatafeed"/>
<item name="OutputDatafeed"/>
</layout>
</layouts>
</package>
Datafeeds and Datasheets
Notice that we have added a <datafeeds> (plural) child element to our <transformer>. This element can contain any number of <datafeed> (singular) elements.
Along with familar attributes like name and displayName, each Datafeed must have its dataScope defined; the dataScope attribute defines the position of the Datafeed in the Library object hierarchy. In this example we have set dataScope="Scenario" for both our Datafeeds, indicating that values for these Datafeeds will be specified for every Scenario in our Library; other options for dataScope are Project (when values specified once for each Project) and Library (when values specified once for the entire Library).
The <datasheets> (plural) child element of each <datafeed> contains one or more <datasheet> (singular) elements. Each <datasheet> must contain one or more <column> elements, where a column is defined by its name and dataType. Each Datasheet requires a single primary key column (i.e. setting isPrimary="True") so that individual records can be updated in the SyncroSim database. For a Scenario scoped Datasheet, a column named ScenarioID with dataType=Integer is also required. After that you can define any number of additional columns, as required by your model.
Layouts
If you are only interested in using your Package from the command-line, through the rsyncrosim R Package or through the pysyncrosim Python Package, then your XML configuration file is complete. However if you would like your model inputs and outputs to appear automatically in the SyncroSim Library Explorer then you must update the <layouts> (plural) element.
The <layouts> (plural) element tells SyncroSim where to display all of the Package's Datafeeds. In general you should include a <layout> (singular) element to contain each of your Library, Project and Scenario Datafeeds, naming them coreforms_LibraryDatafeeds, coreforms_ProjectDatafeeds and coreforms_ScenarioDatafeeds, respectively. In the previous article we had already added a single built-in Library-level Datafeed (named core_Rconfig or core_Pyconfig) to allow users to specify the location of their R or Python executable file. Here we have added a second layout to display our two new Scenario-level Datafeeds.
Step 2 - Modify the Model Script
You will now need to modify the R script from the previous article in order to both read your inputs into R from your SyncroSim Library, and write your outputs from R back to your Library. Below is a modified version of the model.R file to be included in your Package's helloworld subfolder (from the previous article):
library(rsyncrosim) # Load SyncroSim R package
myScenario <- scenario() # Get the SyncroSim Scenario that is currently running
# Load Scenario's input Datasheet from SyncroSim Library into R dataframe
myInputDataframe <- datasheet(myScenario, name = "helloworld_InputDatasheet")
# Extract model inputs from this R dataframe and then do calculations
x <- myInputDataframe$x
a <- myInputDataframe$a
y <- x * a
# Setup an empty R dataframe ready to accept output in SyncroSim datasheet format
myOutputDataframe <- datasheet(myScenario, name = "helloworld_OutputDatasheet")
# Copy output into this R dataframe
myOutputDataframe[1:length(y),"y"] <- y
# Save this R dataframe back to the SyncroSim library's output datasheet
saveDatasheet(myScenario,
data = myOutputDataframe,
name="helloworld_OutputDatasheet")
Step 3 - Rebuild the Package
Use the Package Manager to rebuild the Package using the new package.xml and model.R or model.py files shown above (see Step 4 in the Building a Package article).
Step 4 - Set Model Inputs
- 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. In this tab, also ensure that the Run directly option is selected.
- Edit the Scenario inputs - Right-click on the auto-generated empty New Scenario in the Library Explorer and select Properties. Then select the Inputs tab and enter pairs of values for your x and a model inputs in the grid.
Step 5 - Run the Model
Right-click on this New Scenario again in the Library Explorer and select Run again to run this Scenario.
Step 6 - View the Results
- Once the run is complete, return to the Library Explorer. Expand the node beside the New Scenario to reveal a Results folder containing your results, then expand the node beside the Results folder to show the newly generated date/time stamped Results Scenario. Each Results Scenario contains a read-only snapshot copy of all your inputs at the time of your run, along with values for your model generated outputs.
- Right-click on this Results Scenario and select Properties to view the details of this Results Scenario; you will find your calculated outputs under the Outputs tab.
What Next?
- Enhance your package by incorporating more advanced features