BMIModel

Properties

Property Characteristic Dimension Description
InputPixelType compulsory,
user-defined, default: unknown
0 The data type of the input image pixels.
OutputPixelType compulsory,
user-defined, default: unknown
0 The data type of the output image pixels.
NumDimensions compulsory,
user-defined, default: 2
0 The number of image dimensions (axes) of input and output images.
YamlConfigFileName compulsory,
user-defined
0 A configuration file detailing some important model information required for instantiation and execution of the model (s. YamlConfigFile below).

Supported Image & Pipeline Features

Feature Details Comments
Image dimensions 1D, 2D, 3D  
Multi-band images no  
Pipeline role process, sink s. YamlConfigFile
Sequential processing yes  
Parallel processing no Python implementations
Number of inputs 1..multiple as returned by <BmiSubclass>.get_input_item_count()
Number of outputs 1..multiple as returned by <BmiSubclass>.get_output_item_count()
Input image names defined by inputs’ UserID input names shall match the names returned by <BmiSubclass>.get_input_var_names()
Output image names defined by BMI model as returned by <BmiSubclass>.get_output_var_names()

Info: For BMI models written in Python, we recommend the use of Numba to parallelise pixel-based processing ‘inside’ the BMI model.

Overview

The BMIModel component enables the integration of Python model components that implement the Basic Model Interface (BMI) into a LUMASS processing pipeline. However, to exploit the sequential processing capabilities of a processing pipeline, LUMASS needs to be in charge of reading and writing the respective input and output images, including memory management. Therefore, the BMI model needs to fulfil a few additional requirements. We provide a sample implementation as part of the LUMASS source tree that can be subclassed and adapted to the specific model requirements. Key aspects of a compatible BMI model implementation are outlined below:

  • The model must not allocate any image memory as part of the model, i.e. it must not create any input or ouput arrays itself, except for intermediary data that is only stored temporarily
  • The model should not read datasets byitself, but use the <BmiSubclass>.set_value() method to set pre-allocated named (numpy) arrays

Important: If different InputPixelType and OutputPixelType are specified, it is the BMI model’s responsibility to appropriately cast between those types before populating the output image(s).

YamlConfigFile

LumassBMIConfig:

    # bmi interface type <bmi-cxx | bmi-python>
    type: "bmi-python"

    # path to bmi library
    #       python: path to *.py module file
    #          e.g.: /home/python
    #                C:/src/python
    #
    #       note: 
    #       - multiple path entries may be concatenated with the
    #         operating system's path separator, for example ';'
    #         on windows and ':' on linux
    #       - for type 'bmi-python' the specified path(s) will be
    #         apped to python's search path for python modules
    #         (=PYTHONPATH)
    #
    # path: "C:/src/python/watyield/bmi;C:/src/python/bmi-python;C:/src/python/watyield"
    path: "/home/herziga/garage/python/watyield/bmi:/home/herziga/garage/python/bmi-python:/home/herziga/garage/python/watyield"
    
    # name of library contaning the bmi::Bmi subclass (s. class_name)
    # note: its path needs to be set with path (s. above)
    # 
    #   python: C:/src/python/watyieldbmi.py 
    #   C++: windows: C:/src/cpp/awesome_bmi_lib.dll 
    #           linux:   /home/alex/cpp/awesome_bmi_lib.so
    library_name: "watyieldbmi.py"
    
    # name of class implementing the BMI interface
    #    python: Bmi subclass
    #    C++: bmi::Bmi subclass            
    class_name: "WatYieldBMI"
    
    # whether or not the model component produces and output that can
    # be fetched by a downstream component, i.e. the component doesn't 
    # write its output 
    # if issink == true, the component becomes executable and will be 
    # called by the lumas model controller depending on the time level
    # of its host BMIModel component
    issink: false 
    
    # whether the component's implemented algorithm supports streaming, 
    # i.e. the sequential processing of parts of the input array; 
    streamable: true

    # whether or not the component is threadable, i.e. can be called
    # safely from multiple threads of the processing pipeline; 
    # note: for python-bmi we assume that any threading is done 
    # within the component, e.g. using numba, since the python interpreter cannot be called safely from multiple threads 
    threadable: false