CARETask Python : how to get a float from a python script?


#1

Hello,

I have a model written in python which basically looks like this :

import sys
param1 = float(sys.argv[1])
param2 = float(sys.argv[2])
pyResult = param1 + param2

and I simply want to store pyResult in an Open Mole variable as a float so I can run a Replication task on the CARETask, get the mean and variance of them, and so on.

The OpenMole script looks like :

val param1 = Val[Double]
val param2 = Val[Double]
val OMresult = Val[Double]

val makeAsum =
CARETask(“sumTask.tgz.bin”, "python sumTask.py ${param1} ${param2}) set (
< Some Missing Code>
param1 := 5.0,
param2 := 1.0
)

makeAsum hook ToStringHook()

How can I put pyResult from the python script in the Open Mole variable OMresult ?
Can I cast the stdout of the python script in a float for instance or is it mandatory to write the output of the model in a file as shown in the Native Application Tutorial from the Market Place ?


(Mathieu Leclaire) #2

Hi Leonard,

to do so, first create a String variable (since what you get from stdout is a string):

val OMResult = Val[String]

Then set the special variable stdOut with this variable:

stdOut := OMResult

Your stdout is now available in this variable. The Random Forest project in the market place uses this (in the Learn.oms file).

Would you like to participate to the documentation and add this tips in the Python section ?

Mathieu


(Jonathan Passerat Palmbach) #3

Hi Leonard,

you’ve got two ways to make the python script within your CARETask communicate with OpenMOLE variables:

  • write pyResult to the standard output at the end of your python script (print(pyResult)) and capture it to a Val[String] variable in OpenMOLE via the stdOut option of the CARETask (see the documentation for more details)
  • another option is to write this same pyResult to a file and then process it in OpenMOLE

In any case, you’ll have some boilerplate to write if you want to convert this Val[String] to an actual Val[Double].
You can do this with a simple ScalaTask, chained after your CARETask:

val s = ScalaTask("val pyResultDouble = pyResult.toDouble") set (
  inputs += pyResult,
  outputs += pyResultDouble
)

#4

Hello,
thanks to both of you for your help, I’m planning to use this scala task :). For now, I can’t get the standard output to work in the CARETask. Here is what I have so far, I can’t figure why it’s not working, I don’t get error messages from OpenMole v7.1

Python Script, sumTask.py :

import sys
param1 = float(sys.argv[1])
param2 = float(sys.argv[2])

sumTaskResult = param1 + param2

print("%f" % sumTaskResult )             #I'm currently using this, it's from the Random Forest exemple
# sys.stdout.write(str(sumTaskResult)) #This is the an other way for making a std output with Python

Using the care command :

care -o sumTask.tgz.bin python sumTask.py 5 8

I get the following :

care info: concealed path: $HOME /home/leonard
care info: concealed path: /tmp
care info: revealed path: $PWD /home/leonard/Documents/LIP6/Codes LIP6/openMole
care info: revealed path: /home/leonard/anaconda3/bin/python3.6
care info: ----------------------------------------------------------------------
13.000000
care info: ----------------------------------------------------------------------
care info: Hints:
care info: - search for “conceal” in care -h if the execution didn’t go as expected.
care info: - run ./sumTask.tgz.bin or care -x sumTask.tgz.bin to extract the output archive correctly.

And the OpenMole script, model.oms :

val param1 = Val[Double]
val param2 = Val[Double]

val strResult = Val[String]

val makeAsum =
  CARETask("sumTask.tgz.bin", "python sumTask.py ${param1} ${param2}") set (
    inputs += (param1, param2),
    outputs += (param1, param2, strResult),
    
    stdOut := strResult,
    
    param1 := 5.0,
    param2 := 8.0
)

 makeAsum hook ToStringHook()

And I have model.oms, sumTask.py and sumTask.tgz.bin in the same folder in openMole.

About the documentation, i will be happy to provide you some MWE with python/cython Tasks.


#5

Hi Leonard,

I just tried you workflow and it works on the 7.1 for me. You should just fix the path of your care archive, as follow:

val param1 = Val[Double]
val param2 = Val[Double]

val strResult = Val[String]

val makeAsum =
  CARETask(workDirectory / "sum.tgz.bin", "python sum.py ${param1} ${param2}") set (
    inputs += (param1, param2),
    outputs += (param1, param2, strResult),
    
    stdOut := strResult,
    
    param1 := 5.0,
    param2 := 8.0
)

 makeAsum hook ToStringHook()
 

(notice the workDirectory /)

You will then find the values for you 3 variables in the output display in the execution panel.

Romain


#6

Thank you ! It’s working now,
final python code (sumTask.py) :

import sys
param1 = float(sys.argv[1])
param2 = float(sys.argv[2])

sumTaskResult = param1 + param2

sys.stdout.write(str(sumTaskResult))

care command :
care -o sumTask.tgz.bin python sumTask.py 5 8

Open Mole script (model.oms) :

val param1 = Val[Double]
val param2 = Val[Double]

val strResult = Val[String]
val doubleResult = Val[Double]

val makeAsum =
   CARETask( workDirectory / "sumTask.tgz.bin", "python sumTask.py ${param1} ${param2}") set (
    inputs += (param1, param2),
    outputs += (param1, param2, strResult),
     
    stdOut := strResult,
     
    param1 := 5.0,
    param2 := 8.0
 )

val toDouble = ScalaTask("val doubleResult = strResult.toDouble") set (
   inputs += strResult,
   outputs += doubleResult
)

makeAsum -- toDouble hook ToStringHook()

The three files; sumTask.py, model.oms, sumTask.tgz.bin, must be in the same directory.

I’m going to adapt more scripts of the Model Exploration Tutorial in the context of python CARETask, can I post this work somewhere here ?


#7

Great!

You may contribute in 3 ways: