Skip to content

Commit 6132357

Browse files
gselzerhinerm
authored andcommitted
Create Concepts document
1 parent 2669074 commit 6132357

4 files changed

Lines changed: 80 additions & 5 deletions

File tree

docs/ops/doc/CallingOps.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Calling Ops with the `OpBuilder`
22

3+
4+
35
Use of the Ops framework centers on a process of matching Op requests to algorithm implementations based on the parameters provided. The easiest way to make these queries is to use the `OpBuilder` syntax, which follows the [builder pattern](https://refactoring.guru/design-patterns/builder) to assemble the required components of an Op matching request from a particular `OpEnvironment`.
46

57
In this page, we start after having [identified a Gaussian Blur Op](SearchingForOps) that we would like to use. We assume we already have created an `OpEnvironment` named `ops`, as well as the input image to blur, and a pre-allocated output image for the result—`inImage` and `outImage`, respectively.

docs/ops/doc/Concepts.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Concepts
2+
3+
This page is designed to help *Ops users* understand the SciJava Ops concepts powering the framework.
4+
5+
## Ops
6+
An **algorithm** is a mathematical routine that transforms, interrogate, or refines input values into output values, and are used throughout scientific computing.
7+
8+
SciJava Ops attempts to abstract algorithm implementations into a more abstract, language independent form, called an **Op**. Ops have:
9+
* a **name**, defining its purpose. An Op's name describes *what* the Op does, but not *how* the Op does it.
10+
* An Op adding two Java `Integer`s would be named `math.add`
11+
* An Op convolving an image with a kernel might be named `filter.convolve`, *regardless* of whether it performs that convolution in the physical or frequency domain.
12+
* a number of **inputs** and **outputs**, defined by language-specific **types**.
13+
* A `math.add` Op might take two Java `Integer` inputs and return a Java `Integer` output
14+
* A `filter.convolve` Op might take two OpenCV `Mat` inputs, storing the convolved result into an OpenCV `Mat` output *buffer*.
15+
* behavior adhering to a **functional interface** defined below.
16+
17+
## Computers
18+
19+
A **Computer** accepts `n` immutable inputs and a **container** as input parameters. Their singular method, `compute()`, executes an algorithm and *stores the result within* the container parameter, overwriting its contents.
20+
21+
For example, consider the following pseudocode, which replaces the contents of a list of integers `outList` with the elementwise addition of integer `val` to the list of integers `inList`:
22+
```text
23+
math.add(inList: list[int], val: int, outList: list[int]):
24+
outList.clear()
25+
for i in 1..size(inList):
26+
outList[i] = inList[i] + val
27+
28+
```
29+
30+
## Functions
31+
32+
A **Function** accepts `n` immutable inputs as parameters. Their singular method, `apply()`, executes an algorithm and *returns* a new output object to the user.
33+
34+
For example, consider the following pseudocode, which returns a list of integers with the elementwise addition of integer `val` to the list of integers `inList`:
35+
```text
36+
math.add(inList: list[int], val: int) -> list[int]:
37+
outList = list()
38+
for i in 1..size(inList):
39+
outList[i] = inList[i] + val
40+
return outList
41+
```
42+
43+
Creating a new output object on every execution is a double-edged sword: on one hand, it can be convenient to delegate creation to the Op. On the other hand, output creation can be expensive and unnecessary if the Op is called many times.
44+
45+
## Inplaces
46+
47+
A **Inplace** accepts `n` input parameters, **only one** of which is mutable. Their singular method, `mutate()`, executes an algorithm and *overwrites* the single mutable parameter with the algorithm results.
48+
49+
For example, consider the following pseudocode, which mutates a list of integers `inList` by adding the integer `val` to each:
50+
```text
51+
math.add(inList: list[int], val: int):
52+
for i in 1..size(inList):
53+
inList[i] = inList[i] + val
54+
```
55+
56+
A major advantage of Inplaces is the efficiency gained by the absence of an output buffer. On the other hand, the input data is lost through computation.
57+
58+
## OpEnvironment
59+
60+
The Op environment collects all available Ops, and provides access to their functionality. `OpEnvironment` objects are instantiated using the line shown below, and once created will contain all available Ops:
61+
```java
62+
OpEnvironment ops = OpEnvironment.build();
63+
```
64+
65+
With an `OpEnvironment`, users can:
66+
* Find Ops, using the `OpEnvironment.help()` API (see [Searching For Ops](SearchingForOps.md))
67+
* Execute Ops, using the `OpEnvironment.op()` API (see [Calling Ops](CallingOps.md), and the `OpBuilder` section below.)
68+
69+
## OpBuilder
70+
71+
The `OpBuilder` constructs an Op request piece-by-piece using many function calls. The name Op Builder draws upon the [builder pattern](https://refactoring.guru/design-patterns/builder) it follows, and an Op Builder construction is started via the method `OpEnvironment.op()`.
72+
73+
The Op Builder syntax is extremely powerful, as learning to use it enables the execution of any Op in the Op environment, regardless of the language or library that it comes from. See [Calling Ops](CallingOps.md) for a tutorial on the Op Builder!
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Why Use SciJava Ops?
1+
# Purpose
22

33
The fundamental goal of SciJava Ops is to fit the "best" algorithm possible to each task. Historically, identifying and applying the "best" algorithm has been difficult for a variety of reasons:
44
* **Technology iterates quickly:** the "best" algorithm five years ago may be replaced by "better" algorithms within new libraries, in different programming languages, incompatible with established workflows.
@@ -7,12 +7,11 @@ The fundamental goal of SciJava Ops is to fit the "best" algorithm possible to e
77

88
SciJava Ops takes strides to ease these burdens by separating the *what* ("I want to perform a gaussian blur on this image with this sigma value) from the *how* (using scikit-image on zarr arrays). By creating these abstractions, we move towards a single unified, standardized mechanism for applying algorithms. In such an environment, portable workflows can be created quickly and new technologies can be integrated seamlessly.
99

10-
## What are the driving values of SciJava Ops?
10+
## Driving Values
1111

1212
1. **Consistency**: All Ops are called in the same way, regardless of the mechanisms used by the underlying framework. This means that you don't have to learn Python to call Ops written in Python, but it also means that you could pass the output from an Op written in Python to an Op written in Java, all with the same syntax!
1313
2. **Reusability**: Ops extends Java's mantra of "write once, run anywhere" to image processing algorithms. Algorithms written for the SciJava Ops framework are usable as-is from any SciJava-compatible software project including Fiji, or from Python using PyImageJ.
14-
3. **Reproducibility**: Ops are deterministic: calling the same op twice with the same arguments yields the same result, always. Ops are also versioned, meaning that if you use the same Op environment with the same library versions, you will always have reproducible workflows.
15-
4. **Flexibility**: Through adaptation and simplification pathways, Ops can be applied to all kinds of inputs, relaxing considerations for data structures. For example, binary numerical Ops are automatically looped and parallelized to operate on images. New data types extending core interfaces can be supported immediately, without rewriting existing algorithms.
14+
4. **Flexibility**: Through adaptation and conversion pathways, Ops can be applied to all kinds of inputs, relaxing considerations for data structures. For example, binary numerical Ops are automatically looped and parallelized to operate on images. New data types extending core interfaces can be supported immediately, without rewriting existing algorithms.
1615
5. **Safety**: An op may consist of any number of strongly typed inputs, and calls to access those ops can be as specific as desired. This allows analyst users to use ops without regard for data structure, while developers can rely on the type safety guarantees needed for optimization.
1716
6. **Extensibility**: Ops provides a mechanism for incorporating existing algorithm implementations into the framework code-free. Existing ops can always be extended in new directions or specialized for particular inputs.
1817
7. **Performance**: The Ops framework provides a means to override any general-but-slow op with a faster-but-more-specific alternative and the execution framework adds minimal overhead.

docs/ops/doc/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ The combination of these libraries allows declarative image analysis workflows,
1313
:maxdepth: 2
1414
:caption: 🚀 Getting Started
1515

16-
WhyOps
16+
Purpose
17+
Concepts
1718
Installation
1819
ScriptingInFiji
1920

0 commit comments

Comments
 (0)