:depth: 3
Below we describe an example procedure for adding a new algorithm.
Prerequisite
- Sample Algorithm Name ...
new_algo
- Sample Algorithm Function Name ...
new_algo_func
- {OPTINIST_SRC_DIR} ... Replace with the actual source storage directory path.
First, prepare the necessary directories and files for the algorithm.
-
{OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
- __init__.py
- xxxx/
- yyyy/
- ...
new_algo/
(*1)- __init__.py (*2)
new_algo_func.py
(*3)- ... (*4)
-
Explanation:
- (*1) The name is arbitrary, but
{algorithm name}
is the standard. - (*2) Empty first.
- (*3) Empty first.
- (*4) Prepare other files to be added.
- (*1) The name is arbitrary, but
- Target file
- {OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
new_algo
/new_algo_func
.py
- {OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
from studio.app.common.dataclass import *
- Explanation:
- If the required dataclass does not exist, you can add your own.
- see. DataClass
- Target file
- {OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
new_algo_wrapper
/new_algo_func
.py
- {OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
The function code is described below.
def new_algo_func( # (*1)
image_data: ImageData, # (*2)
output_dir: str, # (*3)
params: dict=None # (*4)
**kwargs, # (*3)
) -> dict(fluo=FluoData): # (*5)
import numpy as np
info = {
"fluo": FluoData(np.random.rand(100, 20), file_name="fluo"),
"image": ImageData(np.random.rand(10, 100, 100), file_name="image"),
"heatmap": HeatMapData(np.random.rand(20, 20), file_name="heatmap")
}
return info
- Explanation:
- (*1) Function name can be any content.
- (*2) The first argument specifies the input data type. (This is also reflected in the GUI.)
- (*3) Add these arguments. These arguments are required for the handling workflow.
- (*4) This argument receives the function parameters.
- (*5) The return value is a dictionary type. (This is also reflected in the GUI.)
- Target file
- {OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
new_algo
/__init__.py
- {OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
from studio.app.optinist.wrappers.new_algo.new_algo_func import new_algo_func
new_algo_wrapper_dict = { # (*1)
'new_algo': { # (*2)
'new_algo_func': { # (*3)
'function': new_algo_func, # (*4)
'conda_name': 'new_algo', # (*5)
},
}
}
- Explanation:
- (*1) The variable name is arbitrary, but
{algorithm_name}_wrapper_dict
is the standard. - (*2) Algorithm name can be any text (display label to GUI)
- (*3) Algorithm function name can be any text (display label to GUI)
- (*4) Algorithm function name specifies the actual function name
- (*4, 5) The conda setting is optional (to be defined when using conda with snakemake)
- (*1) The variable name is arbitrary, but
Register the created algorithm to the application by adding the following settings.
- Target file
- {OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/__init__.py
from studio.app.optinist.wrappers.xxxx import xxxx_wrapper_dict
from studio.app.optinist.wrappers.yyyy import yyyy_wrapper_dict
...
from studio.app.optinist.wrappers.new_algo import new_algo_wrapper_dict # <-- Add
wrapper_dict = {}
wrapper_dict.update(**xxxx_wrapper_dict)
wrapper_dict.update(**yyyy_wrapper_dict)
...
wrapper_dict.update(**new_algo_wrapper_dict) # <-- Add
After the registration process up to this point, restart the application browser to confirm that the algorithm has been added.
Optinist defines several DataClasses to ensure consistency between Input and Output types. The main data types are as follows. These correspond to the color of each Node's handle.
Optinist support datatype.
- ImageData
- TimeSeriesData
- FluoData
- BehaviorData
- IscellData
- Suite2pData
- ScatterData
- BarData
In the following example, the new_algo_func function takes ImageData and returns FluoData.
from studio.app.common.dataclass import *
def new_algo_func(
image_data: ImageData,
output_dir: str,
params: dict=None,
**kwargs,
) -> dict(fluo=FluoData):
return
Restart the Application and place new_algo_func on the GUI , and you will see that the handle color has changed.
Function input parameters (input on GUI) can be defined in the following file.
-
{OPTINIST_SRC_DIR}/studio/app/optinist/wrappers/
new_algo
/params/{algorithm_function_name}.yaml -
Sample:
new_algo_params_1: filtersize1: 10 filtersize2: 20 new_algo_params_2: filtersize3: 30 filtersize4: 40
-
Explanation:
- {algorithm_function_name} must match the actual function name.
- Above we described the node input and output handle, here we describe the visualization of the result.
- The output of the function is a dictionary. (Here we use the variable info.)
- First, the fluo variable that is the return value of the new_algo_func function is output by Wrap with FluoData. The name of the key in this case must match the fluo of the return value when declaring the function.
- In addition, variables to be visualized are wrapped with their data types and output. In this example, ImageData and HeatMap are output.
def new_algo_func(
image_data: ImageData,
output_dir: str,
params: dict=None,
**kwargs,
) -> dict(fluo=FluoData):
import numpy as np
info = {
"fluo": FluoData(np.random.rand(100, 20), file_name="fluo"),
"image": ImageData(np.random.rand(10, 100, 100), file_name="image"),
"heatmap": HeatMapData(np.random.rand(20, 20), file_name="heatmap")
}
return info
Restart the Application, connect imageNode and run it, and you will see the output as follows.
- Note:
- This is a quick process (only a few seconds), so if the process does not terminate, an error may have occurred. If the error persists, please submit a question to the issue.
You can set plot title and axis labels to some output.
To do this,
-
import PlotMetaData in the algorithm function file.
-
Add PlotMetaData to the output dataclass's
meta
attribute with title or labels you want. If you need only one of them, you can omit the other attributes.from studio.app.common.schemas.outputs import PlotMetaData def new_algo_func( image_data: ImageData, output_dir: str, params: dict=None, **kwargs, ) -> dict(fluo=FluoData): import numpy as np info = { "fluo": FluoData( np.random.rand(100, 20), file_name="fluo" meta=PlotMetaData( title="my fluo", xlabel="my xlabel", ylabel="my ylabel", ), "image": ImageData(np.random.rand(10, 100, 100), file_name="image"), "heatmap": HeatMapData( np.random.rand(20, 20), file_name="heatmap", meta=PlotMetaData( title="my heatmap", # You don't have to set all attributes ) ) } return info
.. note:: Following dataclasses are not supported to visualize these metadata. - CsvData - HTMLData