... | ... | @@ -2,12 +2,6 @@ |
|
|
|
|
|
This page describes how to add a feature in Nabu.
|
|
|
|
|
|
## A brief recall about Nabu classes
|
|
|
|
|
|
As explained in the [documentation](http://www.silx.org/pub/nabu/doc/processing_components.html), there are two main types of classes in Nabu when it comes to process data:
|
|
|
- "Processing" classes. These are classes implementing a feature to process data (ex. correct rings artefacts). A Processing class is first instantiated with the relevant parameters. Then, it is executed on an image (or stack of images). These classes are the building blocks of the Nabu library.
|
|
|
- "Component" classes. They are a wrapper around the former "Processing" class, ensuring that user options are passed correctly, and memory is efficiently used. These classes are the building blocks of a Nabu application.
|
|
|
|
|
|
## Guidelines to add a new feature
|
|
|
|
|
|
### Processing class
|
... | ... | @@ -31,12 +25,6 @@ The unit test is likely to need data. There are two options: |
|
|
- Or, the data can be "real data" (with proper permissions). It is hosted on "edna-site", and must use `nabu.testutils.get_data` (relying on `silx.resources.ExternalResources`).
|
|
|
|
|
|
|
|
|
|
|
|
### Application Component (optional)
|
|
|
|
|
|
If you wish to expose the new feature as an application component, you have to create a class inheriting from `nabu.app.component.Component`. Please refer to the API documentation.
|
|
|
|
|
|
|
|
|
## Example
|
|
|
|
|
|
Let us take the example of the feature "Correct the rings artefacts on the sinogram".
|
... | ... | @@ -95,31 +83,3 @@ class Deringer(SinoProcessing): |
|
|
output[i] = self._destripe_sinogram(sinos[i])
|
|
|
return output
|
|
|
``` |
|
|
|
|
|
Now the `Component` will look like this:
|
|
|
|
|
|
```python
|
|
|
class DeringerComponent(Component):
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
super().__init__(*args, **kwargs)
|
|
|
self.get_backend({
|
|
|
"cuda": (False, "not implemented yet"),
|
|
|
"opencl": (False, "not implemented yet")
|
|
|
})
|
|
|
self._init_deringer()
|
|
|
|
|
|
def _init_deringer(self):
|
|
|
deringer_cls = Deringer
|
|
|
deringer_cls_args = [self.options["fw_sigma"], self.options["fw_levels"]]
|
|
|
deringer_cls_kwargs = {
|
|
|
"radios_shape": self.shape,
|
|
|
}
|
|
|
self.deringer = deringer_cls(*deringer_cls_args, **deringer_cls_kwargs)
|
|
|
self.logger.debug("Deringer initialized with backend %s" % self.backend)
|
|
|
|
|
|
def execute(self, radios):
|
|
|
return self.deringer.correct_rings(radios, output=radios)
|
|
|
```
|
|
|
|
|
|
|
|
|
|