Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
# Conflicts:
#	cdl/core/model/base.py
  • Loading branch information
PierreRaybaut committed Nov 14, 2024
2 parents 2135c15 + ee5bfa5 commit 610a4c4
Show file tree
Hide file tree
Showing 86 changed files with 5,277 additions and 3,082 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.12"]
python-version: ["3.9", "3.12"]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
6 changes: 3 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
],
"env": {
// "DEBUG": "1",
"LANG": "en",
// "LANG": "en",
// "QT_COLOR_MODE": "light",
}
},
Expand Down Expand Up @@ -61,7 +61,7 @@
// "1000"
],
"env": {
// "DEBUG": "1",
"DEBUG": "1",
// "TEST_SEGFAULT_ERROR": "1",
"LANG": "en",
"QT_COLOR_MODE": "light",
Expand All @@ -84,7 +84,7 @@
"--unattended",
],
"env": {
// "DEBUG": "1",
"DEBUG": "1",
// The `CDL_DATA` environment variable is set here just for checking
// that the data path is not added twice to the test data path list:
"CDL_DATA": "${workspaceFolder}/cdl/data/tests",
Expand Down
95 changes: 0 additions & 95 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -288,34 +288,6 @@
"clear": false
}
},
{
"label": "Upgrade PlotPyStack packages (Python 3.8)",
"type": "shell",
"command": "cmd",
"args": [
"/c",
"upgrade_stack.bat"
],
"options": {
"cwd": "scripts",
"env": {
"PYTHON": "${env:CDL_PYTHONEXE_PY38}",
"UNATTENDED": "1"
}
},
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
}
},
{
"label": "Clean Up",
"type": "shell",
Expand Down Expand Up @@ -638,73 +610,6 @@
"Create installer"
]
},
{
"label": "Create Windows 7 executable",
"type": "shell",
"command": "cmd",
"options": {
"cwd": "scripts",
"env": {
"PYTHON": "${env:CDL_PYTHONEXE_PY38}",
"RELEASE": "1",
"UNATTENDED": "1"
}
},
"args": [
"/c",
"build_exe.bat"
],
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": true
}
},
{
"label": "New Windows 7 release",
"type": "shell",
"command": "cmd",
"args": [
"/c",
"release_win7.bat"
],
"options": {
"cwd": "scripts",
"env": {
"PYTHON": "${env:CDL_PYTHONEXE_PY38}",
"RELEASE": "1",
"UNATTENDED": "1"
}
},
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": true
},
"dependsOrder": "sequence",
"dependsOn": [
"Clean Up",
"Upgrade PlotPyStack packages (Python 3.8)",
"Create Windows 7 executable",
"Create installer"
]
},
{
"label": "Run _tests_.bat",
"type": "shell",
Expand Down
43 changes: 39 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,41 @@

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

## DataLab Version 0.18.0 ##

ℹ️ General information:

* PlotPy v2.7 is required for this release.
* Dropped support for Python 3.8.
* Python 3.13 is not supported yet, due to the fact that some dependencies are not compatible with this version.

💥 New features and enhancements:

* New operation mode feature:
* Added "Operation mode" feature to the "Processing" tab in the "Settings" dialog box
* This feature allows to choose between "single" and "pairwise" operation modes for all basic operations (addition, subtraction, multiplication, division, etc.):
* "Single" mode: single operand mode (default mode: the operation is done on each object independently)
* "Pairwise" mode: pairwise operand mode (the operation is done on each pair of objects)
* This applies to both signals and images, and to computations taking *N* inputs
* Computations taking *N* inputs are the ones where:
* *N(>=2)* objects in give *N* objects out
* *N(>=1)* object(s) + 1 object in give N objects out

* New ROI (Region Of Interest) features:
* New polygonal ROI feature
* Complete redesign of the ROI editor user interfaces, improving ergonomics and consistency with the rest of the application
* Major internal refactoring of the ROI system to make it more robust (more tests) and easier to maintain

* 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.

* 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.

* 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.

🛠️ Bug fixes:

* Fixed [Issue #103](https://github.com/DataLab-Platform/DataLab/issues/103) - `proxy.add_annotations_from_items`: circle shape color seems to be ignored.

## DataLab Version 0.17.1 ##

ℹ️ PlotPy v2.6.2 is required for this release.
Expand Down Expand Up @@ -492,7 +527,7 @@ NumPy 2.0 support has been added with this release.
* Circle and ellipse results now also show area (A)
* Added "Plot results" entry in "Analysis" menu:
* This feature allows to plot analysis results (1D or 2D)
* 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)
* 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)
* Increased default width of the object selection dialog box:
* The object selection dialog box is now wider by default, so that the full signal/image/group titles may be more easily readable
* Delete metadata feature:
Expand Down Expand Up @@ -544,9 +579,9 @@ NumPy 2.0 support has been added with this release.

