Input and Output handling in GIMIAS Processors

From user's Wiki!
Jump to: navigation, search

Input and Output handling in GIMIAS Processor

Constructor

In the constructor we define the type of our inputs and other important properties. It's not necessary to do the same with the output.


SetName( "TemplProcessor" );
	
BaseProcessor::SetNumberOfInputs( INPUTS_NUMBER );
GetInputPort(INPUT_0)->SetName(  "Input Image" );
GetInputPort(INPUT_0)->SetDataEntityType( Core::ImageTypeId);
GetInputPort(INPUT_1)->SetName(  "Input Surface" );
GetInputPort(INPUT_1)->SetDataEntityType( Core::SurfaceMeshTypeId );
BaseProcessor::SetNumberOfOutputs( OUTPUTS_NUMBER );

where INPUTS_NUMBER has been defined in the header file. Possible types of inputs/outpus are the DataEntityTypes, they correspond to a particular ProcessingData here you can find a table of the relations between DataEntityType and ProcessingData:

DataEntityType ProcessingData
Core::UnknownTypeId unknown
Core::ImageTypeId vtkImageData, blSliceImage, mitk::Image, itk::Image
Core::SurfaceMeshTypeId vtkPolyData, mitk::Surface, Netgen mesh
Core::VolumeMeshTypeId vtkUnstructuredGrid
Core::SignalTypeId blSignalCollective
Core::TransformFileId itk::TransformBase
Core::SkeletonTypeId vtkPolyData( only Lines)
Core::PointSetTypeId vtkPolyData(only points), mitk::PointSet
Core::MITKDataTypeId MITK::BaseData
Core::ContourTypeId std::vector<float>
Core::MeasurementTypeId Measurement??
Core::ROITypeId Roi image data (mask Image)
Core::SliceImageTypeId by slices and orientations
Core::NumericDataTypeId blTagMap. Doesn't have rendering data
Core::TensorTypeId itk::Image<itk::DTITensor<float>,3>

How to get an input

Inside the Processor we will need to access the processingData contained in our input data entities in order to use it. This can be done in two different ways, using an internal function:

template <class ProcessingDataType>

void Core::BaseFilter::GetProcessingData( 
	int num,
	ProcessingDataType &processingData,
	int iTimeStep /*= 0*/ )

Here you can see un example of how to call it inside the processor

vtkImageData* vtkImage;
GetProcessingData(INPUT_0,vtkImage);

ImageType::Pointer itkInputImage;
GetProcessingData<ImageType::Pointer>(INPUT_0,
		itkInputImage);

or using a static function from coreDataEntityHelper.h (DEPRECATED, do not use if you can) .


How to update an output

Once that your algorithm/filter has been called inside the processor you have to update your output, that means that you're notifing that your result is ready to be used and rendered ( PublishOutput in the PanelWidget class)

Option 1: Core::BaseProcessor::UpdateOutput(...)

You can do it using the function that is available in the Core::BaseProcessor class, the input variables are :

void  UpdateOutput(
     int iIndex,                                 // output index
     boost::any data,                            // processing data
     std::string strDataEntityName,              // name
     bool bReuseOutput /* = false */,            // if you want to reuse the same data entity when you update the output
     int iTotalTimeSteps /* = 1 */,               // number of time steps
     Core::DataEntity::Pointer fatherDataEntity /*= NULL*/)  // if you want to set a "father" for your data entity

Or if you want to update a vector of outputs (that means more than one timestep at the same time) you can use this function:

template <typename T>
void Core::BaseProcessor::UpdateOutput( 
	int iIndex, 
	std::vector<T> dataVector,
	std::string dataEntityName,
	bool bReuseOutput /*= false*/,
	Core::DataEntity::Pointer fatherDataEntity /*= NULL */)

Here you have some examples:

UpdateOutput( 0 ,itkInputImage, "NameImage");	 //itkInputImage --> itk::ImageType
UpdateOutput(1, vtkInputMesh, "NameSurface", true, 1);   // vtkInputMesh --> vtkPolyData*
std::vector<ImageType::Pointer> outputVector;
outputVector.push_back( filter->GetOutput() );
UpdateOutput<ImageType::Pointer>( 
              0,
              outputVector, 
              "ResampleProcessor", 
              true, 
              GetInputDataEntity( 0 ) );             


Option 2: Core::BaseFilterOutputPort::UpdateOutput(...)

In this case too the input variables are always the same independently from the processing data:

void Core::BaseFilterOutputPort::UpdateOutput(   
	boost::any any,                               // processing data
	int timeStepNumber,                           // number of time step
	Core::DataEntity::Pointer fatherDataEntity )  //"father" data entity for your output

Here there is an example of how to call this method and how to set some other variables:

vtkPolyData* surfaceMesh;
GetOutputPort( num )->SetReuseOutput(true);
GetOutputPort( num )->SetDataEntityName("name");
GetOutputPort( num )->UpdateOutput( surfaceMesh, timeStep, GetInputDataEntity( 0 ) );

Go back to Developers