Calling a Mo.net Projection from a Python Script

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:

  1. Launch Mo.net Model Development Studio
  2. Click New in the backstage menu
  3. Click Installed and then select the Sample Projects tab
  4. Now select Linked Funds Dynamic Basis from the list of available projects
  5. 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
  1. Click Create to create the project
  2. When the project opens navigate to the Tasks view
  3. Click on the Linked projection task
  4. Now select Create DLL / EXE from the Compile menu
  5. Click on the expand button to show the advanced options
  6. Select Projection DLL and enter a suitable location for the DLL to be created – e.g. C:\Mo.net Projects\LinkedFundsForPython\Linked_DLL
  7. Ensure that Merge Table Data is ticked
  8. Ensure that Target 64-bit is ticked (assuming the 64-bit version of Python is installed)
  1. 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.

LineCommentary
6This 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-12These are two of the Mo.net kernel assemblies that the common language runtime needs to know about
16This creates a reference to the Mo.net DLL itself.  This is the name of the DLL found in the path defined at line 6
17This defines the monet_type, which is used to invoke specific Mo.net methods
21-22This invokes the Mo.net command line interface
24-25This invokes the Mo.net initialise method
27-28This invokes the Mo.net initialise projections method
32This gets a list of the projections inside the Mo.net DLL
36Creates a reference to the Linked projection task
41Uncomment this line to override the SterlInt parameter associated with the Linked projection task
45This runs the projection
49-50This 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.

Contact Us

Need a Mo.net licence? Get in touch with us today to discuss your modelling requirements.

Was this article helpful?
YesNo

Comments are closed.