Migration de DataLab v0.20 vers v1.0#

Avertissement

Note de compatibilité critique :

DataLab v1.0 introduit des changements majeurs qui ne sont pas rétrocompatibles avec v0.20.

  • Les plugins développés pour v0.20 ne fonctionneront pas et doivent être mis à jour

  • Les changements d’API nécessitent des modifications de code pour toutes les intégrations personnalisées

Veuillez lire ce guide attentivement avant de passer à la v1.0.

DataLab v1.0 introduit des changements architecturaux importants par rapport à la v0.20. Le changement le plus important est l”externalisation des fonctionnalités de traitement du signal et de l’image dans une bibliothèque séparée appelée Sigima.

Ce changement architectural améliore la modularité, la testabilité et permet la réutilisation des fonctions de traitement dans d’autres projets. Cependant, cela nécessite des mises à jour des plugins existants pour s’adapter à la nouvelle API.

Ce guide décrit les étapes pour migrer les plugins de DataLab v0.20 vers v1.0.

Qu’est-ce qui a changé dans la v1.0 ?#

Changements architecturaux majeurs#

Le changement le plus significatif dans DataLab v1.0 est la création de la bibliothèque Sigima, qui contient désormais :

  • Objets signal et image (SignalObj, ImageObj, classes ROI)

  • Paramètres de traitement (toutes les classes *Param)

  • Fonctions de traitement (modules sigima.proc.signal et sigima.proc.image)

  • Algorithmes pour le traitement du signal et de l’image, ou conversion de types de données, transformation de coordonnées, … (module sigima.tools)

  • Fonctions d’entrée/sortie (lecture et écriture de signaux/images)

  • Utilitaires de données de test (génération de signaux et d’images de test)

  • Objets résultat (TableResult et GeometryResult, remplaçant ResultProperties et ResultShape)

Ce qui reste dans DataLab :

  • Composants d’interface graphique (panneaux, widgets, intégration de tracés)

  • Système de plugins (module datalab.plugins)

  • Logique applicative (fenêtre principale, configuration, gestion de projet)

  • Adaptateurs de métadonnées de résultats (TableAdapter, GeometryAdapter pour stocker les résultats dans les métadonnées des objets)

Renommage du package#

Le package DataLab a été renommé de cdl à datalab par souci de clarté :

# v0.20
import cdl.obj
import cdl.param
from cdl.plugins import PluginBase

# v1.0
import sigima.objects
import sigima.params
from datalab.plugins import PluginBase

Convention de nommage des fichiers de plugin#

Les noms de fichiers de plugin doivent suivre la nouvelle convention de nommage :

Important

Les fichiers de plugin doivent être renommés de cdl_*.py en datalab_*.py.

Exemples :

  • cdl_myplugin.pydatalab_myplugin.py

  • cdl_custom_filters.pydatalab_custom_filters.py

  • cdl_example.pydatalab_example.py

Cette convention de nommage est requise pour que DataLab découvre et charge automatiquement les plugins au démarrage. Les plugins qui ne suivent pas ce schéma de nommage ne seront pas chargés.

Note

Le mécanisme de découverte des plugins recherche les fichiers Python correspondant au motif datalab_*.py dans le répertoire des plugins. Assurez-vous de mettre à jour les noms de fichiers de vos plugins en conséquence.

Nouveaux objets résultat#

DataLab v1.0 introduit deux nouveaux types de résultats immuables :

  • TableResult : Remplace ResultProperties pour les résultats scalaires tabulaires (par exemple, statistiques, mesures)

  • GeometryResult : Remplace ResultShape pour les résultats géométriques (par exemple, caractéristiques détectées, contours)

Ces nouveaux types de résultats sont orientés calcul et exempts de logique spécifique à l’application (par exemple, Qt, métadonnées). Tous les comportements liés aux métadonnées ont été migrés vers la couche applicative de DataLab en utilisant des classes d’adaptation (TableAdapter, GeometryAdapter).

Accès à l’UUID de l’objet#

La manière d’accéder à l’UUID d’un objet a changé :

# v0.20 - Direct attribute access
obj_uuid = obj.uuid

