BrainVoyager Python Developer Guide 0.9
BrainVoyager Data Access Module
In order to provide fast access to internal BrainVoyager data arrays, a special Python C extension module has been developed that allows to access memory blocks of BrainVoyager documents directly as numpy arrays. This "bva" (BrainVoyager Array access) module can be imported like any other Python module:
import bva import numpy as np
# A VMR document is assumed to be the active document in BV's workspace doc_vmr = brainvoyager.active_document
arr = bva.vmrarray(doc_vmr) arr *= -1
The code above demonstrates how the bv module can be used to access the data of a VMR directly as a numpy array (named "arr" above). This requires to load a VMR document or to access a VMR document that is currently the active (selected) document. To assess the VMR data as a numpy array, the "vmrarray" function of the bv modules is called returning the internal VMR data memory block as a numpy array. Note that this does not require to copy data since the numpy array is constructed such that it wraps the memory block directly. This strategy is used whenever possible since it provides maximal performance. This also means that changing the content of the returned "arr" array will change the content of the VMR directly without the need to "write" back. The line "arr *= -1" is executed directly on the VMR data; furthermore, no explicit loops are required using ndarray's vectorized math.
In case that a memory wrapping approach is not possible, the returned numpy array is constructed by allocating memory and any changes made need to be written back to BrainVoyager's internal data. This is also the case when changing the data type of an array:
import bva import numpy as np
doc_vmr = bv.adoc arr = bva.vmrarray(doc_vmr)
arrf = arr.astype(np.float32)
arrf2 = 225. - 1.0*arrf
arr_ui8 = arrf2.astype(np.uint8)
ret = bv.set_vmrarray(doc_vmr, arr_ui8)
In this version, the byte array returned from the "vmrarray" function is converted into a float array "arrf". The intensity values are then inverted followed by converting the new values into a byte array that is compatible with BrainVoyager's internal VMR data array. In order to set this new data array as the data for the VMR the "set_vmrarray()" function of the bv module is called with the VMR document ("doc") as the first parameter and the new byte array ("arr_ui8") as the second parameter. In order to visualize the changed VMR data in BrainVoyager immediately, the "UpdateWindow()" scripting command is called on the VMR document.
The screenshot above shows a VMR document before and after running the Python code. While this is a very simple example - converting the intensities of a VMR - the important point is that executing this "plugin" results in an almost immediate display of the result indicating the high efficiency of the underlying operations, which is orders of magnitude faster than using standard scripts using loops to access intensity values of individual voxels.
In order to help getting started with plugin development using the bv module and numpy arrays, simple examples are placed in the "Documents/PythonPlugins" folder after installation of BrainVoyager 20 (or later). There are also examples demonstrating how to use the "bv" module to access volume and surface maps as well as FMR arrays and mesh coordinate arrays. The example Python files can be accessed by clicking the Plugins tab in the Files pane on the left side of the Python IDE window and they may serve as starting points for developing own plugins.
BV Module Commands
The currently supported bv module commands are described below:
- uint8-array vmrarray(vmr-document)
- "Get the volume of VMR document as a contigous 1D numpy array. Note: This provides direct access to the original byte (uint8) memory block (no copy).
- set_vmrarray(vmr-document, uint8-array)
- Sets the values of the volume of VMR document from provided uint8 numpy array.
- float32-array fmrarray_t(fmr-document, t)
- Get volume for specified time point t of FMR document as a contigous 1D numpy array. Note: This provides direct access to the original (float32) memory block (no copy).
- set_fmrarray_t(fmr_document, t, float32-array)
- Sets the values of the volume for the specified time point t of FMR document from provided float32 numpy array.
- float32-array vmparray_i(vmp, i)
- Get volume map for specified index i of hosting VMR document as a contigous 1D numpy array. Note: This provides direct access to the original (float32) memory block (no copy).
- set_vmparray_i(vmp, i, float32-array)
- Sets the values of volume map specified with index i of hosting VMR document from provided float32 numpy array.
- (coords-x-float32-array, coords-y-float32-array, coords-z-float32-array) mesharrays(mesh-document)
- Get three arrays of the x, y, z coordinates of the vertices of a mesh (SRF) document as contigous 1D numpy arrays. Note: This function provides direct access to the original (float32) memory blocks (no copy).
- set_mesharrays(coords-x-float32-array, coords-y-float32-array, coords-z-float32-array)
- Sets the values of the x, y, z coordinates of the vertices of a mesh (SRF) document from 3 provided float32 numpy arrays.
- float32-array smparray_i(smp, i)
- Get surface map for specified index i of hosting VMR-SRF document as a contigous 1D numpy array. Note: This function provides direct access to the original (float32) memory block (no copy).
- set_smparray_i(smp, i, float32-array)
- Sets the values of surface map specified with index i of hosting VMR-SRF document from provided float32 numpy array.
Copyright © 2020 Rainer Goebel. All rights reserved.