macro

MacroBlock

ORSServiceClass.macro.macroblock.orsMacroBlock(macroUUID, executeMacroBlock=False, inputs=None, outputs=None)

Gets the MacroBlock associated to a macro UUID, or gets the results of the macro execution.

# Getting the macro block from the macro UUID
macroUUID = 'e48f181365b411e8bd53448a5b5d70c0'
aMacroBlock = orsMacroBlock(macroUUID)
Parameters:
  • macroUUID (str) – a macro UUID (ex: ‘e48f181365b411e8bd53448a5b5d70c0’)
  • executeMacroBlock (bool) – if True, the macro will be executed with the provided inputs and outputs. If False (default), the MacroBlock instance is returned.
  • inputs (dict where the keys are the declared variables names and the values are the associated values) – unresolved variables to define before executing the macro
  • outputs (set of str) – name of variables to return from the macro execution
Return:

if executeMacroBlock is False, instance of MacroBlock; otherwise, outputs of the macro execution (being a dictionary where the keys are the names of the variables from the argument “output” and the values are the values of the macro execution)

Rtype:

MacroBlock or dict

class ORSServiceClass.macro.macroblock.MacroBlock

This class is used for the manipulation of macro elements (blocks).

See also

ORSServiceClass.macro.macroblock.orsMacroBlock() to get a macro block instance from the macro UUID.

Executing a macro

Executing a macro can be done by calling on the MacroBlock instance:

aMacroBlock()

Getting the input variables of a macro

The unresolved variables of a macro can be obtained as:

macroCanBeExecuted, orderedDictOfInputVariables = aMacroBlock.getDeclaredVariablesInput()
namesOfUnresolvedVariables = list(orderedDictOfInputVariables.keys())
classmethod createFromMacroBlockExecution(aMacroBlockExecution)

Creates a new MacroBlock using the code string from the provided execution macro block

Parameters:aMacroBlockExecution (MacroBlockExecution) – a macro block execution
Returns:output (MacroBlock) – new instance of MacroBlock
extractCode()

Gets the whole code from the current MacroBlock

It is a concatenation of the code from the current MacroBlock sub blocks. All the docstrings of the individual sub blocks are removed.

Return:whole macro code to be executed
Rtype:str
getDeclaredVariablesInput()

Gets the input variables with their corresponding descriptor.

Only the unresolved variables are returned.

Return:True if the macro can be executed; False otherwise.
Rtype:bool
Return:OrderedDict where each key is a declared variable name and the corresponding value is the descriptor object.
Rtype:collections.OrderedDict
getDeclaredVariablesOutput()

Gets the output variables with their corresponding descriptor.

Return:True if the macro can be executed; False otherwise.
Rtype:bool
Return:OrderedDict where each key is a declared variable name and the corresponding value is the descriptor object.
Rtype:collections.OrderedDict
getSubBlocks()

Gets the MacroBlocks composing the current MacroBlock

Return:MacroBlocks composing the current MacroBlock
Rtype:list of MacroBlock
setFromUUID(macroUUID)

Sets the macro code (string) from a macro UUID.

Parameters:macroUUID (str) – the macro UUID (ex: ‘e48f181365b411e8bd53448a5b5d70c0’)
Return:error message (empty if no error)
Rtype:str

MacroPlayer

class ORSServiceClass.macro.macroplayer.MacroPlayer

This class is used for playing (executing) existing macros.

Macro file structure

A macro file is a Python (.py) file in which identified sections get executed. As such, this file can be manually modified.

Here is an example of a macro file:

"""
This is an example of macro.

It creates a ROI from a structuredGrid (dataset, ROI or MultiROI), sets his title and color
and fills the ROI by inverting the initialized (empty) ROI.

.. versionchanged:: 1.0.3
    - Inverting the ROI to fill it;
    - Changing the color of the ROI.

:author: ORS Team
:contact: http://theobjects.com
:email: info@theobjects.com
:organization: Object Research Systems (ORS), Inc.
:address: 760 St-Paul West, suite 101, Montréal, Québec, Canada, H3C 1M4
:copyright: Object Research Systems (ORS), Inc. All rights reserved 2018.
:date: Aug 03 2017 15:58
:dragonflyVersion: 3.1.0.286 (D)
:UUID: ff5c65e7788511e7a301448a5b5d70c0
"""