# v1.0 - Use helper function from datalab.objectmodel
from datalab.objectmodel import get_uuid
obj_uuid = get_uuid(obj)

# Alternative in v1.0 - Access metadata directly
obj_uuid = obj.get_metadata_option("uuid")

Ce changement s’applique aux objets SignalObj et ImageObj. L’UUID est désormais stocké dans les métadonnées de l’objet plutôt que comme un attribut direct.

Note

La fonction get_uuid() est définie dans datalab.objectmodel, et non comme une méthode de l’objet lui-même. Importez-la avant utilisation : from datalab.objectmodel import get_uuid.

Interface processeur unifiée#

Les méthodes du processeur ont été unifiées et renommées :

  • La plupart des méthodes spécifiques compute_* utilisent désormais la méthode générique run_feature()

  • Conventions de nommage mises à jour : compute_11compute_1_to_1, compute_10compute_1_to_0, etc.

Mise à jour des imports#

Changements des chemins d’import#

Le tableau suivant donne l’équivalence entre les imports DataLab v0.20 et v1.0.

Le tableau ci-dessous présente la correspondance entre l’API DataLab v0.20 et v1.0. Pour la plupart des entrées, seule l’instruction d’import doit être mise à jour.

Tableau de compatibilité DataLab v0.20 vers v1.0#

DataLab v0.20

DataLab v1.0

Renommages de modules/packages

cdl

datalab

cdl.obj

sigima.objects

cdl.param

sigima.params

cdl.computation.image

sigima.proc.image

cdl.computation.signal

sigima.proc.signal

cdl.plugins

datalab.plugins

Création et manipulation d’objets

cdl.obj.create_image()

sigima.objects.create_image()

cdl.obj.create_signal()

sigima.objects.create_signal()

cdl.obj.ImageObj

sigima.objects.ImageObj

cdl.obj.SignalObj

sigima.objects.SignalObj

cdl.obj.create_image_roi()

sigima.objects.create_image_roi()

cdl.obj.create_signal_roi()

sigima.objects.create_signal_roi()

cdl.obj.ImageROI

sigima.objects.ImageROI

cdl.obj.SignalROI

sigima.objects.SignalROI

Classes de paramètres

cdl.param.BinningParam

sigima.params.BinningParam

cdl.param.MovingMedianParam

sigima.params.MovingMedianParam

cdl.param.BlobOpenCVParam

sigima.params.BlobOpenCVParam

cdl.param.GaussianParam

sigima.params.GaussianParam

cdl.param.*Param

sigima.params.*Param

Enveloppes de fonctions de calcul

cdl.computation.image.Wrap11Func

sigima.proc.image.Wrap1to1Func

cdl.computation.signal.Wrap11Func

sigima.proc.signal.Wrap1to1Func

cdl.computation.image.dst_11()

sigima.proc.image.dst_1to1()

cdl.computation.signal.dst_11()

sigima.proc.signal.dst_1to1()

Méthodes du processeur (p est une instance de processeur de signal ou d’image)

p.compute_11(...)

p.compute_1_to_1(...)

p.compute_10(...)

p.compute_1_to_0(...)

p.compute_n1(...)

p.compute_n_to_1(...)

p.compute_binning(param)

p.run_feature("binning", param)

p.compute_moving_median(param)

p.run_feature("moving_median", param)

p.compute_blob_opencv(param)

p.run_feature("blob_opencv", param)

p.compute_*(param)

p.run_feature("feature_name", param)

Objets résultat

cdl.obj.ResultProperties

sigima.objects.TableResult

cdl.obj.ResultShape

sigima.objects.GeometryResult

result.add_to(obj)

TableAdapter(result).add_to(obj)

ResultShape.from_metadata_entry()

GeometryAdapter.from_metadata_entry()

result.to_html(obj)

ResultHtmlGenerator.generate_html(result, obj)

Fonctions de données de test

cdl.tests.data.*

sigima.tests.data.*

cdl.tests.data.create_paracetamol_signal()

sigima.tests.data.create_paracetamol_signal()

cdl.tests.data.add_gaussian_noise_to_signal()

sigima.tests.data.add_gaussian_noise_to_signal()

cdl.tests.data.create_noisygauss_image()

sigima.tests.data.create_noisy_gaussian_image()

cdl.tests.data.create_multigauss_image()

sigima.tests.data.create_multigaussian_image()

Nouveaux paramètres d’image

edit_new_image_parameters(hide_image_dtype=True)

edit_new_image_parameters(hide_dtype=True)

edit_new_image_parameters(hide_image_type=True)

edit_new_image_parameters(hide_type=True)

edit_new_image_parameters(hide_image_height=True)

edit_new_image_parameters(hide_height=True)

Fonctions d’entrée/sortie

cdl.io.image.read_image()

sigima.io.image.read_image()

cdl.io.image.write_image()

sigima.io.image.write_image()

cdl.io.signal.read_signal()

sigima.io.signal.read_signal()

cdl.io.signal.write_signal()

sigima.io.signal.write_signal()

Énumérations

cdl.obj.ImageDatatypes

sigima.objects.ImageDatatypes

cdl.obj.ImageTypes

sigima.objects.ImageTypes

Fonctionnalités spécifiques à DataLab

cdl.config._

datalab.config._

cdl.plugins.PluginBase

datalab.plugins.PluginBase

cdl.plugins.PluginInfo

datalab.plugins.PluginInfo

Migration du code des plugins#

Exemple 1 : Plugin de traitement simple#

Voici comment un plugin de filtre personnalisé simple doit être mis à jour :

DataLab v0.20 :

import numpy as np
import scipy.ndimage as spi

import cdl.computation.image as cpi
import cdl.obj
import cdl.param
import cdl.plugins


