3.2. pci.nspio module

Applications can generate various kinds of nonspatial I/O (NSPIO), including the following:

  • Debug information: highly detailed information that can be used for debugging errors.

  • Audit/logging information: information that is required by specific applications; for example, parameters of a CATALYST function.

  • Progress information: information that is related to the amount of work that has been done.

  • Report information: information that describes the outcome of an execution; for example, a graph or a table of results.

  • Warnings: information that indicates exceptional situations that are not fatal.

The NSPIO framework classes are used to provide a standard interface for this data in all supported programming environments. These frameworks ensure that information, such as that from a Python application that uses CATALYST Python API, is handled consistently.

The NSPIO framework classes share a common basic interface that provides common methods for dynamically registering and removing custom implementations. With each NSPIO framework, you can register interfaces or call a previously registered interface.

3.2.1. Registering custom NSPIO implementations

You can register a custom NSPIO implementation by using the addInstance() or registerInstance() function for the appropriate NSPIO framework class.

3.2.1.1. Function signature

When writing a function, ensure that it matches the interface of appropriate function for the framework type.

Notice that most of these functions contain default arguments. The function that you write can either have these arguments in the signature, or it may omit them. Additionally, your function can also take variable arguments using *args as an argument. Passing parameters as keyword arguments, with **kwargs, is not supported.

For example, any of the following functions can be registered as a Counter implementation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def update(d):
    '''
    Counter instance to handle only the progress
    '''
    status = '{}% complete'.format(d*100)
    print(status)

def update_with_msg(d, msg):
    '''
    Counter instance to handle progress and message
    '''
    status = '{}% complete'.format(d*100)
    if msg:
        status += ' - ' + msg
    print(status)

def update_with_vargargs(*args):
    '''
    Counter instance to handle only progress and message as varargs
    '''
    status = '{}% complete'.format(args[0]*100)
    if args[1]:
        status += ' - ' + args[1]
    print(status)

3.2.1.2. Registering function objects

In addition to being able to register a function as an NSPIO handler, you can also register a function object. In Python, you can create a function object by writing a class with a __call__() member function. This member function is called by the NSPIO framework.

