Custom Loading Function

<< Click to Display Table of Contents >>

Navigation:  XStream® HDVR® SDK > Implementation Concepts > Data Loading Fundamentals >

Custom Loading Function

Previous pageReturn to chapter overviewNext page

C++ C++ Java Java .NET .NET

Summary

 

The XStream® HDVR® SDK includes built-in class methods for loading DICOM and RAW datasets. This chapter describes the custom loading function, a mechanism for defining a server side, user-defined data-loading function. This function can be used to load any type of dataset, or to implement a third party DICOM loader or the developer’s own data-loading code. The custom loading function can then be called within the server from a client application. This chapter includes the following sections:

 

oDefining the Custom Loading Function
oSetting the Custom Loading Function
oCalling the Custom Loading Function
oAsynchronous Data Loading

 

Defining the Custom Loading Function (Server API)

 

The first step to define a custom server function is to write the server-side routine itself. The custom server function must conform to the segmentfunc type as shown below. This function must be defined in the XStream HDVR Server API as it runs in the server application process space. The advantage to running on the server is that all image data is already in memory and shared, and more importantly, does not need to be downloaded and processed on the client.

 

NOTE:  The XStream HDVR Server API is only available in the C++ language, although the client can invoke it from any client API.

 

 

typedef h_int32 (loadfunc)(h_int32 loadtype, char* psz, IVolumeData**, ITaskProgress* piTask, h_int64 taskID);

 

The custom loading function takes the following parameters:

A block of data that has been cast to the char* type

h_int32 loadtype

The custom server function ID value (see Setting the Custom Loading Function).

char *psz

A character string containing the path to the dataset. Other data may be included in this string if desired.

IVolumeData **pVolumeData

The IVolumeData object associated with this function call.

ITaskProgress *piTask

Address of the ITaskProgress object used to track asynchronous loading.

h_int64 taskID

The task ID associated with this task, used for asynchronous loading.

 

Setting the Custom Loading Function (Server API)

 

Once the custom loading function has been defined, it is then registered with the server through the XStream HDVR Server API IHdrcServer::SetDatasetLoadFunc() method. This method takes two input parameters. The first parameter serves as the function ID, and is used to reference the custom server function from the client application. It must be cast to the ENUM_LOAD_FUNC enumeration and be between the ENUM_LOAD_FUNC::LF_CUSTOM_START and ENUM_LOAD_FUNC::lF_CUSTOM_END values. The second input parameter is a pointer to the custom server function itself. If only one custom load function is to be defined, the developer may use the predefined ENUM_LOAD_FUNC::LF_CUSTOM value. The second input parameter is a pointer to the user defined loading function conforming to loadfunc prototype.

 

// Custom function prototype (in header file)

RRESULT CustomLoad(h_int32 loadtype, char* psz, IVolumeData** ppi, ITaskProgress* piTask, h_int64 taskID);

 

// Assign custom function (in program code)

pServer->SetDatasetLoadFunc(ENUM_LOAD_FUNC(42), CustomLoad);

 

Asynchronous Dataset Loading (Server API)

 

The server side custom loading function takes the address of an ITaskProgress object as an input parameter. This object is used to track loading progress when using the client side Asynchronous Dataset Loading mechanism. Use the ITaskProgress::StartTask() method to initiate the task tracking mechanism when first starting the custom loading function. As the loading process advances, use the ITaskProgress::SetProgress() method to set the task progress level from 0 (just started) to 100 (complete). When the loading process has completed, call the ITaskProgress::FinishTask() to flag the task as complete.

 

RRESULT CustomLoad(h_int32 loadtype, char* psz, IVolumeData** ppi, ITaskProgress* piTask, h_int64 taskID) {

 

}

 

Calling the Custom Loading Function (Client API)

 

Once the custom server function has been defined and registered with the server application, it can be called from a client application.

 

Using the C++ client API, the custom server function is invoked using the IServerContext::LoadCustomDataset() method. This method takes three input parameters. The first parameter is an IVolumeDataContext object that will be used to store the loaded volume data. The second parameter is an integer cast to the ENUM_LOAD_DATASET_OPTIONS enumeration. This value corresponds to the ENUM_LOAD_FUNC value passed to the server side IHdrcServer::SetDatasetLoadFunc() method that identifies the custom loading function to be called. The third parameter is a character string. This string is generally used to store the path to the dataset to be loaded, but it can be used to convey any other data to the server side custom loading function. Note that the IServerContext::LoadCustomDataset() method will block until the server side custom loading function has completed.

 

char *userData = "c:/data/dicom_files";

pServerContext->LoadCustomDataset(pVolumeData, ENUM_LOAD_DATASET_OPTIONS(42), userData);

 

Using the Java/.NET APIs, the custom server function is invoked using the hdrcServerContext.loadCustomDataset() method. This method takes three input parameters. The first parameter is a hdrcVolumeDataContext object that will be used to store the loaded volume data. The second parameter is an integer. This value corresponds to the ENUM_LOAD_FUNC value passed to the server side IHdrcServer::SetDatasetLoadFunc() method that identifies the custom loading function to be called. The third parameter is a character string. This string is generally be to store the path to the dataset to be loaded, but it can be used to convey any other data to the server side custom loading function. Note that the hdrcServerContext.loadCustomDataset() method will block until the server side custom loading function has completed.

 

String userData = "c:/data/dicom_files";

serverContext->LoadCustomDataset(volumeData, 42, userData);

 

Asynchronous Dataset Loading

 

