Back and Forth#

author: OpenTPS team

This example shows how two different python environements can be used together. A parent script launches a child script which uses a different python environement but shares the same image data. It is possible to pass commands back and forth between the two scripts. The child script in this example simulates the use of an AI model. The first command passed to the child script is to initialise the model (the neural network structure is created and its weights are loaded for example). Then, later in the parent script, another command is passed to the child script to use the AI model, multiple times in a row if necessary.

Important to note: the code executed in the child script must end with a print to send a response, else the script is stuck waiting for the response

Key features: - Use of multiple python envs in communicating scripts. - Share RAM memory space between 2 scripts without the need to save and load data on/from hard drives. - The possibility to initialise first, then later in the parent script, use the AI model.

running time: ~ 5 minutes

Setting up the environment in google collab#

import sys
if "google.colab" in sys.modules:
    from IPython import get_ipython
    get_ipython().system('git clone https://gitlab.com/openmcsquare/opentps.git')
    get_ipython().system('pip install ./opentps')
    get_ipython().system('pip install scipy==1.10.1')
    import opentps

imports

import matplotlib.pyplot as plt
import numpy as np
from multiprocessing import shared_memory
from subprocess import Popen, PIPE
from pathlib import Path
import subprocess

from opentps.core.examples.syntheticData import createSynthetic3DCT

Set the child script environnement path and child scrip file path

childEnvPath = sys.executable  # absolute path to current python
childScriptPath = str(Path.cwd() / "backAndForthChild.py")

Create test image to share between scripts

ct = createSynthetic3DCT()
sliceToShow = 100

Initialize shared memory and copy image array to this space

print(ct.imageArray.shape) ## These must be either passed to the child script as arguments or fixed and known
print(ct.imageArray.dtype) ## These must be either passed to the child script as arguments or fixed and known
print(ct.imageArray.nbytes) ## These must be either passed to the child script as arguments or fixed and known
shm = shared_memory.SharedMemory(create=True, size=ct.imageArray.nbytes, name='sharedArray')
sharedTestArray = np.ndarray(ct.imageArray.shape, dtype=ct.imageArray.dtype, buffer=shm.buf)
sharedTestArray[:] = ct.imageArray[:]
(170, 170, 100)
int64
23120000

# Plot initial image

plt.figure()
plt.title("Before initialize")
plt.imshow(sharedTestArray[:, sliceToShow, :])
plt.show()
Before initialize

Launch child process

process = Popen([childEnvPath, childScriptPath],
                stdin=PIPE, stdout=PIPE, encoding='utf-8', text=True)

Send the command ‘init’ to second process

process.stdin.write('init' + '\n')
process.stdin.flush()

Get the response from the second script

response = process.stdout.readline().strip()
print(f'Back in script 1 after init command: Response: {response}')

print('Do something else in script 1')
Back in script 1 after init command: Response: Initialize AI Model. testVariable = 0
Do something else in script 1

Plot image after init command

ct.imageArray[:] = sharedTestArray[:]
plt.figure()
plt.title("After initialize")
plt.imshow(ct.imageArray[:, sliceToShow, :])
plt.show()

for i in range(3):

    ## Send command 'processImage'
    process.stdin.write('processImage' + '\n')
    process.stdin.flush()

    ## Get the response from the second script
    response = process.stdout.readline().strip()
    print(f'Back in script 1 after command "processImage": Response: {response}')

    ## Plot image after process image command
    ct.imageArray[:] = sharedTestArray[:]
    plt.figure()
    plt.title("After process image")
    plt.imshow(ct.imageArray[:, sliceToShow, :])
    plt.show()
  • After initialize
  • After process image
  • After process image
  • After process image
Back in script 1 after command "processImage": Response: Executing processImage of AI Model. testVariable = 1
Back in script 1 after command "processImage": Response: Executing processImage of AI Model. testVariable = 2
Back in script 1 after command "processImage": Response: Executing processImage of AI Model. testVariable = 3

Close the communication

process.stdin.close()
process.stdout.close()

Close the shared memory

shm.close()
try:
    shm.unlink()
except FileNotFoundError:
    print("Shared memory already unlinked, skipping.")

print('End of script 1')
End of script 1

Total running time of the script: (0 minutes 0.829 seconds)

Gallery generated by Sphinx-Gallery