__version__ = '1.0.3'

"""
This is an example of macro.

It creates a ROI from a structuredGrid, sets his title and color.

:author: ORS Team
:contact: http://theobjects.com
:email: info@theobjects.com
:organization: Object Research Systems (ORS), Inc.
:address: 760 St-Paul West, suite 101, Montréal, Québec, Canada, H3C 1M4
:copyright: Object Research Systems (ORS), Inc. All rights reserved 2018.
:date: Aug 03 2017 15:58
:dragonflyVersion: 3.1.0.286 (D)
:UUID: ff5c65e7788511e7a301448a5b5d70c0
"""

# Action log Thu Aug 3 16:01:16 2017

# Macro name: macro example

# ********** BEGIN MACRO ********** #
"""
Creates an empty ROI from a structured grid.
This is a description that can be put on
multiple lines.

:name: my first step
:execution: execute

:param structuredGrid: reference shape of the new ROI.
    The description of the parameter can be put
    also on multiple lines, all indented with 4 spaces.
:type structuredGrid: ORSModel.ors.StructuredGrid
:param title: title of the new ROI
:type title: str
:param ROIColor: color of the new ROI
:type ROIColor: ORSModel.ors.Color

:return output: created ROI
:rtype output: ORSModel.ors.ROI
"""

# ----- BEGIN INPUT ARGUMENT DEFINITION ----- #
title = 'my ROI'

ROIColor = orsColor(0.9019607843137255, 0.8431372549019608, 0.0, 1.0)

# ----- END INPUT ARGUMENT DEFINITION ----- #
# Interface method
output = OrsVolumeROITools.createEmptyROIFromStructuredGrid(structuredGrid=structuredGrid,
                                                            title=title,
                                                            ROIColor=ROIColor)

# ----- BEGIN RETURNED VALUES DEFINITION ----- #
# output = orsObj('870036688405782212CxvVolume_ROI')

# ----- END RETURNED VALUES DEFINITION ----- #
# ********** END MACRO ********** #

# ********** BEGIN MACRO ********** #
"""
Publishes an object.

:name: publish
:execution: execute

:param output: an object
:type output: ORSModel.ors.Managed
"""

# Interface method
ManagedHelper.publish(anObject=output)

# ********** END MACRO ********** #

# ********** BEGIN MACRO ********** #
"""
Reverse the inclusion state of each voxel.

:name: reverse
:execution: execute

:param listROIToModify: ROI to modify
:type listROIToModify: ORSModel.ors.ROI
:count listROIToModify: [1, None]
:param currentTime: Time step of the ROI
:type currentTime: int
"""

# ----- BEGIN INPUT ARGUMENT DEFINITION ----- #
listROIToModify = [output]

currentTime = 0

# ----- END INPUT ARGUMENT DEFINITION ----- #
# Interface method
OrsVolumeROITools.reverse(listROIToModify=listROIToModify,
                          currentTime=currentTime)

# ********** END MACRO ********** #

These are the essential elements of a macro file:

Element Purpose
Docstring header

Documentation

  • describes what the macro does;
  • changes from the previous version. Use the syntax of the example (where versionchanged refers to the Sphinx directive), with the actual version number of the macro;
  • bibliography information.
Version number Current version of the macro
Docstring headers of the previous macros versions Keeping the information of the previous authors, their documentation and changes from previous versions
Date of recording/ file saving Keeping track of the date/time at which the file was created by recording or by saving changes
Macro name Short name of the macro. This can be changed at will.
Sequence of macro steps Code to be executed and associated documentation