The C++ API IServerContext::LoadCustomDataset() method is a synchronous blocking method. It will not return until the server side custom loading function has completed. Loading a dataset can take a significant amount of time, and it may not be optimal to have the application block while the dataset is being loaded. Additionally, display of a progress bar or other user interface data may be useful while dataset loading is in process. For these reasons, an asynchronous loading method is provided. Asynchronous dataset loading is accomplished with the IServerContext::StartJobLoadCustomDataset(), IServerContext::GetJobInfo(), and IServerContext::FinishJobCustomLoadDataset() methods.

 

The IServerContext::StartJobLoadCustomDataset() method begins the dataset loading process. This method takes three parameters. The first parameter is a pointer to an integer used to store the job ID associated with the loading process: this will be returned as an output parameter when the IServerContext::StartJobLoadCustomDataset() method returns. The second parameter is an integer cast to the ENUM_LOAD_DATASET_OPTIONS enumeration. This value corresponds to the ENUM_LOAD_FUNC value passed to the server side IHdrcServer::SetDatasetLoadFunc() method that identifies the custom loading function to call. The third parameter is a character string. This string will generally be used to store the path to the dataset to load, but it can be used to convey any other data to the server side custom loading function.

 

The IServerContext::GetJobInfo() method is used to return information on the progress and status of the loading operation. This method takes as an input parameter the jobID value returned from the IServerContext::StartJobLoadCustomDataset() method, that is used to identify the asynchronous loading operation. The IServerContext::GetJobInfo() method returns as an output parameter a pointer to a JOBINFO structure. The JOBINFO::jobprog value stores the job progress. This value will be 0 to 100, representing percentage of job completion, with a value of 100 indicating completion of the job. The JOBINFO::jobret value stores the return value from the server side custom loading function when it has completed.

 

The IServerContext::FinishJobCustomLoadDataset() method is used to finalize the loading process. This method takes two parameters. The first parameter is the address of an IVolumeDataContext pointer that will be set to the IVolumeDataContext object that represents the loaded volume data. The second parameter is the job ID for the desired asynchronous loading operation returned by the IServerContext::StartJobLoadCustomDataset() method. Note that the IServerContext::FinishJobCustomLoadDataset() method will block until the server side loading function completes.

 

char *userData = "c:/data/dicom_files";

h_int64 jobID;

 

// Start the asynchronous loading operation.

pServerContext->StartJobLoadCustomDataset(&jobID, ENUM_LOAD_DATASET_OPTIONS(42), userData);

 

JOBINFO jobInfo;

while(jobInfo.jobprog < 100) {

   // Get loading progress

   pServerContext->GetJobInfo(jobID, &jobInfo);

 

// Loading process is complete

IVolumeDataContext *pVolumeData = NULL;

pServerContext->FinishJobCustomLoadDataset(&pVolumeData, jobID);

 

The Java/.NET API hdrcServerContext.loadCustomDataset() method is a synchronous blocking method. It will not return until the server side custom loading function has completed. Loading a dataset can take a significant amount of time, and it may not be optimal to have the application block while the dataset is being loaded. Additionally, display of a progress bar or other user interface data may be useful while dataset loading is in process. For these reasons, an asynchronous loading method is provided. Asynchronous dataset loading is accomplished with the hdrcServerContext.startJobLoadCustomDataset(), hdrcServerContext.getJobInfo(), and hdrcServerContext.finishJobCustomLoadDataset() methods.

 

The hdrcServerContext.startJobLoadCustomDataset() method begins the dataset loading process. This method takes two parameters. The first parameter is an integer that identifies the server side custom loading function to call. This value corresponds to the ENUM_LOAD_FUNC value passed to the server side IHdrcServer::SetDatasetLoadFunc() method when the custom loading function is registerd. The second parameter is a character string. This string will generally be used to store the path to the dataset to load, but it can be used to convey any other data to the server side custom loading function. The hdrcServerContext.startJobLoadCustomDataset() method returns an integer that represents the job ID associated with the asynchronous loading process.

 

The hdrcServerContext.getJobInfo() method is used to return information on the progress and status of the loading operation. This method takes as an input parameter the jobID value returned from the hdrcServerContext.startJobLoadCustomDataset() method that is used to identify the asynchronous loading operation. The hdrcServerContext.getJobInfo() method returns a reference to a hdrcJobInfo structure. The hdrcJobInfo.m_prog value stores the job progress. This value will be 0 to 100, representing the percentage of job completion, with a value of 100 indicating completion of the job. The hdrcJobInfo.m_err value stores the return value from the server side custom loading function when it has completed.

 

The hdrcServerContext.finishJobCustomLoadDataset() method is used to finalize the loading process. This method takes as an input parameter the job ID for the desired asynchronous loading operation returned by the hdrcServerContext.startJobLoadCustomDataset() method. The hdrcServerContext.finishJobCustomLoadDataset() method returns a reference to a hdrcVolumeDataContext object that represents the loaded volume data. Note that the hdrcServerContext.finishJobCustomLoadDataset() method will block until the server side loading function completes.

 

String userData = "c:/data/dicom_files";

 

// Start the asynchronous loading operation.

long jobID = serverContext.startJobLoadCustomDataset(42, userData);

 

hdrcJobInfo jobInfo;

while(jobInfo.m_prog < 100) {

   // Get loading progress

   jobInfo = serverContext.getJobInfo(jobID);

 

// Loading process is complete

hdrcVolumeDataContext volumeData;

volumeData = serverContext.finishJobCustomLoadDataset(jobID);