CTL
0.6.1
Computed Tomography Library
|
The ProjectorExtension class provides the interface to extend projectors with additional functionality using the concept of decoration. More...
#include <projectorextension.h>
Classes | |
class | MetaProjector |
Public Types | |
enum | { Type = 100 } |
![]() | |
enum | { Type = 0 } |
![]() | |
enum | { Type = -1, UserType = 65536 } |
Public Member Functions | |
int | type () const override |
void | configure (const AcquisitionSetup &setup) override |
ProjectionData | project (const VolumeData &volume) override |
ProjectorExtension (AbstractProjector *projector=nullptr) | |
ProjectorExtension (std::unique_ptr< AbstractProjector > projector) | |
ProjectionData | projectComposite (const CompositeVolume &volume) override |
Provides the functionality to forward project CompositeVolume data. More... | |
ProjectionData | projectSparse (const SparseVoxelVolume &volume) override |
Provides the functionality to forward project SparseVoxelVolume data. More... | |
bool | isLinear () const override |
Returns true if the projection operation is linear. More... | |
virtual void | use (AbstractProjector *other) |
void | use (std::unique_ptr< AbstractProjector > other) |
void | fromVariant (const QVariant &variant) override |
Sets the contents of the object based on the QVariant variant. More... | |
QVariant | toVariant () const override |
Stores the contents of this instance in a QVariant. More... | |
AbstractProjector * | release () |
void | reset () |
![]() | |
AbstractProjector (const AbstractProjector &)=delete | |
AbstractProjector (AbstractProjector &&)=default | |
AbstractProjector & | operator= (const AbstractProjector &)=delete |
AbstractProjector & | operator= (AbstractProjector &&)=default |
~AbstractProjector () override=default | |
ProjectionData | configureAndProject (const AcquisitionSetup &setup, const VolumeData &volume) |
Performs a forward projection with a precedent configuration of the projector. More... | |
ProjectionData | configureAndProject (const AcquisitionSetup &setup, const CompositeVolume &volume) |
Performs a forward projection with a precedent configuration of the projector. More... | |
ProjectionData | configureAndProject (const AcquisitionSetup &setup, const SparseVoxelVolume &volume) |
Performs a forward projection with a precedent configuration of the projector. More... | |
virtual QVariant | parameter () const |
Returns the parameters of this instance as QVariant. More... | |
virtual void | setParameter (const QVariant ¶meter) |
Sets the parameters of this instance based on the passed QVariant parameter. Parameters need to follow the naming convention as described in parameter(). More... | |
virtual ProjectorNotifier * | notifier () |
Returns a pointer to the notifier of the projector. More... | |
void | connectNotifierToMessageHandler (bool includeProgress=false) |
Connects the notifier to the CTL's MessageHandler. More... | |
![]() | |
virtual | ~SerializationInterface ()=default |
Protected Member Functions | |
virtual ProjectionData | extendedProject (const MetaProjector &nestedProjector) |
![]() | |
SerializationInterface ()=default | |
SerializationInterface (const SerializationInterface &)=default | |
SerializationInterface (SerializationInterface &&)=default | |
SerializationInterface & | operator= (const SerializationInterface &)=default |
SerializationInterface & | operator= (SerializationInterface &&)=default |
Private Attributes | |
std::unique_ptr< AbstractProjector > | _projector |
The nested projector object. | |
Friends | |
template<class > | |
struct | SerializationHelper::RegisterWithSerializationHelper |
Related Functions | |
(Note that these are not member functions.) | |
std::unique_ptr< ProjectorExtensionType > | makeExtension (AbstractProjector *projector=nullptr) |
std::unique_ptr< ProjectorExtensionType > | makeExtension (std::unique_ptr< AbstractProjector > projector) |
![]() | |
VolumeData | |
Alias name for CTL::SpectralVolumeData. More... | |
std::unique_ptr< ProjectorType > | makeProjector (ConstructorArguments &&... arguments) |
The ProjectorExtension class provides the interface to extend projectors with additional functionality using the concept of decoration.
The ProjectorExtension class allowes to extend the functionalty of any projector, i.e. of any class derived from AbstractProjector. The idea is that an extension uses another projector as a nested projector that is called. Before and after that call any modification can be made. The nested projector itself may also be an extension. Note that the nested projector is owned by the extension meaning that when the extension gets destroyed the nested projector will be destroyed too.
There are several syntactical ways to extend another projector/extension. The following snippets show exemplarily the PoissonNoiseExtension extending the OCL::RayCasterProjector. Each pattern supports raw pointers as well as std::unique_ptr
s.
pipe
function for two raw pointers (because two raw pointers cannot be combined via '|
' or '|=
') In order to build and manage a larger pipeline of ProjectorExtension
s, see the helper class ProjectionPipeline. A pre-defined (suggested) pipeline is provided by the StandardPipeline class.
When implementing a custom extension, your class must be a subclass of ProjectorExtension. There are two possiblilties to implement such an extension:
extendedProject
, orproject
, projectComposite
, and projectSparse
.Doing 1. and 2. at the same time is not sensible as the implementation of extendedProject
will have no effect.
You would like to override the AbstractProjector::configure method as well in order to initialize your Extension with informations from the AcquisitionSetup. When doing so, you should also call ProjectorExtension::configure in order to configure the nested projector.
If your extension \( E \) leads to a non-linear projector (regarding project
or projectComposite
), i.e. \( E(a\boldsymbol{v_{1}}+\boldsymbol{v_{2}})\neq aE\boldsymbol{v_{1}}+E\boldsymbol{v_{2}} \) , with volumes \( \boldsymbol{v_{1}} \), \( \boldsymbol{v_{2}} \) and \( a\in \mathbb{R} \), then you should override AbstractProjector::isLinear so that it returns false. Otherwise do not override this method—in particular do not override with true
.
The full effect of an extension can be formalized as follows. An extension \( E \) can be decomposed into three operators:
\( E\left\{A_{\boldsymbol{\pi}}\right\}\boldsymbol{v}=P\,A_{\Pi\boldsymbol{\pi}}\,V\boldsymbol{v}, \)
a modficication \( V \) of the VolumeData
\( \boldsymbol{v} \), a modification \( \Pi \) of the AcquisitionSetup \( \boldsymbol{\pi} \) and a modification \( P \) of the ProjectionData after projection with the nested projector \( A_{\Pi\boldsymbol{\pi}} \) (that uses the modified AcquisitionSetup \( \Pi\boldsymbol{\pi} \)). All three operators "maintain the dimensionality" of the objects they affect. Only the nested projector \( A \) maps from volume space to projection space. In case you directly use the ProjectorExtension class (without any customization) all three operators are identity maps, i.e. it reduces to
\( E\left\{A_{\boldsymbol{\pi}}\right\}\boldsymbol{v}=A_{\boldsymbol{\pi}}\,\boldsymbol{v}\,, \)
meaning that only the nested projector is applied.
In case you opt for variant 1, i.e. you override the extendedProject
method, you can only implement the \( P \) and \( \Pi \) operators, i.e.
\( E\left\{A_{\boldsymbol{\pi}}\right\}\boldsymbol{v}=PA_{\Pi\boldsymbol{\pi}}\,\boldsymbol{v}\,. \)
If even a custom \( \Pi \) is not provided, it leads to an extension that performs only post-processing of the ProjectionData, i.e. it represents a part in a classical pipeline. The variant 2 effectively enables the implementation of all the three operators \( V \), \( \Pi \) and \( P \).
When considering a concatenation of two extensions, first/inner \( E_1 \) and then/outer \( E_2 \) (i.e. E2->use(E1)
or equivalent E1|E2
), the following order of operators is applied by design:
\( \left(E_{2}\circ E_{1}\right)\left\{ A_{\boldsymbol{\pi}}\right\} \boldsymbol{v}= P_{2}P_{1}\,A_{\Pi_{1}\Pi_{2}\boldsymbol{\boldsymbol{\pi}}}\,V_{1}V_{2}\boldsymbol{v}. \)
In other words \( P \) is a post-processing operator while \( \Pi \) and \( V \) are pre-processing operators. This is simply due to the fact that the AcquisitionSetup
/VolumeData
could be changed before calling configure
/project
(Composite
) of the nested projector whereas the ProjectionData may be changed afterwards.
|
explicit |
Constructs a ProjectorExtension object and sets the nested projector to projector. The nested projector is internally used as a basis for computing forward projections. Note that the constructed object takes over the ownership of projector.
|
explicit |
Constructs a ProjectorExtension object and sets the nested projector to projector. A good practice to create a ProjectorExtension on the heap is to use the make function makeExtension(std::unique_ptr<AbstractProjector> projector) which will interally use this constructor.
|
overridevirtual |
This overrides the configure() method and calls the configure method of the nested projector object.
Re-implement this method to retrieve all information required for the purpose of the desired extension. Make sure to delegate this call to the base class (ProjectorExtension) at the end of the method.
Throws std::runtime_error if the nested projector object is unset.
Implements CTL::AbstractProjector.
Reimplemented in CTL::SpectralEffectsExtension.
|
protectedvirtual |
This protected virtual method can be overridden in a subclass in order to implement a custom ProjectorExtension. An implementation of extendedProject is convenient, because an implementation of the two functions project and projectComposite can be avoided. However, this strategy enables only ProjectorExtension
s that perform post-processing of the ProjectionData from the nested projector and/or a modification of the AcquisitionSetup (by calling ProjectorExtension::configure
), but no change of the VolumeData.
You can simply obtain the ProjectionData from the nestedProjector via the call nestedProjector.project()
, no matter if the client called project
or projectComposite
. Subsequent processing can be implemented before the data will be returned.
Reimplemented in CTL::ArealFocalSpotExtension, CTL::PoissonNoiseExtension, and CTL::DetectorSaturationExtension.
|
overridevirtual |
Sets the contents of the object based on the QVariant variant.
Implementation of the deserialization interface. This method uses setParameter() to deserialize class members.
Reimplemented from CTL::AbstractProjector.
|
overridevirtual |
Returns true if the projection operation is linear.
By default, this method returns true. Override this method to return false in case of sub-classing that leads to non-linear operations. Overrides of this method should never return an unconditional true
(as this might outrule underlying non-linearity).
Reimplemented from CTL::AbstractProjector.
Reimplemented in CTL::SpectralEffectsExtension.
|
overridevirtual |
This overrides the project() method and calls the project method of the nested projector object.
Re-implement this method to modify the projections in order to realize the desired functionality of your extension.
Throws std::runtime_error if the nested projector object is unset.
Implements CTL::AbstractProjector.
Reimplemented in CTL::SpectralEffectsExtension.
|
overridevirtual |
Provides the functionality to forward project CompositeVolume data.
This method takes a composite dataset volume and returns the full set of forward projections according to the AcquisitionSetup set in the configure() step.
By default, this method performs separate calls to project() for each individual voxel volume stored in the composite volume. The final projection result is the sum of all these individual projections (extinction domain). Change this behavior in sub-classes, if this is not suitable for your desired purpose. This is typically the case for non-linear operations.
If you intend to call configure() and projectComposite() directly after each other, you should use configureAndProject() instead.
Reimplemented from CTL::AbstractProjector.
Reimplemented in CTL::SpectralEffectsExtension.
|
overridevirtual |
Provides the functionality to forward project SparseVoxelVolume data.
This method takes a sparse dataset volume and returns the full set of forward projections according to the AcquisitionSetup set in the configure() step.
By default, this method performs converts volume to a regular VoxelVolume<float> and calls project() with it. Re-implement this method in sub-classes if you can provide more efficient ways of forward projecting sparse data.
If you intend to call configure() and projectSparse() directly after each other, you should use configureAndProject() instead.
Reimplemented from CTL::AbstractProjector.
Reimplemented in CTL::SpectralEffectsExtension.
AbstractProjector * CTL::ProjectorExtension::release | ( | ) |
Releases the nested projector object.
This transfers the ownership of the projector object to the caller. The internal nested projector pointer is set to nullptr.
void CTL::ProjectorExtension::reset | ( | ) |
Resets this instance. This deletes the nested projector object and sets the internal pointer to nullptr.
|
overridevirtual |
Stores the contents of this instance in a QVariant.
Implementation of the serialization interface. Stores the object's type-id (from SerializationInterface::toVariant()).
This method uses parameter() to serialize class members.
Reimplemented from CTL::AbstractProjector.
Reimplemented in CTL::SpectralEffectsExtension.
|
inlineoverridevirtual |
Returns the type-id of the serializable object. Used in deserialization to determine the proper object type.
Add derived classes to the enumeration using the CTL_TYPE_ID macro.
Reimplemented from CTL::AbstractProjector.
Reimplemented in CTL::SpectralEffectsExtension.
|
virtual |
Sets the nested projector to other.
This will overwrite any projector object that is already in place by deleting it. If this is unintended, consider retrieving the nested projector first using release(). Note that it takes over the ownership of projector.
void CTL::ProjectorExtension::use | ( | std::unique_ptr< AbstractProjector > | other | ) |
Overload of use(AbstractProjector* other) that takes a std::unique_ptr of the other projector.
|
related |
Global (free) make function that creates a new ProjectorExtension by taking over the ownership of a projector. The projector will be the nested projector of the returned ProjectorExtension. The component is returned as a std::unique_ptr<ProjectorExtensionType>
, whereas ProjectorExtensionType
is the template argument of this function that needs to be specified.
|
related |
Global (free) make function that creates a new ProjectorExtension by taking over the ownership of a projector. The projector will be the nested projector of the returned ProjectorExtension. The component is returned as a std::unique_ptr<ProjectorExtensionType>
, whereas ProjectorExtensionType
is the template argument of this function that needs to be specified.