The following example shows how to write a function object class and then register an instance as a Report handler.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class MyReport:
    '''
    Report instance
    '''
    def __init__(self, title):
        self.title = title

    def __call__(self, msg):
        print('{}:\t{}".format(self.title, msg[:-1]))

 # register MyReport instance
 instance_name = pci.nspio.Report.registerInstance(MyReport('my_title'))

3.2.1.3. NSPIO implementation naming

NSPIO provides you with the ability to register handlers, and then unregister them by name.

The following criteria is used to determine the name of your instance (for registered function myfunc()).

  1. If your instance has a name attribute, the name will be myfunc.name.

  2. If your instance has a __module__ attribute and a __name__ attribute, the name will be myfunc.__module__ + ‘.’ + myfunc.__name__.

  3. If your instance has a __name__ attribute, the name will be myfunc.__name__.

  4. If your instance’s class has a __name__ attribute, the name will be myfunc.__class__.__name__.

  5. In the unlikely event that none of these attributes are defined, then a default name is used for each framework; for example, the default name for Report is ‘pci::nspio::python::Report’.

New in version 2017.

3.2.2. NSPIO framework classes

class pci.nspio.Counter

Bases: Boost.Python.instance

The Counter interface allows you to register and use instances to handle an update in progress.

The default Counter implementation ignores all updates.

static addInstance((object)f) → str :

Add python function f as implementation for Counter, if another python function was registered as an implementation, it will be removed. The function must have the same signature as the update() static method.

static clear() → None :

Remove all registered Counter implementations.

static getInstanceNames() → StringVec :

Get a list of names of registered Counter instances.

static hasInstance((string_)name) → bool :

Return True if a Counter instance called name is currently registered.

static isEmpty() → bool :

Return True if there are no registered Counter instances, False otherwise.

static registerInstance((object)f) → str :

Add python function f as implementation for Counter. The function must have the same signature as the update() static method.

static removeInstance((string_)name) → None :

Remove the Counter instance identified by name.

static update((float)d[, (string_)msg='']) → bool :

Indicate the ratio of progress d, between 0 and 1, that has been completed. Returns True if the process has not been cancelled.

All registered Counter implementations are called when this function is called.

class pci.nspio.Debugger

Bases: Boost.Python.instance

static addInstance((object)f) → str :

Add python function f as implementation for Debugger, if another python function was registered as an implementation, it will be removed. The function must have the same signature as the debug() static method.

static clear() → None :

Remove all registered Debugger implementations.

static debug((string_)message[, (uint_)level=0[, (string_)group='Python'[, (string_)file=''[, (uint_)line=0]]]]) → None :

Set the debug message message, with debug level level belonging to user defined debug group group. Optionally, you can indicate the file and line of the debug information.

All registered Debugger implementations are called when this function is called.

static getDebugLevel() → int :

Get the current debug level.

static getInstanceNames() → StringVec :

Get a list of names of registered Debugger instances.

static hasInstance((string_)name) → bool :

Return True if a Debugger instance called name is currently registered.

static isEmpty() → bool :

Return True if there are no registered Debugger instances, False otherwise.

static registerInstance((object)f) → str :

Add python function f as implementation for Debugger. The function must have the same signature as the debug() static method.

static removeInstance((string_)name) → None :

Remove the Debugger instance identified by name.

class pci.nspio.Logger

Bases: Boost.Python.instance

The Logger interface allows you to register and use instances to handle audit/logging information.

The default Logger implementation ignores all logged events.

static addInstance((object)f) → str :

Add python function f as implementation for Logger, if another python function was registered as an implementation, it will be removed. The function must have the same signature as the logEvent() static method.

static clear() → None :

Remove all registered Logger implementations.

static getInstanceNames() → StringVec :

Get a list of names of registered Logger instances.

static hasInstance((string_)name) → bool :

Return True if a Logger instance called name is currently registered.

static isEmpty() → bool :

Return True if there are no registered Logger instances, False otherwise.

static logEvent((string_)message[, (string_)file=''[, (uint_)line=0]]) → None :

Log the event with message message. Optionally, you can indicate the file and line of the event information.

All registered Logger implementations are called when this function is called.

static registerInstance((object)f) → str :

Add python function f as implementation for Logger. The function must have the same signature as the logEvent() static method.

static removeInstance((string_)name) → None :

Remove the Logger instance identified by name.

class pci.nspio.PCIWarning

Bases: Boost.Python.instance

The PCIWarning interface allows you to register and use instances to handle non-fatal warning messages.

The default PCIWarning implementation prints all report information to stdout.

static addInstance((object)f) → str :

Add python function f as implementation for PCIWarning, if another python function was registered as an implementation, it will be removed. The function must have the same signature as the warn() static method.

static clear() → None :

Remove all registered PCIWarning implementations.

static getInstanceNames() → StringVec :

Get a list of names of registered PCIWarning instances.

static hasInstance((string_)name) → bool :

Return True if a PCIWarning instance called name is currently registered.

static isEmpty() → bool :

Return True if there are no registered PCIWarning instances, False otherwise.

static registerInstance((object)f) → str :

Add python function f as implementation for PCIWarning. The function must have the same signature as the warn() static method.

static removeInstance((string_)name) → None :

Remove the PCIWarning instance identified by name.

static warn((string_)message[, (string_)file='.py'[, (uint_)line=0]]) → None :

Indicate a warning with message message. Optionally, you can indicate the file and line of the event information.

All registered PCIWarning implementations are called when this function is called.

class pci.nspio.Report

Bases: Boost.Python.instance

The Report interface allows you to register and use instances to handle report information.

The default Report implementation prints all report information to stdout.

static addInfo((string_)message) → None :

Add the message message to the Report.

All registered Report implementations are called when this function is called.

static addInstance((object)f) → str :

Add python function f as implementation for Report, if another python function was registered as an implementation, it will be removed. The function must have the same signature as the addInfo() static method.

static clear() → None :

Remove all registered Report implementations.

static getInstanceNames() → StringVec :

Get a list of names of registered Report instances.

static hasInstance((string_)name) → bool :

Return True if a Report instance called name is currently registered.

static isEmpty() → bool :

Return True if there are no registered Report instances, False otherwise.

static registerInstance((object)f) → str :

Add python function f as implementation for Report. The function must have the same signature as the addInfo() static method.

static removeInstance((string_)name) → None :

Remove the Report instance identified by name.

pci.nspio.enableDefaultCounter([(str)mode='ON']) → bool :

Change the status of default Counter implementation. Set mode to ‘ON’ to turn it on or ‘OFF’ to turn it on.

pci.nspio.enableDefaultReport([(str)output='term']) → bool :

Enable the default Report implementation. set output to ‘term’ to send report information to the terminal window(or stdout), or sety it to filename to send report information to that file.

3.2.2.1. Example

The following example shows how to write a function and register it as a report handler, and the result from running fexport() and fimport():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import os
from pci.fimport import fimport
from pci.fexport import fexport
import pci.nspio

def my_report(msg):
    print("Python:\t"+msg[:-1])

def _run():
    pci.nspio.Report.clear()
    instance_name = pci.nspio.Report.registerInstance(my_report)
    pci.nspio.Report.addInfo("Running algorithms\n")
    irvine_pix = os.path.join(pci.getHomePath(), 'demo', 'irvine.pix')
    fexport(irvine_pix,"irvine.tif",[],[1,2,3],[],[],[],[],"TIF","")
    fimport("irvine.tif","irv.pix",[],"OFF","PIXEL")
    pci.nspio.Report.addInfo("\nExiting algorithms\n")

if __name__ == "__main__":
    _run()

In this example, the my_report() function handles report information from the FEXPORT and FIMPORT algorithms.

Note that the signature of my_report() matches with that of Report.addInfo().

The output from this script is as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PCI Pluggable Framework environment successfully loaded.
Python:  Running algorithms
Python:
Python:  Source File: irvine.tif
Python:  Source File Type: TIF/TIFF 6.0
Python:
Creating     512P     512L    3C file: irv.pix
Python:   Creating segment:  1  [ 150: Georeferencing        ]        8 Blocks long
Python:
Exiting algorithms