Custom Functions

Custom Functions

The F.A.S.T. Cloud SDK provides features to allow the client to call custom functions that will be run on the server. You will write these functions in C++ and they will be dynamically linked (.dll's in Windows, and runtime loaded .so's in Linux) into the address space of the server. You will have access to all the relevant data structures in memory so you can perform almost any processing you wish. We recomend that processing which requires high compute resources and/or acces to the original DICOM images be done through custom functions. You can also perform I/O operations for any data (although if you are loading images, we do recomend using the Custom Data Loading mechanism)

Client Side

Invoke the server-side custom functions with a call to Fovia.ServerContext.callCustomFunction passing in an array of Volumes, an array of Octrees, an array of Render Engines, an array of Segmentation objects and a JSON object of parameters that you build up as required. The Arrays can be either null (If that data structure is not needed by your custom functions on the other side) or an array of one or more objects (for most cases only one is needed, but we wanted to allow for flexibility in case you wanted to do something which combined multiple volumes) The JSON object you build as required since you will decode it on the other side.

The call returns a promise that is fulfilled when the custom function completes on the server side. Another JSON object is returned which you built on the server side so you can decode it here.

Server Side

On the server side there is an example CustomFunctions makefile Visual Studio Solution file in the exmaples directory of the deployment.

You can see in the example FoviaCustomFunctions::callCustomFunction() routine that all the parameters above are passed through from the client to the server and finally to the function. Do not change this function signature or the server can not call it correctly. You can change the internals of this function, although we recommend to leave this function as is and only add new custom functions called from the if-block. Notice that the way that it is currently setup there should be functionID in the JSON you pass in that will allow you to decide which custom function to specifically call. As a rule of thumb, we try to make this match the functionName on the server side. You are free to do this however you like. We also keep to the habit of keeping all the individual custom functions to have the same function signature and pass the parameters all the way through.

There are examples included that show how to access all the parameters, how to segment data, how to changes volumes, etc. When writing C++ code for the server side you will utilize the "In Process" API.

Keep in mind that if you change the segmentation context or the volume data itself, then you will need to rebuild the octree (see example code).

Open up the Visual Studio solution file to review the complete project.

1) The "fovia" directory contains abstract, base classes for 2D/3D CustomDataLoader and CustomFunctions and should NOT be modified.  These classes will convert between JSON and C++ data structures and then invoke the "dispatch" methods defined in the FoviaCustomDataLoader and FoviaCustomFunctions classes found in the top level directory.
2) The top-level directory contain the concrete classes for 2D/3D FoviaCustomDataLoader and FoviaCustomFunctions.   You should change the "dispatch" methods to invoke your callback function.
3) The "sample" directory has various example 2D and 3D custom data loaders and custom server functions for reference.  These can be used as a starting point.
4) Each callback function registered on the server side is uniquely identified by string function identifier, which is used by "dispatch" to select which native callback to invoke.
5) In calls to custom functions, you can pass various parameters through JavaScript to native code, including image data, render engines, segmentation data, and input/ out put JSON data.
6) While the abstract base class includes a global try...catch surrounds all native code, it is  expected that all the error handling and detect crash scenario will be handled in your native code, to ensure the server does not crash.  Errors are propagated through the return string value to JavaScript.
7) The output, as described above, is named FoviaCustomFunctions.dll and is placed in nodeaddon which is available at run time
8) In order to call the registered callback/s, from the JavaScript side, use the Fovia.ServerContext.callCustomFunction with the id specified in the C++ function above and the parameter to be passed onto the function

2D Custom Functions.

2D Custom Functions works the same as 3D, except rather than having an array of volumes, octrees, renderEngines and segmentationContexts, you pass in an array of SeriesDataContexts and 2DsegmentationContexts.

Concurrent Processing.

Crashes or data corruption could happen if custom functions are running and changing data while the server is trying to render. For this reason you want to avoid the possiblity of calling custom functions to change data while rendering or segmenting data on server side. You can do this inside your app, or you can use the two functions below.

pauseServerOperations() with the same parameters as the callCustomFunctions(). It will pause and return a promise that is fulfilled only when all operations on those data structures are completed and flag is set indicating that no more can start.

resumeServerOperations() either again with all the objects that would like to resume or resumeAllServerOperations() which will enable all operations on all objects.