Using IPL in a task type

IPL can be used in a task type via the Python module iplutil.

For example the Scanco.IPL.Invert task type uses the IPL command /invert_ow for inverting an image:

The main script.py contains the boilerplate XamFlow input and output handling, and uses iplutil.run_ipl() to execute an IPL script:

import xfworkerutil
import iplutil


worker = xfworkerutil.XFWorkerJob()

inputs = worker.job['inputs']

# Download input files
seg_path = worker.get_ipl_image_path(inputs['segments'])
gobj_path = worker.download_input_file(inputs['gobj']) if inputs['gobj'] is not None else None

seg_out_path = worker.create_related_path(seg_path, '_inv.aim')

# Run IPL
parameters = {
    "ipl_segaim": iplutil.checked_aim_image(seg_path),
    "ipl_gobj": iplutil.quoted_path(gobj_path) if gobj_path is not None else "none", # Special IPL string
    "ipl_segaim_out": iplutil.quoted_path(seg_out_path),
    "ipl_compress": "bin" if inputs['compressed'] else "none",
}

iplutil.run_ipl("IPLV6_INV.IPL", parameters)

# Upload output files
worker.upload_output_file(seg_out_path)

# Save outputs
size = inputs['segments']['size']
outputs = {
    "segments": worker.create_output_image(seg_out_path.name, size),
}
worker.finish(outputs)

The IPLV6_INV.IPL scripts contains the IPL commands:

/read seg "ipl_segaim

/invert_ow
  -in_out                    seg
  -gobj_filename             "ipl_gobj
  -peel_iter                 -1

/write_new  seg  "ipl_segaim_out
  -compress    "ipl_compress

..

Parsing parameter output

IPL evaluation parameters can be parsed using for example iplutil.parse_ipl_parameter_float():

import xfworkerutil
import iplutil
import omni


worker = xfworkerutil.XFWorkerJob()

inputs = worker.job['inputs']
region_number = inputs['region_number']
peel_iter = inputs['peel_iter']
gobj_mask_input = inputs['gobj_mask']
seg_mask_input = inputs['seg_mask']

# Download input files
aim_path = worker.get_ipl_image_path(inputs['image'])

image = worker.get_omni_image(inputs['image'])
if image.type == omni.Image.TYPE_SEGMENTS:
    worker.error("Expected a grayscale image, not a segments image.")

mask_path = None
if gobj_mask_input is not None:
    mask_path = worker.download_input_file(gobj_mask_input)
elif seg_mask_input is not None:
    mask_path = worker.get_ipl_image_path(seg_mask_input)
else:
    mask_path = None

# Run IPL
parameters = {
    "ipl_aim": iplutil.checked_aim_image(aim_path),
    "ipl_region_number": str(region_number),
    "ipl_peel_iter": str(peel_iter),
    "ipl_mask_filename": iplutil.quoted_path(mask_path) if mask_path is not None else 'none',
}
ipl_result = iplutil.run_ipl("IPLV6_EVAL_VOX.IPL" if mask_path is None else "IPLV6_EVAL_VOXGOBJ.IPL" , parameters)

param_mean   = iplutil.parse_ipl_parameter(ipl_result.stdout, "mean_unit")
param_sd     = iplutil.parse_ipl_parameter(ipl_result.stdout, "mean_sd") # IPL label for sd_unit

# Save outputs
outputs = {
    "mean": param_mean.get_float(),
    "sd": param_sd.get_float(),
}
units = {
    "mean": param_mean.unit,
    "sd": param_sd.unit,
}
worker.finish(outputs, units)