These are the essential elements of each macro step:

Element Purpose
Identifier of the beginning of the macro step Marking the beginning of a macro step. It is identified by a comment (#) followed by BEGIN MACRO. All other characters of that line are ignored.
Docstring
  • Documentation of the step;
  • :name: short description of the macro step. May contain spaces;
  • :execution: default execution status of the step:
    • execute: the step is executed without interruption;
    • pause: the execution of the macro is interrupted (paused) before executing this step and resumes upon the user request;
    • skip: the step is not executed and the macro continues.
  • fields to declare each input variable that could be set dynamically by the user if they are unresolved at execution time. The syntax should respect that of interface methods (see Interface methods);
  • fields to declare each output variable that may be used in another macro step;
Code to execute

Actual code that will be executed.

Before the macro gets executed, common imports are made, including those of OrsHelpers, all plugins and generic menu items.

In this section, comments may be added and/or removed at will.

In the example, comments have no other purpose than separating visually the sections in the step and keeping some information about the variables.

Note

Only the code surrounded by the identifiers of a macro step may be executed by a macro.

Variables can be set and the values may be modified. Assignment can be made by a literal value (ex: anInt = 3), by referring to a previous variable (preferably declared in a previous step) (ex: anInt = anotherInt), or by a general expression to be evaluated (ex: anInt = 3 + 5*2 + 4*anotherInt).

Note

Values that should be passed to an interface method should first be assigned in a variable. For example, aModule.aFunction(3) will not work. Instead, do:

aTempValue = 3
aModule.aFunction(aTempValue)
Identifier of the ending of the macro step Marking the end of a macro step. It is identified by a comment (#) followed by END MACRO. All other characters of that line are ignored.

Batching

Example of batching using a macro in which the variable aROI is unresolved:

# Importing the MacroPlayer class
from ORSServiceClass.macro.macroplayer import MacroPlayer

# Instantiating a MacroPlayer
aMacroPlayer = MacroPlayer()

# Setting a macro to execute ('C:/Users/RD/AppData/Local/' corresponds to the Windows %LOCALAPPDATA%)
aMacroPlayer.setMacroFromPath('C:/Users/RD/AppData/Local/ORS/Dragonfly31/pythonUserExtensions/Macros/testpaint_10df629377b511e7a5a6448a5b5d70c0.py')

# Defining values to be used in batching
aListOfROIs = [orsObj('0051677970698237624CxvVolume_ROI'), orsObj('5620777970215437624CxvVolume_ROI')]

# Launching the batch
for myROI in aListOfROIs:
    # Defining unresolved values of the macro
    dictValues = {'aROI': myROI}
    aMacroPlayer.defineVariables(dictValues)

    # Executing the macro
    aMacroPlayer.executeMacro()

    # Making sure the macro is ready to start from the beginning at the next iteration
    aMacroPlayer.stopMacro()

MacroNodeVisitor

class ORSServiceClass.macro.macronodevisitor.MacroNodeVisitor(dictLocals, dictDeclaredVariableDescriptors, automaticSelectionSingleElement=False)

Class used to analyze the code in a macro before its actual execution for the purpose of:

  • identifying errors;
  • identifying the variables that should be resolved.

This analysis uses the code compiled in a Python Abstract Syntax Tree (AST).

The code in a macro, supported by this analysis, should respect these limitations:

  • any call to a function decorated by interfaceMethod or ORSModelInterfaceMethod cannot be explicitly written as an argument of another call to a function decorated by interfaceMethod or ORSModelInterfaceMethod. For example, this is not permitted:

    aPlugin1.aFct(5, 6, aPlugin2.anotherFct())
    

    It would have to be written this way:

    tempOutput = aPlugin2.anotherFct()
    aPlugin1.aFct(5, 6, tempOutput)
    
  • when a declared variable acts as the instance on which an instance method is called, that instance cannot be None. There will be no attempt to try to get a valid instance, since that variable was already resolved.