Author: Guy Shepherd
In the last article I demonstrated how to run a Python script with arguments from a Mo.net group projection task and return the results from the script back to Mo.net.
I will reverse the scenario and use a Python script to call a Mo.net projection task in this example. While the real-world use case for such a solution is perhaps less obvious, it may be useful for developers who are undertaking R&D or prototyping activity and wish to use an existing Mo.net model together with a Python script as the basis for the work.
Environmental Configuration
The environment used for this example is identical to the previous example and again uses out-of-the-box installations of both Mo.net Model Development Studio and Python:
- Mo.net Model Development Studio (Standard, Professional or Enterprise) v7.0 or later
- Python 3.5 or later (64-bit edition preferred)
The Mo.net Projection
This example uses the compile to EXE / DLL feature of Mo.net Model Development Studio to create a Windows DLL from a given Mo.net projection task. This DLL is then called from the Python script as outlined in the steps below.
To keep things simple, I will generate a DLL from one of the sample projects included with Mo.net Model Development Studio, but the same approach can be used for any Mo.net project
To generate a Mo.net projection DLL follow the steps below:
- Launch Mo.net Model Development Studio
- Click New in the backstage menu
- Click Installed and then select the Sample Projects tab
- Now select Linked Funds Dynamic Basis from the list of available projects
- Give the project a suitable name – .e.g. LinkedFundsForPython and choose a folder in which to store the project – e.g. C:\Mo.net Projects\LinkedFundsForPython
- Click Create to create the project
- When the project opens navigate to the Tasks view
- Click on the Linked projection task
- Now select Create DLL / EXE from the Compile menu
- Click on the expand button to show the advanced options
- Select Projection DLL and enter a suitable location for the DLL to be created – e.g. C:\Mo.net Projects\LinkedFundsForPython\Linked_DLL
- Ensure that Merge Table Data is ticked
- Ensure that Target 64-bit is ticked (assuming the 64-bit version of Python is installed)
- Click OK to create the DLL
Before attempting to run the projection from Python, you will need to copy the Tables folder from: C:\Mo.net Projects\LinkedFundsForPython\
to… C:\Mo.net Projects\LinkedFundsForPython\Linked_DLL.
After this step there should be a number of files in:
C:\Mo.net Projects\LinkedFundsForPython\Linked_DLL\Tables
We are now in a position to call the Mo.net projection DLL from Python.
Python Script
The script below illustrates how to call the Mo.net projection DLL created above, overriding a projection parameter and retrieving a result from the projection. This script can be saved as a .py file (or copied into a Python IDE, such as IDLE or PyCharm) and run.
import sys import clr # define path to the Mo.net Linked DLL and add this to system path assembly_path = r"C:\Mo.net Projects\LinkedFundsForPython\Linked_DLL" sys.path.append(assembly_path) # add Mo.net kernel assembly references to the CLR clr.AddReference("Sal.CalculationEngine.GenCore") clr.AddReference("Sal.CalculationEngine.Interfaces.Entities") # add Mo.net projection DLL reference to the CLR clr_ref = clr.AddReference("Linked_Monet") monet_type = clr_ref.GetType('Monet') # invoke Mo.net interface methods initCmdLine_method = monet_type.GetMethod('InitCommandLine') initCmdLine_method.Invoke(None, [None]) init_method = monet_type.GetMethod('Initialise') init_method.Invoke(None, [True]) initProj_method = monet_type.GetMethod('InitialiseProjections') initProj_method.Invoke(None, []) # obtain a list of the projections inside the DLL projections = monet_type.GetProperty('Projections') # create a reference to the Linked projection task linkedproj = projections.GetValue(None).Linked # uncomment the next line to override the SterlInt parameter associated with the # Linked projection # linkedproj.SterlInt = 0.1 # run the projection linkedproj.Run() # show the sterling result at time=0 print(f'SterlInt = {linkedproj.SterlInt}') print(f'SterlRes(0) = {linkedproj.SterlRes(0)}')
When the script is run for the first time, the following results should be shown in the console.
SterlInt = 0.03 SterlRes(0) = -3310.1472717414354
Removing the comment from line 41 in the script will override the SterlInt parameter. Re-running the script should then show the following results:
SterlInt = 0.1 SterlRes(0) = -1673.3090454761546
Other projection parameters can be overridden in a similar way.
What’s Going On?
The key elements of the Python script are as follows.
Line | Commentary |
---|---|
6 | This defines the location of the Mo.net DLL. The path should be changed to reflect the location of DLL on the user’s environment. |
11-12 | These are two of the Mo.net kernel assemblies that the common language runtime needs to know about |
16 | This creates a reference to the Mo.net DLL itself. This is the name of the DLL found in the path defined at line 6 |
17 | This defines the monet_type, which is used to invoke specific Mo.net methods |
21-22 | This invokes the Mo.net command line interface |
24-25 | This invokes the Mo.net initialise method |
27-28 | This invokes the Mo.net initialise projections method |
32 | This gets a list of the projections inside the Mo.net DLL |
36 | Creates a reference to the Linked projection task |
41 | Uncomment this line to override the SterlInt parameter associated with the Linked projection task |
45 | This runs the projection |
49-50 | This prints the overridden SterlInt parameter (to confirm it has been correctly passed to the projection), and the calculated value of the sterling reserve (SterlRes) at time 0 to the console |
Conclusion
I hope this series of articles has helped to demonstrate how Mo.net and Python can complement each other and allow users to develop comprehensive modelling solutions which leverage the features from both platforms without the need to refactor anything.
Related Posts
Contact Us
Need a Mo.net licence? Get in touch with us today to discuss your modelling requirements.
Comments are closed.