* Fixed [Issue #29](https://github.com/DataLab-Platform/DataLab/issues/29) - Polynomial fit error: `QDialog [...] argument 1 has an unexpected type 'SignalProcessor'`
* Image ROI extraction feature:
* 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)
* 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)
* 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
* 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)
* 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)
* This fixes [Issue #31](https://github.com/DataLab-Platform/DataLab/issues/31) - Single circular ROI extraction: automatically switch to `extract_single_roi` function
* Analysis on circular ROI:
* 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).
Expand Down Expand Up @@ -640,7 +675,7 @@ NumPy 2.0 support has been added with this release.
🛠️ Bug fixes:

* Region of interest (ROI) extraction feature for images:
* 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)
* 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)
* 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`)
* 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)
* Macro-command console is now read-only:
Expand Down
4 changes: 3 additions & 1 deletion DataLab.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ for %%a in ("%CDL_PYTHONEXE%") do set "p_dir=%%~dpa"
for %%a in (%p_dir:~0,-1%) do set "WINPYDIRBASE=%%~dpa"
call %WINPYDIRBASE%scripts\env_for_icons.bat %*
cd/D %~dp0
set PYTHONPATH=%cd%
set ORIGINAL_PYTHONPATH=%PYTHONPATH%
for /F "tokens=*" %%A in (.env) do (set %%A)
set PYTHONPATH=%PYTHONPATH%;%ORIGINAL_PYTHONPATH%
start "" "%WINPYDIR%\pythonw.exe" cdl\start.pyw %*
1 change: 0 additions & 1 deletion DataLab.spec
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ from PyInstaller.utils.hooks import collect_submodules, collect_data_files
all_hidden_imports = collect_submodules('cdl')
datas = collect_data_files('cdl') + [('cdl\\plugins', 'cdl\\plugins')]
datas += collect_data_files('guidata') + collect_data_files('plotpy')
datas += collect_data_files('skimage')

a = Analysis(
['cdl\\start.pyw'],
Expand Down
2 changes: 1 addition & 1 deletion cdl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import os

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

Expand Down
12 changes: 4 additions & 8 deletions cdl/algorithms/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,10 @@ def get_centroid_fourier(data: np.ndarray) -> tuple[float, float]:

row = (np.arctan(b / a) + rphi) * (rows - 1) / (2 * np.pi) + 1
col = (np.arctan(d / c) + cphi) * (cols - 1) / (2 * np.pi) + 1
try:
row = int(row)
except ma.MaskError:
row = np.nan
try:
col = int(col)
except ma.MaskError:
col = np.nan

row = np.nan if row is np.ma.masked else row
col = np.nan if col is np.ma.masked else col

return row, col


Expand Down
28 changes: 14 additions & 14 deletions cdl/algorithms/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def sort_frequencies(x: np.ndarray, y: np.ndarray) -> np.ndarray:
# MARK: Peak detection -----------------------------------------------------------------


def peak_indexes(
def peak_indices(
y, thres: float = 0.3, min_dist: int = 1, thres_abs: bool = False
) -> np.ndarray:
# Copyright (c) 2014 Lucas Hermann Negri
Expand Down Expand Up @@ -202,7 +202,7 @@ def peak_indexes(
Returns
-------
ndarray
Array containing the numeric indexes of the peaks that were detected
Array containing the numeric indices of the peaks that were detected
"""
if isinstance(y, np.ndarray) and np.issubdtype(y.dtype, np.unsignedinteger):
raise ValueError("y must be signed")
Expand All @@ -222,11 +222,11 @@ def peak_indexes(
return np.array([])

if len(zeros):
# compute first order difference of zero indexes
# compute first order difference of zero indices
zeros_diff = np.diff(zeros)
# check when zeros are not chained together
(zeros_diff_not_one,) = np.add(np.where(zeros_diff != 1), 1)
# make an array of the chained zero indexes
# make an array of the chained zero indices
zero_plateaus = np.split(zeros, zeros_diff_not_one)

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

# for each chain of zero indexes
# for each chain of zero indices
for plateau in zero_plateaus:
median = np.median(plateau)
# set leftmost values to leftmost non zero values
Expand Down Expand Up @@ -281,7 +281,7 @@ def xpeak(x: np.ndarray, y: np.ndarray) -> float:
Returns:
Peak X-position
"""
peaks = peak_indexes(y)
peaks = peak_indices(y)
if peaks.size == 1:
return x[peaks[0]]
return np.average(x, weights=y)
Expand Down Expand Up @@ -527,13 +527,13 @@ def fwhm(cls, amp, sigma):


def find_nearest_zero_point_idx(y: np.ndarray) -> np.ndarray:
"""Find the x indexes where the corresponding y is the closest to zero
"""Find the x indices where the corresponding y is the closest to zero
Args:
y: Y data
Returns:
Indexes of the points right before or at zero crossing
Indices of the points right before or at zero crossing
"""
xi = np.where((y[:-1] >= 0) & (y[1:] <= 0) | (y[:-1] <= 0) & (y[1:] >= 0))[0]
return xi
Expand Down Expand Up @@ -856,13 +856,13 @@ def fwhm(
dx, dy, base = np.max(x) - np.min(x), np.max(y) - np.min(y), np.min(y)
sigma, mu = dx * 0.1, xpeak(x, y)
if isinstance(xmin, float):
indexes = np.where(x >= xmin)[0]
x = x[indexes]
y = y[indexes]
indices = np.where(x >= xmin)[0]
x = x[indices]
y = y[indices]
if isinstance(xmax, float):
indexes = np.where(x <= xmax)[0]
x = x[indexes]
y = y[indexes]
indices = np.where(x <= xmax)[0]
x = x[indices]
y = y[indices]

if method == "zero-crossing":
hmax = dy * 0.5 + np.min(y)
Expand Down
25 changes: 1 addition & 24 deletions cdl/computation/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,28 +153,6 @@ def get_suffix(self, data: np.ndarray) -> str:
upper = gds.FloatItem(_("Upper limit"), default=None, check=False)


class ROIDataParam(gds.DataSet):
"""ROI Editor data"""

roidata = gds.FloatArrayItem(
_("ROI data"),
help=_(
"For convenience, this item accepts a 2D NumPy array, a list of list "
"of numbers, or None. In the end, the data is converted to a 2D NumPy "
"array of integers (if not None)."
),
)
singleobj = gds.BoolItem(
_("Single object"),
help=_("Whether to extract the ROI as a single object or not."),
)

@property
def is_empty(self) -> bool:
"""Return True if there is no ROI"""
return self.roidata is None or np.array(self.roidata).size == 0


class FFTParam(gds.DataSet):
"""FFT parameters"""

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

res = []
roi_nb = 0 if obj.roi is None else obj.roi.shape[0]
for i_roi in [None] + list(range(roi_nb)):
for i_roi in [None] + list(obj.iterate_roi_indices()):
data_roi = obj.get_data(i_roi)
val_roi = -1 if i_roi is None else i_roi
res.append([val_roi] + [fn(data_roi) for fn in labeledfuncs.values()])
Expand Down
Loading

0 comments on commit 610a4c4

Please sign in to comment.