ITK  4.12.0
Insight Segmentation and Registration Toolkit

#include <itkDataObject.h>

+ Inheritance diagram for DataObject:

Detailed Description

Base class for all data objects in ITK.

This is the base class for all data objects in the Insight data processing pipeline. A data object is an object that represents and provides access to data. ProcessObjects (i.e., filters) operate on input data objects, producing new data objects as output. ProcessObject and DataObject are connected together into data flow pipelines.

The data flow pipeline architecture requires that DataObjects and ProcessObjects negotiate the flow of information. When the tail of a pipeline is instructed to Update(), a series of requests are propagated up the pipeline (from a ProcessObject to its inputs (DataObjects), from these inputs to their sources (ProcessObjects), etc.). A call to Update() entails 3 passes up the pipeline (though not all passes will traverse the entire pipeline). The first pass up the pipeline determines when various components of the pipeline were last modified and hence which components will need to be updated. As this first pass in unwinding, meta information about the DataObjects (for instance image spacing and data size) are passed down the pipeline. The second pass up the pipeline propagates a request for a specific piece of information (for instance a sub-region of an image). A request for a piece of a DataObject is propagated to its source, from there to its inputs, etc. allowing each ProcessObject to determine whether (1) it can already satisfy the request (the requested block of data is already available) or (2) the ProcessObject will need to request a new block of data on input to satisfy the output request. Finally, a pass is made up the pipeline to actually calculate the values for the various blocks of data requested (i.e. pixel values are finally calculated). This final pass will only traverse up the pipeline as far as the first two passes have identified. For instance, to satisfy a given request at the tail of a pipeline, only the lower few ProcessObjects may have to re-execute.

There are three types of information negotiated by the pipeline (prior to actual calculation of the bulk data): modified times, meta data, and regions. The modified times keep track of when various data objects were last modified and/updated and the when the various process objects were modified. The meta data is any extra information about the data object that is not part of the bulk data. For instance, an Image maintains pixel spacing and origin meta data. Finally, the pipeline negotiation process passes requests up the pipeline in the form of Regions. A DataObject can have as many as three regions (which themselves could be considered meta data): LargestPossibleRegion, RequestedRegion, and BufferedRegion. The LargestPossibleRegion is the entirety of the dataset (for instance how big is the dataset on disk). LargestPossibleRegions are negotiated during the first pass of a pipeline update (via the method ProcessObject::GenerateOutputInformation() which is called from ProcessObject::UpdateOutputInformation(). The RequestedRegion is the amount of the DataObject that is requested by the user or pipeline. RequestedRegions are negotiated during the second pass of a pipeline update (via the methods ProcessObject::EnlargeOutputRequestedRegion(), ProcessObject::GenerateOutputRequestedRegion(), ProcessObject::GenerateInputRequestedRegion() which are called from ProcessObject::PropagateRequestedRegion()). The BufferedRegion is the amount of the DataObject that is currently in memory. BufferedRegions are defined during the final pass of a pipeline update (when ProcessObjects finally calculate the bulk data via the methods ProcessObject::GenerateData() or ProcessObject::ThreadedGenerateData() which are called by ProcessObject::UpdateOutputData()). These three regions can be different but must satisfy the relationship RequestedRegion <= BufferedRegion <= LargestPossibleRegion. For instance, an Image could be 512x512x200 on disk (LargestPossibleRegion) but the application may only have a 256x256x50 section of the dataset in memory (BufferedRegion) and the user wants to operate on a 100x100x1 section of the buffer (RequestedRegion).

Region negotiation is not applicable for all types of DataObjects. For instance, an EquivalencyTable of segmentation labels can be passed from ProcessObject to ProcessObject as any other DataObject but an EquivalencyTable does not support the concept of a sub-region. Therefore, the region negotiations at the DataObject (superclass) level are implemented as "abstract" concepts (not to be confused with a C++ abstract methods), allowing subclasses to provide specialized implementations on an as needed basis. There are five methods provided in DataObject that a subclass of DataObject may have to override for that particular type of DataObject to flow through the pipeline. These methods should only have to be specialized for DataObjects that do support regions. These methods are:

void UpdateOutputInformation(): This method implements the first pass of the pipeline update mechanism outlined above. It is responsible for identifying when upstream components of the pipeline have been change (ModifiedTimes and Pipeline ModifiedTimes) and is responsible for propagating meta data through the pipeline. In the simplest case, this method simply calls the DataObject's source's UpdateOutputInformation() method (this is the default implementation). For DataObjects that support streaming, this method also propagates LargestPossibleRegions to downstream ProcessObjects.

bool VerifyRequestedRegion(): Verify that the RequestedRegion is within the LargestPossibleRegion. For DataObjects that do not support Regions, this method always returns true.

bool RequestedRegionIsOutsideOfTheBufferedRegion(): Determine whether the RequestedRegion is outside of the current BufferedRegion. This method is used by the second pass of a pipeline update outlined above. It is used to determine whether a filter needs to re-execute in order to satisfy a given request. For DataObjects that do not support Regions, this method always returns false. By always returning false, these types of DataObjects will update solely on the basis of modified times (whereas Images update based on either modified times or the RequestedRegion needs). If this method always returned true, the DataObject would be updated on every single call to Update() (not recommended).

void SetRequestedRegion(const DataObject *): Sets the RequestedRegion of this DataObject to match the RequestedRegion of the DataObject that is passed in as a parameter. This method is used by ProcessObject::GenerateOutputRequestedRegion() and by ProcessObject::SetNthOutput(). In the former case, it used as an abstract API so that a ProcessObject can copy a requested region from one output to all its outputs without knowing the particular subclass of DataObject. In the latter case, it used when a ProcessObject has to create an output object to replace one of its outputs (and needs to copy the former object's RequestedRegion). In either case, it allows ProcessObject to perform these actions without knowing the specifics about the particular subclass of DataObject. For DataObjects that do not support Regions, this method does nothing.

void SetRequestedRegionToLargestPossibleRegion(): Sets the RequestedRegion of this DataObject to match its LargestPossibleRegion. This method is used to force a filter to produce all of its output on the next call to Update(). For DataObjects that do not support Regions, this method does nothing.

See Also
ProcessObject
ImageBase
Mesh

The documentation for this class was generated from the following file: