Skip to content

Commit 49d03bc

Browse files
committed
Fix: Add "Replace X by other signal's Y" for calibration workflows
Fixes #273
1 parent a4f6d74 commit 49d03bc

9 files changed

Lines changed: 192 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ See DataLab [roadmap page](https://datalab-platform.com/en/contributing/roadmap.
66

77
### 🛠️ Bug Fixes ###
88

9+
**Signal axis calibration - Replace X by other signal's Y:**
10+
11+
* Added new "Replace X by other signal's Y" operation in Processing > Axis transformation menu for signal calibration workflows
12+
* Addresses critical missing functionality reported by users who needed to apply wavelength calibration or similar transformations to spectroscopy data
13+
* The operation combines two signals: uses Y values from one signal as the new X coordinates for another signal's Y values
14+
* Unlike X-Y mode (which resamples and interpolates), this operation directly uses Y arrays without interpolation, preserving exact calibration values
15+
* Requires both signals to have the same number of points - raises clear error message if sizes don't match
16+
* Automatically transfers metadata: X axis label/unit taken from calibration signal's Y label/unit
17+
* Menu location: Processing > Axis transformation > "Replace X by other signal's Y"
18+
* This closes [Issue #273](https://github.com/datalab-platform/datalab/issues/273) - Missing signal axis calibration: no way to replace X with Y from another signal
19+
20+
**X-Y mode:**
21+
22+
* The X-Y mode processing operation for signals has been moved to Processing > Axis transformation > "X-Y mode" for better discoverability
23+
* The nuance between X-Y mode (which resamples/interpolates) and the new "Replace X by other signal's Y" operation has been clarified in documentation
24+
925
**Lock LUT setting persistence:**
1026

1127
* Fixed "Lock LUT range when updating data" setting not persisting in Settings > Visualization > Images > Default Image visualization settings

datalab/gui/actionhandler.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,9 @@ def cra_fit(title, fitdlgfunc, tip: str | None = None):
12691269
with self.new_menu(_("Axis transformation")):
12701270
self.action_for("transpose")
12711271
self.action_for("reverse_x")
1272-
self.action_for("to_cartesian")
1272+
self.action_for("replace_x_by_other_y")
1273+
self.action_for("xy_mode")
1274+
self.action_for("to_cartesian", separator=True)
12731275
self.action_for("to_polar")
12741276
with self.new_menu(_("Frequency filters"), icon_name="highpass.svg"):
12751277
self.action_for("lowpass")
@@ -1364,7 +1366,6 @@ def cra_fit(title, fitdlgfunc, tip: str | None = None):
13641366
separator=True,
13651367
tip=_("Compute all stability features"),
13661368
)
1367-
self.action_for("xy_mode", separator=True)
13681369

13691370
# MARK: ANALYSIS
13701371
with self.new_category(ActionCategory.ANALYSIS):

datalab/gui/processor/signal.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,16 @@ def register_operations(self) -> None:
164164
icon_name="convolution.svg",
165165
obj2_name=_("signal to convolve with"),
166166
)
167+
self.register_2_to_1(
168+
sips.replace_x_by_other_y,
169+
_("Replace X by other signal's Y"),
170+
comment=_(
171+
"Replace X coordinates using Y values from another signal.\n"
172+
"Useful for calibration: plot data vs wavelength scale."
173+
),
174+
obj2_name=_("signal providing Y values for X axis"),
175+
skip_xarray_compat=True,
176+
)
167177
self.register_2_to_1(
168178
sips.deconvolution,
169179
_("Deconvolution"),

datalab/locale/fr/LC_MESSAGES/datalab.po

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ msgid ""
66
msgstr ""
77
"Project-Id-Version: datalab\n"
88
"Report-Msgid-Bugs-To: p.raybaut@codra.fr\n"
9-
"POT-Creation-Date: 2025-11-29 16:49+0100\n"
9+
"POT-Creation-Date: 2025-12-03 12:01+0100\n"
1010
"PO-Revision-Date: 2025-05-22 15:46+0200\n"
1111
"Last-Translator: Christophe Debonnel <c.debonnel@codra.fr>\n"
1212
"Language: fr\n"
@@ -1891,6 +1891,19 @@ msgstr "Intégrale"
18911891
msgid "signal to convolve with"
18921892
msgstr "signal pour la convolution"
18931893

1894+
msgid "Replace X by other signal's Y"
1895+
msgstr "Remplacer X par le Y d'un autre signal"
1896+
1897+
msgid ""
1898+
"Replace X coordinates using Y values from another signal.\n"
1899+
"Useful for calibration: plot data vs wavelength scale."
1900+
msgstr ""
1901+
"Remplacer les coordonnées X en utilisant les valeurs Y d'un autre signal.\n"
1902+
"Utile pour l'étalonnage : tracer des données en fonction d'une échelle de longueurs d'onde."
1903+
1904+
msgid "signal providing Y values for X axis"
1905+
msgstr "signal fournissant les valeurs Y pour l'axe X"
1906+
18941907
msgid "signal to deconvolve with"
18951908
msgstr "signal pour la déconvolution"
18961909

doc/features/signal/menu_processing.rst

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,48 @@ Reverse X-axis
5151

5252
Create a new signal which is the result of reversing X data.
5353

54+
Replace X by other signal's Y
55+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56+
57+
Create a new signal by combining two signals, using Y values from the second signal
58+
as X coordinates for the first signal's Y values.
59+
60+
This feature is particularly useful for calibration scenarios, such as:
61+
62+
- Applying wavelength calibration to spectroscopy data
63+
- Using a calibrated reference signal to rescale measurement data
64+
- Combining signals where one contains calibration points
65+
66+
The two signals must have the same number of points. The operation directly uses
67+
the Y arrays without interpolation.
68+
69+
.. list-table::
70+
:header-rows: 1
71+
:widths: 40, 60
72+
73+
* - Input
74+
- Description
75+
* - Signal 1
76+
- Provides the Y data for the output signal
77+
* - Signal 2
78+
- Provides the Y data that becomes the X coordinates of the output signal
79+
80+
X-Y mode
81+
~~~~~~~~
82+
83+
Create a new signal by simulating the X-Y mode of an oscilloscope.
84+
85+
This operation plots one signal as a function of another by:
86+
87+
1. Finding the overlapping X range between both signals
88+
2. Resampling both signals onto a common X grid within that overlap
89+
3. Using the resampled Y values as coordinates (first signal's Y as X, second signal's Y as Y)
90+
91+
.. note::
92+
93+
This is different from "Replace X by other signal's Y" as it performs interpolation to handle signals
94+
with different X arrays.
95+
5496
Convert to Cartesian coordinates
5597
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5698

@@ -481,9 +523,3 @@ The following stability analysis methods are available:
481523
.. note::
482524

483525
The "All stability features" option allows to compute all stability analysis methods at once.
484-
485-
486-
X-Y Mode
487-
^^^^^^^^
488-
489-
Simulate the X-Y mode of an oscilloscope.

doc/intro/keyfeatures.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ Signal Image Feature
6161
✓ ✓ Linear calibration
6262
✓ ✓ Normalization, Clipping, Offset correction
6363
.. Reverse X-axis
64+
.. Replace X by other signal's Y (calibration)
65+
.. X-Y mode
6466
.. ✓ Thresholding (manual, Otsu...)
6567
✓ ✓ Gaussian filter, Wiener filter
6668
✓ ✓ Moving average, moving median
6769
✓ ✓ FFT, inverse FFT, Power/Phase/Magnitude spectrum, Power Spectral Density
6870
.. Interpolation, resampling
6971
.. Detrending
70-
.. X-Y mode
7172
.. Interactive fit: Gauss, Lorentz, Voigt, polynomial, CDF...
7273
.. Interactive multigaussian fit
7374
.. Frequency filters (low-pass, high-pass, band-pass, band-stop)

doc/locale/fr/LC_MESSAGES/changelog.po

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: DataLab \n"
99
"Report-Msgid-Bugs-To: \n"
10-
"POT-Creation-Date: 2025-11-30 15:30+0100\n"
10+
"POT-Creation-Date: 2025-12-03 12:01+0100\n"
1111
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1212
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313
"Language: fr\n"
@@ -30,6 +30,42 @@ msgstr "DataLab Version 1.0.2 (non publiée)"
3030
msgid "🛠️ Bug Fixes"
3131
msgstr "🛠️ Correctifs"
3232

33+
msgid "**Signal axis calibration - Replace X by other signal's Y:**"
34+
msgstr "**Calibration de l'axe des signaux - Remplacer X par le Y d'un autre signal :**"
35+
36+
msgid "Added new \"Replace X by other signal's Y\" operation in Processing > Axis transformation menu for signal calibration workflows"
37+
msgstr "Ajout de la nouvelle opération \"Remplacer X par le Y d'un autre signal\" dans le menu Traitement > Transformation d'axe pour les flux de travail de calibration des signaux"
38+
39+
msgid "Addresses critical missing functionality reported by users who needed to apply wavelength calibration or similar transformations to spectroscopy data"
40+
msgstr "Répond à une fonctionnalité critique manquante signalée par les utilisateurs qui avaient besoin d'appliquer une calibration en longueur d'onde ou des transformations similaires aux données de spectroscopie"
41+
42+
msgid "The operation combines two signals: uses Y values from one signal as the new X coordinates for another signal's Y values"
43+
msgstr "L'opération combine deux signaux : elle utilise les valeurs Y d'un signal comme nouvelles coordonnées X pour les valeurs Y d'un autre signal"
44+
45+
msgid "Unlike X-Y mode (which resamples and interpolates), this operation directly uses Y arrays without interpolation, preserving exact calibration values"
46+
msgstr "Contrairement au mode X-Y (qui rééchantillonne et interpole), cette opération utilise directement les tableaux Y sans interpolation, préservant ainsi les valeurs de calibration exactes"
47+
48+
msgid "Requires both signals to have the same number of points - raises clear error message if sizes don't match"
49+
msgstr "Nécessite que les deux signaux aient le même nombre de points - affiche un message d'erreur clair si les tailles ne correspondent pas"
50+
51+
msgid "Automatically transfers metadata: X axis label/unit taken from calibration signal's Y label/unit"
52+
msgstr "Transfert automatique des métadonnées : l'étiquette/unité de l'axe X est prise à partir de l'étiquette/unité Y du signal de calibration"
53+
54+
msgid "Menu location: Processing > Axis transformation > \"Replace X by other signal's Y\""
55+
msgstr "Emplacement dans le menu : Traitement > Transformation d'axe > \"Remplacer X par le Y d'un autre signal\""
56+
57+
msgid "This closes [Issue #273](https://github.com/datalab-platform/datalab/issues/273) - Missing signal axis calibration: no way to replace X with Y from another signal"
58+
msgstr "Ceci clôture [Issue #273](https://github.com/datalab-platform/datalab/issues/273) - Calibration de l'axe des signaux manquante : aucun moyen de remplacer X par Y d'un autre signal"
59+
60+
msgid "**X-Y mode:**"
61+
msgstr "**Mode X-Y :**"
62+
63+
msgid "The X-Y mode processing operation for signals has been moved to Processing > Axis transformation > \"X-Y mode\" for better discoverability"
64+
msgstr "Le traitement Mode X-Y pour les signaux a été déplacé vers Traitement > Transformation des axes > \"Mode X-Y\" pour une meilleure découvrabilité"
65+
66+
msgid "The nuance between X-Y mode (which resamples/interpolates) and the new \"Replace X by other signal's Y\" operation has been clarified in documentation"
67+
msgstr "La nuance entre le mode X-Y (qui rééchantillonne/interpole) et la nouvelle opération \"Remplacer X par le Y d'un autre signal\" a été clarifiée dans la documentation"
68+
3369
msgid "**Lock LUT setting persistence:**"
3470
msgstr "**Persistance du paramètre de verrouillage de la LUT :**"
3571

doc/locale/fr/LC_MESSAGES/features/signal/menu_processing.po

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: DataLab \n"
1010
"Report-Msgid-Bugs-To: \n"
11-
"POT-Creation-Date: 2025-10-27 18:12+0100\n"
11+
"POT-Creation-Date: 2025-12-03 11:35+0100\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414
"Language: fr\n"
@@ -75,6 +75,66 @@ msgstr "Inverser l'axe des X"
7575
msgid "Create a new signal which is the result of reversing X data."
7676
msgstr "Crée un signal à partir des données inversées de l'axe des X du signal sélectionné."
7777

78+
msgid "Replace X by other signal's Y"
79+
msgstr "Remplacer X par le Y d'un autre signal"
80+
81+
msgid "Create a new signal by combining two signals, using Y values from the second signal as X coordinates for the first signal's Y values."
82+
msgstr "Crée un nouveau signal en combinant deux signaux, en utilisant les valeurs Y du second signal comme coordonnées X pour les valeurs Y du premier signal."
83+
84+
msgid "This feature is particularly useful for calibration scenarios, such as:"
85+
msgstr "Cette fonctionnalité est particulièrement utile pour les scénarios d'étalonnage, tels que :"
86+
87+
msgid "Applying wavelength calibration to spectroscopy data"
88+
msgstr "Appliquer un étalonnage en longueur d'onde aux données de spectroscopie"
89+
90+
msgid "Using a calibrated reference signal to rescale measurement data"
91+
msgstr "Utiliser un signal de référence étalonné pour recalibrer les données de mesure"
92+
93+
msgid "Combining signals where one contains calibration points"
94+
msgstr "Combiner des signaux où l'un contient des points d'étalonnage"
95+
96+
msgid "The two signals must have the same number of points. The operation directly uses the Y arrays without interpolation."
97+
msgstr "Les deux signaux doivent avoir le même nombre de points. L'opération utilise directement les tableaux Y sans interpolation."
98+
99+
msgid "Input"
100+
msgstr "Entrée"
101+
102+
msgid "Description"
103+
msgstr "Description"
104+
105+
msgid "Signal 1"
106+
msgstr "Signal 1"
107+
108+
msgid "Provides the Y data for the output signal"
109+
msgstr "Fournit les données Y pour le signal de sortie"
110+
111+
msgid "Signal 2"
112+
msgstr "Signal 2"
113+
114+
msgid "Provides the Y data that becomes the X coordinates of the output signal"
115+
msgstr "Fournit les données Y qui deviennent les coordonnées X du signal de sortie"
116+
117+
msgid "X-Y mode"
118+
msgstr "Mode X-Y"
119+
120+
msgid "Create a new signal by simulating the X-Y mode of an oscilloscope."
121+
msgstr "Crée un nouveau signal en simulant le mode X-Y d'un oscilloscope."
122+
123+
msgid "This operation plots one signal as a function of another by:"
124+
msgstr "Cette opération trace un signal en fonction d'un autre en :"
125+
126+
msgid "Finding the overlapping X range between both signals"
127+
msgstr "Trouvant la plage X qui se chevauche entre les deux signaux"
128+
129+
msgid "Resampling both signals onto a common X grid within that overlap"
130+
msgstr "Rééchantillonnant les deux signaux sur une grille X commune dans ce chevauchement"
131+
132+
msgid "Using the resampled Y values as coordinates (first signal's Y as X, second signal's Y as Y)"
133+
msgstr "Utilisant les valeurs Y rééchantillonnées comme coordonnées (Y du premier signal comme X, Y du second signal comme Y)"
134+
135+
msgid "This is different from \"Replace X by other signal's Y\" as it performs interpolation to handle signals with different X arrays."
136+
msgstr "Ceci est différent de \"Remplacer X par le Y d'un autre signal\" car il effectue une interpolation pour gérer les signaux avec des tableaux X différents."
137+
78138
msgid "Convert to Cartesian coordinates"
79139
msgstr "Convertir en coordonnées cartésiennes"
80140

@@ -108,7 +168,6 @@ msgstr "Normalisation"
108168
msgid "Maximum"
109169
msgstr "Maximum"
110170

111-
#, python-brace-format
112171
msgid ":math:`y_{1}= \\dfrac{y_{0}}{\\max\\left(y_{0}\\right)}`"
113172
msgstr ""
114173

@@ -157,9 +216,6 @@ msgstr "Génère de nouveaux signaux en ajoutant le même bruit à chaque signal
157216
msgid "Noise"
158217
msgstr "Bruit"
159218

160-
msgid "Description"
161-
msgstr "Description"
162-
163219
msgid "Gaussian"
164220
msgstr "Gaussien"
165221

@@ -786,9 +842,3 @@ msgstr "Dérivée de la déviation d'Allan, quantifie la stabilité en termes de
786842

787843
msgid "The \"All stability features\" option allows to compute all stability analysis methods at once."
788844
msgstr "L'option \"Toutes les analyses de stabilité\" permet de calculer toutes les méthodes d'analyse de stabilité en une seule fois."
789-
790-
msgid "X-Y Mode"
791-
msgstr "Mode XY"
792-
793-
msgid "Simulate the X-Y mode of an oscilloscope."
794-
msgstr "Simuler le mode XY d'un oscilloscope."

doc/locale/fr/LC_MESSAGES/intro/keyfeatures.po

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: DataLab \n"
1010
"Report-Msgid-Bugs-To: \n"
11-
"POT-Creation-Date: 2025-09-10 10:01+0200\n"
11+
"POT-Creation-Date: 2025-12-03 11:35+0100\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -140,6 +140,12 @@ msgstr "Normalisation, rognage, correction de décalage"
140140
msgid "Reverse X-axis"
141141
msgstr "Inversion de l'axe X"
142142

143+
msgid "Replace X by other signal's Y (calibration)"
144+
msgstr "Remplacer X par le Y d'un autre signal (calibration)"
145+
146+
msgid "X-Y mode"
147+
msgstr "Mode X-Y"
148+
143149
msgid "Thresholding (manual, Otsu...)"
144150
msgstr "Seuillage (manuel, Otsu...)"
145151

@@ -158,9 +164,6 @@ msgstr "Interpolation, rééchantillonnage"
158164
msgid "Detrending"
159165
msgstr "Elimination de tendance"
160166

161-
msgid "X-Y mode"
162-
msgstr "Mode XY"
163-
164167
msgid "Interactive fit: Gauss, Lorentz, Voigt, polynomial, CDF..."
165168
msgstr "Ajustement interactif : Gauss, Lorentz, Voigt, polynôme, CDF..."
166169

0 commit comments

Comments
 (0)