def weighted_average_denoise(data: np.ndarray) -> np.ndarray:
    """Apply a custom denoising filter to an image."""
    def filter_func(values: np.ndarray) -> float:
        central_pixel = values[len(values) // 2]
        differences = np.abs(values - central_pixel)
        weights = np.exp(-differences / np.mean(differences))
        return np.average(values, weights=weights)
    return spi.generic_filter(data, filter_func, size=5)


class CustomFilters(cdl.plugins.PluginBase):
    """DataLab Custom Filters Plugin"""

    PLUGIN_INFO = cdl.plugins.PluginInfo(
        name="My custom filters",
        version="1.0.0",
        description="This is an example plugin",
    )

    def create_actions(self) -> None:
        """Create actions"""
        acth = self.imagepanel.acthandler
        proc = self.imagepanel.processor
        with acth.new_menu(self.PLUGIN_INFO.name):
            for name, func in (("Weighted average denoise", weighted_average_denoise),):
                # Wrap function to handle ImageObj objects
                wrapped_func = cpi.Wrap11Func(func)
                acth.new_action(
                    name, triggered=lambda: proc.compute_11(wrapped_func, title=name)
                )

DataLab v1.0 :

import numpy as np
import scipy.ndimage as spi
import sigima.proc.image as sipi

import datalab.plugins


def weighted_average_denoise(data: np.ndarray) -> np.ndarray:
    """Apply a custom denoising filter to an image."""
    def filter_func(values: np.ndarray) -> float:
        central_pixel = values[len(values) // 2]
        differences = np.abs(values - central_pixel)
        weights = np.exp(-differences / np.mean(differences))
        return np.average(values, weights=weights)
    return spi.generic_filter(data, filter_func, size=5)


class CustomFilters(datalab.plugins.PluginBase):
    """DataLab Custom Filters Plugin"""

    PLUGIN_INFO = datalab.plugins.PluginInfo(
        name="My custom filters",
        version="1.0.0",
        description="This is an example plugin",
    )

    def create_actions(self) -> None:
        """Create actions"""
        acth = self.imagepanel.acthandler
        proc = self.imagepanel.processor
        with acth.new_menu(self.PLUGIN_INFO.name):
            for name, func in (("Weighted average denoise", weighted_average_denoise),):
                # Wrap function to handle ImageObj objects
                wrapped_func = sipi.Wrap1to1Func(func)
                acth.new_action(
                    name,
                    triggered=lambda: proc.compute_1_to_1(wrapped_func, title=name),
                )

Changements clés :

  1. cdl.computation.imagesigima.proc.image

  2. cdl.pluginsdatalab.plugins

  3. Wrap11FuncWrap1to1Func

  4. compute_11compute_1_to_1

Exemple 2 : Plugin utilisant des fonctionnalités intégrées#

DataLab v0.20 :

import cdl.obj
import cdl.param
import cdl.plugins


class ExtractBlobs(cdl.plugins.PluginBase):
    """DataLab Example Plugin"""

    PLUGIN_INFO = cdl.plugins.PluginInfo(
        name="Extract blobs (example)",
        version="1.0.0",
        description="This is an example plugin",
    )

    def preprocess(self) -> None:
        """Preprocess image"""
        panel = self.imagepanel
        param = cdl.param.BinningParam.create(sx=2, sy=2)
        panel.processor.compute_binning(param)
        panel.processor.compute_moving_median(cdl.param.MovingMedianParam.create(n=5))

    def detect_blobs(self) -> None:
        """Detect circular blobs"""
        panel = self.imagepanel
        param = cdl.param.BlobOpenCVParam()
        param.filter_by_color = False
        param.min_area = 600.0
        param.max_area = 6000.0
        param.filter_by_circularity = True
        param.min_circularity = 0.8
        param.max_circularity = 1.0
        panel.processor.compute_blob_opencv(param)

    def create_actions(self) -> None:
        """Create actions"""
        acth = self.imagepanel.acthandler
        with acth.new_menu(self.PLUGIN_INFO.name):
            acth.new_action("Preprocess image", triggered=self.preprocess)
            acth.new_action("Detect circular blobs", triggered=self.detect_blobs)

DataLab v1.0 :

import sigima.objects
import sigima.params

import datalab.plugins


class ExtractBlobs(datalab.plugins.PluginBase):
    """DataLab Example Plugin"""

    PLUGIN_INFO = datalab.plugins.PluginInfo(
        name="Extract blobs (example)",
        version="1.0.0",
        description="This is an example plugin",
    )

    def preprocess(self) -> None:
        """Preprocess image"""
        panel = self.imagepanel
        param = sigima.params.BinningParam.create(sx=2, sy=2)
        panel.processor.run_feature("binning", param)
        panel.processor.run_feature(
            "moving_median", sigima.params.MovingMedianParam.create(n=5)
        )

    def detect_blobs(self) -> None:
        """Detect circular blobs"""
        panel = self.imagepanel
        param = sigima.params.BlobOpenCVParam()
        param.filter_by_color = False
        param.min_area = 600.0
        param.max_area = 6000.0
        param.filter_by_circularity = True
        param.min_circularity = 0.8
        param.max_circularity = 1.0
        panel.processor.run_feature("blob_opencv", param)

    def create_actions(self) -> None:
        """Create actions"""
        acth = self.imagepanel.acthandler
        with acth.new_menu(self.PLUGIN_INFO.name):
            acth.new_action("Preprocess image", triggered=self.preprocess)
            acth.new_action("Detect circular blobs", triggered=self.detect_blobs)

Changements clés :

  1. cdl.paramsigima.params

  2. cdl.pluginsdatalab.plugins

  3. compute_binning(param)run_feature("binning", param)

  4. compute_moving_median(param)run_feature("moving_median", param)

  5. compute_blob_opencv(param)run_feature("blob_opencv", param)

Exemple 3 : Plugin créant des objets et gérant les résultats#

DataLab v0.20 :

import numpy as np
import cdl.obj as dlo
import cdl.tests.data as test_data
from cdl.computation import image as cpima
from cdl.config import _
from cdl.plugins import PluginBase, PluginInfo


def add_noise_to_image(src: dlo.ImageObj, p: dlo.NormalRandomParam) -> dlo.ImageObj:
    """Add gaussian noise to image"""
    dst = cpima.dst_11(src, "add_gaussian_noise", f"mu={p.mu},sigma={p.sigma}")
    test_data.add_gaussian_noise_to_image(dst, p)
    return dst


class PluginTestData(PluginBase):
    """DataLab Test Data Plugin"""

    PLUGIN_INFO = PluginInfo(
        name=_("Test data"),
        version="1.0.0",
        description=_("Testing DataLab functionalities"),
    )

    def add_noise_to_image(self) -> None:
        """Add noise to image"""
        self.imagepanel.processor.compute_11(
            add_noise_to_image,
            paramclass=dlo.NormalRandomParam,
            title=_("Add noise"),
        )

    def create_noisygauss_image(self) -> None:
        """Create 2D noisy gauss image"""
        newparam = self.edit_new_image_parameters(
            hide_image_height=True, hide_image_type=True
        )
        if newparam is not None:
            obj = test_data.create_noisygauss_image(newparam, add_annotations=False)
            self.proxy.add_object(obj)

    def create_actions(self) -> None:
        """Create actions"""
        iah = self.imagepanel.acthandler
        with iah.new_menu(_("Test data")):
            iah.new_action(_("Add noise to image"), triggered=self.add_noise_to_image)
            iah.new_action(
                _("Create 2D noisy gauss image"),
                triggered=self.create_noisygauss_image,
                select_condition="always",
            )

DataLab v1.0 :

import numpy as np
import sigima.objects
import sigima.tests.data as test_data
from sigima.proc import image as sipi
from datalab.config import _
from datalab.plugins import PluginBase, PluginInfo


def add_noise_to_image(
    src: sigima.objects.ImageObj, p: sigima.objects.NormalDistribution2DParam
) -> sigima.objects.ImageObj:
    """Add gaussian noise to image"""
    dst = sipi.dst_1to1(src, "add_gaussian_noise", f"mu={p.mu},sigma={p.sigma}")
    test_data.add_gaussian_noise_to_image(dst, p)
    return dst


class PluginTestData(PluginBase):
    """DataLab Test Data Plugin"""

    PLUGIN_INFO = PluginInfo(
        name=_("Test data"),
        version="1.0.0",
        description=_("Testing DataLab functionalities"),
    )

    def add_noise_to_image(self) -> None:
        """Add noise to image"""
        self.imagepanel.processor.compute_1_to_1(
            add_noise_to_image,
            paramclass=sigima.objects.NormalDistribution2DParam,
            title=_("Add noise"),
        )

    def create_noisy_gaussian_image(self) -> None:
        """Create 2D noisy gauss image"""
        newparam = self.edit_new_image_parameters(
            hide_height=True, hide_type=True
        )
        if newparam is not None:
            obj = test_data.create_noisy_gaussian_image(newparam, add_annotations=False)
            self.proxy.add_object(obj)

    def create_actions(self) -> None:
        """Create actions"""
        iah = self.imagepanel.acthandler
        with iah.new_menu(_("Test data")):
            iah.new_action(_("Add noise to image"), triggered=self.add_noise_to_image)
            iah.new_action(
                _("Create 2D noisy gaussian image"),
                triggered=self.create_noisy_gaussian_image,
                select_condition="always",
            )

Changements clés :

  1. cdl.objsigima.objects

  2. cdl.tests.datasigima.tests.data

  3. cdl.computation.imagesigima.proc.image

  4. dst_11dst_1to1

  5. compute_11compute_1_to_1

  6. dlo.NormalRandomParamsigima.objects.NormalDistribution2DParam

  7. create_noisygauss_imagecreate_noisy_gaussian_image

  8. hide_image_heighthide_height, hide_image_typehide_type

Travailler avec les objets résultat#

Modifications des objets résultat#

L’architecture des objets résultat a été complètement repensée dans la v1.0 :

Objets résultat v0.20 :

  • ResultProperties : Pour les résultats tabulaires (statistiques, etc.)

  • ResultShape : Pour les résultats géométriques (caractéristiques détectées, etc.)

  • Ces objets contenaient du code spécifique à Qt et de la logique de gestion des métadonnées

  • Les méthodes comme add_to(obj) et from_metadata_entry() faisaient partie de la classe résultat

Objets résultat v1.0 :

  • TableResult : Résultats tabulaires immuables, orientés calcul

  • GeometryResult : Résultats géométriques immuables, orientés calcul

  • Aucune dépendance Qt ou métadonnées

  • La gestion des métadonnées a été déplacée vers les classes d’adaptation DataLab

Utilisation de TableResult et GeometryResult#

Dans la v1.0, lorsque votre plugin reçoit des résultats d’opérations compute_1_to_0, vous travaillerez avec des objets TableResult ou GeometryResult.

Exemple 1 : Calcul des paramètres dynamiques du signal (TableResult)

Cet exemple montre comment calculer les paramètres dynamiques (ENOB, SINAD, THD, etc.) et travailler avec le TableResult résultant :

import sigima.params
import sigima.proc.signal
from datalab.adapters_metadata import TableAdapter

# Get the current signal from the panel
panel = self.signalpanel
obj = panel.objview.get_current_object()

# Compute dynamic parameters
param = sigima.params.DynamicParam.create(full_scale=1.0)
table = sigima.proc.signal.dynamic_parameters(obj, param)

# Access specific values from the table
enob = table["enob"][0]  # Effective Number of Bits
sinad = table["sinad"][0]  # Signal-to-Noise and Distortion Ratio
thd = table["thd"][0]  # Total Harmonic Distortion

# Convert to dictionary for easy access
result_dict = table.as_dict()
print(f"ENOB: {result_dict['enob']}")
print(f"SINAD: {result_dict['sinad']} dB")

# Store result in object metadata using adapter
adapter = TableAdapter(table)
adapter.add_to(obj)

# Convert to pandas DataFrame for further processing
df = table.to_dataframe()
print(df)

Exemple 2 : Détection de pics dans une image (GeometryResult)

Cet exemple montre comment détecter des pics dans une image et travailler avec le GeometryResult résultant :

import sigima.params
import sigima.proc.image
from datalab.adapters_metadata import GeometryAdapter

# Get the current image from the panel
panel = self.imagepanel
obj = panel.objview.get_current_object()

# Configure peak detection parameters
param = sigima.params.Peak2DDetectionParam.create(
    size=50,  # Neighborhood size
    threshold=0.5,  # Relative threshold
    create_rois=True  # Create ROI for each peak
)

# Compute peak detection
geometry = sigima.proc.image.peak_detection(obj, param)

# Access geometry data
coords = geometry.coords  # numpy array of shape (n_peaks, 2)
n_peaks = len(coords)
print(f"Detected {n_peaks} peaks")

# Iterate over detected peaks
for i, (x, y) in enumerate(coords):
    print(f"Peak {i+1}: x={x:.2f}, y={y:.2f}")

# Check geometry kind
from sigima.objects import KindShape
assert geometry.kind == KindShape.POINT

# Store geometry in object metadata using adapter
adapter = GeometryAdapter(geometry)
adapter.add_to(obj)

Exemple 3 : Calcul de la bande passante (GeometryResult avec segments)

Cet exemple montre comment calculer la bande passante d’un signal, qui renvoie une géométrie de segment :

import sigima.proc.signal
from datalab.adapters_metadata import GeometryAdapter

# Get the current signal from the panel
panel = self.signalpanel
obj = panel.objview.get_current_object()

# Compute -3dB bandwidth
geometry = sigima.proc.signal.bandwidth_3db(obj)

# Access segment coordinates [x0, y0, x1, y1]
x0, y0, x1, y1 = geometry.coords[0]
print(f"Bandwidth segment: ({x0}, {y0}) to ({x1}, {y1})")

# Calculate bandwidth length
bandwidth = geometry.segments_lengths()[0]
print(f"Bandwidth@-3dB: {bandwidth:.2f}")

# Store in metadata
adapter = GeometryAdapter(geometry)
adapter.add_to(obj)

Récupération des résultats depuis les métadonnées#

Pour récupérer les résultats stockés dans les métadonnées de l’objet :

from datalab.adapters_metadata import TableAdapter, GeometryAdapter

obj = ...  # Some signal or image object

# Iterate over all table results
for adapter in TableAdapter.iterate_from_obj(obj):
    result = adapter.result  # TableResult instance
    title = adapter.title
    df = result.to_dataframe()

# Iterate over all geometry results
for adapter in GeometryAdapter.iterate_from_obj(obj):
    result = adapter.result  # GeometryResult instance
    title = adapter.title
    coords = result.coords

Modifications des méthodes du processeur#

L’interface du processeur a été unifiée dans la v1.0. La plupart des méthodes spécifiques compute_* utilisent désormais la méthode générique run_feature().

Utilisation de run_feature()#

La méthode run_feature() est une interface unifiée pour exécuter des fonctionnalités de traitement :

# v1.0 - Generic interface
proc = panel.processor

# Simple features (no parameters)
proc.run_feature("normalize")
proc.run_feature("fft")

# Features with parameters
param = sigima.params.GaussianParam.create(sigma=2.0)
proc.run_feature("gaussian_filter", param)

# Features with direct function reference
import sigima.proc.image as sipi
proc.run_feature(sipi.normalize)
proc.run_feature(sipi.gaussian_filter, param)

Renommage des méthodes#

Plusieurs méthodes du processeur ont été renommées par souci de cohérence :

v0.20

v1.0

compute_11(func, ...)

compute_1_to_1(func, ...)

compute_10(func, ...)

compute_1_to_0(func, ...)

compute_n1(func, ...)

compute_n_to_1(func, ...)

compute_1n(func, ...)

compute_1_to_n(func, ...)

compute_21(func, ...)

compute_2_to_1(func, ...)

Fonctionnalités intégrées utilisant run_feature#

La plupart des fonctionnalités de traitement intégrées qui avaient auparavant des méthodes dédiées compute_* utilisent désormais run_feature() :

# v0.20
proc.compute_binning(param)
proc.compute_moving_median(param)
proc.compute_blob_opencv(param)
proc.compute_gaussian_filter(param)

# v1.0
proc.run_feature("binning", param)
proc.run_feature("moving_median", param)
proc.run_feature("blob_opencv", param)
proc.run_feature("gaussian_filter", param)

Certaines fonctionnalités complexes ont toujours des méthodes dédiées :

# These still use dedicated methods in v1.0
proc.compute_roi_extraction(roi)
proc.compute_multigaussianfit()
proc.compute_peak_detection(param)

Tester votre plugin#

Après la migration, testez minutieusement votre plugin :

  1. Vérification des imports : Vérifiez que tous les imports fonctionnent correctement

  2. Création de paramètres : Vérifiez que les classes de paramètres sont correctement instanciées

  3. Création d’objets : Testez les fonctions de création d’objets signal/image

  4. Opérations de traitement : Vérifiez que toutes les fonctionnalités de traitement fonctionnent comme prévu

  5. Gestion des résultats : Vérifiez que les résultats sont correctement générés et stockés

  6. Intégration de l’interface graphique : Testez que les menus et actions apparaissent correctement

Problèmes courants et solutions#

Erreurs d’import#

Problème : ModuleNotFoundError: No module named 'cdl'

Solution : Mettez à jour tous les imports de cdl.* vers soit datalab.* soit sigima.* selon le module.

Erreurs d’attribut sur le processeur#

Problème : AttributeError: 'ImageProcessor' object has no attribute 'compute_binning'

Solution : Remplacez les appels de méthode compute_* par des appels run_feature() :

# Wrong (v0.20 style)
proc.compute_binning(param)

# Correct (v1.0 style)
proc.run_feature("binning", param)

Incompatibilité d’objet résultat#

Problème : AttributeError: 'TableResult' object has no attribute 'add_to'

Solution : Utilisez des classes d’adaptation pour les opérations de métadonnées :

# Wrong (v0.20 style)
result.add_to(obj)

# Correct (v1.0 style)
from datalab.adapters_metadata import TableAdapter
TableAdapter(result).add_to(obj)

Paramètres manquants#

Problème : ImportError: cannot import name 'SomeParam' from 'datalab'

Solution : Importez les paramètres depuis sigima.params au lieu de cdl.param :

# Wrong
from cdl.param import GaussianParam

# Correct
from sigima.params import GaussianParam

Ressources supplémentaires#

Obtenir de l’aide#

Si vous rencontrez des problèmes pendant la migration :

  1. Consultez le suivi des problèmes GitHub

  2. Consultez les exemples de plugins intégrés dans le répertoire datalab/plugins