Data Loading

Basic DICOM Data Loading

The F.A.S.T. Cloud SDK provides three approached to facilitate the loading of DICOM images.  For partners that want to extend their existing DICOM loading mechanism, such as through memory sharing or loading through their PACS system, they should consider using the the custom data loader described below. 

loadDICOMDir

The most straight forward approach to create a 3D volume is:

loadDICOMDir("data/democases/DICOM2").then(function(vdc)

Fovia.ServerContext.loadDICOMDir(directoryPath) loads a single DICOM series from a directory using a relative path from ./foviasever, and specifically ./foviaserver/data/democases directory.  Alternatively, it can also be an absolute path when preceded by a / or drive letter (X:/), such as "C:/temp/DICOM".  The directory MUST contain a single DICOM series with no additional files, otherwise it may return an error.  It will load the dataset and use the default set of presets.  It returns in the callback function parameter a VolumeDataContext structure containing property fields for the loaded dataset.

loadDICOMDir('data/democases/DICOM2').then(function(vdc)

You will also see the following line used in many demos:

loadDICOMDir(Fovia.Util.getDemoStudyDirectory()).then(function(vdc)

Fovia.Util.getDemoStudyDirectory()  returns a demo folder path.  By default, it returns 'data/democases/DICOM2', however, the demo applications can load your image data by using the URL parameter to specify a folder using ?study=yourstudy, assuming the DICOM series is placed inside the ./foviaserver/data/democases/yourstudy or alternatively, an absolute path can be specified by using ?study=d:/yourdir/yourstudy.

scanDICOMDir


A more general appraoch for creating a 3D volume or to load individual DICOM slices of 2D data, the following appraoch is recommended:

scanDICOMDir("data/democases/DICOM2").then(function(scanDirResults)

Fovia.ServerContext.scanDICOMDir(directoryPath) parses the directory and returns a JSON object that describes the complete DICOM structure of all files in the directory.  Look at the web console output for the following:

// print out the study details for each study found
for (var i = 0; i < scanDirResults.getNumStudies(); i++) {
   console.log("ScanDirSeriesResults[" + i + "]");
   console.log(scanDirResults.findStudy(i));
}


Each study will contain one or more ScanDirSeriesResults for each DICOM series, which includes the seriesInstanceUID, the dicomSeries(SeriesDataContext), and a flag if the object containsSubSeries.  If the flag containsSubSeries is true, an array of subSeries(SeriesDataContext) objects is available that organizes the DICOM series into chunks based the internal splitting logic, which may be useful for display or creating 3D volumes.  The dicomSeries and optional subSeries are a SeriesDataContext, which include a set of series and image level DICOM tag values, along with a flag is3DableSeries.  Any SeriesDataContext that has a is3DableSeries flag of true can be used to build a 3D volume Fovia.ServerContext.loadVolumeFromSeries(sdc).  The following code will create a volume for the first series of the first study:, of course, your code should verify that it is an is3DableSeries.

var seriesList = scanDirResults.findStudy(0);
var sdc = seriesList[0].dicomSeries;
loadVolumeFromSeries(sdc).then(function (volumeDataContext)



The datasets referenced in the example code, including the lung, cardiac, kidneys, fusion, and HEART_CT example workflows are available for download from: http://www.fovia.com/bdtransfer/builds/websdk_democases.zip and should be placed inside /fovia/data/democases directory.

Custom Data Loading

A more general loading mechanism utilizes a native C++ library which is invoked for loading of slices of data.  In this way, it can directly access data that may be on a separate system, such as PACS or VNA. The following example app is provided:


Custom Data Loading

The localhost:8088/apps/customload/customload.html app shows how to invoke a simple raw dataloader to load data into the Cloud SDK.  Documented source code is found inside ./foviaserver/public/apps/customload/customload.js. In order for the app to run, the supplied raw.zip should be uncompressed into the ./foviaserver/data/democases directory.

In JavaScript, custom data is loaded in the same manner as DICOM data.  Specifically:

        var jsonToSend = {
            "functionID": "customLoadFuncRaw512Cubed16bitUnsigned",
            "parameters": "data/democases/raw//BinaryCube512x512x512x2/Cube"
        }
        Fovia.ServerContext.loadCustomData(jsonToSend).then(function (data) {
            g_volumeDataInfo1 = data.volumeDataContext;

Fovia.ServerContext.loadCustomData(jsonToSend) takes a json object which includes parameters that are passed into the native level.  json objects can be constructured in either JavaScript or native code and passed back and forth.  In this example, a numeric functionID and string parameter are passed into a native level DLL that load the volume data.  The data.volumeDataContext structure containing property fields for the loaded dataset. is returned. An optional json object is returned in  data.jsonReturnData, and in this example is a duplicate copy of the volumeDataContext, but anything can be returned.  More complex json objects can be passed back and forth, as is shown in the example.  

A custom DLL (FoviaCustomFunctions.dll)  is included in the distribution and can be found inside ./foviaserver/nodeaddon.  The source code and Microsoft Visual Studio solution or Linux makefiles can be found inside ./examples/customfunctions.  Open up ./examples/customfunctions/FoviaCustomDataLoader.cpp, and the following method corresponds to the above JavaScript call:

string FoviaCustomDataLoader::dispatchLoadCustomDataset3D(std::string functionID, const nlohmann::json pJSONObjectInput, IVolumeData** pData, nlohmann::json pJSONObjectOutput)

The first parameter is the function identifier, the second  parameter is the input JSON, the third parameter is the IVolumeData structure which contains the slices of data, and the final parameter is the output JSON data. 

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) During data loading, you can pass various parameters through JavaScript to native code, and use those to  connect to your PACS server or read data from a shared memory location and fill up the VOLUME_DATA_PARAMS structure
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.loadcustom with the id specified in the C++ function above and the parameter to be passed onto the function.