Skip to content

Commit 610a4c4

Browse files
committed
Merge branch 'develop'
# Conflicts: # cdl/core/model/base.py
2 parents 2135c15 + ee5bfa5 commit 610a4c4

File tree

86 files changed

+5277
-3082
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+5277
-3082
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ jobs:
2121
strategy:
2222
fail-fast: false
2323
matrix:
24-
python-version: ["3.8", "3.12"]
24+
python-version: ["3.9", "3.12"]
2525

2626
steps:
27-
- uses: actions/checkout@v3
27+
- uses: actions/checkout@v4
2828
- name: Set up Python ${{ matrix.python-version }}
29-
uses: actions/setup-python@v3
29+
uses: actions/setup-python@v5
3030
with:
3131
python-version: ${{ matrix.python-version }}
3232
- name: Install dependencies

.vscode/launch.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
],
2323
"env": {
2424
// "DEBUG": "1",
25-
"LANG": "en",
25+
// "LANG": "en",
2626
// "QT_COLOR_MODE": "light",
2727
}
2828
},
@@ -61,7 +61,7 @@
6161
// "1000"
6262
],
6363
"env": {
64-
// "DEBUG": "1",
64+
"DEBUG": "1",
6565
// "TEST_SEGFAULT_ERROR": "1",
6666
"LANG": "en",
6767
"QT_COLOR_MODE": "light",
@@ -84,7 +84,7 @@
8484
"--unattended",
8585
],
8686
"env": {
87-
// "DEBUG": "1",
87+
"DEBUG": "1",
8888
// The `CDL_DATA` environment variable is set here just for checking
8989
// that the data path is not added twice to the test data path list:
9090
"CDL_DATA": "${workspaceFolder}/cdl/data/tests",

.vscode/tasks.json

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -288,34 +288,6 @@
288288
"clear": false
289289
}
290290
},
291-
{
292-
"label": "Upgrade PlotPyStack packages (Python 3.8)",
293-
"type": "shell",
294-
"command": "cmd",
295-
"args": [
296-
"/c",
297-
"upgrade_stack.bat"
298-
],
299-
"options": {
300-
"cwd": "scripts",
301-
"env": {
302-
"PYTHON": "${env:CDL_PYTHONEXE_PY38}",
303-
"UNATTENDED": "1"
304-
}
305-
},
306-
"group": {
307-
"kind": "build",
308-
"isDefault": true
309-
},
310-
"presentation": {
311-
"echo": true,
312-
"reveal": "always",
313-
"focus": false,
314-
"panel": "shared",
315-
"showReuseMessage": true,
316-
"clear": false
317-
}
318-
},
319291
{
320292
"label": "Clean Up",
321293
"type": "shell",
@@ -638,73 +610,6 @@
638610
"Create installer"
639611
]
640612
},
641-
{
642-
"label": "Create Windows 7 executable",
643-
"type": "shell",
644-
"command": "cmd",
645-
"options": {
646-
"cwd": "scripts",
647-
"env": {
648-
"PYTHON": "${env:CDL_PYTHONEXE_PY38}",
649-
"RELEASE": "1",
650-
"UNATTENDED": "1"
651-
}
652-
},
653-
"args": [
654-
"/c",
655-
"build_exe.bat"
656-
],
657-
"problemMatcher": [],
658-
"group": {
659-
"kind": "build",
660-
"isDefault": true
661-
},
662-
"presentation": {
663-
"echo": true,
664-
"reveal": "always",
665-
"focus": false,
666-
"panel": "shared",
667-
"showReuseMessage": true,
668-
"clear": true
669-
}
670-
},
671-
{
672-
"label": "New Windows 7 release",
673-
"type": "shell",
674-
"command": "cmd",
675-
"args": [
676-
"/c",
677-
"release_win7.bat"
678-
],
679-
"options": {
680-
"cwd": "scripts",
681-
"env": {
682-
"PYTHON": "${env:CDL_PYTHONEXE_PY38}",
683-
"RELEASE": "1",
684-
"UNATTENDED": "1"
685-
}
686-
},
687-
"problemMatcher": [],
688-
"group": {
689-
"kind": "build",
690-
"isDefault": true
691-
},
692-
"presentation": {
693-
"echo": true,
694-
"reveal": "always",
695-
"focus": false,
696-
"panel": "shared",
697-
"showReuseMessage": true,
698-
"clear": true
699-
},
700-
"dependsOrder": "sequence",
701-
"dependsOn": [
702-
"Clean Up",
703-
"Upgrade PlotPyStack packages (Python 3.8)",
704-
"Create Windows 7 executable",
705-
"Create installer"
706-
]
707-
},
708613
{
709614
"label": "Run _tests_.bat",
710615
"type": "shell",

CHANGELOG.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,41 @@
22

33
See DataLab [roadmap page](https://datalab-platform.com/en/contributing/roadmap.html) for future and past milestones.
44

5+
## DataLab Version 0.18.0 ##
6+
7+
ℹ️ General information:
8+
9+
* PlotPy v2.7 is required for this release.
10+
* Dropped support for Python 3.8.
11+
* Python 3.13 is not supported yet, due to the fact that some dependencies are not compatible with this version.
12+
13+
💥 New features and enhancements:
14+
15+
* New operation mode feature:
16+
* Added "Operation mode" feature to the "Processing" tab in the "Settings" dialog box
17+
* This feature allows to choose between "single" and "pairwise" operation modes for all basic operations (addition, subtraction, multiplication, division, etc.):
18+
* "Single" mode: single operand mode (default mode: the operation is done on each object independently)
19+
* "Pairwise" mode: pairwise operand mode (the operation is done on each pair of objects)
20+
* This applies to both signals and images, and to computations taking *N* inputs
21+
* Computations taking *N* inputs are the ones where:
22+
* *N(>=2)* objects in give *N* objects out
23+
* *N(>=1)* object(s) + 1 object in give N objects out
24+
25+
* New ROI (Region Of Interest) features:
26+
* New polygonal ROI feature
27+
* Complete redesign of the ROI editor user interfaces, improving ergonomics and consistency with the rest of the application
28+
* Major internal refactoring of the ROI system to make it more robust (more tests) and easier to maintain
29+
30+
* Implemented [Issue #102](https://github.com/DataLab-Platform/DataLab/issues/102) - Launch DataLab using `datalab` instead of `cdl`. Note that the `cdl` command is still available for backward compatibility.
31+
32+
* Implemented [Issue #101](https://github.com/DataLab-Platform/DataLab/issues/101) - Configuration: set default image interpolation to anti-aliasing (`5` instead of `0` for nearest). This change is motivated by the fact that a performance improvement was made in PlotPy v2.7 on Windows, which allows to use anti-aliasing interpolation by default without a significant performance impact.
33+
34+
* Implemented [Issue #100](https://github.com/DataLab-Platform/DataLab/issues/100) - Use the same installer and executable on Windows 7 SP1, 8, 10, 11. Before this change, a specific installer was required for Windows 7 SP1, due to the fact that Python 3.9 and later versions are not supported on this platform. A workaround was implemented to make DataLab work on Windows 7 SP1 with Python 3.9.
35+
36+
🛠️ Bug fixes:
37+
38+
* Fixed [Issue #103](https://github.com/DataLab-Platform/DataLab/issues/103) - `proxy.add_annotations_from_items`: circle shape color seems to be ignored.
39+
540
## DataLab Version 0.17.1 ##
641

742
ℹ️ PlotPy v2.6.2 is required for this release.
@@ -492,7 +527,7 @@ NumPy 2.0 support has been added with this release.
492527
* Circle and ellipse results now also show area (A)
493528
* Added "Plot results" entry in "Analysis" menu:
494529
* This feature allows to plot analysis results (1D or 2D)
495-
* It creates a new signal with X and Y axes corresponding to user-defined parameters (e.g. X = indexes and Y = radius for circle results)
530+
* It creates a new signal with X and Y axes corresponding to user-defined parameters (e.g. X = indices and Y = radius for circle results)
496531
* Increased default width of the object selection dialog box:
497532
* The object selection dialog box is now wider by default, so that the full signal/image/group titles may be more easily readable
498533
* Delete metadata feature:
@@ -544,9 +579,9 @@ NumPy 2.0 support has been added with this release.
544579

545580
* Fixed [Issue #29](https://github.com/DataLab-Platform/DataLab/issues/29) - Polynomial fit error: `QDialog [...] argument 1 has an unexpected type 'SignalProcessor'`
546581
* Image ROI extraction feature:
547-
* Before this release, when extracting a single circular ROI from an image with the "Extract all regions of interest into a single image object" option enabled, the result was a single image without the ROI mask (the ROI mask was only available when extracting ROI with the option disabled)
582+
* Before this release, when extracting a single circular ROI from an image with the "Extract all ROIs into a single image object" option enabled, the result was a single image without the ROI mask (the ROI mask was only available when extracting ROI with the option disabled)
548583
* This was leading to an unexpected behavior, because one could interpret the result (a square image without the ROI mask) as the result of a single rectangular ROI
549-
* Now, when extracting a single circular ROI from an image with the "Extract all regions of interest into a single image object" option enabled, the result is a single image with the ROI mask (as if the option was disabled)
584+
* Now, when extracting a single circular ROI from an image with the "Extract all ROIs into a single image object" option enabled, the result is a single image with the ROI mask (as if the option was disabled)
550585
* This fixes [Issue #31](https://github.com/DataLab-Platform/DataLab/issues/31) - Single circular ROI extraction: automatically switch to `extract_single_roi` function
551586
* Analysis on circular ROI:
552587
* Before this release, when running computations on a circular ROI, the results were unexpected in terms of coordinates (results seemed to be computed in a region located above the actual ROI).
@@ -640,7 +675,7 @@ NumPy 2.0 support has been added with this release.
640675
🛠️ Bug fixes:
641676

642677
* Region of interest (ROI) extraction feature for images:
643-
* ROI extraction was not working properly when the "Extract all regions of interest into a single image object" option was enabled if there was only one defined ROI. The result was an image positioned at the origin (0, 0) instead of the expected position (x0, y0) and the ROI rectangle itself was not removed as expected. This is now fixed (see [Issue #6](https://github.com/DataLab-Platform/DataLab/issues/6) - 'Extract multiple ROI' feature: unexpected result for a single ROI)
678+
* ROI extraction was not working properly when the "Extract all ROIs into a single image object" option was enabled if there was only one defined ROI. The result was an image positioned at the origin (0, 0) instead of the expected position (x0, y0) and the ROI rectangle itself was not removed as expected. This is now fixed (see [Issue #6](https://github.com/DataLab-Platform/DataLab/issues/6) - 'Extract multiple ROI' feature: unexpected result for a single ROI)
644679
* ROI rectangles with negative coordinates were not properly handled: ROI extraction was raising a `ValueError` exception, and the image mask was not displayed properly. This is now fixed (see [Issue #7](https://github.com/DataLab-Platform/DataLab/issues/7) - Image ROI extraction: `ValueError: zero-size array to reduction operation minimum which has no identity`)
645680
* ROI extraction was not taking into account the pixel size (dx, dy) and the origin (x0, y0) of the image. This is now fixed (see [Issue #8](https://github.com/DataLab-Platform/DataLab/issues/8) - Image ROI extraction: take into account pixel size)
646681
* Macro-command console is now read-only:

DataLab.bat

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ for %%a in ("%CDL_PYTHONEXE%") do set "p_dir=%%~dpa"
33
for %%a in (%p_dir:~0,-1%) do set "WINPYDIRBASE=%%~dpa"
44
call %WINPYDIRBASE%scripts\env_for_icons.bat %*
55
cd/D %~dp0
6-
set PYTHONPATH=%cd%
6+
set ORIGINAL_PYTHONPATH=%PYTHONPATH%
7+
for /F "tokens=*" %%A in (.env) do (set %%A)
8+
set PYTHONPATH=%PYTHONPATH%;%ORIGINAL_PYTHONPATH%
79
start "" "%WINPYDIR%\pythonw.exe" cdl\start.pyw %*

DataLab.spec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ from PyInstaller.utils.hooks import collect_submodules, collect_data_files
77
all_hidden_imports = collect_submodules('cdl')
88
datas = collect_data_files('cdl') + [('cdl\\plugins', 'cdl\\plugins')]
99
datas += collect_data_files('guidata') + collect_data_files('plotpy')
10-
datas += collect_data_files('skimage')
1110

1211
a = Analysis(
1312
['cdl\\start.pyw'],

cdl/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import os
1515

16-
__version__ = "0.17.1"
16+
__version__ = "0.18.0"
1717
__docurl__ = __homeurl__ = "https://datalab-platform.com/"
1818
__supporturl__ = "https://github.com/DataLab-Platform/DataLab/issues/new/choose"
1919

cdl/algorithms/image.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,10 @@ def get_centroid_fourier(data: np.ndarray) -> tuple[float, float]:
258258

259259
row = (np.arctan(b / a) + rphi) * (rows - 1) / (2 * np.pi) + 1
260260
col = (np.arctan(d / c) + cphi) * (cols - 1) / (2 * np.pi) + 1
261-
try:
262-
row = int(row)
263-
except ma.MaskError:
264-
row = np.nan
265-
try:
266-
col = int(col)
267-
except ma.MaskError:
268-
col = np.nan
261+
262+
row = np.nan if row is np.ma.masked else row
263+
col = np.nan if col is np.ma.masked else col
264+
269265
return row, col
270266

271267

cdl/algorithms/signal.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def sort_frequencies(x: np.ndarray, y: np.ndarray) -> np.ndarray:
174174
# MARK: Peak detection -----------------------------------------------------------------
175175

176176

177-
def peak_indexes(
177+
def peak_indices(
178178
y, thres: float = 0.3, min_dist: int = 1, thres_abs: bool = False
179179
) -> np.ndarray:
180180
# Copyright (c) 2014 Lucas Hermann Negri
@@ -202,7 +202,7 @@ def peak_indexes(
202202
Returns
203203
-------
204204
ndarray
205-
Array containing the numeric indexes of the peaks that were detected
205+
Array containing the numeric indices of the peaks that were detected
206206
"""
207207
if isinstance(y, np.ndarray) and np.issubdtype(y.dtype, np.unsignedinteger):
208208
raise ValueError("y must be signed")
@@ -222,11 +222,11 @@ def peak_indexes(
222222
return np.array([])
223223

224224
if len(zeros):
225-
# compute first order difference of zero indexes
225+
# compute first order difference of zero indices
226226
zeros_diff = np.diff(zeros)
227227
# check when zeros are not chained together
228228
(zeros_diff_not_one,) = np.add(np.where(zeros_diff != 1), 1)
229-
# make an array of the chained zero indexes
229+
# make an array of the chained zero indices
230230
zero_plateaus = np.split(zeros, zeros_diff_not_one)
231231

232232
# fix if leftmost value in dy is zero
@@ -239,7 +239,7 @@ def peak_indexes(
239239
dy[zero_plateaus[-1]] = dy[zero_plateaus[-1][0] - 1]
240240
zero_plateaus.pop(-1)
241241

242-
# for each chain of zero indexes
242+
# for each chain of zero indices
243243
for plateau in zero_plateaus:
244244
median = np.median(plateau)
245245
# set leftmost values to leftmost non zero values
@@ -281,7 +281,7 @@ def xpeak(x: np.ndarray, y: np.ndarray) -> float:
281281
Returns:
282282
Peak X-position
283283
"""
284-
peaks = peak_indexes(y)
284+
peaks = peak_indices(y)
285285
if peaks.size == 1:
286286
return x[peaks[0]]
287287
return np.average(x, weights=y)
@@ -527,13 +527,13 @@ def fwhm(cls, amp, sigma):
527527

528528

529529
def find_nearest_zero_point_idx(y: np.ndarray) -> np.ndarray:
530-
"""Find the x indexes where the corresponding y is the closest to zero
530+
"""Find the x indices where the corresponding y is the closest to zero
531531
532532
Args:
533533
y: Y data
534534
535535
Returns:
536-
Indexes of the points right before or at zero crossing
536+
Indices of the points right before or at zero crossing
537537
"""
538538
xi = np.where((y[:-1] >= 0) & (y[1:] <= 0) | (y[:-1] <= 0) & (y[1:] >= 0))[0]
539539
return xi
@@ -856,13 +856,13 @@ def fwhm(
856856
dx, dy, base = np.max(x) - np.min(x), np.max(y) - np.min(y), np.min(y)
857857
sigma, mu = dx * 0.1, xpeak(x, y)
858858
if isinstance(xmin, float):
859-
indexes = np.where(x >= xmin)[0]
860-
x = x[indexes]
861-
y = y[indexes]
859+
indices = np.where(x >= xmin)[0]
860+
x = x[indices]
861+
y = y[indices]
862862
if isinstance(xmax, float):
863-
indexes = np.where(x <= xmax)[0]
864-
x = x[indexes]
865-
y = y[indexes]
863+
indices = np.where(x <= xmax)[0]
864+
x = x[indices]
865+
y = y[indices]
866866

867867
if method == "zero-crossing":
868868
hmax = dy * 0.5 + np.min(y)

cdl/computation/base.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -153,28 +153,6 @@ def get_suffix(self, data: np.ndarray) -> str:
153153
upper = gds.FloatItem(_("Upper limit"), default=None, check=False)
154154

155155

156-
class ROIDataParam(gds.DataSet):
157-
"""ROI Editor data"""
158-
159-
roidata = gds.FloatArrayItem(
160-
_("ROI data"),
161-
help=_(
162-
"For convenience, this item accepts a 2D NumPy array, a list of list "
163-
"of numbers, or None. In the end, the data is converted to a 2D NumPy "
164-
"array of integers (if not None)."
165-
),
166-
)
167-
singleobj = gds.BoolItem(
168-
_("Single object"),
169-
help=_("Whether to extract the ROI as a single object or not."),
170-
)
171-
172-
@property
173-
def is_empty(self) -> bool:
174-
"""Return True if there is no ROI"""
175-
return self.roidata is None or np.array(self.roidata).size == 0
176-
177-
178156
class FFTParam(gds.DataSet):
179157
"""FFT parameters"""
180158

@@ -304,8 +282,7 @@ def calc_resultproperties(
304282
raise ValueError("Values of labeledfuncs must be functions")
305283

306284
res = []
307-
roi_nb = 0 if obj.roi is None else obj.roi.shape[0]
308-
for i_roi in [None] + list(range(roi_nb)):
285+
for i_roi in [None] + list(obj.iterate_roi_indices()):
309286
data_roi = obj.get_data(i_roi)
310287
val_roi = -1 if i_roi is None else i_roi
311288
res.append([val_roi] + [fn(data_roi) for fn in labeledfuncs.values()])

0 commit comments

Comments
 (0)