diff --git a/.env.template b/.env.template index b06759ee2..d5fd29230 100644 --- a/.env.template +++ b/.env.template @@ -7,4 +7,6 @@ VENV_DIR= # Python path for development (sibling packages) PYTHONPATH=. # Locale (e.g. fr) -LANG= \ No newline at end of file +LANG= +# Debug mode (0 or 1) +DATALAB_DEBUG=0 \ No newline at end of file diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml index 1d590bdac..fb051a5b6 100644 --- a/.github/workflows/_build.yml +++ b/.github/workflows/_build.yml @@ -201,7 +201,7 @@ jobs: x11-utils xvfb \ texlive-latex-base texlive-latex-extra texlive-fonts-recommended \ texlive-fonts-extra texlive-lang-french texlive-xetex latexmk \ - fonts-symbola \ + fonts-noto-core fonts-noto-mono fonts-noto-extra \ imagemagick librsvg2-bin /sbin/start-stop-daemon --start --quiet \ --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background \ diff --git a/.github/workflows/release-rc.yml b/.github/workflows/release-rc.yml index 9f9ccab80..f19eabbcb 100644 --- a/.github/workflows/release-rc.yml +++ b/.github/workflows/release-rc.yml @@ -59,6 +59,8 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + id-token: write # required by attest-build-provenance (OIDC) + attestations: write # required by attest-build-provenance steps: - uses: actions/checkout@v4 @@ -85,6 +87,23 @@ jobs: name: msi-installer path: assets/msi + - name: Generate SHA256SUMS + run: | + cd assets + find dists msi pdfs -type f \ + \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.msi' -o -name '*.pdf' \) \ + -printf '%P\n' | sort | xargs -I{} sha256sum {} \ + > SHA256SUMS + cat SHA256SUMS + + - name: Attest build provenance + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + assets/dists/*.whl + assets/dists/*.tar.gz + assets/msi/*.msi + - name: Extract release notes run: | python scripts/ci_release_helpers.py release-notes \ @@ -105,3 +124,4 @@ jobs: assets/msi/*.msi assets/pdfs/DataLab_fr.pdf assets/pdfs/DataLab_en.pdf + assets/SHA256SUMS diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 777c22db5..a2a3a7cb8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -67,6 +67,8 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + id-token: write # required by attest-build-provenance (OIDC) + attestations: write # required by attest-build-provenance steps: - uses: actions/checkout@v4 @@ -93,6 +95,28 @@ jobs: name: msi-installer path: assets/msi + - name: Generate SHA256SUMS + # Single checksums file covering every artifact published in the + # release. Users verify with: `sha256sum -c SHA256SUMS`. + run: | + cd assets + find dists msi pdfs -type f \ + \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.msi' -o -name '*.pdf' \) \ + -printf '%P\n' | sort | xargs -I{} sha256sum {} \ + > SHA256SUMS + echo "--- SHA256SUMS ---" + cat SHA256SUMS + + - name: Attest build provenance + # Produces a Sigstore-backed attestation linking each artifact to + # this exact workflow run. Verifiable with `gh attestation verify`. + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + assets/dists/*.whl + assets/dists/*.tar.gz + assets/msi/*.msi + - name: Extract release notes run: | python scripts/ci_release_helpers.py release-notes \ @@ -114,6 +138,7 @@ jobs: assets/msi/*.msi assets/pdfs/DataLab_fr.pdf assets/pdfs/DataLab_en.pdf + assets/SHA256SUMS # --------------------------------------------------------------------------- # Build & deploy documentation (delegated to pages.yml). Non-blocking. diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 687e6003a..5f53aa7ed 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -372,29 +372,6 @@ "sphinx-intl build", ], }, - { - "label": "đŸ› ïž Generate doc assets", - "command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m guidata.utils.genreqs all; if ($?) { ${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} doc/update_validation_status.py }", - "options": { - "cwd": "${workspaceFolder}", - "statusbar": { - "hide": true, - }, - }, - "group": { - "kind": "build", - "isDefault": false, - }, - "presentation": { - "clear": true, - "echo": true, - "focus": false, - "panel": "dedicated", - "reveal": "always", - "showReuseMessage": true, - }, - "type": "shell", - }, { "label": "đŸ§Ș Coverage tests", "type": "shell", @@ -571,6 +548,30 @@ "clear": true, }, }, + { + "label": "📋 Refresh doc metadata", + "detail": "Regenerate requirements.txt + doc/requirements.rst (via guidata.utils.genreqs) and update Sigima validation status in the docs.", + "command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m guidata.utils.genreqs all; if ($?) { ${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} doc/update_validation_status.py }", + "options": { + "cwd": "${workspaceFolder}", + "statusbar": { + "hide": true, + }, + }, + "group": { + "kind": "build", + "isDefault": false, + }, + "presentation": { + "clear": true, + "echo": true, + "focus": false, + "panel": "dedicated", + "reveal": "always", + "showReuseMessage": true, + }, + "type": "shell", + }, { "label": "đŸ–Œïž Refresh doc screenshots", "detail": "Maintainer task: regenerate PNG screenshots under doc/images/ by launching DataLab for each language (fr + en). Commit the resulting diff in a dedicated 'docs: refresh screenshots' commit.", @@ -601,7 +602,7 @@ }, }, { - "label": "Create executable", + "label": "đŸ—ïž Create executable", "type": "shell", "command": "${command:python.interpreterPath}", "args": [ @@ -636,7 +637,7 @@ }, }, { - "label": "Create installer", + "label": "📩 Create installer", "type": "shell", "command": "${command:python.interpreterPath}", "args": [ @@ -670,7 +671,7 @@ }, }, { - "label": "Build PDF doc", + "label": "📘 Build PDF doc", "type": "shell", "command": "${command:python.interpreterPath}", "options": { @@ -706,7 +707,7 @@ }, "dependsOrder": "sequence", "dependsOn": [ - "đŸ› ïž Generate doc assets", + "📋 Refresh doc metadata", ], }, { @@ -803,7 +804,7 @@ }, "dependsOrder": "sequence", "dependsOn": [ - "đŸ› ïž Generate doc assets", + "📋 Refresh doc metadata", ], }, { @@ -919,8 +920,7 @@ }, "dependsOrder": "sequence", "dependsOn": [ - "đŸ› ïž Generate doc assets", - "Build PDF doc", + "📘 Build PDF doc", ], }, { @@ -958,8 +958,8 @@ "Upgrade Sigima/PlotPyStack", "📚 Compile translations", "Build Python packages", - "Create executable", - "Create installer", + "đŸ—ïž Create executable", + "📩 Create installer", ], }, { diff --git a/datalab/__init__.py b/datalab/__init__.py index b8a132d61..88986cb99 100644 --- a/datalab/__init__.py +++ b/datalab/__init__.py @@ -24,7 +24,7 @@ # this module is imported more than once, e.g. when running tests) pass -__version__ = "1.2.0" +__version__ = "1.2.1" __docurl__ = __homeurl__ = "https://datalab-platform.com/" __supporturl__ = "https://github.com/DataLab-Platform/DataLab/issues/new/choose" diff --git a/datalab/config.py b/datalab/config.py index 976e9568b..ce2032208 100644 --- a/datalab/config.py +++ b/datalab/config.py @@ -67,7 +67,7 @@ def get_config_app_name() -> str: APP_DESC = _("""DataLab is a generic signal and image processing platform""") APP_PATH = osp.dirname(__file__) -DEBUG = os.environ.get("DEBUG", "").lower() in ("1", "true") +DEBUG = os.environ.get("DATALAB_DEBUG", "").lower() in ("1", "true") if DEBUG: print("*** DEBUG mode *** [Reset configuration file, do not redirect std I/O]") diff --git a/datalab/control/baseproxy.py b/datalab/control/baseproxy.py index 638c2144b..1fcc404fc 100644 --- a/datalab/control/baseproxy.py +++ b/datalab/control/baseproxy.py @@ -380,6 +380,14 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]: List of selected objects uuids. """ + @abc.abstractmethod + def get_current_object_uuid(self) -> str | None: + """Return current object uuid in current panel. + + Returns: + UUID of the current object, or None if no object is current. + """ + @abc.abstractmethod def select_objects( self, @@ -815,6 +823,14 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]: """ return self._datalab.get_sel_object_uuids(include_groups) + def get_current_object_uuid(self) -> str | None: + """Return current object uuid in current panel. + + Returns: + UUID of the current object, or None if no object is current. + """ + return self._datalab.get_current_object_uuid() + def add_group( self, title: str, panel: str | None = None, select: bool = False ) -> None: diff --git a/datalab/control/remote.py b/datalab/control/remote.py index 5d8ba1cf0..c58110741 100644 --- a/datalab/control/remote.py +++ b/datalab/control/remote.py @@ -483,6 +483,15 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]: """ return self.win.get_sel_object_uuids(include_groups) + @remote_call + def get_current_object_uuid(self) -> str | None: + """Return current object uuid in current panel. + + Returns: + UUID of the current object, or None if no object is current. + """ + return self.win.get_current_object_uuid() + @remote_call def add_group( self, title: str, panel: str | None = None, select: bool = False diff --git a/datalab/data/logo/DataLab-Banner-150.png b/datalab/data/logo/DataLab-Banner-150.png index a8d09ee87..f47bc7cb6 100644 Binary files a/datalab/data/logo/DataLab-Banner-150.png and b/datalab/data/logo/DataLab-Banner-150.png differ diff --git a/datalab/data/logo/DataLab-Splash.png b/datalab/data/logo/DataLab-Splash.png index 08dd0c18e..3380f939e 100644 Binary files a/datalab/data/logo/DataLab-Splash.png and b/datalab/data/logo/DataLab-Splash.png differ diff --git a/datalab/data/logo/DataLab-watermark.png b/datalab/data/logo/DataLab-watermark.png index 57d5e8817..9b43ab549 100644 Binary files a/datalab/data/logo/DataLab-watermark.png and b/datalab/data/logo/DataLab-watermark.png differ diff --git a/datalab/env.py b/datalab/env.py index 3e2b5ac57..cc6c7735a 100644 --- a/datalab/env.py +++ b/datalab/env.py @@ -19,7 +19,7 @@ from guidata.env import ExecEnv as GuiDataExecEnv # We could import DEBUG from datalab.config, but is it really worth it? -DEBUG = os.environ.get("DEBUG", "").lower() in ("1", "true") +DEBUG = os.environ.get("DATALAB_DEBUG", "").lower() in ("1", "true") class VerbosityLevels(enum.Enum): diff --git a/datalab/gui/actionhandler.py b/datalab/gui/actionhandler.py index 59f16ef41..c36ea21dd 100644 --- a/datalab/gui/actionhandler.py +++ b/datalab/gui/actionhandler.py @@ -1320,6 +1320,7 @@ def cra_fit(title, fitdlgfunc, tip: str | None = None): self.action_for("reverse_x") self.action_for("replace_x_by_other_y") self.action_for("xy_mode") + self.action_for("calibration", separator=True) self.action_for("to_cartesian", separator=True) self.action_for("to_polar") with self.new_menu(_("Frequency filters"), icon_name="highpass.svg"): diff --git a/datalab/gui/docks.py b/datalab/gui/docks.py index 1c523ca28..7fcf20900 100644 --- a/datalab/gui/docks.py +++ b/datalab/gui/docks.py @@ -24,7 +24,6 @@ from typing import TYPE_CHECKING import numpy as np -import scipy.integrate as spt from guidata.configtools import get_icon, get_image_file_path from guidata.qthelpers import create_action, is_dark_theme from guidata.widgets.dockable import DockableWidget @@ -68,69 +67,29 @@ class CurveStatsToolFunctions: """Statistical functions for `CurveStatsTool` and `YRangeCursorTool`""" @classmethod - def set_labelfuncs(cls, statstool: CurveStatsTool) -> None: + def set_labelfuncs(cls, statstool: CurveStatsTool | YRangeCursorTool) -> None: """Set label functions for the statistics tool""" if isinstance(statstool, CurveStatsTool): - labelfuncs = ( - ("%g < x < %g", lambda *args: cls.nan_min_max(args[0])), - ("%g < y < %g", lambda *args: cls.nan_min_max(args[1])), - ("∆x=%g", lambda *args: cls.nan_delta(args[0])), - ("∆y=%g", lambda *args: cls.nan_delta(args[1])), - ("<y>=%g", lambda *args: cls.nan_mean(args[1])), - ("σ(y)=%g", lambda *args: cls.nan_std(args[1])), - ("∑(y)=%g", lambda *args: spt.trapezoid(args[1])), - ("∫ydx=%g
", lambda *args: spt.trapezoid(args[1], args[0])), - ("FWHM=%s", cls.fwhm_info), - ("∆xRISE 10-90=%s", cls.rise_time_info), - ( - "∆xRISE 20-80=%s", - lambda x, y: cls.rise_time_info(x, y, 0.2, 0.8), - ), - ("∆xFALL 90-10=%s", cls.fall_time_info), - ( - "∆xFALL 80-20=%s", - lambda x, y: cls.fall_time_info(x, y, 0.8, 0.2), - ), + labelfuncs = list(CurveStatsTool.LABELFUNCS) + labelfuncs[-1] = (labelfuncs[-1][0] + "
", labelfuncs[-1][1]) + labelfuncs.extend( + [ + ("FWHM=%s", cls.fwhm_info), + ("∆xRISE 10-90=%s", cls.rise_time_info), + ( + "∆xRISE 20-80=%s", + lambda x, y: cls.rise_time_info(x, y, 0.2, 0.8), + ), + ("∆xFALL 90-10=%s", cls.fall_time_info), + ( + "∆xFALL 80-20=%s", + lambda x, y: cls.fall_time_info(x, y, 0.8, 0.2), + ), + ] ) - else: # YRangeCursorTool - labelfuncs = ( - ("%g < y < %g", lambda ymin, ymax: (ymin, ymax)), - ("∆y=%g", lambda ymin, ymax: ymax - ymin), - ) - statstool.set_labelfuncs(labelfuncs) - - @staticmethod - def nan_min_max(arr: np.ndarray) -> tuple[float, float]: - """Return min/max tuple""" - with warnings.catch_warnings(): - warnings.simplefilter("ignore", RuntimeWarning) - min_val = np.nanmin(arr) - max_val = np.nanmax(arr) - return (min_val, max_val) - - @staticmethod - def nan_delta(arr: np.ndarray) -> float: - """Return delta value, ignoring NaNs""" - with warnings.catch_warnings(): - warnings.simplefilter("ignore", RuntimeWarning) - delta_val = np.nanmax(arr) - np.nanmin(arr) - return delta_val - - @staticmethod - def nan_mean(arr: np.ndarray) -> float: - """Return mean value, ignoring NaNs""" - with warnings.catch_warnings(): - warnings.simplefilter("ignore", RuntimeWarning) - mean_val = np.nanmean(arr) - return mean_val - - @staticmethod - def nan_std(arr: np.ndarray) -> float: - """Return standard deviation, ignoring NaNs""" - with warnings.catch_warnings(): - warnings.simplefilter("ignore", RuntimeWarning) - std_val = np.nanstd(arr) - return std_val + statstool.set_labelfuncs(tuple(labelfuncs)) + else: # YRangeCursorTool - use PlotPy's defaults as-is + statstool.set_labelfuncs(YRangeCursorTool.LABELFUNCS) @staticmethod def fwhm_info(x, y): diff --git a/datalab/gui/main.py b/datalab/gui/main.py index fee7dd5eb..45937f7b8 100644 --- a/datalab/gui/main.py +++ b/datalab/gui/main.py @@ -57,6 +57,8 @@ APP_NAME, DATAPATH, DEBUG, + PLOTPY_CONF, + PLOTPY_DEFAULTS, TEST_SEGFAULT_ERROR, Conf, _, @@ -409,6 +411,16 @@ def get_sel_object_uuids(self, include_groups: bool = False) -> list[str]: panel = self.__get_current_basedatapanel() return panel.objview.get_sel_object_uuids(include_groups) + @remote_controlled + def get_current_object_uuid(self) -> str | None: + """Return current object uuid in current panel. + + Returns: + UUID of the current object, or None if no object is current. + """ + panel = self.__get_current_basedatapanel() + return panel.objview.get_current_object_uuid() + @remote_controlled def add_group( self, @@ -2416,6 +2428,7 @@ def __update_color_mode(self, startup: bool = False) -> None: self.setUpdatesEnabled(False) plotpy_config.set_plotpy_color_mode(mode) + PLOTPY_CONF.update_defaults(PLOTPY_DEFAULTS) if self.console is not None: self.console.update_color_mode() diff --git a/datalab/gui/objectview.py b/datalab/gui/objectview.py index 1fd4891a5..0ead2133d 100644 --- a/datalab/gui/objectview.py +++ b/datalab/gui/objectview.py @@ -616,6 +616,11 @@ def get_current_object(self) -> SignalObj | ImageObj | None: return self.objmodel[oid] return None + def get_current_object_uuid(self) -> str | None: + """Return current object uuid, or None if current item is a group + or if no item is current""" + return self.get_current_item_id(object_only=True) + def set_current_object(self, obj: SignalObj | ImageObj) -> None: """Set current object""" self.set_current_item_id(get_uuid(obj)) diff --git a/datalab/gui/panel/base.py b/datalab/gui/panel/base.py index 60c95db76..9fde16514 100644 --- a/datalab/gui/panel/base.py +++ b/datalab/gui/panel/base.py @@ -2980,6 +2980,15 @@ def get_roi_editor_output( source_panel=self, size=self.get_dialog_size(), ) + # Propagate the source plot axis scales (e.g. log) to the ROI editor + # so that signals/images displayed with non-linear scales keep the same + # representation in the ROI editor dialog (see issue: ROI editor was + # always opening with default lin-lin scales). + src_plot = self.plothandler.plot + roi_editor.get_plot().set_scales( + src_plot.get_axis_scale("bottom"), + src_plot.get_axis_scale("left"), + ) if exec_dialog(roi_editor): return roi_editor.get_roieditor_results() return None diff --git a/datalab/locale/fr/LC_MESSAGES/datalab.po b/datalab/locale/fr/LC_MESSAGES/datalab.po index c590f1511..2b92ec46a 100644 --- a/datalab/locale/fr/LC_MESSAGES/datalab.po +++ b/datalab/locale/fr/LC_MESSAGES/datalab.po @@ -1054,7 +1054,7 @@ msgid "Parameters for function `%s`" msgstr "ParamĂštres pour la fonction `%s`" msgid "Created" -msgstr "CrĂ©ation de" +msgstr "Créé" msgid "Original object" msgstr "Objet original" @@ -1205,12 +1205,12 @@ msgstr "Supprimer les mĂ©tadonnĂ©es" msgid "Some selected objects have regions of interest.
Do you want to delete them as well?" msgstr "Certains objets sĂ©lectionnĂ©s ont des rĂ©gions d'intĂ©rĂȘt.
Souhaitez-vous les supprimer Ă©galement ?" -msgid "New group" -msgstr "Nouveau groupe" - msgid "Group name:" msgstr "Nom du groupe :" +msgid "New group" +msgstr "Nouveau groupe" + msgid "Rename object" msgstr "Renommer l'objet" @@ -2854,12 +2854,12 @@ msgstr "Cliquer sur OK pour terminer la dĂ©mo." msgid "Cancel" msgstr "Annuler" -msgid "Error:" -msgstr "Erreur:" - msgid "Context" msgstr "Contexte" +msgid "Error:" +msgstr "Erreur:" + #, python-format msgid "The file %s could not be read:" msgstr "Le fichier %s n'a pas pu ĂȘtre ouvert :" @@ -3040,18 +3040,18 @@ msgstr "DĂ©plier la sĂ©lection" msgid "HDF5 Browser" msgstr "Explorateur HDF5" -msgid "Size" -msgstr "Taille" - -msgid "Type" -msgstr "Type" - msgid "Value" msgstr "Valeur" msgid "Name" msgstr "Nom" +msgid "Size" +msgstr "Taille" + +msgid "Type" +msgstr "Type" + msgid "Unsupported data" msgstr "DonnĂ©es non prises en charge" diff --git a/datalab/tests/features/common/geometry_results_app_test.py b/datalab/tests/features/common/geometry_results_app_test.py index 9bd73d840..dc3cde07e 100644 --- a/datalab/tests/features/common/geometry_results_app_test.py +++ b/datalab/tests/features/common/geometry_results_app_test.py @@ -116,11 +116,20 @@ def test_geometry_results() -> None: with Conf.proc.keep_results.temp(keep_results): # Test merging result shapes (duplicate obj, then compute average): for panel in (win.signalpanel, win.imagepanel): - panel.objview.select_objects((2,)) + src_obj = panel[2] + group_id = panel.objmodel.get_object_group_id(src_obj) + panel.objview.select_objects([src_obj]) panel.duplicate_object() - panel.objview.select_objects((2, len(panel))) + # The duplicate is the last object of the source object's group + duplicate = panel.objmodel[ + panel.objmodel.get_group_object_ids(group_id)[-1] + ] + panel.objview.select_objects([src_obj, duplicate]) panel.processor.run_feature("average") - last_obj = panel[len(panel)] + # The average result is the last object of the source group + last_obj = panel.objmodel[ + panel.objmodel.get_group_object_ids(group_id)[-1] + ] if keep_results: __check_geometry_results_merge(panel[2], last_obj) if panel is win.imagepanel: diff --git a/datalab/tests/features/control/remoteclient_unit.py b/datalab/tests/features/control/remoteclient_unit.py index 352974ca5..c433c2772 100644 --- a/datalab/tests/features/control/remoteclient_unit.py +++ b/datalab/tests/features/control/remoteclient_unit.py @@ -36,6 +36,7 @@ def multiple_commands(remote: RemoteProxy): area = rect.get_rect() remote.add_annotations_from_items([rect]) uuid = remote.get_sel_object_uuids()[0] + assert remote.get_current_object_uuid() == uuid items = remote.get_object_shapes() assert len(items) == 1 and items[0].get_rect() == area remote.add_label_with_title(f"Image uuid: {uuid}") diff --git a/doc/_static/DataLab-Frontpage.png b/doc/_static/DataLab-Frontpage.png index 0f924da98..4618caaf8 100644 Binary files a/doc/_static/DataLab-Frontpage.png and b/doc/_static/DataLab-Frontpage.png differ diff --git a/doc/_static/DataLab-Title.png b/doc/_static/DataLab-Title.png index 9ef669c2e..bbeeca4be 100644 Binary files a/doc/_static/DataLab-Title.png and b/doc/_static/DataLab-Title.png differ diff --git a/doc/conf.py b/doc/conf.py index 20acbfe40..27ea1f143 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -5,10 +5,18 @@ import os import os.path as osp import sys +import warnings import zipfile import guidata.config as gcfg +# Silence Sphinx 10 deprecation warning emitted from cairocffi (third-party, +# used by sphinxcontrib-svg2pdfconverter during LaTeX builds). +warnings.filterwarnings( + "ignore", + message=r".*Sphinx 10 will drop support for representing paths as strings.*", +) + sys.path.insert(0, os.path.abspath("..")) # Importing sigima to avoid re-enabling guidata validation mode @@ -223,20 +231,136 @@ def exclude_api_from_gettext(app): } latex_elements = { + # Drop the cmap package: it is a pdflatex-only helper, emits a noisy + # "pdftex not detected" warning under xelatex, and the resulting PDF + # remains fully searchable thanks to fontspec/XeTeX. + "cmappkg": "", # Use xelatex (set via ``latex_engine`` below): pdflatex chokes on the # emoji / box-drawing / arrow glyphs sprinkled across the docs. The # ``ucharclasses`` package automatically routes whole Unicode blocks - # (emoji, dingbats, box-drawing, ...) to the Symbola fallback font - # (Debian/Ubuntu package ``fonts-symbola``; MiKTeX fetches it on - # demand on Windows). + # to the Noto fallback fonts (SIL OFL, fully redistributable): + # * Noto Sans Symbols 2 -- miscellaneous symbols, arrows, dingbats, + # box drawing, geometric shapes... + # * Noto Emoji -- monochrome emoji (XeLaTeX does not render the + # COLR/CPAL color tables of Noto Color Emoji reliably). + # Install: + # * Debian/Ubuntu: ``apt install fonts-noto-core fonts-noto-mono + # fonts-noto-extra`` (``fonts-noto-extra`` ships the monochrome + # ``NotoEmoji-Regular.ttf``; ``fonts-noto-color-emoji`` is *not* + # usable because XeTeX rejects CBDT/CBLC color-bitmap fonts). + # * Windows: MiKTeX fetches the ``noto`` and ``noto-emoji`` packages + # on demand (``xelatex -enable-installer ...``). "preamble": r""" \usepackage{amsmath} \usepackage{amssymb} \usepackage{mathrsfs} \usepackage{fontspec} - \newfontfamily\unicodefallback{Symbola}[Scale=MatchLowercase] - \usepackage[Symbols]{ucharclasses} - \setTransitionsForSymbols{\unicodefallback}{\normalfont} + % Three complementary Noto fallbacks -- a single one does NOT cover every + % Unicode sub-block we hit in the docs: + % * Noto Sans Symbols -- arrows, box drawing, geometric shapes, + % misc. symbols (info, check mark, sparkles, ...), dingbats. + % * Noto Sans Symbols 2 -- box drawing extensions, transport, misc + % technical (⏱), and a number of pictographs (🛠 🏗 📁 ...) the + % monochrome Noto Emoji does NOT include. + % * Noto Sans Mono -- box drawing characters (─..╿), which + % none of the Symbols fonts cover. + % * Noto Emoji (mono) -- emoji-presentation chars (✅ ✹ ❌ ⚠ â„č). + % Noto Color Emoji is not used because XeTeX rejects CBDT/CBLC bitmap + % fonts. A few extended pictographs (đŸ§± 🧠 đŸ§© đŸ§č) live ONLY in Noto + % Color Emoji and remain reported as missing -- acceptable cosmetic + % limitation. + \newfontfamily\symbolsfallback{NotoSansSymbols-Regular.ttf}[Scale=MatchLowercase] + \newfontfamily\symbolstwofallback{NotoSansSymbols2-Regular.ttf}[Scale=MatchLowercase] + \newfontfamily\monofallback{NotoSansMono-Regular.ttf}[Scale=MatchLowercase] + \newfontfamily\emojifallback{NotoEmoji-Regular.ttf}[Scale=MatchLowercase] + \usepackage[Latin,Arrows,LetterlikeSymbols,BoxDrawing,GeometricShapes,Dingbats,MiscellaneousSymbols,MiscellaneousSymbolsAndArrows,MiscellaneousTechnical,Emoticons,MiscellaneousSymbolsAndPictographs,SupplementalSymbolsAndPictographs,TransportAndMapSymbols,SymbolsAndPictographsExtendedA]{ucharclasses} + % Restore the *current* family (rm / sf / tt) instead of an unconditional + % \normalfont, which would break monospace rendering inside verbatim and + % inline code whenever a Unicode symbol appears nearby. + \makeatletter + \newcommand{\dlrestorefont}{% + \ifx\f@family\ttdefault\ttfamily\else + \ifx\f@family\sfdefault\sffamily\else + \normalfont\fi\fi} + \makeatother + % Force an explicit transition back to the surrounding family whenever we + % re-enter a Latin block. Without this, XeTeX keeps the last font set by + % a Symbols/Emoji transition for every following Latin character, + % producing thousands of "Missing character: There is no in font + % Noto Emoji" warnings and a broken PDF. + \setTransitionsForLatin{\dlrestorefont}{} + % Route blocks to the font that actually covers them. Coverage notes: + % * Box Drawing / Block Elements / Misc Technical live in Symbols 2. + % * ⚠ ✅ ✹ ➝ (Misc Symbols / Dingbats with emoji presentation) + % are only in Noto Emoji. + \setTransitionsFor{Arrows}{\symbolsfallback}{\dlrestorefont} + \setTransitionsFor{LetterlikeSymbols}{\emojifallback}{\dlrestorefont} + \setTransitionsFor{BoxDrawing}{\monofallback}{\dlrestorefont} + \setTransitionsFor{GeometricShapes}{\symbolsfallback}{\dlrestorefont} + \setTransitionsFor{Dingbats}{\emojifallback}{\dlrestorefont} + \setTransitionsFor{MiscellaneousSymbols}{\emojifallback}{\dlrestorefont} + \setTransitionsFor{MiscellaneousSymbolsAndArrows}{\symbolstwofallback}{\dlrestorefont} + \setTransitionsFor{MiscellaneousTechnical}{\symbolstwofallback}{\dlrestorefont} + \setTransitionsFor{Emoticons}{\emojifallback}{\dlrestorefont} + \setTransitionsFor{MiscellaneousSymbolsAndPictographs}{\emojifallback}{\dlrestorefont} + \setTransitionsFor{SupplementalSymbolsAndPictographs}{\emojifallback}{\dlrestorefont} + \setTransitionsFor{TransportAndMapSymbols}{\emojifallback}{\dlrestorefont} + \setTransitionsFor{SymbolsAndPictographsExtendedA}{\emojifallback}{\dlrestorefont} + % Individual overrides for codepoints that are NOT in the block-routed + % font but exist in another installed Noto. The strategy is: + % 1. Reset the codepoint's XeTeX charclass to 0 so the broader block's + % \setTransitionsFor (which would switch to Noto Emoji and miss + % the glyph) no longer fires for it. + % 2. Use \newunicodechar to redefine the character as a macro that + % locally switches to Symbols 2 and emits the glyph via \char to + % avoid the infinite recursion that would occur if the macro body + % contained the active character itself. + % * ➝ HEAVY ROUND-TIPPED RIGHTWARDS ARROW (Dingbats). + % * 🛠 🏗 🗃 đŸ–Œ: pictographs missing from Noto Emoji but present + % in Symbols 2. + \XeTeXcharclass"279D=0 + \XeTeXcharclass"1F6E0=0 + \XeTeXcharclass"1F3D7=0 + \XeTeXcharclass"1F5C3=0 + \XeTeXcharclass"1F5BC=0 + \usepackage{newunicodechar} + \newunicodechar{➝}{{\symbolstwofallback\char"279D\relax}} + \newunicodechar{🛠}{{\symbolstwofallback\char"1F6E0\relax}} + \newunicodechar{🏗}{{\symbolstwofallback\char"1F3D7\relax}} + \newunicodechar{🗃}{{\symbolstwofallback\char"1F5C3\relax}} + \newunicodechar{đŸ–Œ}{{\symbolstwofallback\char"1F5BC\relax}} + % Discard U+FE0F (VARIATION SELECTOR-16) at the input layer: it has no + % visible glyph, only requests the emoji presentation of the preceding + % codepoint. catcode 9 means "ignored character", so XeTeX drops it before + % font selection -- no more "Missing character" warnings for it. + \catcode"FE0F=9\relax + % Silence cosmetic xelatex/LaTeX warnings that are inherent to the + % current Sphinx 9 + XeTeX + Noto fallback setup and do not affect the + % visible PDF output. We deliberately keep real errors and undefined + % cross-references visible. + % * \tracinglostchars=0 mutes the XeTeX "Missing character" terminal + % messages for the handful of color-bitmap-only emoji (đŸ§±đŸ§©đŸ§ đŸ§č) + % that no monochrome Noto font ships. + % * \hbadness / \vbadness raise the threshold so the engine no longer + % reports Underfull \hbox/\vbox notices caused by long identifier + % names in narrow table columns and code-style paragraphs. + % * The silence filters drop predictable, harmless package messages. + \tracinglostchars=0 + % Sphinx resets \hbadness/\vbadness at \begin{document}, so we re-apply + % the thresholds inside an \AtBeginDocument hook to silence Underfull + % \hbox/\vbox reports. Note: residual Overfull \hbox notices inside + % Sphinx tabulary/varwidth cells are not suppressible from here (Sphinx + % resets \hfuzz locally) and remain as informative typographic notices. + \AtBeginDocument{% + \hbadness=99999\relax + \vbadness=99999\relax + } + \usepackage{silence} + \WarningFilter{latexfont}{Font shape} + \WarningFilter{latexfont}{Some font shapes were not available} + \WarningFilter{cmap}{pdftex not detected} + \WarningFilter{longtable}{Table widths have changed} + \WarningFilter{rerunfilecheck}{File} % Prevent orphan section headings at the bottom of a page: force a page % break if there is not enough room for the heading plus a few lines of % its following paragraph. @@ -245,10 +369,25 @@ def exclude_api_from_gettext(app): \pretocmd{\section}{\Needspace{12\baselineskip}}{}{} \pretocmd{\subsection}{\Needspace{10\baselineskip}}{}{} \pretocmd{\subsubsection}{\Needspace{8\baselineskip}}{}{} + % Sphinx 9 wraps every table cell content in \begin{varwidth}[t]{...}. + % Combined with our `m{}` column specs (e.g. intro/operating-modes and + % stakeholders tables), the [t] reference point makes short single-line + % cells sit at the row bottom instead of the visual centre. Forcing the + % varwidth alignment to [c] makes m{} truly centre the content; it is a + % no-op for p{}-style columns where Sphinx ignores the box reference. + \usepackage{varwidth} + \let\dlorigvarwidth\varwidth + \let\dlorigendvarwidth\endvarwidth + \renewenvironment{varwidth}[2][c]{\dlorigvarwidth[c]{#2}}{\dlorigendvarwidth} """ + "\n".join(f"\\newcommand{{\\{cmd}}}{{{defn}}}" for cmd, defn in macros.items()), } latex_engine = "xelatex" +# Sphinx 9 emits the Python Module Index with a \detokenize/\sphinxstyleindexpageref +# pattern whose key does not match the corresponding \label definitions, producing +# spurious "undefined reference" warnings on every entry. The HTML build keeps a +# fully functional modindex; the PDF one is not worth its bogus warnings. +latex_domain_indices = False # -- MathJax configuration for HTML output ----------------------------------- mathjax3_config = { diff --git a/doc/contributing/environment.md b/doc/contributing/environment.md index 5793358b1..abb054cf7 100644 --- a/doc/contributing/environment.md +++ b/doc/contributing/environment.md @@ -95,7 +95,7 @@ Specific environment variables Enable the "debug" mode (no stdin/stdout redirection towards internal console): @REM Mode DEBUG - set DEBUG=1 + set DATALAB_DEBUG=1 Building PDF documentation requires LaTeX. On Windows, the following environment: diff --git a/doc/images/DataLab-Overview.png b/doc/images/DataLab-Overview.png index d4fd55a3f..5aabc7660 100644 Binary files a/doc/images/DataLab-Overview.png and b/doc/images/DataLab-Overview.png differ diff --git a/doc/images/DataLab-Screenshot-Theme.png b/doc/images/DataLab-Screenshot-Theme.png index 584496d36..a87613b31 100644 Binary files a/doc/images/DataLab-Screenshot-Theme.png and b/doc/images/DataLab-Screenshot-Theme.png differ diff --git a/doc/images/DataLab-banner.png b/doc/images/DataLab-banner.png index f86815c2d..081ed6e40 100644 Binary files a/doc/images/DataLab-banner.png and b/doc/images/DataLab-banner.png differ diff --git a/doc/images/shots/s_app_at_startup.en.png b/doc/images/shots/s_app_at_startup.en.png index 7c0f4139b..3c282ce31 100644 Binary files a/doc/images/shots/s_app_at_startup.en.png and b/doc/images/shots/s_app_at_startup.en.png differ diff --git a/doc/images/shots/s_app_at_startup.fr.png b/doc/images/shots/s_app_at_startup.fr.png index 2d70f4f9a..80ccbeec9 100644 Binary files a/doc/images/shots/s_app_at_startup.fr.png and b/doc/images/shots/s_app_at_startup.fr.png differ diff --git a/doc/images/shots/windows_installer.png b/doc/images/shots/windows_installer.png index 6218c0530..dc9ac9749 100644 Binary files a/doc/images/shots/windows_installer.png and b/doc/images/shots/windows_installer.png differ diff --git a/doc/index.rst b/doc/index.rst index 2f8cf679d..7af20b9e1 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -74,10 +74,9 @@ Go to :bdg-ref-success-line:`Installation ` to get started! DataLab has been funded, chronologically, by the following stakeholders: -.. tabularcolumns:: |>{\centering\arraybackslash}m{2cm}|m{\dimexpr\linewidth-2cm-4\tabcolsep\relax}| +.. tabularcolumns:: |>{\centering\arraybackslash}m{1.2cm}|m{\dimexpr\linewidth-1.2cm-4\tabcolsep\relax}| .. list-table:: :header-rows: 0 - :widths: 8 92 * - |cea_logo| - `CEA `_, the French Alternative Energies and Atomic Energy Commission, is the major investor in DataLab, and is the main contributor to the project. @@ -88,23 +87,40 @@ DataLab has been funded, chronologically, by the following stakeholders: * - |nlnet_logo| - `NLnet Foundation `_, as part of the NGI0 Commons Fund, backed by the European Commission, has funded the `redesign of DataLab's core architecture `_. -.. |cea_logo| image:: images/logos/cea.svg - :width: 64px - :height: 64px - :target: https://www.cea.fr - :class: dark-light no-scaled-link +.. Sphinx converts ``px`` to ``bp`` at 72 dpi for LaTeX, which makes ``64px`` + render at ~22mm in the PDF -- way larger than in HTML. Define separate + substitutions per output: pixels for HTML, centimetres for LaTeX. -.. |codra_logo| image:: images/logos/codra.svg - :width: 64px - :height: 64px - :target: https://codra.net - :class: dark-light no-scaled-link +.. only:: html -.. |nlnet_logo| image:: images/logos/nlnet.svg - :width: 64px - :height: 64px - :target: https://nlnet.nl - :class: dark-light no-scaled-link + .. |cea_logo| image:: images/logos/cea.svg + :width: 64px + :height: 64px + :target: https://www.cea.fr + :class: dark-light no-scaled-link + + .. |codra_logo| image:: images/logos/codra.svg + :width: 64px + :height: 64px + :target: https://codra.net + :class: dark-light no-scaled-link + + .. |nlnet_logo| image:: images/logos/nlnet.svg + :width: 64px + :height: 64px + :target: https://nlnet.nl + :class: dark-light no-scaled-link + +.. only:: latex + + .. |cea_logo| image:: images/logos/cea.svg + :width: 1cm + + .. |codra_logo| image:: images/logos/codra.svg + :width: 1cm + + .. |nlnet_logo| image:: images/logos/nlnet.svg + :width: 1cm .. figure:: _static/plotpy-stack-powered.png :align: center diff --git a/doc/intro/index.rst b/doc/intro/index.rst index 53bcc96de..e58484acf 100644 --- a/doc/intro/index.rst +++ b/doc/intro/index.rst @@ -13,10 +13,9 @@ and image analysis tasks. DataLab integrates seemlessly into your workflow thanks to three main operating modes: -.. tabularcolumns:: |>{\centering\arraybackslash}m{2cm}|m{\dimexpr\linewidth-2cm-4\tabcolsep\relax}| +.. tabularcolumns:: |>{\centering\arraybackslash}m{1.2cm}|m{\dimexpr\linewidth-1.2cm-4\tabcolsep\relax}| .. list-table:: :header-rows: 0 - :widths: 8 92 * - |appmode| - **Stand-alone application**, with a graphical user interface that allows you to interact with your data and visualize the results of your analysis in real time. @@ -27,20 +26,37 @@ DataLab integrates seemlessly into your workflow thanks to three main operating * - |remotemode| - **Remotely controlled** from your own software, or from an IDE (e.g., Spyder) or a Jupyter notebook, using the DataLab API. -.. |appmode| image:: ../../resources/DataLab-app.svg - :width: 64px - :height: 64px - :class: dark-light no-scaled-link +.. Sphinx converts ``px`` to ``bp`` at 72 dpi for LaTeX, which makes ``64px`` + render at ~22mm in the PDF -- way larger than in HTML. Define separate + substitutions per output: pixels for HTML, centimetres for LaTeX. -.. |libmode| image:: ../../resources/DataLab-lib.svg - :width: 64px - :height: 64px - :class: dark-light no-scaled-link +.. only:: html -.. |remotemode| image:: ../../resources/DataLab-remote.svg - :width: 64px - :height: 64px - :class: dark-light no-scaled-link + .. |appmode| image:: ../../resources/DataLab-app.svg + :width: 64px + :height: 64px + :class: dark-light no-scaled-link + + .. |libmode| image:: ../../resources/DataLab-lib.svg + :width: 64px + :height: 64px + :class: dark-light no-scaled-link + + .. |remotemode| image:: ../../resources/DataLab-remote.svg + :width: 64px + :height: 64px + :class: dark-light no-scaled-link + +.. only:: latex + + .. |appmode| image:: ../../resources/DataLab-app.svg + :width: 1cm + + .. |libmode| image:: ../../resources/DataLab-lib.svg + :width: 1cm + + .. |remotemode| image:: ../../resources/DataLab-remote.svg + :width: 1cm DataLab leverages the power of Python and its scientific ecosystem, through the use of the following libraries: diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po b/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po index a6ca0421f..bc2318b69 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/plugins.po @@ -292,52 +292,50 @@ msgstr "DĂ©senregistrer le plugin" msgid "Unregister all plugins" msgstr "DĂ©senregistrer tous les plugins" -#, fuzzy msgid "Clear registered plugin classes." -msgstr "Retourne les classes de plugins" +msgstr "Effacer les classes de plugins enregistrĂ©es" msgid "This is mainly useful when reloading plugin modules at runtime." -msgstr "" +msgstr "Ceci est principalement utile lors du rechargement des modules de plugins Ă  l'exĂ©cution." msgid "Record an error traceback that occurred during plugin discovery." -msgstr "" +msgstr "Enregistrer une trace d'erreur survenue lors de la dĂ©couverte des plugins." msgid "Parameters" msgstr "ParamĂštres" msgid "Formatted traceback string" -msgstr "" +msgstr "ChaĂźne de trace d'erreur formatĂ©e" msgid "Return error tracebacks collected during plugin discovery." -msgstr "" +msgstr "Retourner les traces d'erreur collectĂ©es lors de la dĂ©couverte des plugins." msgid "Returns" msgstr "Retourne" msgid "List of formatted traceback strings (may be empty)" -msgstr "" +msgstr "Liste des chaĂźnes de trace d'erreur formatĂ©es (peut ĂȘtre vide)" msgid "Clear recorded discovery errors." -msgstr "" +msgstr "Effacer les erreurs de dĂ©couverte enregistrĂ©es." msgid "Record a plugin that failed to load or instantiate." -msgstr "" +msgstr "Enregistrer un plugin qui n'a pas pu ĂȘtre chargĂ© ou instanciĂ©." -#, fuzzy msgid "Module or plugin class name" -msgstr "Retourne les classes de plugins" +msgstr "Nom du module ou de la classe du plugin" msgid "File path of the plugin module" msgstr "" msgid "Return structured info about plugins that failed to load." -msgstr "" +msgstr "Renvoie des informations structurĂ©es sur les plugins qui n'ont pas pu ĂȘtre chargĂ©s." msgid "List of FailedPluginInfo objects (may be empty)" -msgstr "" +msgstr "Liste des objets FailedPluginInfo (peut ĂȘtre vide)" msgid "Clear recorded failed plugin info." -msgstr "" +msgstr "Effacer les informations sur les plugins ayant Ă©chouĂ©." msgid "Return plugin information (names, versions, descriptions) in html format" msgstr "Retourne les informations sur les plugins (noms, versions, descriptions) au format html" @@ -346,7 +344,7 @@ msgid "return html formatted text (default: True)" msgstr "retourner du texte formatĂ© en html (par dĂ©faut : True)" msgid "Information about a plugin that failed to load or instantiate." -msgstr "" +msgstr "Informations sur un plugin qui n'a pas pu ĂȘtre chargĂ© ou instanciĂ©." msgid "Plugin info" msgstr "Informations sur le plugin" @@ -428,30 +426,28 @@ msgstr "DĂ©couvrir les plugins en utilisant la convention de nommage" #, python-brace-format msgid "This function reloads or imports all modules matching the DataLab plugin naming scheme (``\"{MOD_NAME}_*\"``). Plugin classes are then registered automatically via the :class:`PluginRegistry` metaclass." -msgstr "" +msgstr "Cette fonction recharge ou importe tous les modules correspondant au schĂ©ma de nommage des plugins DataLab (``\"{MOD_NAME}_*\"``). Les classes de plugins sont ensuite enregistrĂ©es automatiquement via la mĂ©taclasse :class:`PluginRegistry`." msgid "Import errors for individual plugins are captured and logged so that one broken plugin does not prevent the others from loading. Error tracebacks are accumulated in :class:`PluginRegistry` class attributes so that callers (e.g. the main window) can replay them into the internal console once it is ready." -msgstr "" +msgstr "Les erreurs d'importation pour les plugins individuels sont capturĂ©es et enregistrĂ©es afin qu'un plugin dĂ©fectueux n'empĂȘche pas les autres de se charger. Les traces d'erreurs sont accumulĂ©es dans les attributs de classe :class:`PluginRegistry` afin que les appelants (par exemple, la fenĂȘtre principale) puissent les rejouer dans la console interne une fois qu'elle est prĂȘte." -#, fuzzy msgid "List of imported/reloaded plugin modules" -msgstr "RedĂ©couvrir et recharger les modules de plugins," +msgstr "Liste des modules de plugins importĂ©s/rechargĂ©s" msgid "Reload plugin modules and reset plugin classes." -msgstr "" +msgstr "Recharger les modules de plugins et rĂ©initialiser les classes de plugins." msgid "This helper is intended for hot-reloading plugins at runtime. It:" -msgstr "" +msgstr "Cet assistant est destinĂ© au rechargement Ă  chaud des plugins Ă  l'exĂ©cution. Il :" msgid "Updates the plugin search path" -msgstr "" +msgstr "Met Ă  jour le chemin de recherche des plugins" -#, fuzzy msgid "Clears the plugin class registry" -msgstr "Retourne les classes de plugins" +msgstr "Efface le registre des classes de plugins" msgid "Reloads or imports all modules matching the plugin naming convention" -msgstr "" +msgstr "Recharge ou importe tous les modules correspondant Ă  la convention de nommage des plugins" msgid "Discover v0.20 plugins (with ``cdl_`` prefix) without importing them" msgstr "DĂ©couvrir les plugins v0.20 (avec le prĂ©fixe ``cdl_``) sans les importer" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po index beb8e1997..6279448b2 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/proxy.po @@ -243,6 +243,12 @@ msgstr "" msgid "Disconnect from DataLab XML-RPC server." msgstr "" +msgid "Return current object uuid in current panel." +msgstr "" + +msgid "UUID of the current object, or None if no object is current." +msgstr "" + msgid "Return current panel name." msgstr "" diff --git a/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po b/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po index b11b11dec..e238365de 100644 --- a/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po +++ b/doc/locale/fr/LC_MESSAGES/features/advanced/remote.po @@ -143,466 +143,460 @@ msgid "Here is a simple example of how to use RemoteClient in a Python script or msgstr "Voici un exemple simple de l'utilisation de RemoteClient dans un script Python ou dans un notebook Jupyter :" msgid "Set XML-RPC port to connect to." -msgstr "" +msgstr "DĂ©finir le port XML-RPC auquel se connecter." msgid "Parameters" msgstr "ParamĂštres" msgid "XML-RPC port to connect to. If None, the port is automatically retrieved from DataLab configuration." -msgstr "" +msgstr "Port XML-RPC auquel se connecter. Si None, le port est automatiquement rĂ©cupĂ©rĂ© depuis la configuration de DataLab." msgid "Try to connect to DataLab XML-RPC server." -msgstr "" +msgstr "Essayer de se connecter au serveur XML-RPC de DataLab." msgid "XML-RPC port to connect to. If not specified, the port is automatically retrieved from DataLab configuration." -msgstr "" +msgstr "Port XML-RPC auquel se connecter. Si non spĂ©cifiĂ©, le port est automatiquement rĂ©cupĂ©rĂ© depuis la configuration de DataLab." msgid "Maximum time to wait for connection in seconds. Defaults to 5.0. This is the total maximum wait time, not per retry." -msgstr "" +msgstr "Temps maximum d'attente de connexion en secondes. Par dĂ©faut 5.0. Il s'agit du temps d'attente maximum total, et non par tentative." msgid "Number of retries. Defaults to 10. This parameter is deprecated and will be removed in a future version (kept for backward compatibility)." -msgstr "" +msgstr "Nombre de tentatives. Par dĂ©faut 10. Ce paramĂštre est dĂ©prĂ©ciĂ© et sera supprimĂ© dans une version future (conservĂ© pour la compatibilitĂ© ascendante)." msgid "Raises" -msgstr "" +msgstr "LĂšve" msgid "Unable to connect to DataLab" -msgstr "" +msgstr "Impossible de se connecter Ă  DataLab" msgid "Invalid timeout (must be >= 0.0)" -msgstr "" +msgstr "DĂ©lai d'attente invalide (doit ĂȘtre >= 0.0)" msgid "Invalid number of retries (must be >= 1)" -msgstr "" +msgstr "Nombre de tentatives invalide (doit ĂȘtre >= 1)" msgid "Disconnect from DataLab XML-RPC server." -msgstr "" +msgstr "Se dĂ©connecter du serveur XML-RPC de DataLab." msgid "Return True if connected to DataLab XML-RPC server." -msgstr "" +msgstr "Renvoie True si connectĂ© au serveur XML-RPC de DataLab." msgid "Return list of available methods." -msgstr "" +msgstr "Renvoie la liste des mĂ©thodes disponibles." msgid "Add signal data to DataLab." -msgstr "" +msgstr "Ajouter des donnĂ©es de signal Ă  DataLab." msgid "Signal title" -msgstr "" +msgstr "Titre du signal" msgid "X data" -msgstr "" +msgstr "DonnĂ©es X" msgid "Y data" -msgstr "" +msgstr "DonnĂ©es Y" msgid "X unit. Defaults to \"\"" -msgstr "" +msgstr "UnitĂ© X. Par dĂ©faut \"\"" msgid "Y unit. Defaults to \"\"" -msgstr "" +msgstr "UnitĂ© Y. Par dĂ©faut \"\"" msgid "X label. Defaults to \"\"" -msgstr "" +msgstr "LibellĂ© X. Par dĂ©faut \"\"" msgid "Y label. Defaults to \"\"" -msgstr "" +msgstr "LibellĂ© Y. Par dĂ©faut \"\"" msgid "group id in which to add the signal. Defaults to \"\"" -msgstr "" +msgstr "Identifiant du groupe dans lequel ajouter le signal. Par dĂ©faut \"\"" msgid "if True, set the added signal as current" -msgstr "" +msgstr "si True, dĂ©finit le signal ajoutĂ© comme courant" msgid "Returns" -msgstr "" +msgstr "Renvoie" msgid "True if signal was added successfully, False otherwise" -msgstr "" +msgstr "True si le signal a Ă©tĂ© ajoutĂ© avec succĂšs, False sinon" msgid "Invalid xdata dtype" -msgstr "" +msgstr "Type de donnĂ©es xdata invalide" msgid "Invalid ydata dtype" -msgstr "" +msgstr "Type de donnĂ©es ydata invalide" msgid "Add image data to DataLab." -msgstr "" +msgstr "Ajouter des donnĂ©es d'image Ă  DataLab." msgid "Image title" -msgstr "" +msgstr "Titre de l'image" msgid "Image data" -msgstr "" +msgstr "DonnĂ©es de l'image" msgid "Z unit. Defaults to \"\"" -msgstr "" +msgstr "UnitĂ© Z. Par dĂ©faut \"\"" msgid "Z label. Defaults to \"\"" -msgstr "" +msgstr "LibellĂ© Z. Par dĂ©faut \"\"" msgid "group id in which to add the image. Defaults to \"\"" -msgstr "" +msgstr "Identifiant du groupe dans lequel ajouter l'image. Par dĂ©faut \"\"" msgid "if True, set the added image as current" -msgstr "" +msgstr "si True, dĂ©finit l'image ajoutĂ©e comme courante" msgid "True if image was added successfully, False otherwise" -msgstr "" +msgstr "True si l'image a Ă©tĂ© ajoutĂ©e avec succĂšs, False sinon" msgid "Invalid data dtype" -msgstr "" +msgstr "Type de donnĂ©es invalide" msgid "Add object to DataLab." -msgstr "" +msgstr "Ajouter un objet Ă  DataLab." -#, fuzzy msgid "Signal or image object" -msgstr "Basculer vers le panneau de signal ou d'image" +msgstr "Objet signal ou image" msgid "group id in which to add the object. Defaults to \"\"" -msgstr "" +msgstr "Identifiant du groupe dans lequel ajouter l'objet. Par dĂ©faut \"\"" msgid "if True, set the added object as current" -msgstr "" +msgstr "si True, dĂ©finit l'objet ajoutĂ© comme courant" msgid "Set object data in DataLab." -msgstr "" +msgstr "DĂ©finir les donnĂ©es d'un objet dans DataLab." msgid "Update an existing object in DataLab with new data from ``obj``. The object is identified by its UUID (which is carried by ``obj`` from a previous :meth:`get_object` call)." -msgstr "" +msgstr "Mettre Ă  jour un objet existant dans DataLab avec les nouvelles donnĂ©es de ``obj``. L'objet est identifiĂ© par son UUID (qui est portĂ© par ``obj`` depuis un appel prĂ©cĂ©dent Ă  :meth:`get_object`)." msgid "Signal or image object (must have the same UUID as an existing object in DataLab)" -msgstr "" +msgstr "Objet signal ou image (doit avoir le mĂȘme UUID qu'un objet existant dans DataLab)" msgid "if no object with matching UUID is found" -msgstr "" +msgstr "si aucun objet avec un UUID correspondant n'est trouvĂ©" msgid "Call computation feature ``name``" -msgstr "" +msgstr "Appeler la fonctionnalitĂ© de calcul ``name``" msgid "This calls either the processor's ``compute_`` method (if it exists), or the processor's ```` computation feature (if it is registered, using the ``run_feature`` method). It looks for the function in all panels, starting with the current one." -msgstr "" +msgstr "Ceci appelle soit la mĂ©thode ``compute_`` du processeur (si elle existe), soit la fonctionnalitĂ© de calcul ```` du processeur (si elle est enregistrĂ©e, en utilisant la mĂ©thode ``run_feature``). La fonction est recherchĂ©e dans tous les panneaux, en commençant par le panneau courant." msgid "Compute function name" -msgstr "" +msgstr "Nom de la fonction de calcul" msgid "Compute function parameter. Defaults to None." -msgstr "" +msgstr "ParamĂštre de la fonction de calcul. Par dĂ©faut None." msgid "unknown function" -msgstr "" +msgstr "fonction inconnue" -#, fuzzy msgid "Get object (signal/image) from index." -msgstr "Ouvrir un signal ou une image Ă  partir d'un fichier" +msgstr "Obtenir un objet (signal/image) Ă  partir de l'index." msgid "Object number, or object id, or object title. Defaults to None (current object)." -msgstr "" +msgstr "NumĂ©ro de l'objet, identifiant de l'objet, ou titre de l'objet. Par dĂ©faut None (objet courant)." msgid "Panel name. Defaults to None (current panel)." -msgstr "" +msgstr "Nom du panneau. Par dĂ©faut None (panneau courant)." msgid "Object" -msgstr "" +msgstr "Objet" msgid "if object not found" -msgstr "" +msgstr "si l'objet n'est pas trouvĂ©" msgid "Get plot item shapes associated to object (signal/image)." -msgstr "" +msgstr "Obtenir les formes des Ă©lĂ©ments graphiques associĂ©es Ă  l'objet (signal/image)." msgid "List of plot item shapes" -msgstr "" +msgstr "Liste des formes des Ă©lĂ©ments graphiques" msgid "Add object annotations (annotation plot items)." -msgstr "" +msgstr "Ajouter des annotations Ă  l'objet (Ă©lĂ©ments graphiques d'annotation)." msgid "annotation plot items" -msgstr "" +msgstr "Ă©lĂ©ments graphiques d'annotation" msgid "refresh plot. Defaults to True." -msgstr "" +msgstr "rafraĂźchir le graphique. Par dĂ©faut True." msgid "panel name (valid values: \"signal\", \"image\"). If None, current panel is used." -msgstr "" +msgstr "nom du panneau (valeurs valides : \"signal\", \"image\"). Si None, le panneau courant est utilisĂ©." msgid "Call a public method on a panel or main window." -msgstr "" +msgstr "Appeler une mĂ©thode publique sur un panneau ou la fenĂȘtre principale." msgid "Method resolution order when panel is None: 1. Try main window (DLMainWindow) 2. If not found, try current panel (BaseDataPanel)" -msgstr "" +msgstr "Ordre de rĂ©solution des mĂ©thodes quand panel est None : 1. Essayer la fenĂȘtre principale (DLMainWindow) 2. Si non trouvĂ©, essayer le panneau courant (BaseDataPanel)" msgid "Name of the method to call" -msgstr "" +msgstr "Nom de la mĂ©thode Ă  appeler" msgid "Positional arguments to pass to the method" -msgstr "" +msgstr "Arguments positionnels Ă  passer Ă  la mĂ©thode" msgid "Panel name (\"signal\", \"image\", or None for auto-detection). Defaults to None." -msgstr "" +msgstr "Nom du panneau (\"signal\", \"image\", ou None pour la dĂ©tection automatique). Par dĂ©faut None." msgid "Keyword arguments to pass to the method" -msgstr "" +msgstr "Arguments nommĂ©s Ă  passer Ă  la mĂ©thode" msgid "The return value of the called method" -msgstr "" +msgstr "La valeur de retour de la mĂ©thode appelĂ©e" msgid "If the method does not exist or is not public" -msgstr "" +msgstr "Si la mĂ©thode n'existe pas ou n'est pas publique" msgid "If the panel name is invalid" -msgstr "" +msgstr "Si le nom du panneau est invalide" msgid "Start the WebAPI server." -msgstr "" +msgstr "DĂ©marrer le serveur WebAPI." msgid "Host address to bind to. Defaults to \"127.0.0.1\"." -msgstr "" +msgstr "Adresse hĂŽte Ă  laquelle se lier. Par dĂ©faut \"127.0.0.1\"." msgid "Port number. Defaults to 8080." -msgstr "" +msgstr "NumĂ©ro de port. Par dĂ©faut 8080." msgid "Dictionary with server info including 'url' and 'token'." -msgstr "" +msgstr "Dictionnaire avec les informations du serveur incluant 'url' et 'token'." msgid "Stop the WebAPI server." -msgstr "" +msgstr "ArrĂȘter le serveur WebAPI." msgid "True if server was stopped, False if it wasn't running." -msgstr "" +msgstr "True si le serveur a Ă©tĂ© arrĂȘtĂ©, False s'il n'Ă©tait pas en cours d'exĂ©cution." msgid "Get the current status of the WebAPI server." -msgstr "" +msgstr "Obtenir l'Ă©tat actuel du serveur WebAPI." msgid "Dictionary with status info including 'running', 'url', and 'port'." -msgstr "" +msgstr "Dictionnaire avec les informations d'Ă©tat incluant 'running', 'url' et 'port'." msgid "Add group to DataLab." -msgstr "" +msgstr "Ajouter un groupe Ă  DataLab." msgid "Group title" -msgstr "" +msgstr "Titre du groupe" msgid "Panel name (valid values: \"signal\", \"image\"). Defaults to None." -msgstr "" +msgstr "Nom du panneau (valeurs valides : \"signal\", \"image\"). Par dĂ©faut None." msgid "Select the group after creation. Defaults to False." -msgstr "" +msgstr "SĂ©lectionner le groupe aprĂšs sa crĂ©ation. Par dĂ©faut False." msgid "Add a label with object title on the associated plot" -msgstr "" +msgstr "Ajouter un libellĂ© avec le titre de l'objet sur le graphique associĂ©" msgid "Label title. Defaults to None. If None, the title is the object title." -msgstr "" +msgstr "Titre du libellĂ©. Par dĂ©faut None. Si None, le titre est le titre de l'objet." -#, fuzzy msgid "Close DataLab application" -msgstr "Depuis une application tierce" +msgstr "Fermer l'application DataLab" msgid "Return a context manager to temporarily disable auto refresh." -msgstr "" +msgstr "Renvoie un gestionnaire de contexte pour dĂ©sactiver temporairement le rafraĂźchissement automatique." msgid "Context manager" -msgstr "" +msgstr "Gestionnaire de contexte" -#, fuzzy msgid "Example" -msgstr "Exemples" +msgstr "Exemple" msgid "Delete metadata of selected objects" -msgstr "" +msgstr "Supprimer les mĂ©tadonnĂ©es des objets sĂ©lectionnĂ©s" msgid "Refresh plot. Defaults to True." -msgstr "" +msgstr "RafraĂźchir le graphique. Par dĂ©faut True." msgid "Keep ROI. Defaults to False." -msgstr "" +msgstr "Conserver les ROI. Par dĂ©faut False." + +msgid "Return current object uuid in current panel." +msgstr "Renvoie l'UUID de l'objet courant dans le panneau courant." + +msgid "UUID of the current object, or None if no object is current." +msgstr "UUID de l'objet courant, ou None si aucun objet n'est courant." msgid "Return current panel name." -msgstr "" +msgstr "Renvoie le nom du panneau courant." msgid "\"signal\", \"image\", \"macro\"))" -msgstr "" +msgstr "\"signal\", \"image\", \"macro\"))" msgid "Return type" -msgstr "" +msgstr "Type de retour" msgid "Return groups titles and lists of inner objects uuids and titles." -msgstr "" +msgstr "Renvoie les titres des groupes et les listes des UUID et titres des objets internes." msgid "groups titles, lists of inner objects uuids and titles" -msgstr "" +msgstr "titres des groupes, listes des UUID et titres des objets internes" msgid "Get object (signal/image) list for current panel. Objects are sorted by group number and object index in group." -msgstr "" +msgstr "Obtenir la liste des objets (signal/image) pour le panneau courant. Les objets sont triĂ©s par numĂ©ro de groupe et index de l'objet dans le groupe." msgid "panel name (valid values: \"signal\", \"image\", \"macro\"). If None, current data panel is used (i.e. signal or image panel)." -msgstr "" +msgstr "nom du panneau (valeurs valides : \"signal\", \"image\", \"macro\"). Si None, le panneau de donnĂ©es courant est utilisĂ© (c'est-Ă -dire le panneau signal ou image)." -#, fuzzy msgid "List of object titles" -msgstr "Obtenir la liste des objets" +msgstr "Liste des titres des objets" msgid "if panel not found" -msgstr "" +msgstr "si le panneau n'est pas trouvĂ©" msgid "Get object (signal/image) uuid list for current panel. Objects are sorted by group number and object index in group." -msgstr "" +msgstr "Obtenir la liste des UUID des objets (signal/image) pour le panneau courant. Les objets sont triĂ©s par numĂ©ro de groupe et index de l'objet dans le groupe." msgid "Group number, or group id, or group title. Defaults to None (all groups)." -msgstr "" +msgstr "NumĂ©ro du groupe, identifiant du groupe, ou titre du groupe. Par dĂ©faut None (tous les groupes)." -#, fuzzy msgid "List of object uuids" -msgstr "Obtenir la liste des objets" +msgstr "Liste des UUID des objets" msgid "Return all public methods of the class, except itself." -msgstr "" +msgstr "Renvoie toutes les mĂ©thodes publiques de la classe, sauf elle-mĂȘme." msgid "List of public methods" -msgstr "" +msgstr "Liste des mĂ©thodes publiques" msgid "Return selected objects uuids." -msgstr "" +msgstr "Renvoie les UUID des objets sĂ©lectionnĂ©s." msgid "If True, also return objects from selected groups." -msgstr "" +msgstr "Si True, renvoie Ă©galement les objets des groupes sĂ©lectionnĂ©s." msgid "List of selected objects uuids." -msgstr "" +msgstr "Liste des UUID des objets sĂ©lectionnĂ©s." msgid "Return DataLab public version." -msgstr "" +msgstr "Renvoie la version publique de DataLab." msgid "DataLab version" -msgstr "" +msgstr "Version de DataLab" msgid "Open DataLab HDF5 browser to Import HDF5 file." -msgstr "" +msgstr "Ouvrir le navigateur HDF5 de DataLab pour importer un fichier HDF5." -#, fuzzy msgid "HDF5 file name" -msgstr "Parcourir un fichier HDF5" +msgstr "Nom du fichier HDF5" msgid "Reset all application data. Defaults to None." -msgstr "" +msgstr "RĂ©initialiser toutes les donnĂ©es de l'application. Par dĂ©faut None." msgid "Import macro from file" -msgstr "" +msgstr "Importer une macro depuis un fichier" msgid "Filename." -msgstr "" +msgstr "Nom du fichier." msgid "Open objects from directory in current panel (signals/images)." -msgstr "" +msgstr "Ouvrir des objets depuis un rĂ©pertoire dans le panneau courant (signaux/images)." msgid "directory path" -msgstr "" +msgstr "chemin du rĂ©pertoire" msgid "Open objects from files in current panel (signals/images)." -msgstr "" +msgstr "Ouvrir des objets depuis des fichiers dans le panneau courant (signaux/images)." msgid "list of file names" -msgstr "" +msgstr "liste des noms de fichiers" msgid "Load native DataLab HDF5 workspace files without any GUI elements." -msgstr "" +msgstr "Charger des fichiers d'espace de travail HDF5 natifs DataLab sans aucun Ă©lĂ©ment d'interface graphique." msgid "This method can be safely called from scripts (e.g., internal console, macros) as it does not create any Qt widgets, dialogs, or progress bars." -msgstr "" +msgstr "Cette mĂ©thode peut ĂȘtre appelĂ©e en toute sĂ©curitĂ© depuis des scripts (par exemple, console interne, macros) car elle ne crĂ©e aucun widget Qt, boĂźte de dialogue ou barre de progression." msgid "This method only supports native DataLab HDF5 files. For importing arbitrary HDF5 files (non-native), use :meth:`open_h5_files` or :meth:`import_h5_file` instead." -msgstr "" +msgstr "Cette mĂ©thode ne prend en charge que les fichiers HDF5 natifs DataLab. Pour importer des fichiers HDF5 arbitraires (non natifs), utilisez plutĂŽt :meth:`open_h5_files` ou :meth:`import_h5_file`." -#, fuzzy msgid "List of native DataLab HDF5 filenames" -msgstr "Enregistrer la session en cours dans un fichier HDF5" +msgstr "Liste des noms de fichiers HDF5 natifs DataLab" msgid "Reset all application data before importing. Defaults to False." -msgstr "" +msgstr "RĂ©initialiser toutes les donnĂ©es de l'application avant l'importation. Par dĂ©faut False." msgid "If a file is not a valid native DataLab HDF5 file" -msgstr "" +msgstr "Si un fichier n'est pas un fichier HDF5 natif DataLab valide" msgid "Open a DataLab HDF5 file or import from any other HDF5 file." -msgstr "" +msgstr "Ouvrir un fichier HDF5 DataLab ou importer depuis tout autre fichier HDF5." msgid "List of HDF5 files to open. Defaults to None." -msgstr "" +msgstr "Liste des fichiers HDF5 Ă  ouvrir. Par dĂ©faut None." msgid "Import all objects from HDF5 files. Defaults to None." -msgstr "" +msgstr "Importer tous les objets depuis les fichiers HDF5. Par dĂ©faut None." msgid "Raise DataLab window" -msgstr "" +msgstr "Mettre la fenĂȘtre DataLab au premier plan" msgid "Remove current object from current panel." -msgstr "" +msgstr "Supprimer l'objet courant du panneau courant." msgid "if True, remove object without confirmation. Defaults to False." -msgstr "" +msgstr "si True, supprimer l'objet sans confirmation. Par dĂ©faut False." msgid "Reset all application data" -msgstr "" +msgstr "RĂ©initialiser toutes les donnĂ©es de l'application" msgid "Run macro." -msgstr "" +msgstr "ExĂ©cuter une macro." msgid "Macro number, or macro title. Defaults to None (current macro)." -msgstr "" +msgstr "NumĂ©ro de la macro, ou titre de la macro. Par dĂ©faut None (macro courante)." msgid "if macro not found" -msgstr "" +msgstr "si la macro n'est pas trouvĂ©e" msgid "Save current workspace to a native DataLab HDF5 file without GUI elements." -msgstr "" +msgstr "Enregistrer l'espace de travail courant dans un fichier HDF5 natif DataLab sans Ă©lĂ©ments d'interface graphique." -#, fuzzy msgid "HDF5 filename to save to" -msgstr "Parcourir un fichier HDF5" +msgstr "Nom du fichier HDF5 dans lequel enregistrer" msgid "If file cannot be saved" -msgstr "" +msgstr "Si le fichier ne peut pas ĂȘtre enregistrĂ©" -#, fuzzy msgid "Save to a DataLab HDF5 file." -msgstr "Enregistrer la session en cours dans un fichier HDF5" +msgstr "Enregistrer dans un fichier HDF5 DataLab." msgid "Select groups in current panel." -msgstr "" +msgstr "SĂ©lectionner des groupes dans le panneau courant." msgid "List of group numbers (1 to N), or list of group uuids, or None to select all groups. Defaults to None." -msgstr "" +msgstr "Liste des numĂ©ros de groupes (1 Ă  N), ou liste des UUID de groupes, ou None pour sĂ©lectionner tous les groupes. Par dĂ©faut None." msgid "panel name (valid values: \"signal\", \"image\"). If None, current panel is used. Defaults to None." -msgstr "" +msgstr "nom du panneau (valeurs valides : \"signal\", \"image\"). Si None, le panneau courant est utilisĂ©. Par dĂ©faut None." msgid "Select objects in current panel." -msgstr "" +msgstr "SĂ©lectionner des objets dans le panneau courant." msgid "List of object numbers (1 to N) or uuids to select" -msgstr "" +msgstr "Liste des numĂ©ros d'objets (1 Ă  N) ou UUID Ă  sĂ©lectionner" -#, fuzzy msgid "Switch to panel." -msgstr "Basculer vers le panneau de signal ou d'image" +msgstr "Basculer vers le panneau." msgid "Panel name (valid values: \"signal\", \"image\", \"macro\"))" -msgstr "" +msgstr "Nom du panneau (valeurs valides : \"signal\", \"image\", \"macro\"))" msgid "Stop macro." -msgstr "" +msgstr "ArrĂȘter la macro." msgid "Toggle auto refresh state." -msgstr "" +msgstr "Basculer l'Ă©tat du rafraĂźchissement automatique." msgid "Auto refresh state" -msgstr "" +msgstr "État du rafraĂźchissement automatique" msgid "Toggle show titles state." -msgstr "" +msgstr "Basculer l'Ă©tat d'affichage des titres." msgid "Show titles state" -msgstr "" - +msgstr "État d'affichage des titres" diff --git a/doc/locale/fr/LC_MESSAGES/features/validation/status.po b/doc/locale/fr/LC_MESSAGES/features/validation/status.po index fa93b4b4d..e0a849268 100644 --- a/doc/locale/fr/LC_MESSAGES/features/validation/status.po +++ b/doc/locale/fr/LC_MESSAGES/features/validation/status.po @@ -126,7 +126,7 @@ msgstr "" msgid "Compute absolute value with :py:data:`numpy.absolute`" msgstr "" -msgid "`test_signal_absolute `_" +msgid "`test_signal_absolute `_" msgstr "" msgid ":py:func:`add_gaussian_noise `" @@ -135,7 +135,7 @@ msgstr "" msgid "Add normal noise to the input signal" msgstr "" -msgid "`test_signal_add_gaussian_noise `_" +msgid "`test_signal_add_gaussian_noise `_" msgstr "" msgid ":py:func:`add_poisson_noise `" @@ -144,7 +144,7 @@ msgstr "" msgid "Add Poisson noise to the input signal" msgstr "" -msgid "`test_signal_add_poisson_noise `_" +msgid "`test_signal_add_poisson_noise `_" msgstr "" msgid ":py:func:`add_uniform_noise `" @@ -153,7 +153,7 @@ msgstr "" msgid "Add uniform noise to the input signal" msgstr "" -msgid "`test_signal_add_uniform_noise `_" +msgid "`test_signal_add_uniform_noise `_" msgstr "" msgid ":py:func:`addition `" @@ -162,7 +162,7 @@ msgstr "" msgid "Compute the element-wise sum of multiple signals" msgstr "" -msgid "`test_signal_addition `_" +msgid "`test_signal_addition `_" msgstr "" msgid ":py:func:`addition_constant `" @@ -171,7 +171,7 @@ msgstr "" msgid "Compute the sum of a signal and a constant value" msgstr "" -msgid "`test_signal_addition_constant `_" +msgid "`test_signal_addition_constant `_" msgstr "" msgid ":py:func:`allan_deviation `" @@ -180,7 +180,7 @@ msgstr "" msgid "Compute Allan deviation" msgstr "Calculer la dĂ©viation d'Allan" -msgid "`test_signal_allan_deviation `_" +msgid "`test_signal_allan_deviation `_" msgstr "" msgid ":py:func:`allan_variance `" @@ -189,7 +189,7 @@ msgstr "" msgid "Compute Allan variance" msgstr "" -msgid "`test_signal_allan_variance `_" +msgid "`test_signal_allan_variance `_" msgstr "" msgid ":py:func:`apply_window `" @@ -198,7 +198,7 @@ msgstr "" msgid "Compute windowing" msgstr "Calculer la fenĂȘtrage" -msgid "`test_signal_apply_window `_" +msgid "`test_signal_apply_window `_" msgstr "" msgid ":py:func:`arithmetic `" @@ -207,7 +207,7 @@ msgstr "" msgid "Perform an arithmetic operation on two signals" msgstr "" -msgid "`test_signal_arithmetic `_" +msgid "`test_signal_arithmetic `_" msgstr "" msgid ":py:func:`astype `" @@ -216,7 +216,7 @@ msgstr "" msgid "Convert data type" msgstr "" -msgid "`test_signal_astype `_" +msgid "`test_signal_astype `_" msgstr "" msgid ":py:func:`average `" @@ -225,7 +225,7 @@ msgstr "" msgid "Compute the element-wise average of multiple signals" msgstr "" -msgid "`test_signal_average `_" +msgid "`test_signal_average `_" msgstr "" msgid ":py:func:`bandpass `" @@ -234,7 +234,7 @@ msgstr "" msgid "Compute band-pass filter" msgstr "" -msgid "`test_signal_bandpass `_" +msgid "`test_signal_bandpass `_" msgstr "" msgid ":py:func:`bandstop `" @@ -243,7 +243,7 @@ msgstr "" msgid "Compute band-stop filter" msgstr "" -msgid "`test_signal_bandstop `_" +msgid "`test_signal_bandstop `_" msgstr "" msgid ":py:func:`bandwidth_3db `" @@ -252,7 +252,7 @@ msgstr "" msgid "Compute bandwidth at -3 dB" msgstr "" -msgid "`test_signal_bandwidth_3db `_" +msgid "`test_signal_bandwidth_3db `_" msgstr "" msgid ":py:func:`calibration `" @@ -261,7 +261,7 @@ msgstr "" msgid "Compute linear calibration" msgstr "" -msgid "`test_signal_calibration `_" +msgid "`test_signal_calibration `_" msgstr "" msgid ":py:func:`cdf_fit `" @@ -270,7 +270,7 @@ msgstr "" msgid "Compute CDF fit" msgstr "" -msgid "`test_signal_cdf_fit `_" +msgid "`test_signal_cdf_fit `_" msgstr "" msgid ":py:func:`clip `" @@ -279,7 +279,7 @@ msgstr "" msgid "Compute maximum data clipping" msgstr "" -msgid "`test_signal_clip `_" +msgid "`test_signal_clip `_" msgstr "" msgid ":py:func:`complex_from_magnitude_phase `" @@ -288,7 +288,7 @@ msgstr "" msgid "Combine magnitude and phase signals into a complex signal" msgstr "" -msgid "`test_signal_complex_from_magnitude_phase `_" +msgid "`test_signal_complex_from_magnitude_phase `_" msgstr "" msgid ":py:func:`complex_from_real_imag `" @@ -297,7 +297,7 @@ msgstr "" msgid "Combine two real signals into a complex signal using real + i * imag" msgstr "" -msgid "`test_signal_complex_from_real_imag `_" +msgid "`test_signal_complex_from_real_imag `_" msgstr "" msgid ":py:func:`contrast `" @@ -306,7 +306,7 @@ msgstr "" msgid "Compute contrast" msgstr "Calculer le contraste" -msgid "`test_signal_contrast `_" +msgid "`test_signal_contrast `_" msgstr "" msgid ":py:func:`convolution `" @@ -315,7 +315,7 @@ msgstr "" msgid "Compute convolution of two signals" msgstr "" -msgid "`test_signal_convolution `_" +msgid "`test_signal_convolution `_" msgstr "" msgid ":py:func:`deconvolution `" @@ -324,7 +324,7 @@ msgstr "" msgid "Compute deconvolution" msgstr "Calculer la dĂ©convolution" -msgid "`test_signal_deconvolution `_" +msgid "`test_signal_deconvolution `_" msgstr "" msgid ":py:func:`derivative `" @@ -333,7 +333,7 @@ msgstr "" msgid "Compute derivative" msgstr "Calculer la dĂ©rivĂ©e" -msgid "`test_signal_derivative `_" +msgid "`test_signal_derivative `_" msgstr "" msgid ":py:func:`detrending `" @@ -342,7 +342,7 @@ msgstr "" msgid "Detrend data" msgstr "" -msgid "`test_signal_detrending `_" +msgid "`test_signal_detrending `_" msgstr "" msgid ":py:func:`difference `" @@ -351,7 +351,7 @@ msgstr "" msgid "Compute the element-wise difference between two signals" msgstr "" -msgid "`test_signal_difference `_" +msgid "`test_signal_difference `_" msgstr "" msgid ":py:func:`difference_constant `" @@ -360,7 +360,7 @@ msgstr "" msgid "Compute the difference between a signal and a constant value" msgstr "" -msgid "`test_signal_difference_constant `_" +msgid "`test_signal_difference_constant `_" msgstr "" msgid ":py:func:`division `" @@ -369,7 +369,7 @@ msgstr "" msgid "Compute the element-wise division between two signals" msgstr "" -msgid "`test_signal_division `_" +msgid "`test_signal_division `_" msgstr "" msgid ":py:func:`division_constant `" @@ -378,7 +378,7 @@ msgstr "" msgid "Compute the division of a signal by a constant value" msgstr "" -msgid "`test_signal_division_constant `_" +msgid "`test_signal_division_constant `_" msgstr "" msgid ":py:func:`dynamic_parameters `" @@ -387,7 +387,7 @@ msgstr "" msgid "Compute Dynamic parameters" msgstr "" -msgid "`test_dynamic_parameters `_" +msgid "`test_dynamic_parameters `_" msgstr "" msgid ":py:func:`evaluate_fit `" @@ -396,7 +396,7 @@ msgstr "" msgid "Evaluate fit function from src1 on the x-axis of src2" msgstr "" -msgid "`test_signal_evaluate_fit `_" +msgid "`test_signal_evaluate_fit `_" msgstr "" msgid ":py:func:`exp `" @@ -405,7 +405,7 @@ msgstr "" msgid "Compute exponential with :py:data:`numpy.exp`" msgstr "" -msgid "`test_signal_exp `_" +msgid "`test_signal_exp `_" msgstr "" msgid ":py:func:`exponential_fit `" @@ -414,7 +414,7 @@ msgstr "" msgid "Compute exponential fit" msgstr "Calculer l'ajustement exponentiel" -msgid "`test_signal_exponential_fit `_" +msgid "`test_signal_exponential_fit `_" msgstr "" msgid ":py:func:`extract_pulse_features `" @@ -423,7 +423,7 @@ msgstr "" msgid "Extract pulse features" msgstr "" -msgid "`test_signal_extract_pulse_features `_" +msgid "`test_signal_extract_pulse_features `_" msgstr "" msgid ":py:func:`extract_roi `" @@ -432,7 +432,7 @@ msgstr "" msgid "Extract single region of interest from data" msgstr "" -msgid "`test_signal_extract_roi `_" +msgid "`test_signal_extract_roi `_" msgstr "" msgid ":py:func:`extract_rois `" @@ -441,7 +441,7 @@ msgstr "" msgid "Extract multiple regions of interest from data" msgstr "" -msgid "`test_signal_extract_rois `_" +msgid "`test_signal_extract_rois `_" msgstr "" msgid ":py:func:`fft `" @@ -450,13 +450,13 @@ msgstr "" msgid "Compute FFT" msgstr "Calculer la FFT" -msgid "`test_signal_fft `_" +msgid "`test_signal_fft `_" msgstr "" msgid ":py:func:`full_width_at_y `" msgstr "" -msgid "`test_signal_full_width_at_y `_" +msgid "`test_signal_full_width_at_y `_" msgstr "" msgid ":py:func:`fw1e2 `" @@ -465,7 +465,7 @@ msgstr "" msgid "Compute FW at 1/eÂČ" msgstr "" -msgid "`test_signal_fw1e2 `_" +msgid "`test_signal_fw1e2 `_" msgstr "" msgid ":py:func:`fwhm `" @@ -474,7 +474,7 @@ msgstr "" msgid "Compute FWHM" msgstr "Fonctions de calcul" -msgid "`test_signal_fwhm `_" +msgid "`test_signal_fwhm `_" msgstr "" msgid ":py:func:`gaussian_filter `" @@ -483,7 +483,7 @@ msgstr "" msgid "Compute gaussian filter" msgstr "" -msgid "`test_signal_gaussian_filter `_" +msgid "`test_signal_gaussian_filter `_" msgstr "" msgid ":py:func:`gaussian_fit `" @@ -492,7 +492,7 @@ msgstr "" msgid "Compute Gaussian fit" msgstr "Calculer la dĂ©viation d'Allan" -msgid "`test_signal_gaussian_fit `_" +msgid "`test_signal_gaussian_fit `_" msgstr "" msgid ":py:func:`hadamard_variance `" @@ -501,7 +501,7 @@ msgstr "" msgid "Compute Hadamard variance" msgstr "" -msgid "`test_signal_hadamard_variance `_" +msgid "`test_signal_hadamard_variance `_" msgstr "" msgid ":py:func:`highpass `" @@ -510,7 +510,7 @@ msgstr "" msgid "Compute high-pass filter" msgstr "" -msgid "`test_signal_highpass `_" +msgid "`test_signal_highpass `_" msgstr "" msgid ":py:func:`histogram `" @@ -519,7 +519,7 @@ msgstr "" msgid "Compute histogram" msgstr "Calculer l'histogramme" -msgid "`test_signal_histogram `_" +msgid "`test_signal_histogram `_" msgstr "" msgid ":py:func:`ifft `" @@ -528,7 +528,7 @@ msgstr "" msgid "Compute the inverse FFT" msgstr "" -msgid "`test_signal_ifft `_" +msgid "`test_signal_ifft `_" msgstr "" msgid ":py:func:`imag `" @@ -537,7 +537,7 @@ msgstr "" msgid "Compute imaginary part" msgstr "" -msgid "`test_signal_imag `_" +msgid "`test_signal_imag `_" msgstr "" msgid ":py:func:`integral `" @@ -546,7 +546,7 @@ msgstr "" msgid "Compute integral" msgstr "Calculer l'intĂ©grale" -msgid "`test_signal_integral `_" +msgid "`test_signal_integral `_" msgstr "" msgid ":py:func:`interpolate `" @@ -555,7 +555,7 @@ msgstr "" msgid "Interpolate data" msgstr "" -msgid "`test_signal_interpolate `_" +msgid "`test_signal_interpolate `_" msgstr "" msgid ":py:func:`inverse `" @@ -564,7 +564,7 @@ msgstr "" msgid "Compute the element-wise inverse of a signal" msgstr "" -msgid "`test_signal_inverse `_" +msgid "`test_signal_inverse `_" msgstr "" msgid ":py:func:`linear_fit `" @@ -573,7 +573,7 @@ msgstr "" msgid "Compute linear fit" msgstr "Calculer l'ajustement linĂ©aire" -msgid "`test_signal_linear_fit `_" +msgid "`test_signal_linear_fit `_" msgstr "" msgid ":py:func:`log10 `" @@ -582,7 +582,7 @@ msgstr "" msgid "Compute Log10 with :py:data:`numpy.log10`" msgstr "" -msgid "`test_signal_log10 `_" +msgid "`test_signal_log10 `_" msgstr "" msgid ":py:func:`lorentzian_fit `" @@ -591,7 +591,7 @@ msgstr "" msgid "Compute Lorentzian fit" msgstr "Calculer l'ajustement lorentzien" -msgid "`test_signal_lorentzian_fit `_" +msgid "`test_signal_lorentzian_fit `_" msgstr "" msgid ":py:func:`lowpass `" @@ -600,7 +600,7 @@ msgstr "" msgid "Compute low-pass filter" msgstr "" -msgid "`test_signal_lowpass `_" +msgid "`test_signal_lowpass `_" msgstr "" msgid ":py:func:`magnitude_spectrum `" @@ -609,7 +609,7 @@ msgstr "" msgid "Compute magnitude spectrum" msgstr "" -msgid "`test_signal_magnitude_spectrum `_" +msgid "`test_signal_magnitude_spectrum `_" msgstr "" msgid ":py:func:`modified_allan_variance `" @@ -618,7 +618,7 @@ msgstr "" msgid "Compute Modified Allan variance" msgstr "" -msgid "`test_signal_modified_allan_variance `_" +msgid "`test_signal_modified_allan_variance `_" msgstr "" msgid ":py:func:`moving_average `" @@ -627,7 +627,7 @@ msgstr "" msgid "Compute moving average" msgstr "" -msgid "`test_signal_moving_average `_" +msgid "`test_signal_moving_average `_" msgstr "" msgid ":py:func:`moving_median `" @@ -636,7 +636,7 @@ msgstr "" msgid "Compute moving median" msgstr "" -msgid "`test_signal_moving_median `_" +msgid "`test_signal_moving_median `_" msgstr "" msgid ":py:func:`normalize `" @@ -645,7 +645,7 @@ msgstr "" msgid "Normalize data" msgstr "" -msgid "`test_signal_normalize `_" +msgid "`test_signal_normalize `_" msgstr "" msgid ":py:func:`offset_correction `" @@ -654,7 +654,7 @@ msgstr "" msgid "Correct offset: subtract the mean value of the signal in the specified range" msgstr "" -msgid "`test_signal_offset_correction `_" +msgid "`test_signal_offset_correction `_" msgstr "" msgid ":py:func:`overlapping_allan_variance `" @@ -663,7 +663,7 @@ msgstr "" msgid "Compute Overlapping Allan variance" msgstr "" -msgid "`test_signal_overlapping_allan_variance `_" +msgid "`test_signal_overlapping_allan_variance `_" msgstr "" msgid ":py:func:`peak_detection `" @@ -672,7 +672,7 @@ msgstr "" msgid "Peak detection" msgstr "" -msgid "`test_signal_peak_detection `_" +msgid "`test_signal_peak_detection `_" msgstr "" msgid ":py:func:`phase `" @@ -681,7 +681,7 @@ msgstr "" msgid "Compute the phase (argument) of a complex signal" msgstr "" -msgid "`test_signal_phase `_" +msgid "`test_signal_phase `_" msgstr "" msgid ":py:func:`phase_spectrum `" @@ -690,7 +690,7 @@ msgstr "" msgid "Compute phase spectrum" msgstr "" -msgid "`test_signal_phase_spectrum `_" +msgid "`test_signal_phase_spectrum `_" msgstr "" msgid ":py:func:`piecewiseexponential_fit `" @@ -699,7 +699,7 @@ msgstr "" msgid "Compute piecewise exponential fit (raise-decay)" msgstr "Calculer l'ajustement exponentiel par morceaux (augmentation-dĂ©croissance)" -msgid "`test_signal_piecewiseexponential_fit `_" +msgid "`test_signal_piecewiseexponential_fit `_" msgstr "" msgid ":py:func:`planckian_fit `" @@ -708,7 +708,7 @@ msgstr "" msgid "Compute Planckian fit" msgstr "Calculer l'ajustement de Planck" -msgid "`test_signal_planckian_fit `_" +msgid "`test_signal_planckian_fit `_" msgstr "" msgid ":py:func:`polynomial_fit `" @@ -717,7 +717,7 @@ msgstr "" msgid "Compute polynomial fit" msgstr "Calculer l'ajustement polynomial" -msgid "`test_polynomial_fit `_" +msgid "`test_polynomial_fit `_" msgstr "" msgid ":py:func:`power `" @@ -726,7 +726,7 @@ msgstr "" msgid "Compute power with :py:data:`numpy.power`" msgstr "" -msgid "`test_signal_power `_" +msgid "`test_signal_power `_" msgstr "" msgid ":py:func:`product `" @@ -735,7 +735,7 @@ msgstr "" msgid "Compute the element-wise product of multiple signals" msgstr "" -msgid "`test_signal_product `_" +msgid "`test_signal_product `_" msgstr "" msgid ":py:func:`product_constant `" @@ -744,7 +744,7 @@ msgstr "" msgid "Compute the product of a signal and a constant value" msgstr "" -msgid "`test_signal_product_constant `_" +msgid "`test_signal_product_constant `_" msgstr "" msgid ":py:func:`psd `" @@ -753,7 +753,7 @@ msgstr "" msgid "Compute power spectral density" msgstr "" -msgid "`test_signal_psd `_" +msgid "`test_signal_psd `_" msgstr "" msgid ":py:func:`quadratic_difference `" @@ -762,7 +762,7 @@ msgstr "" msgid "Compute the normalized difference between two signals" msgstr "" -msgid "`test_signal_quadratic_difference `_" +msgid "`test_signal_quadratic_difference `_" msgstr "" msgid ":py:func:`real `" @@ -771,7 +771,7 @@ msgstr "" msgid "Compute real part" msgstr "Calculer la partie rĂ©elle" -msgid "`test_signal_real `_" +msgid "`test_signal_real `_" msgstr "" msgid ":py:func:`replace_x_by_other_y `" @@ -780,7 +780,7 @@ msgstr "" msgid "Create a new signal using Y from src1 and Y from src2 as X coordinates" msgstr "" -msgid "`test_replace_x_by_other_y `_" +msgid "`test_replace_x_by_other_y `_" msgstr "" msgid ":py:func:`resampling `" @@ -789,7 +789,7 @@ msgstr "" msgid "Resample data" msgstr "" -msgid "`test_signal_resampling `_" +msgid "`test_signal_resampling `_" msgstr "" msgid ":py:func:`reverse_x `" @@ -798,7 +798,7 @@ msgstr "" msgid "Reverse x-axis" msgstr "" -msgid "`test_signal_reverse_x `_" +msgid "`test_signal_reverse_x `_" msgstr "" msgid ":py:func:`sampling_rate_period `" @@ -807,7 +807,7 @@ msgstr "" msgid "Compute sampling rate and period" msgstr "" -msgid "`test_signal_sampling_rate_period `_" +msgid "`test_signal_sampling_rate_period `_" msgstr "" msgid ":py:func:`sigmoid_fit `" @@ -816,7 +816,7 @@ msgstr "" msgid "Compute sigmoid fit" msgstr "Calculer l'ajustement sigmoĂŻde" -msgid "`test_signal_sigmoid_fit `_" +msgid "`test_signal_sigmoid_fit `_" msgstr "" msgid ":py:func:`signals_to_image `" @@ -825,7 +825,7 @@ msgstr "" msgid "Combine multiple signals into an image" msgstr "" -msgid "`test_signal_signals_to_image `_" +msgid "`test_signal_signals_to_image `_" msgstr "" msgid ":py:func:`sinusoidal_fit `" @@ -834,7 +834,7 @@ msgstr "" msgid "Compute sinusoidal fit" msgstr "Calculer l'ajustement sinusoĂŻdal" -msgid "`test_sinusoidal_fit `_" +msgid "`test_sinusoidal_fit `_" msgstr "" msgid ":py:func:`sqrt `" @@ -843,7 +843,7 @@ msgstr "" msgid "Compute square root with :py:data:`numpy.sqrt`" msgstr "" -msgid "`test_signal_sqrt `_" +msgid "`test_signal_sqrt `_" msgstr "" msgid ":py:func:`standard_deviation `" @@ -852,7 +852,7 @@ msgstr "" msgid "Compute the element-wise standard deviation of multiple signals" msgstr "" -msgid "`test_signal_standard_deviation `_" +msgid "`test_signal_standard_deviation `_" msgstr "" msgid ":py:func:`stats `" @@ -861,7 +861,7 @@ msgstr "" msgid "Compute statistics on a signal" msgstr "" -msgid "`test_signal_stats_unit `_" +msgid "`test_signal_stats_unit `_" msgstr "" msgid ":py:func:`time_deviation `" @@ -870,7 +870,7 @@ msgstr "" msgid "Compute Time Deviation (TDEV)" msgstr "" -msgid "`test_signal_time_deviation `_" +msgid "`test_signal_time_deviation `_" msgstr "" msgid ":py:func:`to_cartesian `" @@ -879,7 +879,7 @@ msgstr "" msgid "Convert polar coordinates to Cartesian coordinates" msgstr "" -msgid "`test_signal_to_cartesian `_" +msgid "`test_signal_to_cartesian `_" msgstr "" msgid ":py:func:`to_polar `" @@ -888,7 +888,7 @@ msgstr "" msgid "Convert Cartesian coordinates to polar coordinates" msgstr "" -msgid "`test_signal_to_polar `_" +msgid "`test_signal_to_polar `_" msgstr "" msgid ":py:func:`total_variance `" @@ -897,7 +897,7 @@ msgstr "" msgid "Compute Total variance" msgstr "" -msgid "`test_signal_total_variance `_" +msgid "`test_signal_total_variance `_" msgstr "" msgid ":py:func:`transpose `" @@ -906,7 +906,7 @@ msgstr "" msgid "Transpose signal (swap X and Y axes)" msgstr "" -msgid "`test_signal_transpose `_" +msgid "`test_signal_transpose `_" msgstr "" msgid ":py:func:`twohalfgaussian_fit `" @@ -915,7 +915,7 @@ msgstr "" msgid "Compute two-half-Gaussian fit" msgstr "" -msgid "`test_signal_twohalfgaussian_fit `_" +msgid "`test_signal_twohalfgaussian_fit `_" msgstr "" msgid ":py:func:`voigt_fit `" @@ -924,7 +924,7 @@ msgstr "" msgid "Compute Voigt fit" msgstr "Calculer l'ajustement de Voigt" -msgid "`test_signal_voigt_fit `_" +msgid "`test_signal_voigt_fit `_" msgstr "" msgid ":py:func:`wiener `" @@ -933,19 +933,19 @@ msgstr "" msgid "Compute Wiener filter" msgstr "" -msgid "`test_signal_wiener `_" +msgid "`test_signal_wiener `_" msgstr "" msgid ":py:func:`x_at_minmax `" msgstr "" -msgid "`test_signal_x_at_minmax `_" +msgid "`test_signal_x_at_minmax `_" msgstr "" msgid ":py:func:`x_at_y `" msgstr "" -msgid "`test_signal_x_at_y `_" +msgid "`test_signal_x_at_y `_" msgstr "" msgid ":py:func:`xy_mode `" @@ -954,13 +954,13 @@ msgstr "" msgid "Simulate the X-Y mode of an oscilloscope" msgstr "" -msgid "`test_signal_xy_mode `_" +msgid "`test_signal_xy_mode `_" msgstr "" msgid ":py:func:`y_at_x `" msgstr "" -msgid "`test_signal_y_at_x `_" +msgid "`test_signal_y_at_x `_" msgstr "" msgid ":py:func:`zero_padding `" @@ -969,7 +969,7 @@ msgstr "" msgid "Compute zero padding" msgstr "" -msgid "`test_signal_zero_padding `_" +msgid "`test_signal_zero_padding `_" msgstr "" msgid "Image Compute Functions" @@ -984,7 +984,7 @@ msgstr "Etat de validation des fonctions de calcul image" msgid ":py:func:`absolute `" msgstr "" -msgid "`test_image_absolute `_" +msgid "`test_image_absolute `_" msgstr "" msgid ":py:func:`add_gaussian_noise `" @@ -993,7 +993,7 @@ msgstr "" msgid "Add Gaussian (normal) noise to the input image" msgstr "" -msgid "`test_image_add_gaussian_noise `_" +msgid "`test_image_add_gaussian_noise `_" msgstr "" msgid ":py:func:`add_poisson_noise `" @@ -1002,7 +1002,7 @@ msgstr "" msgid "Add Poisson noise to the input image" msgstr "" -msgid "`test_image_add_poisson_noise `_" +msgid "`test_image_add_poisson_noise `_" msgstr "" msgid ":py:func:`add_uniform_noise `" @@ -1011,7 +1011,7 @@ msgstr "" msgid "Add uniform noise to the input image" msgstr "" -msgid "`test_image_add_uniform_noise `_" +msgid "`test_image_add_uniform_noise `_" msgstr "" msgid ":py:func:`addition `" @@ -1020,7 +1020,7 @@ msgstr "" msgid "Add images in the list and return the result image object" msgstr "" -msgid "`test_image_addition `_" +msgid "`test_image_addition `_" msgstr "" msgid ":py:func:`addition_constant `" @@ -1029,7 +1029,7 @@ msgstr "" msgid "Add **dst** and a constant value and return the new result image object" msgstr "" -msgid "`test_image_addition_constant `_" +msgid "`test_image_addition_constant `_" msgstr "" msgid ":py:func:`adjust_gamma `" @@ -1038,7 +1038,7 @@ msgstr "" msgid "Gamma correction" msgstr "" -msgid "`test_adjust_gamma `_" +msgid "`test_adjust_gamma `_" msgstr "" msgid ":py:func:`adjust_log `" @@ -1047,7 +1047,7 @@ msgstr "" msgid "Compute log correction" msgstr "Calculer l'ajustement logarithmique" -msgid "`test_adjust_log `_" +msgid "`test_adjust_log `_" msgstr "" msgid ":py:func:`adjust_sigmoid `" @@ -1056,7 +1056,7 @@ msgstr "" msgid "Compute sigmoid correction" msgstr "Calculer l'ajustement sigmoĂŻde" -msgid "`test_adjust_sigmoid `_" +msgid "`test_adjust_sigmoid `_" msgstr "" msgid ":py:func:`arithmetic `" @@ -1065,7 +1065,7 @@ msgstr "" msgid "Compute arithmetic operation on two images" msgstr "" -msgid "`test_image_arithmetic `_" +msgid "`test_image_arithmetic `_" msgstr "" msgid ":py:func:`astype `" @@ -1074,7 +1074,7 @@ msgstr "" msgid "Convert image data type" msgstr "" -msgid "`test_image_astype `_" +msgid "`test_image_astype `_" msgstr "" msgid ":py:func:`average `" @@ -1083,7 +1083,7 @@ msgstr "" msgid "Compute the average of images in the list and return the result image object" msgstr "" -msgid "`test_image_average `_" +msgid "`test_image_average `_" msgstr "" msgid ":py:func:`average_profile `" @@ -1092,7 +1092,7 @@ msgstr "" msgid "Compute horizontal or vertical average profile" msgstr "" -msgid "`test_average_profile `_" +msgid "`test_average_profile `_" msgstr "" msgid ":py:func:`binning `" @@ -1101,7 +1101,7 @@ msgstr "" msgid "Binning: image pixel binning (or aggregation)" msgstr "" -msgid "`test_binning `_" +msgid "`test_binning `_" msgstr "" msgid ":py:func:`black_tophat `" @@ -1110,7 +1110,7 @@ msgstr "" msgid "Compute Black Top-Hat" msgstr "" -msgid "`test_black_tophat `_" +msgid "`test_black_tophat `_" msgstr "" msgid ":py:func:`blob_dog `" @@ -1119,7 +1119,7 @@ msgstr "" msgid "Compute blobs using Difference of Gaussian method" msgstr "" -msgid "`test_image_blob_dog `_" +msgid "`test_image_blob_dog `_" msgstr "" msgid ":py:func:`blob_doh `" @@ -1128,7 +1128,7 @@ msgstr "" msgid "Compute blobs using Determinant of Hessian method" msgstr "" -msgid "`test_image_blob_doh `_" +msgid "`test_image_blob_doh `_" msgstr "" msgid ":py:func:`blob_log `" @@ -1137,7 +1137,7 @@ msgstr "" msgid "Compute blobs using Laplacian of Gaussian method" msgstr "" -msgid "`test_image_blob_log `_" +msgid "`test_image_blob_log `_" msgstr "" msgid ":py:func:`blob_opencv `" @@ -1146,7 +1146,7 @@ msgstr "" msgid "Compute blobs using OpenCV" msgstr "" -msgid "`test_image_blob_opencv `_" +msgid "`test_image_blob_opencv `_" msgstr "" msgid ":py:func:`butterworth `" @@ -1155,7 +1155,7 @@ msgstr "" msgid "Compute Butterworth filter" msgstr "" -msgid "`test_butterworth `_" +msgid "`test_butterworth `_" msgstr "" msgid ":py:func:`calibration `" @@ -1164,7 +1164,7 @@ msgstr "" msgid "Compute polynomial calibration" msgstr "Calculer l'Ă©talonnage polynomial" -msgid "`test_image_calibration `_" +msgid "`test_image_calibration `_" msgstr "" msgid ":py:func:`canny `" @@ -1173,7 +1173,7 @@ msgstr "" msgid "Compute Canny filter" msgstr "" -msgid "`test_canny `_" +msgid "`test_canny `_" msgstr "" msgid ":py:func:`centroid `" @@ -1182,7 +1182,7 @@ msgstr "" msgid "Compute centroid" msgstr "" -msgid "`test_image_centroid `_" +msgid "`test_image_centroid `_" msgstr "" msgid ":py:func:`clip `" @@ -1191,7 +1191,7 @@ msgstr "" msgid "Apply clipping" msgstr "" -msgid "`test_image_clip `_" +msgid "`test_image_clip `_" msgstr "" msgid ":py:func:`closing `" @@ -1200,7 +1200,7 @@ msgstr "" msgid "Compute morphological closing" msgstr "" -msgid "`test_closing `_" +msgid "`test_closing `_" msgstr "" msgid ":py:func:`complex_from_magnitude_phase `" @@ -1209,7 +1209,7 @@ msgstr "" msgid "Combine magnitude and phase images into a complex image" msgstr "" -msgid "`test_image_complex_from_magnitude_phase `_" +msgid "`test_image_complex_from_magnitude_phase `_" msgstr "" msgid ":py:func:`complex_from_real_imag `" @@ -1218,7 +1218,7 @@ msgstr "" msgid "Combine two real images into a complex image using real + i * imag" msgstr "" -msgid "`test_image_complex_from_real_imag `_" +msgid "`test_image_complex_from_real_imag `_" msgstr "" msgid ":py:func:`contour_shape `" @@ -1228,7 +1228,7 @@ msgstr "" msgid "Compute contour shape" msgstr "Calculer le contraste" -msgid "`test_contour_shape `_" +msgid "`test_contour_shape `_" msgstr "" msgid ":py:func:`convolution `" @@ -1237,7 +1237,7 @@ msgstr "" msgid "Convolve an image with a kernel" msgstr "" -msgid "`test_image_convolution `_" +msgid "`test_image_convolution `_" msgstr "" msgid ":py:func:`deconvolution `" @@ -1246,7 +1246,7 @@ msgstr "" msgid "Deconvolve a kernel from an image using Fast Fourier Transform (FFT)" msgstr "" -msgid "`test_image_deconvolution `_" +msgid "`test_image_deconvolution `_" msgstr "" msgid ":py:func:`denoise_bilateral `" @@ -1255,7 +1255,7 @@ msgstr "" msgid "Compute bilateral filter denoising" msgstr "" -msgid "`test_denoise_bilateral `_" +msgid "`test_denoise_bilateral `_" msgstr "" msgid ":py:func:`denoise_tophat `" @@ -1264,7 +1264,7 @@ msgstr "" msgid "Denoise using White Top-Hat" msgstr "" -msgid "`test_denoise_tophat `_" +msgid "`test_denoise_tophat `_" msgstr "" msgid ":py:func:`denoise_tv `" @@ -1273,7 +1273,7 @@ msgstr "" msgid "Compute Total Variation denoising" msgstr "" -msgid "`test_denoise_tv `_" +msgid "`test_denoise_tv `_" msgstr "" msgid ":py:func:`denoise_wavelet `" @@ -1282,7 +1282,7 @@ msgstr "" msgid "Compute Wavelet denoising" msgstr "" -msgid "`test_denoise_wavelet `_" +msgid "`test_denoise_wavelet `_" msgstr "" msgid ":py:func:`difference `" @@ -1291,7 +1291,7 @@ msgstr "" msgid "Compute difference between two images" msgstr "" -msgid "`test_image_difference `_" +msgid "`test_image_difference `_" msgstr "" msgid ":py:func:`difference_constant `" @@ -1300,7 +1300,7 @@ msgstr "" msgid "Subtract a constant value from an image and return the new result image object" msgstr "" -msgid "`test_image_difference_constant `_" +msgid "`test_image_difference_constant `_" msgstr "" msgid ":py:func:`dilation `" @@ -1309,7 +1309,7 @@ msgstr "" msgid "Compute Dilation" msgstr "Calculer la dilatation" -msgid "`test_dilation `_" +msgid "`test_dilation `_" msgstr "" msgid ":py:func:`division `" @@ -1318,7 +1318,7 @@ msgstr "" msgid "Compute division between two images" msgstr "" -msgid "`test_image_division `_" +msgid "`test_image_division `_" msgstr "" msgid ":py:func:`division_constant `" @@ -1327,7 +1327,7 @@ msgstr "" msgid "Divide an image by a constant value and return the new result image object" msgstr "" -msgid "`test_image_division_constant `_" +msgid "`test_image_division_constant `_" msgstr "" msgid ":py:func:`enclosing_circle `" @@ -1336,7 +1336,7 @@ msgstr "" msgid "Compute minimum enclosing circle" msgstr "" -msgid "`test_image_enclosing_circle `_" +msgid "`test_image_enclosing_circle `_" msgstr "" msgid ":py:func:`equalize_adapthist `" @@ -1345,7 +1345,7 @@ msgstr "" msgid "Adaptive histogram equalization" msgstr "" -msgid "`test_equalize_adapthist `_" +msgid "`test_equalize_adapthist `_" msgstr "" msgid ":py:func:`equalize_hist `" @@ -1354,7 +1354,7 @@ msgstr "" msgid "Histogram equalization" msgstr "" -msgid "`test_equalize_hist `_" +msgid "`test_equalize_hist `_" msgstr "" msgid ":py:func:`erase `" @@ -1363,7 +1363,7 @@ msgstr "" msgid "Erase an area of the image using the mean value of the image" msgstr "" -msgid "`test_erase `_" +msgid "`test_erase `_" msgstr "" msgid ":py:func:`erosion `" @@ -1372,13 +1372,13 @@ msgstr "" msgid "Compute Erosion" msgstr "Calculer l'Ă©rosion" -msgid "`test_erosion `_" +msgid "`test_erosion `_" msgstr "" msgid ":py:func:`exp `" msgstr "" -msgid "`test_image_exp `_" +msgid "`test_image_exp `_" msgstr "" msgid ":py:func:`extract_roi `" @@ -1387,13 +1387,13 @@ msgstr "" msgid "Extract single ROI" msgstr "" -msgid "`test_image_extract_roi `_" +msgid "`test_image_extract_roi `_" msgstr "" msgid ":py:func:`extract_rois `" msgstr "" -msgid "`test_image_extract_rois `_" +msgid "`test_image_extract_rois `_" msgstr "" msgid ":py:func:`farid `" @@ -1402,7 +1402,7 @@ msgstr "" msgid "Compute Farid filter" msgstr "" -msgid "`test_farid `_" +msgid "`test_farid `_" msgstr "" msgid ":py:func:`farid_h `" @@ -1411,7 +1411,7 @@ msgstr "" msgid "Compute horizontal Farid filter" msgstr "" -msgid "`test_farid_h `_" +msgid "`test_farid_h `_" msgstr "" msgid ":py:func:`farid_v `" @@ -1420,13 +1420,13 @@ msgstr "" msgid "Compute vertical Farid filter" msgstr "" -msgid "`test_farid_v `_" +msgid "`test_farid_v `_" msgstr "" msgid ":py:func:`fft `" msgstr "" -msgid "`test_image_fft `_" +msgid "`test_image_fft `_" msgstr "" msgid ":py:func:`flatfield `" @@ -1435,7 +1435,7 @@ msgstr "" msgid "Compute flat field correction" msgstr "Calculer la correction de champ plat" -msgid "`test_flatfield `_" +msgid "`test_flatfield `_" msgstr "" msgid ":py:func:`fliph `" @@ -1444,7 +1444,7 @@ msgstr "" msgid "Flip data horizontally" msgstr "" -msgid "`test_image_fliph `_" +msgid "`test_image_fliph `_" msgstr "" msgid ":py:func:`flipv `" @@ -1453,13 +1453,13 @@ msgstr "" msgid "Flip data vertically" msgstr "" -msgid "`test_image_flipv `_" +msgid "`test_image_flipv `_" msgstr "" msgid ":py:func:`gaussian_filter `" msgstr "" -msgid "`test_image_gaussian_filter `_" +msgid "`test_image_gaussian_filter `_" msgstr "" msgid ":py:func:`gaussian_freq_filter `" @@ -1468,7 +1468,7 @@ msgstr "" msgid "Apply a Gaussian filter in the frequency domain" msgstr "" -msgid "`test_gaussian_freq_filter `_" +msgid "`test_gaussian_freq_filter `_" msgstr "" msgid ":py:func:`histogram `" @@ -1477,7 +1477,7 @@ msgstr "" msgid "Compute histogram of the image data," msgstr "" -msgid "`test_image_histogram `_" +msgid "`test_image_histogram `_" msgstr "" msgid ":py:func:`horizontal_projection `" @@ -1486,7 +1486,7 @@ msgstr "" msgid "Compute the sum of pixel intensities along each col. (projection on the x-axis)" msgstr "" -msgid "`test_image_horizontal_projection `_" +msgid "`test_image_horizontal_projection `_" msgstr "" msgid ":py:func:`hough_circle_peaks `" @@ -1495,7 +1495,7 @@ msgstr "" msgid "Compute Hough circles" msgstr "" -msgid "`test_image_hough_circle_peaks `_" +msgid "`test_image_hough_circle_peaks `_" msgstr "" msgid ":py:func:`ifft `" @@ -1504,13 +1504,13 @@ msgstr "" msgid "Compute inverse FFT" msgstr "" -msgid "`test_image_ifft `_" +msgid "`test_image_ifft `_" msgstr "" msgid ":py:func:`imag `" msgstr "" -msgid "`test_image_imag `_" +msgid "`test_image_imag `_" msgstr "" msgid ":py:func:`inverse `" @@ -1519,7 +1519,7 @@ msgstr "" msgid "Compute the inverse of an image and return the new result image object" msgstr "" -msgid "`test_image_inverse `_" +msgid "`test_image_inverse `_" msgstr "" msgid ":py:func:`laplace `" @@ -1528,7 +1528,7 @@ msgstr "" msgid "Compute Laplace filter" msgstr "" -msgid "`test_laplace `_" +msgid "`test_laplace `_" msgstr "" msgid ":py:func:`line_profile `" @@ -1537,7 +1537,7 @@ msgstr "" msgid "Compute horizontal or vertical profile" msgstr "" -msgid "`test_line_profile `_" +msgid "`test_line_profile `_" msgstr "" msgid ":py:func:`log10 `" @@ -1546,7 +1546,7 @@ msgstr "" msgid "Compute log10 with :py:data:`numpy.log10`" msgstr "" -msgid "`test_image_log10 `_" +msgid "`test_image_log10 `_" msgstr "" msgid ":py:func:`log10_z_plus_n `" @@ -1555,31 +1555,31 @@ msgstr "" msgid "Compute log10(z+n) with :py:data:`numpy.log10`" msgstr "" -msgid "`test_image_log10_z_plus_n `_" +msgid "`test_image_log10_z_plus_n `_" msgstr "" msgid ":py:func:`magnitude_spectrum `" msgstr "" -msgid "`test_image_magnitude_spectrum `_" +msgid "`test_image_magnitude_spectrum `_" msgstr "" msgid ":py:func:`moving_average `" msgstr "" -msgid "`test_image_moving_average `_" +msgid "`test_image_moving_average `_" msgstr "" msgid ":py:func:`moving_median `" msgstr "" -msgid "`test_image_moving_median `_" +msgid "`test_image_moving_median `_" msgstr "" msgid ":py:func:`normalize `" msgstr "" -msgid "`test_image_normalize `_" +msgid "`test_image_normalize `_" msgstr "" msgid ":py:func:`offset_correction `" @@ -1588,7 +1588,7 @@ msgstr "" msgid "Apply offset correction" msgstr "" -msgid "`test_image_offset_correction `_" +msgid "`test_image_offset_correction `_" msgstr "" msgid ":py:func:`opening `" @@ -1597,7 +1597,7 @@ msgstr "" msgid "Compute morphological opening" msgstr "" -msgid "`test_opening `_" +msgid "`test_opening `_" msgstr "" msgid ":py:func:`peak_detection `" @@ -1606,7 +1606,7 @@ msgstr "" msgid "Compute 2D peak detection" msgstr "" -msgid "`test_image_peak_detection `_" +msgid "`test_image_peak_detection `_" msgstr "" msgid ":py:func:`phase `" @@ -1615,13 +1615,13 @@ msgstr "" msgid "Compute the phase (argument) of a complex image" msgstr "" -msgid "`test_image_phase `_" +msgid "`test_image_phase `_" msgstr "" msgid ":py:func:`phase_spectrum `" msgstr "" -msgid "`test_image_phase_spectrum `_" +msgid "`test_image_phase_spectrum `_" msgstr "" msgid ":py:func:`prewitt `" @@ -1630,7 +1630,7 @@ msgstr "" msgid "Compute Prewitt filter" msgstr "" -msgid "`test_prewitt `_" +msgid "`test_prewitt `_" msgstr "" msgid ":py:func:`prewitt_h `" @@ -1639,7 +1639,7 @@ msgstr "" msgid "Compute horizontal Prewitt filter" msgstr "" -msgid "`test_prewitt_h `_" +msgid "`test_prewitt_h `_" msgstr "" msgid ":py:func:`prewitt_v `" @@ -1648,7 +1648,7 @@ msgstr "" msgid "Compute vertical Prewitt filter" msgstr "" -msgid "`test_prewitt_v `_" +msgid "`test_prewitt_v `_" msgstr "" msgid ":py:func:`product `" @@ -1657,7 +1657,7 @@ msgstr "" msgid "Multiply images in the list and return the result image object" msgstr "" -msgid "`test_image_product `_" +msgid "`test_image_product `_" msgstr "" msgid ":py:func:`product_constant `" @@ -1666,13 +1666,13 @@ msgstr "" msgid "Multiply **dst** by a constant value and return the new result image object" msgstr "" -msgid "`test_image_product_constant `_" +msgid "`test_image_product_constant `_" msgstr "" msgid ":py:func:`psd `" msgstr "" -msgid "`test_image_psd `_" +msgid "`test_image_psd `_" msgstr "" msgid ":py:func:`quadratic_difference `" @@ -1681,7 +1681,7 @@ msgstr "" msgid "Compute quadratic difference between two images" msgstr "" -msgid "`test_image_quadratic_difference `_" +msgid "`test_image_quadratic_difference `_" msgstr "" msgid ":py:func:`radial_profile `" @@ -1690,13 +1690,13 @@ msgstr "" msgid "Compute radial profile around the centroid" msgstr "" -msgid "`test_radial_profile `_" +msgid "`test_radial_profile `_" msgstr "" msgid ":py:func:`real `" msgstr "" -msgid "`test_image_real `_" +msgid "`test_image_real `_" msgstr "" msgid ":py:func:`resampling `" @@ -1705,7 +1705,7 @@ msgstr "" msgid "Resample image to new coordinate grid using interpolation" msgstr "" -msgid "`test_image_resampling `_" +msgid "`test_image_resampling `_" msgstr "" msgid ":py:func:`rescale_intensity `" @@ -1714,7 +1714,7 @@ msgstr "" msgid "Rescale image intensity levels" msgstr "" -msgid "`test_rescale_intensity `_" +msgid "`test_rescale_intensity `_" msgstr "" msgid ":py:func:`resize `" @@ -1723,7 +1723,7 @@ msgstr "" msgid "Zooming function" msgstr "Fonction de zoom" -msgid "`test_image_resize `_" +msgid "`test_image_resize `_" msgstr "" msgid ":py:func:`roberts `" @@ -1732,7 +1732,7 @@ msgstr "" msgid "Compute Roberts filter" msgstr "" -msgid "`test_roberts `_" +msgid "`test_roberts `_" msgstr "" msgid ":py:func:`rotate `" @@ -1741,7 +1741,7 @@ msgstr "" msgid "Rotate data" msgstr "" -msgid "`test_image_rotate `_" +msgid "`test_image_rotate `_" msgstr "" msgid ":py:func:`rotate270 `" @@ -1750,7 +1750,7 @@ msgstr "" msgid "Rotate data 270°" msgstr "" -msgid "`test_image_rotate270 `_" +msgid "`test_image_rotate270 `_" msgstr "" msgid ":py:func:`rotate90 `" @@ -1759,7 +1759,7 @@ msgstr "" msgid "Rotate data 90°" msgstr "" -msgid "`test_image_rotate90 `_" +msgid "`test_image_rotate90 `_" msgstr "" msgid ":py:func:`scharr `" @@ -1768,7 +1768,7 @@ msgstr "" msgid "Compute Scharr filter" msgstr "" -msgid "`test_scharr `_" +msgid "`test_scharr `_" msgstr "" msgid ":py:func:`scharr_h `" @@ -1777,7 +1777,7 @@ msgstr "" msgid "Compute horizontal Scharr filter" msgstr "" -msgid "`test_scharr_h `_" +msgid "`test_scharr_h `_" msgstr "" msgid ":py:func:`scharr_v `" @@ -1786,7 +1786,7 @@ msgstr "" msgid "Compute vertical Scharr filter" msgstr "" -msgid "`test_scharr_v `_" +msgid "`test_scharr_v `_" msgstr "" msgid ":py:func:`segment_profile `" @@ -1795,7 +1795,7 @@ msgstr "" msgid "Compute segment profile" msgstr "" -msgid "`test_segment_profile `_" +msgid "`test_segment_profile `_" msgstr "" msgid ":py:func:`set_uniform_coords `" @@ -1804,7 +1804,7 @@ msgstr "" msgid "Convert image to uniform coordinate system" msgstr "" -msgid "`test_set_uniform_coords `_" +msgid "`test_set_uniform_coords `_" msgstr "" msgid ":py:func:`sobel `" @@ -1813,7 +1813,7 @@ msgstr "" msgid "Compute Sobel filter" msgstr "" -msgid "`test_sobel `_" +msgid "`test_sobel `_" msgstr "" msgid ":py:func:`sobel_h `" @@ -1822,7 +1822,7 @@ msgstr "" msgid "Compute horizontal Sobel filter" msgstr "" -msgid "`test_sobel_h `_" +msgid "`test_sobel_h `_" msgstr "" msgid ":py:func:`sobel_v `" @@ -1831,7 +1831,7 @@ msgstr "" msgid "Compute vertical Sobel filter" msgstr "" -msgid "`test_sobel_v `_" +msgid "`test_sobel_v `_" msgstr "" msgid ":py:func:`standard_deviation `" @@ -1840,7 +1840,7 @@ msgstr "" msgid "Compute the element-wise standard deviation of multiple images" msgstr "" -msgid "`test_image_standard_deviation `_" +msgid "`test_image_standard_deviation `_" msgstr "" msgid ":py:func:`stats `" @@ -1849,7 +1849,7 @@ msgstr "" msgid "Compute statistics on an image" msgstr "" -msgid "`test_image_stats_unit `_" +msgid "`test_image_stats_unit `_" msgstr "" msgid ":py:func:`threshold `" @@ -1858,7 +1858,7 @@ msgstr "" msgid "Compute the threshold, using one of the available algorithms" msgstr "" -msgid "`test_threshold `_" +msgid "`test_threshold `_" msgstr "" msgid ":py:func:`threshold_isodata `" @@ -1867,7 +1867,7 @@ msgstr "" msgid "Compute the threshold using the Isodata algorithm with default parameters" msgstr "" -msgid "`test_threshold_isodata `_" +msgid "`test_threshold_isodata `_" msgstr "" msgid ":py:func:`threshold_li `" @@ -1876,7 +1876,7 @@ msgstr "" msgid "Compute the threshold using the Li algorithm with default parameters" msgstr "" -msgid "`test_threshold_li `_" +msgid "`test_threshold_li `_" msgstr "" msgid ":py:func:`threshold_mean `" @@ -1885,7 +1885,7 @@ msgstr "" msgid "Compute the threshold using the Mean algorithm" msgstr "" -msgid "`test_threshold_mean `_" +msgid "`test_threshold_mean `_" msgstr "" msgid ":py:func:`threshold_minimum `" @@ -1894,7 +1894,7 @@ msgstr "" msgid "Compute the threshold using the Minimum algorithm with default parameters" msgstr "" -msgid "`test_threshold_minimum `_" +msgid "`test_threshold_minimum `_" msgstr "" msgid ":py:func:`threshold_otsu `" @@ -1903,7 +1903,7 @@ msgstr "" msgid "Compute the threshold using the Otsu algorithm with default parameters" msgstr "" -msgid "`test_threshold_otsu `_" +msgid "`test_threshold_otsu `_" msgstr "" msgid ":py:func:`threshold_triangle `" @@ -1912,7 +1912,7 @@ msgstr "" msgid "Compute the threshold using the Triangle algorithm with default parameters" msgstr "" -msgid "`test_threshold_triangle `_" +msgid "`test_threshold_triangle `_" msgstr "" msgid ":py:func:`threshold_yen `" @@ -1921,7 +1921,7 @@ msgstr "" msgid "Compute the threshold using the Yen algorithm with default parameters" msgstr "" -msgid "`test_threshold_yen `_" +msgid "`test_threshold_yen `_" msgstr "" msgid ":py:func:`translate `" @@ -1930,7 +1930,7 @@ msgstr "" msgid "Translate data" msgstr "" -msgid "`test_image_translate `_" +msgid "`test_image_translate `_" msgstr "" msgid ":py:func:`transpose `" @@ -1939,7 +1939,7 @@ msgstr "" msgid "Transpose image" msgstr "" -msgid "`test_image_transpose `_" +msgid "`test_image_transpose `_" msgstr "" msgid ":py:func:`vertical_projection `" @@ -1948,7 +1948,7 @@ msgstr "" msgid "Compute the sum of pixel intensities along each row (projection on the y-axis)" msgstr "" -msgid "`test_image_vertical_projection `_" +msgid "`test_image_vertical_projection `_" msgstr "" msgid ":py:func:`white_tophat `" @@ -1957,13 +1957,13 @@ msgstr "" msgid "Compute White Top-Hat" msgstr "" -msgid "`test_white_tophat `_" +msgid "`test_white_tophat `_" msgstr "" msgid ":py:func:`wiener `" msgstr "" -msgid "`test_image_wiener `_" +msgid "`test_image_wiener `_" msgstr "" msgid ":py:func:`zero_padding `" @@ -1972,6 +1972,6 @@ msgstr "" msgid "Zero-padding: add zeros to image borders" msgstr "" -msgid "`test_image_zero_padding `_" +msgid "`test_image_zero_padding `_" msgstr "" diff --git a/doc/locale/fr/LC_MESSAGES/intro/installation.po b/doc/locale/fr/LC_MESSAGES/intro/installation.po index 1073985cf..3c9cbe7c6 100644 --- a/doc/locale/fr/LC_MESSAGES/intro/installation.po +++ b/doc/locale/fr/LC_MESSAGES/intro/installation.po @@ -208,7 +208,7 @@ msgstr "Langage de programmation Python" msgid "guidata" msgstr "" -msgid ">= 3.13.4" +msgid ">= 3.14.4" msgstr "" msgid "Automatic GUI generation for easy dataset editing and display" @@ -217,7 +217,7 @@ msgstr "GĂ©nĂ©ration automatique d'interfaces graphiques pour l'Ă©dition et l'af msgid "PlotPy" msgstr "" -msgid ">= 2.8.2" +msgid ">= 2.10.0" msgstr "" msgid "Curve and image plotting tools for Python/Qt applications" @@ -226,7 +226,7 @@ msgstr "Outils de tracĂ© de courbes et d'images pour les applications Python/Qt" msgid "Sigima" msgstr "" -msgid ">= 1.1.2" +msgid ">= 1.1.4" msgstr "" msgid "Scientific computing engine for 1D signals and 2D images, part of the DataLab open-source platform." @@ -415,6 +415,9 @@ msgstr "" msgid "Bootstrap-based Sphinx theme from the PyData community" msgstr "ThĂšme Bootstrap pour Sphinx de la communautĂ© PyData" +msgid "sphinxcontrib-svg2pdfconverter[CairoSVG]" +msgstr "" + msgid "Optional modules for running test suite:" msgstr "Modules optionnels pour l'exĂ©cution de la suite de tests :" @@ -438,3 +441,4 @@ msgstr "" msgid "Python 3.11 and PyQt5 are the reference for production release" msgstr "Python 3.11 et PyQt5 sont les rĂ©fĂ©rences pour la version de production" + diff --git a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po index 92df42846..7714e6810 100644 --- a/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po +++ b/doc/locale/fr/LC_MESSAGES/release_notes/release_1.02.po @@ -15,6 +15,84 @@ msgstr "" msgid "Version 1.2" msgstr "Version 1.2" +msgid "DataLab Version 1.2.1" +msgstr "DataLab Version 1.2.1" + +msgid "đŸ› ïž Bug Fixes" +msgstr "đŸ› ïž Corrections de bugs" + +msgid "**Signal panel menus:**" +msgstr "**Menus du panneau Signal :**" + +msgid "Restored the \"Linear calibration\" entry in the \"Processing > Axis transformation\" menu of the Signal panel — it had been inadvertently dropped during a menu reorganization and was no longer reachable from the menu bar, even though the underlying computation was still available (fixes [Issue #312](https://github.com/DataLab-Platform/DataLab/issues/312))" +msgstr "Restauration de l'entrĂ©e « Étalonnage linĂ©aire » dans le menu « Traitement > Transformation des axes » du panneau Signal — elle avait Ă©tĂ© supprimĂ©e par inadvertance lors d'une rĂ©organisation des menus et n'Ă©tait plus accessible depuis la barre de menus, alors mĂȘme que le calcul sous-jacent restait disponible (corrige [Issue #312](https://github.com/DataLab-Platform/DataLab/issues/312))" + +msgid "**Signal panel — Y range cursor:**" +msgstr "**Panneau Signal — curseur de plage Y :**" + +msgid "Fixed the Y range cursor annotation displaying an incorrect inequality (e.g. `5 < y < 2`) and a negative ∆y when the top cursor was dragged below the bottom cursor — the annotation now always shows values in sorted order with a positive range width (fixes [Issue #306](https://github.com/DataLab-Platform/DataLab/issues/306))" +msgstr "Correction de l'annotation du curseur de plage Y affichant une inĂ©galitĂ© incorrecte (par ex. `5 < y < 2`) et un ∆y nĂ©gatif lorsque le curseur supĂ©rieur Ă©tait glissĂ© en dessous du curseur infĂ©rieur — l'annotation affiche dĂ©sormais toujours les valeurs dans l'ordre croissant avec une largeur de plage positive (corrige [Issue #306](https://github.com/DataLab-Platform/DataLab/issues/306))" + +msgid "**Image panel — Z-axis logarithmic scale:**" +msgstr "**Panneau Image — Ă©chelle logarithmique de l'axe Z :**" + +msgid "Fixed the \"Base-10 logarithmic Z axis\" toolbar action being permanently greyed out in the image panel — the tool now works correctly for all image types (fixes [Issue #313](https://github.com/DataLab-Platform/DataLab/issues/313), fixed upstream in PlotPy ≄ 2.10.0)" +msgstr "Correction de l'action « Axe Z logarithmique base 10 » de la barre d'outils restant systĂ©matiquement grisĂ©e dans le panneau Image — l'outil fonctionne dĂ©sormais correctement pour tous les types d'images (corrige [Issue #313](https://github.com/DataLab-Platform/DataLab/issues/313), corrigĂ© en amont dans PlotPy ≄ 2.10.0)" + +msgid "**Image panel — contour detection:**" +msgstr "**Panneau Image — dĂ©tection de contours :**" + +msgid "Fixed ellipse and circle contour detection producing incorrect results (wrong positions and sizes) due to swapped X/Y coordinates and missing unit conversions in the scikit-image model fitting code (fixes [Issue #326](https://github.com/DataLab-Platform/DataLab/issues/326), fixed upstream in Sigima ≄ 1.1.3)" +msgstr "Correction de la dĂ©tection de contours ellipse et cercle produisant des rĂ©sultats incorrects (positions et tailles erronĂ©es) en raison de coordonnĂ©es X/Y inversĂ©es et de conversions d'unitĂ©s manquantes dans le code d'ajustement de modĂšle scikit-image (corrige [Issue #326](https://github.com/DataLab-Platform/DataLab/issues/326), corrigĂ© en amont dans Sigima ≄ 1.1.3)" + +msgid "**ROI editor:**" +msgstr "**Éditeur de ROI :**" + +msgid "Fixed the ROI editor dialog ignoring non-linear axis scales (e.g. logarithmic) of the source plot — the dialog now preserves the same axis scale configuration as the main panel (fixes [Issue #315](https://github.com/DataLab-Platform/DataLab/issues/315))" +msgstr "Correction de la boĂźte de dialogue de l'Ă©diteur de ROI ignorant les Ă©chelles d'axes non linĂ©aires (par ex. logarithmique) du graphique source — la boĂźte de dialogue prĂ©serve dĂ©sormais la mĂȘme configuration d'Ă©chelle d'axes que le panneau principal (corrige [Issue #315](https://github.com/DataLab-Platform/DataLab/issues/315))" + +msgid "**Theme and display:**" +msgstr "**ThĂšme et affichage :**" + +msgid "Fixed plot marker and shape colors being reverted to PlotPy defaults (yellow) instead of DataLab's configured colors (red) when the color mode was explicitly set to \"light\" or \"dark\" in settings — the custom color overrides are now re-applied after each theme switch (fixes [Issue #297](https://github.com/DataLab-Platform/DataLab/issues/297))" +msgstr "Correction des couleurs des marqueurs et formes des graphiques revenant aux valeurs par dĂ©faut de PlotPy (jaune) au lieu des couleurs configurĂ©es de DataLab (rouge) lorsque le mode de couleur Ă©tait explicitement dĂ©fini sur « clair » ou « sombre » dans les paramĂštres — les surcharges de couleurs personnalisĂ©es sont dĂ©sormais rĂ©appliquĂ©es aprĂšs chaque changement de thĂšme (corrige [Issue #297](https://github.com/DataLab-Platform/DataLab/issues/297))" + +msgid "Fixed UI elements (text, icons, dialog layouts) not scaling properly with high-DPI display settings — DataSet HTML rendering, icon sizes, and viewport dimensions now adapt to the system scale factor (fixes [Issue #317](https://github.com/DataLab-Platform/DataLab/issues/317), fixed upstream in guidata ≄ 3.14.4)" +msgstr "Correction des Ă©lĂ©ments d'interface (texte, icĂŽnes, dispositions des boĂźtes de dialogue) ne s'adaptant pas correctement aux paramĂštres d'affichage haute rĂ©solution (High-DPI) — le rendu HTML des DataSet, les tailles d'icĂŽnes et les dimensions de la zone d'affichage s'adaptent dĂ©sormais au facteur d'Ă©chelle du systĂšme (corrige [Issue #317](https://github.com/DataLab-Platform/DataLab/issues/317), corrigĂ© en amont dans guidata ≄ 3.14.4)" + +msgid "**Image properties editor:**" +msgstr "**Éditeur de propriĂ©tĂ©s d'image :**" + +msgid "Fixed pixel size (`Δx` / `Δy`) input field corrupting typed values — most digits typed after the first were misinterpreted as decimal places due to a reactive update loop in the parameter editing widget (fixes [Issue #320](https://github.com/DataLab-Platform/DataLab/issues/320), fixed upstream in guidata ≄ 3.14.4)" +msgstr "Correction du champ de saisie de la taille de pixel (`Δx` / `Δy`) corrompant les valeurs saisies — la plupart des chiffres tapĂ©s aprĂšs le premier Ă©taient interprĂ©tĂ©s comme des dĂ©cimales en raison d'une boucle de mise Ă  jour rĂ©active dans le widget d'Ă©dition de paramĂštres (corrige [Issue #320](https://github.com/DataLab-Platform/DataLab/issues/320), corrigĂ© en amont dans guidata ≄ 3.14.4)" + +msgid "**Debug environment variable renamed:**" +msgstr "**Renommage de la variable d'environnement de dĂ©bogage :**" + +msgid "Renamed the debug environment variable from `DEBUG` to `DATALAB_DEBUG` — the generic `DEBUG` name collided with widely-used third-party conventions (Django, Flask, Node.js tooling, CI systems) and could silently reset the user configuration file at startup when set for unrelated reasons. Setting `DATALAB_DEBUG=1` now activates debug mode; the bare `DEBUG` variable is ignored (fixes [Issue #319](https://github.com/DataLab-Platform/DataLab/issues/319))" +msgstr "Renommage de la variable d'environnement de dĂ©bogage de `DEBUG` Ă  `DATALAB_DEBUG` — le nom gĂ©nĂ©rique `DEBUG` entrait en conflit avec des conventions largement utilisĂ©es par des tiers (Django, Flask, outils Node.js, systĂšmes CI) et pouvait rĂ©initialiser silencieusement le fichier de configuration utilisateur au dĂ©marrage lorsqu'il Ă©tait dĂ©fini pour des raisons non liĂ©es. DĂ©finir `DATALAB_DEBUG=1` active dĂ©sormais le mode dĂ©bogage ; la variable `DEBUG` seule est ignorĂ©e (corrige [Issue #319](https://github.com/DataLab-Platform/DataLab/issues/319))" + +msgid "**Remote control API:**" +msgstr "**API de contrĂŽle Ă  distance :**" + +msgid "Exposed `get_current_object_uuid()` on the proxy API, making it available through XML-RPC and Web API" +msgstr "Exposition de `get_current_object_uuid()` sur l'API proxy, la rendant disponible via XML-RPC et l'API Web" + +msgid "🔧 Improvements" +msgstr "🔧 AmĂ©liorations" + +msgid "**Compatibility:**" +msgstr "**CompatibilitĂ© :**" + +msgid "Updated minimum guidata requirement from 3.14.3 to 3.14.4 (high DPI and screen scaling issue, dataset input field fix, add secure build CLI cmd)" +msgstr "Mise Ă  jour de la version minimale requise de guidata de 3.14.3 Ă  3.14.4 (problĂšme de haute rĂ©solution et de mise Ă  l'Ă©chelle de l'Ă©cran, correction du champ de saisie DataSet, ajout de la commande CLI de compilation sĂ©curisĂ©e)" + +msgid "Updated minimum PlotPy requirement from 2.8.2 to 2.10.0 (Z-axis log scale fix, toolbar overflow button visibility in dark theme, PythonQwt 0.16.0 optimization)" +msgstr "Mise Ă  jour de la version minimale requise de PlotPy de 2.8.2 Ă  2.10.0 (correction de l'Ă©chelle logarithmique de l'axe Z, visibilitĂ© du bouton de dĂ©bordement de la barre d'outils en thĂšme sombre, optimisation PythonQwt 0.16.0)" + +msgid "Updated minimum Sigima requirement from 1.1.2 to 1.1.3 (ellipse/circle contour detection fix)" +msgstr "Mise Ă  jour de la version minimale requise de Sigima de 1.1.2 Ă  1.1.3 (correction de la dĂ©tection de contours ellipse/cercle)" + msgid "DataLab Version 1.2.0 (2026-04-20)" msgstr "DataLab Version 1.2.0 (20/04/2026)" @@ -114,18 +192,13 @@ msgstr "Mise Ă  jour de la documentation des plugins pour dĂ©crire la nouvelle b msgid "Updated third-party plugin development guide with new template references and test coverage information" msgstr "Mise Ă  jour du guide de dĂ©veloppement des plugins tiers avec de nouvelles rĂ©fĂ©rences de modĂšles et des informations sur la couverture des tests" +#, python-brace-format msgid "Expanded Web API reference: documented the binary data transfer options (`?compress=false` for faster uncompressed NPZ downloads, `?overwrite=true` for atomic replacement of existing objects), the in-place `PUT /objects/{name}` endpoint that updates an object while preserving its identity, group membership and position, and the new \"Computation\" section listing the `/select` and `/calc` endpoints used to drive DataLab computations remotely" msgstr "Enrichissement de la rĂ©fĂ©rence de l'API Web : documentation des options de transfert binaire (`?compress=false` pour des tĂ©lĂ©chargements NPZ non compressĂ©s plus rapides, `?overwrite=true` pour le remplacement atomique d'objets existants), du point d'entrĂ©e `PUT /objects/{name}` qui met Ă  jour un objet sur place en prĂ©servant son identitĂ©, son groupe d'appartenance et sa position, ainsi que de la nouvelle section « Calcul » listant les points d'entrĂ©e `/select` et `/calc` permettant de piloter les calculs DataLab Ă  distance" msgid "Updated French translations across all new and modified documentation pages" msgstr "Mise Ă  jour des traductions françaises sur toutes les pages de documentation nouvelles et modifiĂ©es" -msgid "🔧 Improvements" -msgstr "🔧 AmĂ©liorations" - -msgid "**Compatibility:**" -msgstr "**CompatibilitĂ© :**" - msgid "Officially support pandas 3.0.x (updated dependency constraint from `< 3.0` to `< 3.1`)" msgstr "Prise en charge officielle de pandas 3.0.x (contrainte de dĂ©pendance mise Ă  jour de `< 3.0` Ă  `< 3.1`)" @@ -156,9 +229,6 @@ msgstr "Simplification de la gestion des variables d'environnement en supprimant msgid "Fixed Coverage full VS Code task to properly use the `run_with_env.py` wrapper" msgstr "Correction de la tĂąche complĂšte Coverage dans VS Code pour utiliser correctement le wrapper `run_with_env.py`" -msgid "đŸ› ïž Bug Fixes" -msgstr "đŸ› ïž Corrections de bugs" - msgid "**HDF5 workspace - Table serialization:**" msgstr "**Espace de travail HDF5 - SĂ©rialisation des tables :**" diff --git a/doc/locale/fr/LC_MESSAGES/requirements.po b/doc/locale/fr/LC_MESSAGES/requirements.po index 846adab09..9686e4201 100644 --- a/doc/locale/fr/LC_MESSAGES/requirements.po +++ b/doc/locale/fr/LC_MESSAGES/requirements.po @@ -36,7 +36,7 @@ msgstr "Langage de programmation Python" msgid "guidata" msgstr "" -msgid ">= 3.13.4" +msgid ">= 3.14.4" msgstr "" msgid "Automatic GUI generation for easy dataset editing and display" @@ -45,7 +45,7 @@ msgstr "GĂ©nĂ©ration automatique d'interface graphique pour l'Ă©dition et l'affi msgid "PlotPy" msgstr "" -msgid ">= 2.8.2" +msgid ">= 2.10.0" msgstr "" msgid "Curve and image plotting tools for Python/Qt applications" @@ -54,7 +54,7 @@ msgstr "Outils de tracĂ© de courbes et d'images pour les applications Python/Qt" msgid "Sigima" msgstr "" -msgid ">= 1.1.2" +msgid ">= 1.1.4" msgstr "" msgid "Scientific computing engine for 1D signals and 2D images, part of the DataLab open-source platform." @@ -243,6 +243,9 @@ msgstr "" msgid "Bootstrap-based Sphinx theme from the PyData community" msgstr "ThĂšme Sphinx basĂ© sur Bootstrap de la communautĂ© PyData" +msgid "sphinxcontrib-svg2pdfconverter[CairoSVG]" +msgstr "" + msgid "Optional modules for running test suite:" msgstr "Modules optionnels pour exĂ©cuter la suite de tests :" @@ -263,3 +266,4 @@ msgstr "" msgid "The next generation HTTP client." msgstr "" + diff --git a/doc/release_notes/release_1.02.md b/doc/release_notes/release_1.02.md index c40aad273..ff21580ff 100644 --- a/doc/release_notes/release_1.02.md +++ b/doc/release_notes/release_1.02.md @@ -1,5 +1,54 @@ # Version 1.2 # +## DataLab Version 1.2.1 ## + +### đŸ› ïž Bug Fixes ### + +**Signal panel menus:** + +* Restored the "Linear calibration" entry in the "Processing > Axis transformation" menu of the Signal panel — it had been inadvertently dropped during a menu reorganization and was no longer reachable from the menu bar, even though the underlying computation was still available (fixes [Issue #312](https://github.com/DataLab-Platform/DataLab/issues/312)) + +**Signal panel — Y range cursor:** + +* Fixed the Y range cursor annotation displaying an incorrect inequality (e.g. `5 < y < 2`) and a negative ∆y when the top cursor was dragged below the bottom cursor — the annotation now always shows values in sorted order with a positive range width (fixes [Issue #306](https://github.com/DataLab-Platform/DataLab/issues/306)) + +**Image panel — Z-axis logarithmic scale:** + +* Fixed the "Base-10 logarithmic Z axis" toolbar action being permanently greyed out in the image panel — the tool now works correctly for all image types (fixes [Issue #313](https://github.com/DataLab-Platform/DataLab/issues/313), fixed upstream in PlotPy ≄ 2.10.0) + +**Image panel — contour detection:** + +* Fixed ellipse and circle contour detection producing incorrect results (wrong positions and sizes) due to swapped X/Y coordinates and missing unit conversions in the scikit-image model fitting code (fixes [Issue #326](https://github.com/DataLab-Platform/DataLab/issues/326), fixed upstream in Sigima ≄ 1.1.3) + +**ROI editor:** + +* Fixed the ROI editor dialog ignoring non-linear axis scales (e.g. logarithmic) of the source plot — the dialog now preserves the same axis scale configuration as the main panel (fixes [Issue #315](https://github.com/DataLab-Platform/DataLab/issues/315)) + +**Theme and display:** + +* Fixed plot marker and shape colors being reverted to PlotPy defaults (yellow) instead of DataLab's configured colors (red) when the color mode was explicitly set to "light" or "dark" in settings — the custom color overrides are now re-applied after each theme switch (fixes [Issue #297](https://github.com/DataLab-Platform/DataLab/issues/297)) +* Fixed UI elements (text, icons, dialog layouts) not scaling properly with high-DPI display settings — DataSet HTML rendering, icon sizes, and viewport dimensions now adapt to the system scale factor (fixes [Issue #317](https://github.com/DataLab-Platform/DataLab/issues/317), fixed upstream in guidata ≄ 3.14.4) + +**Image properties editor:** + +* Fixed pixel size (`Δx` / `Δy`) input field corrupting typed values — most digits typed after the first were misinterpreted as decimal places due to a reactive update loop in the parameter editing widget (fixes [Issue #320](https://github.com/DataLab-Platform/DataLab/issues/320), fixed upstream in guidata ≄ 3.14.4) + +**Debug environment variable renamed:** + +* Renamed the debug environment variable from `DEBUG` to `DATALAB_DEBUG` — the generic `DEBUG` name collided with widely-used third-party conventions (Django, Flask, Node.js tooling, CI systems) and could silently reset the user configuration file at startup when set for unrelated reasons. Setting `DATALAB_DEBUG=1` now activates debug mode; the bare `DEBUG` variable is ignored (fixes [Issue #319](https://github.com/DataLab-Platform/DataLab/issues/319)) + +**Remote control API:** + +* Exposed `get_current_object_uuid()` on the proxy API, making it available through XML-RPC and Web API + +### 🔧 Improvements ### + +**Compatibility:** + +* Updated minimum guidata requirement from 3.14.3 to 3.14.4 (high DPI and screen scaling issue, dataset input field fix, add secure build CLI cmd) +* Updated minimum PlotPy requirement from 2.8.2 to 2.10.0 (Z-axis log scale fix, toolbar overflow button visibility in dark theme, PythonQwt 0.16.0 optimization) +* Updated minimum Sigima requirement from 1.1.2 to 1.1.3 (ellipse/circle contour detection fix) + ## DataLab Version 1.2.0 (2026-04-20) ## ### ✹ New Features ### diff --git a/doc/requirements.rst b/doc/requirements.rst index 9c04723df..91cb3fa09 100644 --- a/doc/requirements.rst +++ b/doc/requirements.rst @@ -11,13 +11,13 @@ The `datalab-platform` package requires the following Python modules: - >=3.9, <4 - Python programming language * - guidata - - >= 3.13.4 + - >= 3.14.4 - Automatic GUI generation for easy dataset editing and display * - PlotPy - - >= 2.8.2 + - >= 2.10.0 - Curve and image plotting tools for Python/Qt applications * - Sigima - - >= 1.1.2 + - >= 1.1.4 - Scientific computing engine for 1D signals and 2D images, part of the DataLab open-source platform. * - NumPy - >= 1.22, < 2.5 @@ -121,6 +121,9 @@ Optional modules for building the documentation: * - pydata-sphinx-theme - - Bootstrap-based Sphinx theme from the PyData community + * - sphinxcontrib-svg2pdfconverter[CairoSVG] + - + - Optional modules for running test suite: diff --git a/doc/validation_statistics.csv b/doc/validation_statistics.csv index 074b5905b..3d79fd076 100644 --- a/doc/validation_statistics.csv +++ b/doc/validation_statistics.csv @@ -1,3 +1,3 @@ -Number of compute functions,97,115,212 -Number of validated compute functions,97,115,212 +Number of compute functions,96,115,211 +Number of validated compute functions,96,115,211 Percentage of validated compute functions,100%,100%,100% diff --git a/doc/validation_status_image.csv b/doc/validation_status_image.csv index f554075c2..eaac8024d 100644 --- a/doc/validation_status_image.csv +++ b/doc/validation_status_image.csv @@ -1,115 +1,115 @@ -:py:func:`absolute `,Compute absolute value with :py:data:`numpy.absolute`,`test_image_absolute `_ -:py:func:`add_gaussian_noise `,Add Gaussian (normal) noise to the input image,`test_image_add_gaussian_noise `_ -:py:func:`add_poisson_noise `,Add Poisson noise to the input image,`test_image_add_poisson_noise `_ -:py:func:`add_uniform_noise `,Add uniform noise to the input image,`test_image_add_uniform_noise `_ -:py:func:`addition `,Add images in the list and return the result image object,`test_image_addition `_ -:py:func:`addition_constant `,Add **dst** and a constant value and return the new result image object,`test_image_addition_constant `_ -:py:func:`adjust_gamma `,Gamma correction,`test_adjust_gamma `_ -:py:func:`adjust_log `,Compute log correction,`test_adjust_log `_ -:py:func:`adjust_sigmoid `,Compute sigmoid correction,`test_adjust_sigmoid `_ -:py:func:`arithmetic `,Compute arithmetic operation on two images,`test_image_arithmetic `_ -:py:func:`astype `,Convert image data type,`test_image_astype `_ -:py:func:`average `,Compute the average of images in the list and return the result image object,`test_image_average `_ -:py:func:`average_profile `,Compute horizontal or vertical average profile,`test_average_profile `_ -:py:func:`binning `,Binning: image pixel binning (or aggregation),`test_binning `_ -:py:func:`black_tophat `,Compute Black Top-Hat,`test_black_tophat `_ -:py:func:`blob_dog `,Compute blobs using Difference of Gaussian method,`test_image_blob_dog `_ -:py:func:`blob_doh `,Compute blobs using Determinant of Hessian method,`test_image_blob_doh `_ -:py:func:`blob_log `,Compute blobs using Laplacian of Gaussian method,`test_image_blob_log `_ -:py:func:`blob_opencv `,Compute blobs using OpenCV,`test_image_blob_opencv `_ -:py:func:`butterworth `,Compute Butterworth filter,`test_butterworth `_ -:py:func:`calibration `,Compute polynomial calibration,`test_image_calibration `_ -:py:func:`canny `,Compute Canny filter,`test_canny `_ -:py:func:`centroid `,Compute centroid,`test_image_centroid `_ -:py:func:`clip `,Apply clipping,`test_image_clip `_ -:py:func:`closing `,Compute morphological closing,`test_closing `_ -:py:func:`complex_from_magnitude_phase `,Combine magnitude and phase images into a complex image,`test_image_complex_from_magnitude_phase `_ -:py:func:`complex_from_real_imag `,Combine two real images into a complex image using real + i * imag,`test_image_complex_from_real_imag `_ -:py:func:`contour_shape `,Compute contour shape,`test_contour_shape `_ -:py:func:`convolution `,Convolve an image with a kernel,`test_image_convolution `_ -:py:func:`deconvolution `,Deconvolve a kernel from an image using Fast Fourier Transform (FFT),`test_image_deconvolution `_ -:py:func:`denoise_bilateral `,Compute bilateral filter denoising,`test_denoise_bilateral `_ -:py:func:`denoise_tophat `,Denoise using White Top-Hat,`test_denoise_tophat `_ -:py:func:`denoise_tv `,Compute Total Variation denoising,`test_denoise_tv `_ -:py:func:`denoise_wavelet `,Compute Wavelet denoising,`test_denoise_wavelet `_ -:py:func:`difference `,Compute difference between two images,`test_image_difference `_ -:py:func:`difference_constant `,Subtract a constant value from an image and return the new result image object,`test_image_difference_constant `_ -:py:func:`dilation `,Compute Dilation,`test_dilation `_ -:py:func:`division `,Compute division between two images,`test_image_division `_ -:py:func:`division_constant `,Divide an image by a constant value and return the new result image object,`test_image_division_constant `_ -:py:func:`enclosing_circle `,Compute minimum enclosing circle,`test_image_enclosing_circle `_ -:py:func:`equalize_adapthist `,Adaptive histogram equalization,`test_equalize_adapthist `_ -:py:func:`equalize_hist `,Histogram equalization,`test_equalize_hist `_ -:py:func:`erase `,Erase an area of the image using the mean value of the image,`test_erase `_ -:py:func:`erosion `,Compute Erosion,`test_erosion `_ -:py:func:`exp `,Compute exponential with :py:data:`numpy.exp`,`test_image_exp `_ -:py:func:`extract_roi `,Extract single ROI,`test_image_extract_roi `_ -:py:func:`extract_rois `,Extract multiple regions of interest from data,`test_image_extract_rois `_ -:py:func:`farid `,Compute Farid filter,`test_farid `_ -:py:func:`farid_h `,Compute horizontal Farid filter,`test_farid_h `_ -:py:func:`farid_v `,Compute vertical Farid filter,`test_farid_v `_ -:py:func:`fft `,Compute FFT,`test_image_fft `_ -:py:func:`flatfield `,Compute flat field correction,`test_flatfield `_ -:py:func:`fliph `,Flip data horizontally,`test_image_fliph `_ -:py:func:`flipv `,Flip data vertically,`test_image_flipv `_ -:py:func:`gaussian_filter `,Compute gaussian filter,`test_image_gaussian_filter `_ -:py:func:`gaussian_freq_filter `,Apply a Gaussian filter in the frequency domain,`test_gaussian_freq_filter `_ -:py:func:`histogram `,"Compute histogram of the image data,",`test_image_histogram `_ -:py:func:`horizontal_projection `,Compute the sum of pixel intensities along each col. (projection on the x-axis),`test_image_horizontal_projection `_ -:py:func:`hough_circle_peaks `,Compute Hough circles,`test_image_hough_circle_peaks `_ -:py:func:`ifft `,Compute inverse FFT,`test_image_ifft `_ -:py:func:`imag `,Compute imaginary part,`test_image_imag `_ -:py:func:`inverse `,Compute the inverse of an image and return the new result image object,`test_image_inverse `_ -:py:func:`laplace `,Compute Laplace filter,`test_laplace `_ -:py:func:`line_profile `,Compute horizontal or vertical profile,`test_line_profile `_ -:py:func:`log10 `,Compute log10 with :py:data:`numpy.log10`,`test_image_log10 `_ -:py:func:`log10_z_plus_n `,Compute log10(z+n) with :py:data:`numpy.log10`,`test_image_log10_z_plus_n `_ -:py:func:`magnitude_spectrum `,Compute magnitude spectrum,`test_image_magnitude_spectrum `_ -:py:func:`moving_average `,Compute moving average,`test_image_moving_average `_ -:py:func:`moving_median `,Compute moving median,`test_image_moving_median `_ -:py:func:`normalize `,,`test_image_normalize `_ -:py:func:`offset_correction `,Apply offset correction,`test_image_offset_correction `_ -:py:func:`opening `,Compute morphological opening,`test_opening `_ -:py:func:`peak_detection `,Compute 2D peak detection,`test_image_peak_detection `_ -:py:func:`phase `,Compute the phase (argument) of a complex image,`test_image_phase `_ -:py:func:`phase_spectrum `,Compute phase spectrum,`test_image_phase_spectrum `_ -:py:func:`prewitt `,Compute Prewitt filter,`test_prewitt `_ -:py:func:`prewitt_h `,Compute horizontal Prewitt filter,`test_prewitt_h `_ -:py:func:`prewitt_v `,Compute vertical Prewitt filter,`test_prewitt_v `_ -:py:func:`product `,Multiply images in the list and return the result image object,`test_image_product `_ -:py:func:`product_constant `,Multiply **dst** by a constant value and return the new result image object,`test_image_product_constant `_ -:py:func:`psd `,Compute power spectral density,`test_image_psd `_ -:py:func:`quadratic_difference `,Compute quadratic difference between two images,`test_image_quadratic_difference `_ -:py:func:`radial_profile `,Compute radial profile around the centroid,`test_radial_profile `_ -:py:func:`real `,Compute real part,`test_image_real `_ -:py:func:`resampling `,Resample image to new coordinate grid using interpolation,`test_image_resampling `_ -:py:func:`rescale_intensity `,Rescale image intensity levels,`test_rescale_intensity `_ -:py:func:`resize `,Zooming function,`test_image_resize `_ -:py:func:`roberts `,Compute Roberts filter,`test_roberts `_ -:py:func:`rotate `,Rotate data,`test_image_rotate `_ -:py:func:`rotate270 `,Rotate data 270°,`test_image_rotate270 `_ -:py:func:`rotate90 `,Rotate data 90°,`test_image_rotate90 `_ -:py:func:`scharr `,Compute Scharr filter,`test_scharr `_ -:py:func:`scharr_h `,Compute horizontal Scharr filter,`test_scharr_h `_ -:py:func:`scharr_v `,Compute vertical Scharr filter,`test_scharr_v `_ -:py:func:`segment_profile `,Compute segment profile,`test_segment_profile `_ -:py:func:`set_uniform_coords `,Convert image to uniform coordinate system,`test_set_uniform_coords `_ -:py:func:`sobel `,Compute Sobel filter,`test_sobel `_ -:py:func:`sobel_h `,Compute horizontal Sobel filter,`test_sobel_h `_ -:py:func:`sobel_v `,Compute vertical Sobel filter,`test_sobel_v `_ -:py:func:`standard_deviation `,Compute the element-wise standard deviation of multiple images,`test_image_standard_deviation `_ -:py:func:`stats `,Compute statistics on an image,`test_image_stats_unit `_ -:py:func:`threshold `,"Compute the threshold, using one of the available algorithms",`test_threshold `_ -:py:func:`threshold_isodata `,Compute the threshold using the Isodata algorithm with default parameters,`test_threshold_isodata `_ -:py:func:`threshold_li `,Compute the threshold using the Li algorithm with default parameters,`test_threshold_li `_ -:py:func:`threshold_mean `,Compute the threshold using the Mean algorithm,`test_threshold_mean `_ -:py:func:`threshold_minimum `,Compute the threshold using the Minimum algorithm with default parameters,`test_threshold_minimum `_ -:py:func:`threshold_otsu `,Compute the threshold using the Otsu algorithm with default parameters,`test_threshold_otsu `_ -:py:func:`threshold_triangle `,Compute the threshold using the Triangle algorithm with default parameters,`test_threshold_triangle `_ -:py:func:`threshold_yen `,Compute the threshold using the Yen algorithm with default parameters,`test_threshold_yen `_ -:py:func:`translate `,Translate data,`test_image_translate `_ -:py:func:`transpose `,Transpose image,`test_image_transpose `_ -:py:func:`vertical_projection `,Compute the sum of pixel intensities along each row (projection on the y-axis),`test_image_vertical_projection `_ -:py:func:`white_tophat `,Compute White Top-Hat,`test_white_tophat `_ -:py:func:`wiener `,Compute Wiener filter,`test_image_wiener `_ -:py:func:`zero_padding `,Zero-padding: add zeros to image borders,`test_image_zero_padding `_ +:py:func:`absolute `,Compute absolute value with :py:data:`numpy.absolute`,`test_image_absolute `_ +:py:func:`add_gaussian_noise `,Add Gaussian (normal) noise to the input image,`test_image_add_gaussian_noise `_ +:py:func:`add_poisson_noise `,Add Poisson noise to the input image,`test_image_add_poisson_noise `_ +:py:func:`add_uniform_noise `,Add uniform noise to the input image,`test_image_add_uniform_noise `_ +:py:func:`addition `,Add images in the list and return the result image object,`test_image_addition `_ +:py:func:`addition_constant `,Add **dst** and a constant value and return the new result image object,`test_image_addition_constant `_ +:py:func:`adjust_gamma `,Gamma correction,`test_adjust_gamma `_ +:py:func:`adjust_log `,Compute log correction,`test_adjust_log `_ +:py:func:`adjust_sigmoid `,Compute sigmoid correction,`test_adjust_sigmoid `_ +:py:func:`arithmetic `,Compute arithmetic operation on two images,`test_image_arithmetic `_ +:py:func:`astype `,Convert image data type,`test_image_astype `_ +:py:func:`average `,Compute the average of images in the list and return the result image object,`test_image_average `_ +:py:func:`average_profile `,Compute horizontal or vertical average profile,`test_average_profile `_ +:py:func:`binning `,Binning: image pixel binning (or aggregation),`test_binning `_ +:py:func:`black_tophat `,Compute Black Top-Hat,`test_black_tophat `_ +:py:func:`blob_dog `,Compute blobs using Difference of Gaussian method,`test_image_blob_dog `_ +:py:func:`blob_doh `,Compute blobs using Determinant of Hessian method,`test_image_blob_doh `_ +:py:func:`blob_log `,Compute blobs using Laplacian of Gaussian method,`test_image_blob_log `_ +:py:func:`blob_opencv `,Compute blobs using OpenCV,`test_image_blob_opencv `_ +:py:func:`butterworth `,Compute Butterworth filter,`test_butterworth `_ +:py:func:`calibration `,Compute polynomial calibration,`test_image_calibration `_ +:py:func:`canny `,Compute Canny filter,`test_canny `_ +:py:func:`centroid `,Compute centroid,`test_image_centroid `_ +:py:func:`clip `,Apply clipping,`test_image_clip `_ +:py:func:`closing `,Compute morphological closing,`test_closing `_ +:py:func:`complex_from_magnitude_phase `,Combine magnitude and phase images into a complex image,`test_image_complex_from_magnitude_phase `_ +:py:func:`complex_from_real_imag `,Combine two real images into a complex image using real + i * imag,`test_image_complex_from_real_imag `_ +:py:func:`contour_shape `,Compute contour shape,`test_contour_shape `_ +:py:func:`convolution `,Convolve an image with a kernel,`test_image_convolution `_ +:py:func:`deconvolution `,Deconvolve a kernel from an image using Fast Fourier Transform (FFT),`test_image_deconvolution `_ +:py:func:`denoise_bilateral `,Compute bilateral filter denoising,`test_denoise_bilateral `_ +:py:func:`denoise_tophat `,Denoise using White Top-Hat,`test_denoise_tophat `_ +:py:func:`denoise_tv `,Compute Total Variation denoising,`test_denoise_tv `_ +:py:func:`denoise_wavelet `,Compute Wavelet denoising,`test_denoise_wavelet `_ +:py:func:`difference `,Compute difference between two images,`test_image_difference `_ +:py:func:`difference_constant `,Subtract a constant value from an image and return the new result image object,`test_image_difference_constant `_ +:py:func:`dilation `,Compute Dilation,`test_dilation `_ +:py:func:`division `,Compute division between two images,`test_image_division `_ +:py:func:`division_constant `,Divide an image by a constant value and return the new result image object,`test_image_division_constant `_ +:py:func:`enclosing_circle `,Compute minimum enclosing circle,`test_image_enclosing_circle `_ +:py:func:`equalize_adapthist `,Adaptive histogram equalization,`test_equalize_adapthist `_ +:py:func:`equalize_hist `,Histogram equalization,`test_equalize_hist `_ +:py:func:`erase `,Erase an area of the image using the mean value of the image,`test_erase `_ +:py:func:`erosion `,Compute Erosion,`test_erosion `_ +:py:func:`exp `,Compute exponential with :py:data:`numpy.exp`,`test_image_exp `_ +:py:func:`extract_roi `,Extract single ROI,`test_image_extract_roi `_ +:py:func:`extract_rois `,Extract multiple regions of interest from data,`test_image_extract_rois `_ +:py:func:`farid `,Compute Farid filter,`test_farid `_ +:py:func:`farid_h `,Compute horizontal Farid filter,`test_farid_h `_ +:py:func:`farid_v `,Compute vertical Farid filter,`test_farid_v `_ +:py:func:`fft `,Compute FFT,`test_image_fft `_ +:py:func:`flatfield `,Compute flat field correction,`test_flatfield `_ +:py:func:`fliph `,Flip data horizontally,`test_image_fliph `_ +:py:func:`flipv `,Flip data vertically,`test_image_flipv `_ +:py:func:`gaussian_filter `,Compute gaussian filter,`test_image_gaussian_filter `_ +:py:func:`gaussian_freq_filter `,Apply a Gaussian filter in the frequency domain,`test_gaussian_freq_filter `_ +:py:func:`histogram `,"Compute histogram of the image data,",`test_image_histogram `_ +:py:func:`horizontal_projection `,Compute the sum of pixel intensities along each col. (projection on the x-axis),`test_image_horizontal_projection `_ +:py:func:`hough_circle_peaks `,Compute Hough circles,`test_image_hough_circle_peaks `_ +:py:func:`ifft `,Compute inverse FFT,`test_image_ifft `_ +:py:func:`imag `,Compute imaginary part,`test_image_imag `_ +:py:func:`inverse `,Compute the inverse of an image and return the new result image object,`test_image_inverse `_ +:py:func:`laplace `,Compute Laplace filter,`test_laplace `_ +:py:func:`line_profile `,Compute horizontal or vertical profile,`test_line_profile `_ +:py:func:`log10 `,Compute log10 with :py:data:`numpy.log10`,`test_image_log10 `_ +:py:func:`log10_z_plus_n `,Compute log10(z+n) with :py:data:`numpy.log10`,`test_image_log10_z_plus_n `_ +:py:func:`magnitude_spectrum `,Compute magnitude spectrum,`test_image_magnitude_spectrum `_ +:py:func:`moving_average `,Compute moving average,`test_image_moving_average `_ +:py:func:`moving_median `,Compute moving median,`test_image_moving_median `_ +:py:func:`normalize `,,`test_image_normalize `_ +:py:func:`offset_correction `,Apply offset correction,`test_image_offset_correction `_ +:py:func:`opening `,Compute morphological opening,`test_opening `_ +:py:func:`peak_detection `,Compute 2D peak detection,`test_image_peak_detection `_ +:py:func:`phase `,Compute the phase (argument) of a complex image,`test_image_phase `_ +:py:func:`phase_spectrum `,Compute phase spectrum,`test_image_phase_spectrum `_ +:py:func:`prewitt `,Compute Prewitt filter,`test_prewitt `_ +:py:func:`prewitt_h `,Compute horizontal Prewitt filter,`test_prewitt_h `_ +:py:func:`prewitt_v `,Compute vertical Prewitt filter,`test_prewitt_v `_ +:py:func:`product `,Multiply images in the list and return the result image object,`test_image_product `_ +:py:func:`product_constant `,Multiply **dst** by a constant value and return the new result image object,`test_image_product_constant `_ +:py:func:`psd `,Compute power spectral density,`test_image_psd `_ +:py:func:`quadratic_difference `,Compute quadratic difference between two images,`test_image_quadratic_difference `_ +:py:func:`radial_profile `,Compute radial profile around the centroid,`test_radial_profile `_ +:py:func:`real `,Compute real part,`test_image_real `_ +:py:func:`resampling `,Resample image to new coordinate grid using interpolation,`test_image_resampling `_ +:py:func:`rescale_intensity `,Rescale image intensity levels,`test_rescale_intensity `_ +:py:func:`resize `,Zooming function,`test_image_resize `_ +:py:func:`roberts `,Compute Roberts filter,`test_roberts `_ +:py:func:`rotate `,Rotate data,`test_image_rotate `_ +:py:func:`rotate270 `,Rotate data 270°,`test_image_rotate270 `_ +:py:func:`rotate90 `,Rotate data 90°,`test_image_rotate90 `_ +:py:func:`scharr `,Compute Scharr filter,`test_scharr `_ +:py:func:`scharr_h `,Compute horizontal Scharr filter,`test_scharr_h `_ +:py:func:`scharr_v `,Compute vertical Scharr filter,`test_scharr_v `_ +:py:func:`segment_profile `,Compute segment profile,`test_segment_profile `_ +:py:func:`set_uniform_coords `,Convert image to uniform coordinate system,`test_set_uniform_coords `_ +:py:func:`sobel `,Compute Sobel filter,`test_sobel `_ +:py:func:`sobel_h `,Compute horizontal Sobel filter,`test_sobel_h `_ +:py:func:`sobel_v `,Compute vertical Sobel filter,`test_sobel_v `_ +:py:func:`standard_deviation `,Compute the element-wise standard deviation of multiple images,`test_image_standard_deviation `_ +:py:func:`stats `,Compute statistics on an image,`test_image_stats_unit `_ +:py:func:`threshold `,"Compute the threshold, using one of the available algorithms",`test_threshold `_ +:py:func:`threshold_isodata `,Compute the threshold using the Isodata algorithm with default parameters,`test_threshold_isodata `_ +:py:func:`threshold_li `,Compute the threshold using the Li algorithm with default parameters,`test_threshold_li `_ +:py:func:`threshold_mean `,Compute the threshold using the Mean algorithm,`test_threshold_mean `_ +:py:func:`threshold_minimum `,Compute the threshold using the Minimum algorithm with default parameters,`test_threshold_minimum `_ +:py:func:`threshold_otsu `,Compute the threshold using the Otsu algorithm with default parameters,`test_threshold_otsu `_ +:py:func:`threshold_triangle `,Compute the threshold using the Triangle algorithm with default parameters,`test_threshold_triangle `_ +:py:func:`threshold_yen `,Compute the threshold using the Yen algorithm with default parameters,`test_threshold_yen `_ +:py:func:`translate `,Translate data,`test_image_translate `_ +:py:func:`transpose `,Transpose image,`test_image_transpose `_ +:py:func:`vertical_projection `,Compute the sum of pixel intensities along each row (projection on the y-axis),`test_image_vertical_projection `_ +:py:func:`white_tophat `,Compute White Top-Hat,`test_white_tophat `_ +:py:func:`wiener `,Compute Wiener filter,`test_image_wiener `_ +:py:func:`zero_padding `,Zero-padding: add zeros to image borders,`test_image_zero_padding `_ diff --git a/doc/validation_status_signal.csv b/doc/validation_status_signal.csv index 3fa4b7e54..1416ad8c3 100644 --- a/doc/validation_status_signal.csv +++ b/doc/validation_status_signal.csv @@ -1,97 +1,96 @@ -:py:func:`absolute `,Compute absolute value with :py:data:`numpy.absolute`,`test_signal_absolute `_ -:py:func:`add_gaussian_noise `,Add normal noise to the input signal,`test_signal_add_gaussian_noise `_ -:py:func:`add_poisson_noise `,Add Poisson noise to the input signal,`test_signal_add_poisson_noise `_ -:py:func:`add_uniform_noise `,Add uniform noise to the input signal,`test_signal_add_uniform_noise `_ -:py:func:`addition `,Compute the element-wise sum of multiple signals,`test_signal_addition `_ -:py:func:`addition_constant `,Compute the sum of a signal and a constant value,`test_signal_addition_constant `_ -:py:func:`allan_deviation `,Compute Allan deviation ,`test_signal_allan_deviation `_ -:py:func:`allan_variance `,Compute Allan variance ,`test_signal_allan_variance `_ -:py:func:`apply_window `,Compute windowing,`test_signal_apply_window `_ -:py:func:`arithmetic `,Perform an arithmetic operation on two signals,`test_signal_arithmetic `_ -:py:func:`astype `,Convert data type,`test_signal_astype `_ -:py:func:`average `,Compute the element-wise average of multiple signals,`test_signal_average `_ -:py:func:`bandpass `,Compute band-pass filter,`test_signal_bandpass `_ -:py:func:`bandstop `,Compute band-stop filter,`test_signal_bandstop `_ -:py:func:`bandwidth_3db `,Compute bandwidth at -3 dB ,`test_signal_bandwidth_3db `_ -:py:func:`calibration `,Compute linear calibration,`test_signal_calibration `_ -:py:func:`cdf_fit `,Compute CDF fit,`test_signal_cdf_fit `_ -:py:func:`clip `,Compute maximum data clipping,`test_signal_clip `_ -:py:func:`complex_from_magnitude_phase `,Combine magnitude and phase signals into a complex signal,`test_signal_complex_from_magnitude_phase `_ -:py:func:`complex_from_real_imag `,Combine two real signals into a complex signal using real + i * imag,`test_signal_complex_from_real_imag `_ -:py:func:`contrast `,Compute contrast,`test_signal_contrast `_ -:py:func:`convolution `,Compute convolution of two signals,`test_signal_convolution `_ -:py:func:`deconvolution `,Compute deconvolution,`test_signal_deconvolution `_ -:py:func:`derivative `,Compute derivative,`test_signal_derivative `_ -:py:func:`detrending `,Detrend data,`test_signal_detrending `_ -:py:func:`difference `,Compute the element-wise difference between two signals,`test_signal_difference `_ -:py:func:`difference_constant `,Compute the difference between a signal and a constant value,`test_signal_difference_constant `_ -:py:func:`division `,Compute the element-wise division between two signals,`test_signal_division `_ -:py:func:`division_constant `,Compute the division of a signal by a constant value,`test_signal_division_constant `_ -:py:func:`dynamic_parameters `,Compute Dynamic parameters,`test_dynamic_parameters `_ -:py:func:`evaluate_fit `,Evaluate fit function from src1 on the x-axis of src2,`test_signal_evaluate_fit `_ -:py:func:`exp `,Compute exponential with :py:data:`numpy.exp`,`test_signal_exp `_ -:py:func:`exponential_fit `,Compute exponential fit,`test_signal_exponential_fit `_ -:py:func:`extract_peak_positions `,Extract peak positions as an XY-markers table,`test_signal_extract_peak_positions `_ -:py:func:`extract_pulse_features `,Extract pulse features,`test_signal_extract_pulse_features `_ -:py:func:`extract_roi `,Extract single region of interest from data,`test_signal_extract_roi `_ -:py:func:`extract_rois `,Extract multiple regions of interest from data,`test_signal_extract_rois `_ -:py:func:`fft `,Compute FFT,`test_signal_fft `_ -:py:func:`full_width_at_y `,,`test_signal_full_width_at_y `_ -:py:func:`fw1e2 `,Compute FW at 1/eÂČ,`test_signal_fw1e2 `_ -:py:func:`fwhm `,Compute FWHM,`test_signal_fwhm `_ -:py:func:`gaussian_filter `,Compute gaussian filter,`test_signal_gaussian_filter `_ -:py:func:`gaussian_fit `,Compute Gaussian fit,`test_signal_gaussian_fit `_ -:py:func:`hadamard_variance `,Compute Hadamard variance,`test_signal_hadamard_variance `_ -:py:func:`highpass `,Compute high-pass filter,`test_signal_highpass `_ -:py:func:`histogram `,Compute histogram,`test_signal_histogram `_ -:py:func:`ifft `,Compute the inverse FFT,`test_signal_ifft `_ -:py:func:`imag `,Compute imaginary part,`test_signal_imag `_ -:py:func:`integral `,Compute integral,`test_signal_integral `_ -:py:func:`interpolate `,Interpolate data,`test_signal_interpolate `_ -:py:func:`inverse `,Compute the element-wise inverse of a signal,`test_signal_inverse `_ -:py:func:`linear_fit `,Compute linear fit,`test_signal_linear_fit `_ -:py:func:`log10 `,Compute Log10 with :py:data:`numpy.log10`,`test_signal_log10 `_ -:py:func:`lorentzian_fit `,Compute Lorentzian fit,`test_signal_lorentzian_fit `_ -:py:func:`lowpass `,Compute low-pass filter,`test_signal_lowpass `_ -:py:func:`magnitude_spectrum `,Compute magnitude spectrum,`test_signal_magnitude_spectrum `_ -:py:func:`modified_allan_variance `,Compute Modified Allan variance,`test_signal_modified_allan_variance `_ -:py:func:`moving_average `,Compute moving average,`test_signal_moving_average `_ -:py:func:`moving_median `,Compute moving median,`test_signal_moving_median `_ -:py:func:`normalize `,Normalize data,`test_signal_normalize `_ -:py:func:`offset_correction `,Correct offset: subtract the mean value of the signal in the specified range,`test_signal_offset_correction `_ -:py:func:`overlapping_allan_variance `,Compute Overlapping Allan variance,`test_signal_overlapping_allan_variance `_ -:py:func:`peak_detection `,Peak detection ,`test_signal_peak_detection `_ -:py:func:`phase `,Compute the phase (argument) of a complex signal,`test_signal_phase `_ -:py:func:`phase_spectrum `,Compute phase spectrum,`test_signal_phase_spectrum `_ -:py:func:`piecewiseexponential_fit `,Compute piecewise exponential fit (raise-decay) ,`test_signal_piecewiseexponential_fit `_ -:py:func:`planckian_fit `,Compute Planckian fit,`test_signal_planckian_fit `_ -:py:func:`polynomial_fit `,Compute polynomial fit,`test_polynomial_fit `_ -:py:func:`power `,Compute power with :py:data:`numpy.power`,`test_signal_power `_ -:py:func:`product `,Compute the element-wise product of multiple signals,`test_signal_product `_ -:py:func:`product_constant `,Compute the product of a signal and a constant value,`test_signal_product_constant `_ -:py:func:`psd `,Compute power spectral density,`test_signal_psd `_ -:py:func:`quadratic_difference `,Compute the normalized difference between two signals,`test_signal_quadratic_difference `_ -:py:func:`real `,Compute real part,`test_signal_real `_ -:py:func:`replace_x_by_other_y `,Create a new signal using Y from src1 and Y from src2 as X coordinates,`test_replace_x_by_other_y `_ -:py:func:`resampling `,Resample data,`test_signal_resampling `_ -:py:func:`reverse_x `,Reverse x-axis,`test_signal_reverse_x `_ -:py:func:`sampling_rate_period `,Compute sampling rate and period,`test_signal_sampling_rate_period `_ -:py:func:`sigmoid_fit `,Compute sigmoid fit,`test_signal_sigmoid_fit `_ -:py:func:`signals_to_image `,Combine multiple signals into an image,`test_signal_signals_to_image `_ -:py:func:`sinusoidal_fit `,Compute sinusoidal fit,`test_sinusoidal_fit `_ -:py:func:`sqrt `,Compute square root with :py:data:`numpy.sqrt`,`test_signal_sqrt `_ -:py:func:`standard_deviation `,Compute the element-wise standard deviation of multiple signals,`test_signal_standard_deviation `_ -:py:func:`stats `,Compute statistics on a signal,`test_signal_stats_unit `_ -:py:func:`time_deviation `,Compute Time Deviation (TDEV),`test_signal_time_deviation `_ -:py:func:`to_cartesian `,Convert polar coordinates to Cartesian coordinates,`test_signal_to_cartesian `_ -:py:func:`to_polar `,Convert Cartesian coordinates to polar coordinates,`test_signal_to_polar `_ -:py:func:`total_variance `,Compute Total variance,`test_signal_total_variance `_ -:py:func:`transpose `,Transpose signal (swap X and Y axes),`test_signal_transpose `_ -:py:func:`twohalfgaussian_fit `,Compute two-half-Gaussian fit,`test_signal_twohalfgaussian_fit `_ -:py:func:`voigt_fit `,Compute Voigt fit,`test_signal_voigt_fit `_ -:py:func:`wiener `,Compute Wiener filter,`test_signal_wiener `_ -:py:func:`x_at_minmax `,,`test_signal_x_at_minmax `_ -:py:func:`x_at_y `,,`test_signal_x_at_y `_ -:py:func:`xy_mode `,Simulate the X-Y mode of an oscilloscope,`test_signal_xy_mode `_ -:py:func:`y_at_x `,,`test_signal_y_at_x `_ -:py:func:`zero_padding `,Compute zero padding,`test_signal_zero_padding `_ +:py:func:`absolute `,Compute absolute value with :py:data:`numpy.absolute`,`test_signal_absolute `_ +:py:func:`add_gaussian_noise `,Add normal noise to the input signal,`test_signal_add_gaussian_noise `_ +:py:func:`add_poisson_noise `,Add Poisson noise to the input signal,`test_signal_add_poisson_noise `_ +:py:func:`add_uniform_noise `,Add uniform noise to the input signal,`test_signal_add_uniform_noise `_ +:py:func:`addition `,Compute the element-wise sum of multiple signals,`test_signal_addition `_ +:py:func:`addition_constant `,Compute the sum of a signal and a constant value,`test_signal_addition_constant `_ +:py:func:`allan_deviation `,Compute Allan deviation ,`test_signal_allan_deviation `_ +:py:func:`allan_variance `,Compute Allan variance ,`test_signal_allan_variance `_ +:py:func:`apply_window `,Compute windowing,`test_signal_apply_window `_ +:py:func:`arithmetic `,Perform an arithmetic operation on two signals,`test_signal_arithmetic `_ +:py:func:`astype `,Convert data type,`test_signal_astype `_ +:py:func:`average `,Compute the element-wise average of multiple signals,`test_signal_average `_ +:py:func:`bandpass `,Compute band-pass filter,`test_signal_bandpass `_ +:py:func:`bandstop `,Compute band-stop filter,`test_signal_bandstop `_ +:py:func:`bandwidth_3db `,Compute bandwidth at -3 dB ,`test_signal_bandwidth_3db `_ +:py:func:`calibration `,Compute linear calibration,`test_signal_calibration `_ +:py:func:`cdf_fit `,Compute CDF fit,`test_signal_cdf_fit `_ +:py:func:`clip `,Compute maximum data clipping,`test_signal_clip `_ +:py:func:`complex_from_magnitude_phase `,Combine magnitude and phase signals into a complex signal,`test_signal_complex_from_magnitude_phase `_ +:py:func:`complex_from_real_imag `,Combine two real signals into a complex signal using real + i * imag,`test_signal_complex_from_real_imag `_ +:py:func:`contrast `,Compute contrast,`test_signal_contrast `_ +:py:func:`convolution `,Compute convolution of two signals,`test_signal_convolution `_ +:py:func:`deconvolution `,Compute deconvolution,`test_signal_deconvolution `_ +:py:func:`derivative `,Compute derivative,`test_signal_derivative `_ +:py:func:`detrending `,Detrend data,`test_signal_detrending `_ +:py:func:`difference `,Compute the element-wise difference between two signals,`test_signal_difference `_ +:py:func:`difference_constant `,Compute the difference between a signal and a constant value,`test_signal_difference_constant `_ +:py:func:`division `,Compute the element-wise division between two signals,`test_signal_division `_ +:py:func:`division_constant `,Compute the division of a signal by a constant value,`test_signal_division_constant `_ +:py:func:`dynamic_parameters `,Compute Dynamic parameters,`test_dynamic_parameters `_ +:py:func:`evaluate_fit `,Evaluate fit function from src1 on the x-axis of src2,`test_signal_evaluate_fit `_ +:py:func:`exp `,Compute exponential with :py:data:`numpy.exp`,`test_signal_exp `_ +:py:func:`exponential_fit `,Compute exponential fit,`test_signal_exponential_fit `_ +:py:func:`extract_pulse_features `,Extract pulse features,`test_signal_extract_pulse_features `_ +:py:func:`extract_roi `,Extract single region of interest from data,`test_signal_extract_roi `_ +:py:func:`extract_rois `,Extract multiple regions of interest from data,`test_signal_extract_rois `_ +:py:func:`fft `,Compute FFT,`test_signal_fft `_ +:py:func:`full_width_at_y `,,`test_signal_full_width_at_y `_ +:py:func:`fw1e2 `,Compute FW at 1/eÂČ,`test_signal_fw1e2 `_ +:py:func:`fwhm `,Compute FWHM,`test_signal_fwhm `_ +:py:func:`gaussian_filter `,Compute gaussian filter,`test_signal_gaussian_filter `_ +:py:func:`gaussian_fit `,Compute Gaussian fit,`test_signal_gaussian_fit `_ +:py:func:`hadamard_variance `,Compute Hadamard variance,`test_signal_hadamard_variance `_ +:py:func:`highpass `,Compute high-pass filter,`test_signal_highpass `_ +:py:func:`histogram `,Compute histogram,`test_signal_histogram `_ +:py:func:`ifft `,Compute the inverse FFT,`test_signal_ifft `_ +:py:func:`imag `,Compute imaginary part,`test_signal_imag `_ +:py:func:`integral `,Compute integral,`test_signal_integral `_ +:py:func:`interpolate `,Interpolate data,`test_signal_interpolate `_ +:py:func:`inverse `,Compute the element-wise inverse of a signal,`test_signal_inverse `_ +:py:func:`linear_fit `,Compute linear fit,`test_signal_linear_fit `_ +:py:func:`log10 `,Compute Log10 with :py:data:`numpy.log10`,`test_signal_log10 `_ +:py:func:`lorentzian_fit `,Compute Lorentzian fit,`test_signal_lorentzian_fit `_ +:py:func:`lowpass `,Compute low-pass filter,`test_signal_lowpass `_ +:py:func:`magnitude_spectrum `,Compute magnitude spectrum,`test_signal_magnitude_spectrum `_ +:py:func:`modified_allan_variance `,Compute Modified Allan variance,`test_signal_modified_allan_variance `_ +:py:func:`moving_average `,Compute moving average,`test_signal_moving_average `_ +:py:func:`moving_median `,Compute moving median,`test_signal_moving_median `_ +:py:func:`normalize `,Normalize data,`test_signal_normalize `_ +:py:func:`offset_correction `,Correct offset: subtract the mean value of the signal in the specified range,`test_signal_offset_correction `_ +:py:func:`overlapping_allan_variance `,Compute Overlapping Allan variance,`test_signal_overlapping_allan_variance `_ +:py:func:`peak_detection `,Peak detection ,`test_signal_peak_detection `_ +:py:func:`phase `,Compute the phase (argument) of a complex signal,`test_signal_phase `_ +:py:func:`phase_spectrum `,Compute phase spectrum,`test_signal_phase_spectrum `_ +:py:func:`piecewiseexponential_fit `,Compute piecewise exponential fit (raise-decay) ,`test_signal_piecewiseexponential_fit `_ +:py:func:`planckian_fit `,Compute Planckian fit,`test_signal_planckian_fit `_ +:py:func:`polynomial_fit `,Compute polynomial fit,`test_polynomial_fit `_ +:py:func:`power `,Compute power with :py:data:`numpy.power`,`test_signal_power `_ +:py:func:`product `,Compute the element-wise product of multiple signals,`test_signal_product `_ +:py:func:`product_constant `,Compute the product of a signal and a constant value,`test_signal_product_constant `_ +:py:func:`psd `,Compute power spectral density,`test_signal_psd `_ +:py:func:`quadratic_difference `,Compute the normalized difference between two signals,`test_signal_quadratic_difference `_ +:py:func:`real `,Compute real part,`test_signal_real `_ +:py:func:`replace_x_by_other_y `,Create a new signal using Y from src1 and Y from src2 as X coordinates,`test_replace_x_by_other_y `_ +:py:func:`resampling `,Resample data,`test_signal_resampling `_ +:py:func:`reverse_x `,Reverse x-axis,`test_signal_reverse_x `_ +:py:func:`sampling_rate_period `,Compute sampling rate and period,`test_signal_sampling_rate_period `_ +:py:func:`sigmoid_fit `,Compute sigmoid fit,`test_signal_sigmoid_fit `_ +:py:func:`signals_to_image `,Combine multiple signals into an image,`test_signal_signals_to_image `_ +:py:func:`sinusoidal_fit `,Compute sinusoidal fit,`test_sinusoidal_fit `_ +:py:func:`sqrt `,Compute square root with :py:data:`numpy.sqrt`,`test_signal_sqrt `_ +:py:func:`standard_deviation `,Compute the element-wise standard deviation of multiple signals,`test_signal_standard_deviation `_ +:py:func:`stats `,Compute statistics on a signal,`test_signal_stats_unit `_ +:py:func:`time_deviation `,Compute Time Deviation (TDEV),`test_signal_time_deviation `_ +:py:func:`to_cartesian `,Convert polar coordinates to Cartesian coordinates,`test_signal_to_cartesian `_ +:py:func:`to_polar `,Convert Cartesian coordinates to polar coordinates,`test_signal_to_polar `_ +:py:func:`total_variance `,Compute Total variance,`test_signal_total_variance `_ +:py:func:`transpose `,Transpose signal (swap X and Y axes),`test_signal_transpose `_ +:py:func:`twohalfgaussian_fit `,Compute two-half-Gaussian fit,`test_signal_twohalfgaussian_fit `_ +:py:func:`voigt_fit `,Compute Voigt fit,`test_signal_voigt_fit `_ +:py:func:`wiener `,Compute Wiener filter,`test_signal_wiener `_ +:py:func:`x_at_minmax `,,`test_signal_x_at_minmax `_ +:py:func:`x_at_y `,,`test_signal_x_at_y `_ +:py:func:`xy_mode `,Simulate the X-Y mode of an oscilloscope,`test_signal_xy_mode `_ +:py:func:`y_at_x `,,`test_signal_y_at_x `_ +:py:func:`zero_padding `,Compute zero padding,`test_signal_zero_padding `_ diff --git a/pyproject.toml b/pyproject.toml index 8b731f0b9..bcf2e2d2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,9 +41,9 @@ classifiers = [ ] requires-python = ">=3.9, <4" dependencies = [ - "guidata >= 3.13.4", - "PlotPy >= 2.8.2", - "Sigima >= 1.1.2", + "guidata >= 3.14.4", + "PlotPy >= 2.10.0", + "Sigima >= 1.1.4", "NumPy >= 1.22, < 2.5", "SciPy >= 1.10.1, < 1.17", "scikit-image >= 0.19.2, < 0.27", diff --git a/requirements.txt b/requirements.txt index 502640815..651f5cd02 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,14 +1,14 @@ Coverage NumPy >= 1.22, < 2.5 -PlotPy >= 2.8.2 +PlotPy >= 2.10.0 PyQt5 >= 5.15.6 PyWavelets >= 1.2, < 2.0 SciPy >= 1.10.1, < 1.17 -Sigima >= 1.1.2 +Sigima >= 1.1.4 babel build fastapi >= 0.110.0 -guidata >= 3.13.4 +guidata >= 3.14.4 httpx myst_parser opencv-python-headless >= 4.8.1.78 @@ -29,4 +29,5 @@ sphinx-copybutton sphinx-sitemap sphinx_design sphinx_intl +sphinxcontrib-svg2pdfconverter[CairoSVG] uvicorn[standard] >= 0.27.0 diff --git a/resources/DataLab-Reset.ico b/resources/DataLab-Reset.ico index de4839dfe..fe300c4b7 100644 Binary files a/resources/DataLab-Reset.ico and b/resources/DataLab-Reset.ico differ diff --git a/scripts/build_doc.bat b/scripts/build_doc.bat index 63258df7e..dfc6f39a7 100644 --- a/scripts/build_doc.bat +++ b/scripts/build_doc.bat @@ -15,33 +15,40 @@ call %FUNC% UsePython call %FUNC% GetVersion DATALAB_VERSION cd %SCRIPTPATH%\.. -@REM Set light mode for Qt applications and clean previous documentation =============== -set QT_COLOR_MODE=light +@REM Clean previous documentation ====================================================== if exist %MODNAME%\data\doc ( rmdir /s /q %MODNAME%\data\doc ) mkdir %MODNAME%\data\doc @REM Build documentation =============================================================== +@REM Screenshots under doc/images/ are NOT regenerated here: they are a maintainer +@REM responsibility (run scripts\update_screenshots.bat or the dedicated VS Code +@REM task "??? Refresh doc screenshots") and are committed as-is, which lets the +@REM CI doc workflows build the PDF without launching DataLab/Qt. +setlocal enabledelayedexpansion for %%L in (fr en) do ( - @REM ------------------------------------------------------------------------------- - @REM Create dummy PDF file, otherwise the PDF menu entry in "?" menu - @REM won't be visible in the automatic screenshot - echo Dummy PDF file > %MODNAME%\data\doc\DataLab_%%L.pdf - @REM ------------------------------------------------------------------------------- set LANG=%%L - @REM Refresh screenshots (delegated ? same script the maintainer can run - @REM standalone via scripts\update_screenshots.bat or the VS Code task). - %PYTHON% doc/update_screenshots.py if exist build\doc ( rmdir /s /q build\doc ) sphinx-build -b latex -D language=%%L doc build\doc cd build\doc - echo Building PDF documentation for %%L... - xelatex -interaction=nonstopmode -quiet DataLab.tex + @REM Sphinx >= 9 emits a lowercased .tex filename (``datalab.tex``) + @REM regardless of ``project = "DataLab"``. Auto-discover it instead + @REM of hardcoding ``DataLab.tex``: NTFS hides the breakage locally + @REM (case-insensitive lookup) but a case-sensitive filesystem fails. + for %%F in (*.tex) do set "MAIN_TEX=%%F" + echo Building PDF documentation for %%L from !MAIN_TEX!... + @REM -enable-installer: let MiKTeX silently auto-install missing TeX + @REM packages (e.g. ``noto`` and ``noto-emoji`` for the Unicode + @REM fallback fonts referenced by doc/conf.py) instead of popping up + @REM its Qt-based installer dialog (which fails when the venv shadows + @REM Qt plugins). No effect on CI (Ubuntu + TeX Live). + xelatex -enable-installer -interaction=nonstopmode -halt-on-error !MAIN_TEX! @REM Build again to fix table of contents (workaround) - xelatex -interaction=nonstopmode -quiet DataLab.tex + xelatex -enable-installer -interaction=nonstopmode -halt-on-error !MAIN_TEX! echo Done. cd ..\.. - move /Y build\doc\DataLab.pdf %MODNAME%\data\doc\DataLab_%%L.pdf + move /Y build\doc\!MAIN_TEX:.tex=.pdf! %MODNAME%\data\doc\DataLab_%%L.pdf ) +endlocal @REM explorer %MODNAME%\data\doc diff --git a/scripts/build_resources.py b/scripts/build_resources.py index a990e5ff9..e829edb6b 100644 --- a/scripts/build_resources.py +++ b/scripts/build_resources.py @@ -2,22 +2,30 @@ """ Regenerate committed binary graphics resources from their SVG sources. -This script produces three files that are checked into git so that the -release pipeline does not need any external rasteriser: +This script produces the rasterised assets that are checked into git so +that the release pipeline does not need any external rasteriser: - * ``resources/DataLab.ico`` - multi-size Windows icon used by the EXE - * ``wix/dialog.bmp`` - 493x312 background of the WiX UI dialog - * ``wix/banner.bmp`` - 493x58 banner used by the WiX UI + * ``resources/DataLab.ico`` - multi-size Windows icon for the EXE + * ``resources/DataLab-Reset.ico`` - multi-size icon for the reset shortcut + * ``wix/dialog.bmp`` - 493x312 background of the WiX UI dialog + * ``wix/banner.bmp`` - 493x58 banner used by the WiX UI + * ``datalab/data/logo/DataLab.svg`` - copy of the master logo (used at runtime) + * PNG renderings under ``doc/`` and ``datalab/data/logo/`` (splash, + watermark, banners, frontpage, overview, screenshots, ...) -Run this script only when the corresponding SVG sources change -(``resources/DataLab.svg``, ``resources/WixUIDialog.svg``, -``resources/WixUIBanner.svg``). +Run this script only when the corresponding SVG sources change. Requirements ------------ * Qt (via ``qtpy`` / PyQt5) - already a hard dependency of DataLab, used - here through ``QSvgRenderer`` for SVG -> raster conversion. + here through ``QSvgRenderer`` for SVG -> raster conversion of the icon + (multi-size ``.ico``) and WiX bitmap assets. +* CairoSVG - already pulled in by ``sphinxcontrib-svg2pdfconverter[CairoSVG]`` + (PDF documentation build). Used for PNG rasterisation because Qt5's + ``QSvgRenderer`` mis-renders the Inkscape-authored logos (content drawn + outside the declared ``width``/``height``, nested transforms): output is + scaled by an unexpected 4/3 factor and clips the text. * Pillow - already pulled transitively by scikit-image and PlotPy. Handles ICO assembly (with PNG-compressed 256x256 sub-image) and 24 bpp BMP v3 encoding for the WiX UI assets. @@ -28,22 +36,71 @@ from __future__ import annotations import argparse +import base64 import io +import re +import shutil import struct import sys from pathlib import Path +import cairosvg +from PIL import Image +from qtpy.QtSvg import QSvgRenderer + REPO_ROOT = Path(__file__).resolve().parent.parent RESOURCES = REPO_ROOT / "resources" WIX = REPO_ROOT / "wix" +LOGO = REPO_ROOT / "datalab" / "data" / "logo" +DOC_STATIC = REPO_ROOT / "doc" / "_static" +DOC_IMAGES = REPO_ROOT / "doc" / "images" ICO_SIZES = (16, 24, 32, 48, 128, 256) DIALOG_SIZE = (493, 312) BANNER_SIZE = (493, 58) +# Multi-size ``.ico`` files: (source SVG, destination ICO). +ICO_TARGETS: tuple[tuple[Path, Path], ...] = ( + (RESOURCES / "DataLab.svg", RESOURCES / "DataLab.ico"), + (RESOURCES / "DataLab-Reset.svg", RESOURCES / "DataLab-Reset.ico"), +) + +# PNG renderings: (source SVG, destination PNG, width). +# Height is derived from the SVG ``viewBox`` to preserve the aspect ratio. +PNG_TARGETS: tuple[tuple[Path, Path, int], ...] = ( + (RESOURCES / "DataLab-Title.svg", DOC_STATIC / "DataLab-Title.png", 190), + (RESOURCES / "DataLab-Frontpage.svg", DOC_STATIC / "DataLab-Frontpage.png", 1300), + (RESOURCES / "DataLab-Splash.svg", LOGO / "DataLab-Splash.png", 350), + (RESOURCES / "DataLab-watermark.svg", LOGO / "DataLab-watermark.png", 225), + (RESOURCES / "DataLab-Banner.svg", DOC_IMAGES / "DataLab-banner.png", 364), + (RESOURCES / "DataLab-Banner.svg", LOGO / "DataLab-Banner-150.png", 150), + ( + RESOURCES / "DataLab-Screenshot-Theme.svg", + DOC_IMAGES / "DataLab-Screenshot-Theme.png", + 982, + ), + (RESOURCES / "DataLab-Overview.svg", DOC_IMAGES / "DataLab-Overview.png", 1250), + ( + RESOURCES / "DataLab-Windows-Installer.svg", + DOC_IMAGES / "shots" / "windows_installer.png", + 900, + ), +) + +# Plain SVG copies (source -> destination). +SVG_COPIES: tuple[tuple[Path, Path], ...] = ( + (RESOURCES / "DataLab.svg", LOGO / "DataLab.svg"), +) + def _render_svg(src: Path, width: int, height: int): - """Rasterise ``src`` (SVG) at the requested size and return a PIL RGBA image.""" + """Rasterise ``src`` (SVG) at the requested size and return a PIL RGBA image. + + Uses Qt's ``QSvgRenderer``. Suitable for icon and WiX bitmap assets + where Qt rendering is known to match the committed reference output. + For PNG documentation assets, see :func:`_render_svg_png_bytes` + (cairosvg-based), since Qt5 mis-renders the Inkscape-authored logos. + """ from PIL import Image from qtpy.QtCore import QSize from qtpy.QtGui import QImage, QPainter @@ -73,8 +130,21 @@ def _render_svg(src: Path, width: int, height: int): return Image.frombytes("RGBA", (width, height), bytes(ptr)) -def build_ico() -> None: - """Generate ``resources/DataLab.ico`` from ``resources/DataLab.svg``. +def _svg_height_for_width(src: Path, width: int) -> int: + """Return the height that preserves the SVG ``viewBox`` aspect ratio.""" + if not src.is_file(): + raise FileNotFoundError(src) + renderer = QSvgRenderer(str(src)) + if not renderer.isValid(): + raise RuntimeError(f"Invalid SVG: {src}") + vbox = renderer.viewBoxF() + if vbox.width() <= 0 or vbox.height() <= 0: + raise RuntimeError(f"SVG has no usable viewBox: {src}") + return max(1, round(width * vbox.height() / vbox.width())) + + +def _build_one_ico(src: Path, dst: Path) -> None: + """Generate a multi-size ``.ico`` from a single SVG source. Each size is rasterised individually via Qt, then assembled into a multi-image ``.ico``. The 256x256 sub-image is stored PNG-compressed @@ -82,9 +152,6 @@ def build_ico() -> None: of the icon originally committed in 2023 and keeping the file ~100 KB instead of ~350 KB. """ - src = RESOURCES / "DataLab.svg" - dst = RESOURCES / "DataLab.ico" - entries: list[tuple[int, bytes]] = [] # (size, payload bytes as embedded) for size in ICO_SIZES: img = _render_svg(src, size, size) @@ -148,10 +215,17 @@ def build_ico() -> None: data_offset += len(payload) image_blob += payload out += image_blob + dst.parent.mkdir(parents=True, exist_ok=True) dst.write_bytes(bytes(out)) print(f"Wrote {dst.relative_to(REPO_ROOT)}") +def build_icos() -> None: + """Generate every multi-size ``.ico`` declared in :data:`ICO_TARGETS`.""" + for src, dst in ICO_TARGETS: + _build_one_ico(src, dst) + + def _svg_to_bmp(src: Path, dst: Path, width: int, height: int) -> None: """Rasterise ``src`` (SVG) and save it as a 24 bpp BMP v3 (no alpha). @@ -159,8 +233,6 @@ def _svg_to_bmp(src: Path, dst: Path, width: int, height: int) -> None: no alpha channel) - which is exactly what Pillow writes by default when the input image is in RGB mode. """ - from PIL import Image - dst.parent.mkdir(parents=True, exist_ok=True) img = _render_svg(src, width, height) # Convert RGBA -> RGB (flatten on white) to strip the alpha channel, @@ -177,19 +249,110 @@ def build_wix_bitmaps() -> None: _svg_to_bmp(RESOURCES / "WixUIBanner.svg", WIX / "banner.bmp", *BANNER_SIZE) +_NESTED_SVG_HREF_RE = None # lazy-compiled in :func:`_inline_nested_svgs` + + +def _inline_nested_svgs(svg_path: Path) -> str: + """Return the SVG source with ```` references + replaced by base64 PNG data URIs. + + CairoSVG follows ```` hrefs only for raster formats; it silently + drops nested SVG references (used by ``DataLab-Frontpage.svg`` and + ``DataLab-Overview.svg`` to embed ``DataLab-Banner2.svg`` / + ``DataLab-Panorama.svg``). We rasterise each linked SVG to a PNG sized + after its declared ``width`` / ``height`` attributes (oversampled 2x for + quality) and substitute the href in place. + """ + global _NESTED_SVG_HREF_RE + if _NESTED_SVG_HREF_RE is None: + _NESTED_SVG_HREF_RE = re.compile( + r'(]*?\b(?:xlink:href|href)\s*=\s*")([^"]+\.svg)(")', + re.IGNORECASE | re.DOTALL, + ) + + text = svg_path.read_text(encoding="utf-8") + + def _replace(match: "re.Match[str]") -> str: + href = match.group(2) + linked = (svg_path.parent / href).resolve() + if not linked.is_file(): + print(f" warning: linked SVG not found, leaving as-is: {href}") + return match.group(0) + # Render the linked SVG at 2x its declared image size for quality. + # Pull width/height from the parent element attributes. + attrs = match.group(0) + m_w = re.search(r'\bwidth\s*=\s*"([\d.]+)"', attrs) + # m_h = re.search(r'\bheight\s*=\s*"([\d.]+)"', attrs) + target_w = int(float(m_w.group(1)) * 2) if m_w else 2000 + target_w = max(800, min(target_w, 6000)) + target_h = _svg_height_for_width(linked, target_w) + png_bytes = cairosvg.svg2png( + url=str(linked), + output_width=target_w, + output_height=target_h, + ) + data_uri = "data:image/png;base64," + base64.b64encode(png_bytes).decode( + "ascii" + ) + return f"{match.group(1)}{data_uri}{match.group(3)}" + + return _NESTED_SVG_HREF_RE.sub(_replace, text) + + +def build_pngs() -> None: + """Rasterise every PNG declared in :data:`PNG_TARGETS` via CairoSVG. + + CairoSVG (pure Python, libcairo-based) is used here instead of Qt's + ``QSvgRenderer`` because Qt5 mis-renders the Inkscape-authored logos + (content scaled by an unexpected ~4/3 factor, cropping the text). + """ + for src, dst, width in PNG_TARGETS: + if not src.is_file(): + raise FileNotFoundError(src) + height = _svg_height_for_width(src, width) + dst.parent.mkdir(parents=True, exist_ok=True) + svg_source = _inline_nested_svgs(src) + cairosvg.svg2png( + bytestring=svg_source.encode("utf-8"), + url=str(src), # base URL for any remaining relative refs + write_to=str(dst), + output_width=width, + output_height=height, + ) + print(f"Wrote {dst.relative_to(REPO_ROOT)} ({width}x{height})") + + +def copy_svgs() -> None: + """Copy plain SVG sources declared in :data:`SVG_COPIES`.""" + for src, dst in SVG_COPIES: + if not src.is_file(): + raise FileNotFoundError(src) + dst.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(src, dst) + print(f"Wrote {dst.relative_to(REPO_ROOT)}") + + def main(argv: list[str] | None = None) -> int: + """Main entry point for the script.""" parser = argparse.ArgumentParser(description=__doc__.splitlines()[1]) + valid = {"ico", "wix", "png", "copy", "all"} parser.add_argument( "targets", nargs="*", - choices=("ico", "wix", "all"), - default=["all"], - help="Subset of resources to regenerate (default: all).", + help=( + "Subset of resources to regenerate: ico, wix, png, copy, all " + "(default: all)." + ), ) args = parser.parse_args(argv) - targets = set(args.targets) + targets = set(args.targets) or {"all"} + unknown = targets - valid + if unknown: + parser.error( + f"invalid target(s): {sorted(unknown)} (choose from {sorted(valid)})" + ) if "all" in targets: - targets = {"ico", "wix"} + targets = {"ico", "wix", "png", "copy"} # A real QApplication is required so QSvgRenderer can access system fonts # (Century Gothic, etc.). Do NOT use the "offscreen" platform plugin: it @@ -200,9 +363,13 @@ def main(argv: list[str] | None = None) -> int: print(f"Using Qt SVG renderer ({type(app).__module__})") if "ico" in targets: - build_ico() + build_icos() if "wix" in targets: build_wix_bitmaps() + if "png" in targets: + build_pngs() + if "copy" in targets: + copy_svgs() print("Done.") return 0