Compare commits

...

31 Commits
v0.1.0 ... main

Author SHA1 Message Date
34e05476ba add hint for missing models 2025-11-21 07:17:31 +01:00
9f5ea4af5f bump to v0.1.5 2025-11-21 07:08:24 +01:00
507e94a73f add dep dotenv to please anomalib, closes #18 2025-11-21 07:04:42 +01:00
6e3192885b adapted anomaly threshold constant based on tests (#19)
ANOMALY_THRESHOLD changed

Co-authored-by: frasu <frasu@noreply.localhost>
Reviewed-on: #19
2025-11-21 05:58:46 +00:00
80ce3dd46d bump version to v0.1.4 2025-11-20 17:13:09 +01:00
8884ef69be fix result reproduction error on different computers (#17)
fixes #16

Co-authored-by: frasu <frasu@noreply.localhost>
Reviewed-on: #17
Co-authored-by: foefl <f.foerster@d-opt.com>
Co-committed-by: foefl <f.foerster@d-opt.com>
2025-11-20 16:04:26 +00:00
24bba92caf generated by Cython v3.2.1 2025-11-18 15:44:47 +01:00
22296a7bc3 docs: fix typo 2025-11-13 09:07:40 +01:00
4050de98c9 update docs 2025-11-13 09:00:48 +01:00
8ed9c07817 add manual as documentation 2025-11-11 11:39:35 +01:00
60a7c1f765 bump version to 0.1.3 2025-11-11 10:38:37 +01:00
7a6081815c update test case for new exception output 2025-11-11 10:38:24 +01:00
84f1f6fb1b remove unneeded print statement in test case 2025-11-11 10:21:50 +01:00
00214c3b1e update CLI with loading animation, closes #13 2025-11-11 10:14:33 +01:00
04a75838e6 upgrade dopt-basics to newest release to use CLI spinning animation 2025-11-11 10:11:10 +01:00
5037e7733b update CLI to propagate correct exit status code 2025-11-10 15:44:46 +01:00
4a94815bfe add graceful error handling with return of status codes, closes #12 2025-11-10 15:27:39 +01:00
08f70ee672 fix type issue for anomaly label 2025-11-10 14:21:45 +01:00
9e6daa01ea update README as manual, closes #15 2025-11-10 14:01:47 +01:00
7501b1b635 make CLI callable from cmd line with Python executable 2025-11-10 12:22:07 +01:00
158e242c83 add more specific author metadata 2025-11-10 09:22:22 +01:00
f9fab829a0 refactor to make cli standalone script, related to #11; add type hints to cli help messages, closes #10 2025-11-10 09:06:30 +01:00
5dff65992e remove cli entry point, related to #11 2025-11-10 09:02:54 +01:00
cc7b9d8416 move cli out of lib, related to #11 2025-11-10 09:02:07 +01:00
346b905a86 src/dopt_sensor_anomalies/detection.py aktualisiert 2025-11-04 10:24:53 +00:00
7472a128dd src/dopt_sensor_anomalies/detection.py aktualisiert 2025-11-03 16:34:15 +00:00
d074e1a840 rename model files 2025-10-24 13:58:18 +02:00
dd40440843 add simple CLI directly to package, related to #8 2025-10-24 13:03:27 +02:00
1920d01607 bump version to v0.1.1 2025-10-24 10:47:51 +02:00
3e41aa34aa script to run full test suite with Cython modules, closes #6 2025-10-24 10:46:53 +02:00
712a1f534a add C# interface module, closes #4 2025-10-24 10:46:08 +02:00
23 changed files with 3291 additions and 3147 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.pth filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ reports/
*.code-workspace
# credentials
CREDENTIALS*
*.pth
# Byte-compiled / optimized / DLL files
__pycache__/

View File

@ -1,8 +1,64 @@
[![pdm-managed](https://img.shields.io/endpoint?url=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fpdm-project%2F.github%2Fbadge.json)](https://pdm-project.org)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
# EKF Diagnostic: Sensor Anomalies
# EKF Diagnostic: Detektion von Sensor-Anomalien
This project aims to perform anomaly detection on sensor images with a CLI application.
## Übersicht
*Further information is provided at later project stages.*
### Funktion
Die im Rahmen des Projekts erstellte Anwendung erlaubt es, Bilder von Sensoren, die in der laufenden Fertigung während der Inline-Qualitätskontrolle erstellt werden, auf folgende Eigenschaften hin zu überprüfen:
- Abmessungen der Elektroden eines jeden Sensors auf Basis von Kalibrierungswerten (in der Form Pixel/Maßeinheit)
- Erkennung von Anomalien und damit möglichen Defekten eines Sensors
Ein zu analysierendes Bild enthält zwei Sensoren mit ihrer jeweils definierten Anzahl an Elektroden. Ein solches Bild kann über das bereitgestellte Command-Line-Interface (CLI) analysiert werden. Ist die Analyse erfolgreich, wird eine nach dem Bild benannte CSV-Datei im selben Verzeichnis, in welchem sich das Bild befindet, abgelegt. Diese CSV-Datei enthält die ermittelten Werte für die Abmessungen der Elektroden sowie deren Flächeninhalte. Jeder Sensor besitzt drei Elektroden. Demzufolge ergeben sich 2x3x3 = 18 Kennwerte.
Darüber hinaus wird ermittelt, ob die Sensoren jeweils Anomalien aufweisen. Die CSV-Datei enthält zusätzlich zu den 18 Maß-Kennwerten zwei Einträge mit jeweils ``0`` oder ``1``, ein Ergebnis der Anomaliedetektion für jeden Sensor. Bei einem Ergebnis von ``0`` wurde keine Anomalie festgestellt, bei ``1`` hingegen schon.
Im Zuge der Analyse wird eine Heatmap für das Bild erzeugt, welche Rückschlüsse auf Anomaliebereiche erlaubt. Die Datei wird analog der CSV-Datei im entsprechenden Ordner der ursprünglichen Bilddatei mit einem Suffix abgelegt.
### Architektur und Implementierung
Die Anwendung ist vollständig in Python implementiert. Zur Nutzung wird eine vollständige Python-Standalone-Umgebung mit allen erforderlichen Abhängigkeiten bereitgestellt. Das Anwendungsverzeichnis wird als gepacktes ZIP-Archiv bereitgestellt. Die entpackte Größe liegt bei etwa 1,3 GB.
Die Nutzung erfolgt über ein CLI, das über ein Python-Skript abgerufen werden kann. Dieses liegt im Wurzelverzeichnis der Python-Umgebung als ``cli.py`` ab.
## Command-Line-Interface
Die Funktionalität wird über ein CLI nutzbar gemacht. Hierfür liegt in der bereitgestellten Distribution im Ordner "python" ein Python-Skript ab. Dieses muss durch den ebenfalls in diesem Ordner befindlichen Interpreter "python.exe" aufgerufen werden. Erfolgt der Aufruf mit einem anderen Interpreter, werden die installierten Abhängigkeiten nicht gefunden und das Programm funktioniert nicht. Ausgehend vom Ordner, in dem das entpackte Applikationsverzeichnis abliegt, kann die Applikation folgendermaßen aufgerufen werden:
```pwsh
cd ekf-sensor-anomalies-deployment\python
.\python.exe .\cli.py --help
```
Dieser Befehl gibt den folgenden Hilfetext aus:
```
usage: cli.py [-h] img_path calib_value_x calib_value_y
simple CLI tool to analyse single sensor images for anomalies
positional arguments:
img_path file path to the image which is to be analysed
calib_value_x calibration value in pixels per mcm for x axis, type: float
calib_value_y calibration value in pixels per mcm for y axis, type: float
options:
-h, --help show this help message and exit
```
Das CLI besteht entsprechend der obigen Beschreibung aus einer Funktion. Diese benötigt die folgenden Parameter:
- ``img_path``: den Pfad zur Bilddatei, in diesem Projekt Bitmap-Dateien (``.bmp``)
- ``calib_value_x``: den Kalibrierwert in x-Richtung zur Ermittlung der Abmessungen, angegeben in Pixel/µm als Gleitkommazahl
- ``calib_value_y``: den Kalibrierwert in y-Richtung zur Ermittlung der Abmessungen, angegeben in Pixel/µm als Gleitkommazahl
Alle Parameter sind obligatorisch und müssen bereitgestellt werden. Die Analyse ist stets für nur ein Bild zur selben Zeit durchführbar. Eine Übergabe mehrerer Dateien ist nicht möglich. Ausgaben, die nicht auf Fehler zurückzuführen sind, werden standardmäßig über ``STDOUT`` ausgegeben.
### Fehlermeldungen
Die Anwendung führt zahlreiche Verarbeitungsschritte durch. Treten hierbei Fehler auf, werden diese mit ihrer Bezeichnung und einer Fehlerbeschreibung ausgegeben. Dies erlaubt Rückschlüsse, an welcher Stelle der Verarbeitungs-Pipeline Fehler aufgetreten sind und aus welchen Gründen das geschah. Die Fehlerausgabe erfolgt über ``STDERR``.
Ein separates Loggen weiterer Ausgaben erfolgt nicht.

55
cli.py Normal file
View File

@ -0,0 +1,55 @@
import argparse
import dataclasses as dc
import sys
from typing import cast
from dopt_basics import cli
from dopt_sensor_anomalies import _interface
@dc.dataclass()
class CliArgs:
img_path: str
calib_value_x: float
calib_value_y: float
def main() -> int:
parser = argparse.ArgumentParser(
description=("simple CLI tool to analyse single sensor images for anomalies")
)
parser.add_argument(
"img_path",
help="file path to the image which is to be analysed",
type=str,
)
parser.add_argument(
"calib_value_x",
help="calibration value in pixels per mcm for x axis, type: float",
type=float,
)
parser.add_argument(
"calib_value_y",
help="calibration value in pixels per mcm for y axis, type: float",
type=float,
)
args = cast(CliArgs, parser.parse_args())
with cli.LoadingAnimation(
"Perform anomaly detection...",
"Pipeline ended successfully!",
) as loader:
status = _interface.sensor_anomalies_detection(
args.img_path,
args.calib_value_x,
args.calib_value_y,
)
if status != 0:
loader.stop(interrupt=True)
sys.exit(status)
if __name__ == "__main__":
main()

58
cli_mocked.py Normal file
View File

@ -0,0 +1,58 @@
import argparse
import dataclasses as dc
import sys
from typing import cast
from unittest.mock import patch
from dopt_basics import cli
from dopt_sensor_anomalies import _interface
@dc.dataclass()
class CliArgs:
img_path: str
calib_value_x: float
calib_value_y: float
@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "src")
@patch("dopt_sensor_anomalies._find_paths.MODEL_FOLDER_NAME", "tests/_models")
def main() -> int:
parser = argparse.ArgumentParser(
description=("simple CLI tool to analyse single sensor images for anomalies")
)
parser.add_argument(
"img_path",
help="file path to the image which is to be analysed",
type=str,
)
parser.add_argument(
"calib_value_x",
help="calibration value in pixels per mcm for x axis, type: float",
type=float,
)
parser.add_argument(
"calib_value_y",
help="calibration value in pixels per mcm for y axis, type: float",
type=float,
)
args = cast(CliArgs, parser.parse_args())
with cli.LoadingAnimation(
"Perform anomaly detection...",
"Pipeline ended successfully!",
) as loader:
status = _interface.sensor_anomalies_detection(
args.img_path,
args.calib_value_x,
args.calib_value_y,
)
if status != 0:
loader.stop(interrupt=True)
sys.exit(status)
if __name__ == "__main__":
main()

13
docs/header.tex Normal file
View File

@ -0,0 +1,13 @@
\usepackage{listings}
\usepackage[scaled=0.9]{DejaVuSansMono} % or another monospaced font
\renewcommand{\ttdefault}{pcr} % 'pcr' = Courier
\lstset{
basicstyle=\ttfamily\small,
columns=fullflexible,
keepspaces=true,
breaklines=true,
breakatwhitespace=true,
showstringspaces=false,
frame=none,
backgroundcolor=\color{white}
}

63
docs/manual.md Normal file
View File

@ -0,0 +1,63 @@
# EKF Diagnostic: Detektion von Sensor-Anomalien
## Übersicht
### Funktion
Die im Rahmen des Projekts erstellte Anwendung erlaubt es, Bilder von Sensoren, die in der laufenden Fertigung während der Inline-Qualitätskontrolle erstellt werden, auf folgende Eigenschaften hin zu überprüfen:
- Abmessungen der Elektroden eines jeden Sensors auf Basis von Kalibrierungswerten (in der Form Pixel/Maßeinheit)
- Erkennung von Anomalien und damit möglichen Defekten eines Sensors
Ein zu analysierendes Bild enthält zwei Sensoren mit ihrer jeweils definierten Anzahl an Elektroden. Ein solches Bild kann über das bereitgestellte Command-Line-Interface (CLI) analysiert werden. Ist die Analyse erfolgreich, wird eine nach dem Bild benannte CSV-Datei im selben Verzeichnis, in welchem sich das Bild befindet, abgelegt. Diese CSV-Datei enthält die ermittelten Werte für die Abmessungen der Elektroden sowie deren Flächeninhalte. Jeder Sensor besitzt drei Elektroden. Demzufolge ergeben sich 2x3x3 = 18 Kennwerte.
Darüber hinaus wird ermittelt, ob die Sensoren jeweils Anomalien aufweisen. Die CSV-Datei enthält zusätzlich zu den 18 Maß-Kennwerten zwei Einträge mit jeweils ``0`` oder ``1``, ein Ergebnis der Anomaliedetektion für jeden Sensor. Bei einem Ergebnis von ``0`` wurde keine Anomalie festgestellt, bei ``1`` hingegen schon.
Im Zuge der Analyse wird eine Heatmap für das Bild erzeugt, welche Rückschlüsse auf Anomaliebereiche erlaubt. Die Datei wird analog der CSV-Datei im entsprechenden Ordner der ursprünglichen Bilddatei mit einem Suffix abgelegt.
### Architektur und Implementierung
Die Anwendung ist vollständig in Python implementiert. Zur Nutzung wird eine vollständige Python-Standalone-Umgebung mit allen erforderlichen Abhängigkeiten bereitgestellt. Das Anwendungsverzeichnis wird als gepacktes ZIP-Archiv bereitgestellt. Die entpackte Größe liegt bei etwa 1,3 GB.
Die Nutzung erfolgt über ein CLI, das über ein Python-Skript abgerufen werden kann. Dieses liegt im Wurzelverzeichnis der Python-Umgebung als ``cli.py`` ab.
## Command-Line-Interface
Die Funktionalität wird über ein CLI nutzbar gemacht. Hierfür liegt in der bereitgestellten Distribution im Ordner "python" ein Python-Skript ab. Dieses muss durch den ebenfalls in diesem Ordner befindlichen Interpreter "python.exe" aufgerufen werden. Erfolgt der Aufruf mit einem anderen Interpreter, werden die installierten Abhängigkeiten nicht gefunden und das Programm funktioniert nicht. Ausgehend vom Ordner, in dem das entpackte Applikationsverzeichnis abliegt, kann die Applikation folgendermaßen aufgerufen werden:
```pwsh
cd ekf-sensor-anomalies-deployment\python
.\python.exe .\cli.py --help
```
Dieser Befehl gibt den folgenden Hilfetext aus:
```
usage: cli.py [-h] img_path calib_value_x calib_value_y
simple CLI tool to analyse single sensor images for anomalies
positional arguments:
img_path file path to the image which is to be analysed
calib_value_x calibration value in pixels per mcm for x axis, type: float
calib_value_y calibration value in pixels per mcm for y axis, type: float
```
\newpage
```
options:
-h, --help show this help message and exit
```
Das CLI besteht entsprechend der obigen Beschreibung aus einer Funktion. Diese benötigt die folgenden Parameter:
- ``img_path``: den Pfad zur Bilddatei, in diesem Projekt Bitmap-Dateien (``.bmp``)
- ``calib_value_x``: den Kalibrierwert in x-Richtung zur Ermittlung der Abmessungen, angegeben in Pixel/µm als Gleitkommazahl
- ``calib_value_y``: den Kalibrierwert in y-Richtung zur Ermittlung der Abmessungen, angegeben in Pixel/µm als Gleitkommazahl
Alle Parameter sind obligatorisch und müssen bereitgestellt werden. Die Analyse ist stets für nur ein Bild zur selben Zeit durchführbar. Eine Übergabe mehrerer Dateien ist nicht möglich. Ausgaben, die nicht auf Fehler zurückzuführen sind, werden standardmäßig über ``STDOUT`` ausgegeben.
### Fehlermeldungen
Die Anwendung führt zahlreiche Verarbeitungsschritte durch. Treten hierbei Fehler auf, werden diese mit ihrer Bezeichnung und einer Fehlerbeschreibung ausgegeben. Dies erlaubt Rückschlüsse, an welcher Stelle der Verarbeitungs-Pipeline Fehler aufgetreten sind und aus welchen Gründen das geschah. Die Fehlerausgabe erfolgt über ``STDERR``.
Ein separates Loggen weiterer Ausgaben erfolgt nicht.

BIN
docs/manual.pdf Normal file

Binary file not shown.

353
pdm.lock generated
View File

@ -5,7 +5,7 @@
groups = ["default", "dev", "lint", "nb", "tests"]
strategy = ["inherit_metadata"]
lock_version = "4.5.0"
content_hash = "sha256:4b2f0f4a1813aaf44b68052d728903f36f705d12f720b52b18e21131ee7b605a"
content_hash = "sha256:68a0d82fb8cdbb8c525191dfbd6b290c14ccb7b60e44ae1d07760f21fe43bb5e"
[[metadata.targets]]
requires_python = ">=3.11,<3.14"
@ -23,7 +23,7 @@ files = [
[[package]]
name = "aiohttp"
version = "3.13.0"
version = "3.13.2"
requires_python = ">=3.9"
summary = "Async http client/server framework (asyncio)"
groups = ["default"]
@ -38,58 +38,58 @@ dependencies = [
"yarl<2.0,>=1.17.0",
]
files = [
{file = "aiohttp-3.13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:99eb94e97a42367fef5fc11e28cb2362809d3e70837f6e60557816c7106e2e20"},
{file = "aiohttp-3.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4696665b2713021c6eba3e2b882a86013763b442577fe5d2056a42111e732eca"},
{file = "aiohttp-3.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3e6a38366f7f0d0f6ed7a1198055150c52fda552b107dad4785c0852ad7685d1"},
{file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aab715b1a0c37f7f11f9f1f579c6fbaa51ef569e47e3c0a4644fba46077a9409"},
{file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7972c82bed87d7bd8e374b60a6b6e816d75ba4f7c2627c2d14eed216e62738e1"},
{file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca8313cb852af788c78d5afdea24c40172cbfff8b35e58b407467732fde20390"},
{file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c333a2385d2a6298265f4b3e960590f787311b87f6b5e6e21bb8375914ef504"},
{file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc6d5fc5edbfb8041d9607f6a417997fa4d02de78284d386bea7ab767b5ea4f3"},
{file = "aiohttp-3.13.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ddedba3d0043349edc79df3dc2da49c72b06d59a45a42c1c8d987e6b8d175b8"},
{file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23ca762140159417a6bbc959ca1927f6949711851e56f2181ddfe8d63512b5ad"},
{file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bfe824d6707a5dc3c5676685f624bc0c63c40d79dc0239a7fd6c034b98c25ebe"},
{file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3c11fa5dd2ef773a8a5a6daa40243d83b450915992eab021789498dc87acc114"},
{file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:00fdfe370cffede3163ba9d3f190b32c0cfc8c774f6f67395683d7b0e48cdb8a"},
{file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6475e42ef92717a678bfbf50885a682bb360a6f9c8819fb1a388d98198fdcb80"},
{file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:77da5305a410910218b99f2a963092f4277d8a9c1f429c1ff1b026d1826bd0b6"},
{file = "aiohttp-3.13.0-cp311-cp311-win32.whl", hash = "sha256:2f9d9ea547618d907f2ee6670c9a951f059c5994e4b6de8dcf7d9747b420c820"},
{file = "aiohttp-3.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f19f7798996d4458c669bd770504f710014926e9970f4729cf55853ae200469"},
{file = "aiohttp-3.13.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1c272a9a18a5ecc48a7101882230046b83023bb2a662050ecb9bfcb28d9ab53a"},
{file = "aiohttp-3.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:97891a23d7fd4e1afe9c2f4473e04595e4acb18e4733b910b6577b74e7e21985"},
{file = "aiohttp-3.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:475bd56492ce5f4cffe32b5533c6533ee0c406d1d0e6924879f83adcf51da0ae"},
{file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c32ada0abb4bc94c30be2b681c42f058ab104d048da6f0148280a51ce98add8c"},
{file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4af1f8877ca46ecdd0bc0d4a6b66d4b2bddc84a79e2e8366bc0d5308e76bceb8"},
{file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e04ab827ec4f775817736b20cdc8350f40327f9b598dec4e18c9ffdcbea88a93"},
{file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a6d9487b9471ec36b0faedf52228cd732e89be0a2bbd649af890b5e2ce422353"},
{file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e66c57416352f36bf98f6641ddadd47c93740a22af7150d3e9a1ef6e983f9a8"},
{file = "aiohttp-3.13.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:469167d5372f5bb3aedff4fc53035d593884fff2617a75317740e885acd48b04"},
{file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a9f3546b503975a69b547c9fd1582cad10ede1ce6f3e313a2f547c73a3d7814f"},
{file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6b4174fcec98601f0cfdf308ee29a6ae53c55f14359e848dab4e94009112ee7d"},
{file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a533873a7a4ec2270fb362ee5a0d3b98752e4e1dc9042b257cd54545a96bd8ed"},
{file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ce887c5e54411d607ee0959cac15bb31d506d86a9bcaddf0b7e9d63325a7a802"},
{file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d871f6a30d43e32fc9252dc7b9febe1a042b3ff3908aa83868d7cf7c9579a59b"},
{file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:222c828243b4789d79a706a876910f656fad4381661691220ba57b2ab4547865"},
{file = "aiohttp-3.13.0-cp312-cp312-win32.whl", hash = "sha256:682d2e434ff2f1108314ff7f056ce44e457f12dbed0249b24e106e385cf154b9"},
{file = "aiohttp-3.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:0a2be20eb23888df130214b91c262a90e2de1553d6fb7de9e9010cec994c0ff2"},
{file = "aiohttp-3.13.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:00243e51f16f6ec0fb021659d4af92f675f3cf9f9b39efd142aa3ad641d8d1e6"},
{file = "aiohttp-3.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:059978d2fddc462e9211362cbc8446747ecd930537fa559d3d25c256f032ff54"},
{file = "aiohttp-3.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:564b36512a7da3b386143c611867e3f7cfb249300a1bf60889bd9985da67ab77"},
{file = "aiohttp-3.13.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4aa995b9156ae499393d949a456a7ab0b994a8241a96db73a3b73c7a090eff6a"},
{file = "aiohttp-3.13.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:55ca0e95a3905f62f00900255ed807c580775174252999286f283e646d675a49"},
{file = "aiohttp-3.13.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:49ce7525853a981fc35d380aa2353536a01a9ec1b30979ea4e35966316cace7e"},
{file = "aiohttp-3.13.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2117be9883501eaf95503bd313eb4c7a23d567edd44014ba15835a1e9ec6d852"},
{file = "aiohttp-3.13.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d169c47e40c911f728439da853b6fd06da83761012e6e76f11cb62cddae7282b"},
{file = "aiohttp-3.13.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:703ad3f742fc81e543638a7bebddd35acadaa0004a5e00535e795f4b6f2c25ca"},
{file = "aiohttp-3.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5bf635c3476f4119b940cc8d94ad454cbe0c377e61b4527f0192aabeac1e9370"},
{file = "aiohttp-3.13.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cfe6285ef99e7ee51cef20609be2bc1dd0e8446462b71c9db8bb296ba632810a"},
{file = "aiohttp-3.13.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:34d8af6391c5f2e69749d7f037b614b8c5c42093c251f336bdbfa4b03c57d6c4"},
{file = "aiohttp-3.13.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:12f5d820fadc5848d4559ea838aef733cf37ed2a1103bba148ac2f5547c14c29"},
{file = "aiohttp-3.13.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f1338b61ea66f4757a0544ed8a02ccbf60e38d9cfb3225888888dd4475ebb96"},
{file = "aiohttp-3.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:582770f82513419512da096e8df21ca44f86a2e56e25dc93c5ab4df0fe065bf0"},
{file = "aiohttp-3.13.0-cp313-cp313-win32.whl", hash = "sha256:3194b8cab8dbc882f37c13ef1262e0a3d62064fa97533d3aa124771f7bf1ecee"},
{file = "aiohttp-3.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:7897298b3eedc790257fef8a6ec582ca04e9dbe568ba4a9a890913b925b8ea21"},
{file = "aiohttp-3.13.0.tar.gz", hash = "sha256:378dbc57dd8cf341ce243f13fa1fa5394d68e2e02c15cd5f28eae35a70ec7f67"},
{file = "aiohttp-3.13.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4647d02df098f6434bafd7f32ad14942f05a9caa06c7016fdcc816f343997dd0"},
{file = "aiohttp-3.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e3403f24bcb9c3b29113611c3c16a2a447c3953ecf86b79775e7be06f7ae7ccb"},
{file = "aiohttp-3.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:43dff14e35aba17e3d6d5ba628858fb8cb51e30f44724a2d2f0c75be492c55e9"},
{file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2a9ea08e8c58bb17655630198833109227dea914cd20be660f52215f6de5613"},
{file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53b07472f235eb80e826ad038c9d106c2f653584753f3ddab907c83f49eedead"},
{file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e736c93e9c274fce6419af4aac199984d866e55f8a4cec9114671d0ea9688780"},
{file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ff5e771f5dcbc81c64898c597a434f7682f2259e0cd666932a913d53d1341d1a"},
{file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3b6fb0c207cc661fa0bf8c66d8d9b657331ccc814f4719468af61034b478592"},
{file = "aiohttp-3.13.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:97a0895a8e840ab3520e2288db7cace3a1981300d48babeb50e7425609e2e0ab"},
{file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9e8f8afb552297aca127c90cb840e9a1d4bfd6a10d7d8f2d9176e1acc69bad30"},
{file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed2f9c7216e53c3df02264f25d824b079cc5914f9e2deba94155190ef648ee40"},
{file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:99c5280a329d5fa18ef30fd10c793a190d996567667908bef8a7f81f8202b948"},
{file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2ca6ffef405fc9c09a746cb5d019c1672cd7f402542e379afc66b370833170cf"},
{file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:47f438b1a28e926c37632bff3c44df7d27c9b57aaf4e34b1def3c07111fdb782"},
{file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9acda8604a57bb60544e4646a4615c1866ee6c04a8edef9b8ee6fd1d8fa2ddc8"},
{file = "aiohttp-3.13.2-cp311-cp311-win32.whl", hash = "sha256:868e195e39b24aaa930b063c08bb0c17924899c16c672a28a65afded9c46c6ec"},
{file = "aiohttp-3.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:7fd19df530c292542636c2a9a85854fab93474396a52f1695e799186bbd7f24c"},
{file = "aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b"},
{file = "aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc"},
{file = "aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7"},
{file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb"},
{file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3"},
{file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f"},
{file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6"},
{file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e"},
{file = "aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7"},
{file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d"},
{file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b"},
{file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8"},
{file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16"},
{file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169"},
{file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248"},
{file = "aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e"},
{file = "aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45"},
{file = "aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be"},
{file = "aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742"},
{file = "aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293"},
{file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811"},
{file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a"},
{file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4"},
{file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a"},
{file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e"},
{file = "aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb"},
{file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded"},
{file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b"},
{file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8"},
{file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04"},
{file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476"},
{file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23"},
{file = "aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254"},
{file = "aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a"},
{file = "aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca"},
]
[[package]]
@ -153,21 +153,6 @@ files = [
{file = "anomalib-2.1.0.tar.gz", hash = "sha256:b3e21cd6a7a5119151fe0b2b4ccf891b823f62ba540c1ec46b3538d7abdc8940"},
]
[[package]]
name = "anomalib"
version = "2.1.0"
extras = ["vlm_clip"]
requires_python = ">=3.10"
summary = "anomalib - Anomaly Detection Library"
groups = ["default"]
dependencies = [
"anomalib==2.1.0",
]
files = [
{file = "anomalib-2.1.0-py3-none-any.whl", hash = "sha256:b1689a7e50f2be9fc802cd079165f13c3f5708518151702b31bf5cc1512545fd"},
{file = "anomalib-2.1.0.tar.gz", hash = "sha256:b3e21cd6a7a5119151fe0b2b4ccf891b823f62ba540c1ec46b3538d7abdc8940"},
]
[[package]]
name = "antlr4-python3-runtime"
version = "4.9.3"
@ -904,7 +889,7 @@ files = [
[[package]]
name = "dopt-basics"
version = "0.2.0"
version = "0.2.4"
requires_python = ">=3.11"
summary = "basic cross-project tools for Python-based d-opt projects"
groups = ["default"]
@ -912,8 +897,20 @@ dependencies = [
"tzdata>=2025.1",
]
files = [
{file = "dopt_basics-0.2.0-py3-none-any.whl", hash = "sha256:8aba3d512f6356a6a6bbe4188ad399fd465896a4ad4085008fa53552ecf6096c"},
{file = "dopt_basics-0.2.0.tar.gz", hash = "sha256:116cb40885090bfc02143a874e0b0974bfb9dd61cb725576787e3fd7fda4ffd1"},
{file = "dopt_basics-0.2.4-py3-none-any.whl", hash = "sha256:b7d05b80dde1f856b352580aeac500fc7505e4513ed162791d8735cdc182ebc1"},
{file = "dopt_basics-0.2.4.tar.gz", hash = "sha256:c21fbe183bec5eab4cfd1404e10baca670035801596960822d0019e6e885983f"},
]
[[package]]
name = "dotenv"
version = "0.9.9"
summary = "Deprecated package"
groups = ["default"]
dependencies = [
"python-dotenv",
]
files = [
{file = "dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9"},
]
[[package]]
@ -1111,29 +1108,29 @@ files = [
[[package]]
name = "fsspec"
version = "2025.9.0"
version = "2025.10.0"
requires_python = ">=3.9"
summary = "File-system specification"
groups = ["default"]
files = [
{file = "fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7"},
{file = "fsspec-2025.9.0.tar.gz", hash = "sha256:19fd429483d25d28b65ec68f9f4adc16c17ea2c7c7bf54ec61360d478fb19c19"},
{file = "fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d"},
{file = "fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59"},
]
[[package]]
name = "fsspec"
version = "2025.9.0"
version = "2025.10.0"
extras = ["http"]
requires_python = ">=3.9"
summary = "File-system specification"
groups = ["default"]
dependencies = [
"aiohttp!=4.0.0a0,!=4.0.0a1",
"fsspec==2025.9.0",
"fsspec==2025.10.0",
]
files = [
{file = "fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7"},
{file = "fsspec-2025.9.0.tar.gz", hash = "sha256:19fd429483d25d28b65ec68f9f4adc16c17ea2c7c7bf54ec61360d478fb19c19"},
{file = "fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d"},
{file = "fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59"},
]
[[package]]
@ -1245,17 +1242,17 @@ files = [
[[package]]
name = "imageio"
version = "2.37.0"
version = "2.37.2"
requires_python = ">=3.9"
summary = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats."
summary = "Read and write images and video across all major formats. Supports scientific and volumetric data."
groups = ["default"]
dependencies = [
"numpy",
"pillow>=8.3.2",
]
files = [
{file = "imageio-2.37.0-py3-none-any.whl", hash = "sha256:11efa15b87bc7871b61590326b2d635439acc321cf7f8ce996f812543ce10eed"},
{file = "imageio-2.37.0.tar.gz", hash = "sha256:71b57b3669666272c818497aebba2b4c5f20d5b37c81720e5e1a56d59c492996"},
{file = "imageio-2.37.2-py3-none-any.whl", hash = "sha256:ad9adfb20335d718c03de457358ed69f141021a333c40a53e57273d8a5bd0b9b"},
{file = "imageio-2.37.2.tar.gz", hash = "sha256:0212ef2727ac9caa5ca4b2c75ae89454312f440a756fcfc8ef1993e718f50f8a"},
]
[[package]]
@ -1440,7 +1437,7 @@ files = [
[[package]]
name = "jsonargparse"
version = "4.41.0"
version = "4.43.0"
requires_python = ">=3.9"
summary = "Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables."
groups = ["default"]
@ -1448,42 +1445,42 @@ dependencies = [
"PyYAML>=3.13",
]
files = [
{file = "jsonargparse-4.41.0-py3-none-any.whl", hash = "sha256:cd49b6a2fea723ee4d80f9df034f51af226128a7f166be8755d6acdeb3e077a7"},
{file = "jsonargparse-4.41.0.tar.gz", hash = "sha256:ba1806bf0ed0ad1975e403dffb18b3a755fee3bfe4e7b36d8cce2f297b552b5f"},
{file = "jsonargparse-4.43.0-py3-none-any.whl", hash = "sha256:9b0d427277ddf87fd6b7160fe83e83dc4418b0fe71b649b0586e7c56effa49f1"},
{file = "jsonargparse-4.43.0.tar.gz", hash = "sha256:b1a4b4a5f938d2902d5f65e84ba361fb4a451c1f4609aac2c07e9c75d42e111f"},
]
[[package]]
name = "jsonargparse"
version = "4.41.0"
version = "4.43.0"
extras = ["signatures"]
requires_python = ">=3.9"
summary = "Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables."
groups = ["default"]
dependencies = [
"docstring-parser>=0.17",
"jsonargparse==4.41.0",
"jsonargparse==4.43.0",
"jsonargparse[typing-extensions]",
"typeshed-client>=2.8.2",
]
files = [
{file = "jsonargparse-4.41.0-py3-none-any.whl", hash = "sha256:cd49b6a2fea723ee4d80f9df034f51af226128a7f166be8755d6acdeb3e077a7"},
{file = "jsonargparse-4.41.0.tar.gz", hash = "sha256:ba1806bf0ed0ad1975e403dffb18b3a755fee3bfe4e7b36d8cce2f297b552b5f"},
{file = "jsonargparse-4.43.0-py3-none-any.whl", hash = "sha256:9b0d427277ddf87fd6b7160fe83e83dc4418b0fe71b649b0586e7c56effa49f1"},
{file = "jsonargparse-4.43.0.tar.gz", hash = "sha256:b1a4b4a5f938d2902d5f65e84ba361fb4a451c1f4609aac2c07e9c75d42e111f"},
]
[[package]]
name = "jsonargparse"
version = "4.41.0"
version = "4.43.0"
extras = ["typing-extensions"]
requires_python = ">=3.9"
summary = "Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables."
groups = ["default"]
dependencies = [
"jsonargparse==4.41.0",
"jsonargparse==4.43.0",
"typing-extensions>=3.10.0.0; python_version < \"3.10\"",
]
files = [
{file = "jsonargparse-4.41.0-py3-none-any.whl", hash = "sha256:cd49b6a2fea723ee4d80f9df034f51af226128a7f166be8755d6acdeb3e077a7"},
{file = "jsonargparse-4.41.0.tar.gz", hash = "sha256:ba1806bf0ed0ad1975e403dffb18b3a755fee3bfe4e7b36d8cce2f297b552b5f"},
{file = "jsonargparse-4.43.0-py3-none-any.whl", hash = "sha256:9b0d427277ddf87fd6b7160fe83e83dc4418b0fe71b649b0586e7c56effa49f1"},
{file = "jsonargparse-4.43.0.tar.gz", hash = "sha256:b1a4b4a5f938d2902d5f65e84ba361fb4a451c1f4609aac2c07e9c75d42e111f"},
]
[[package]]
@ -1809,48 +1806,48 @@ files = [
[[package]]
name = "kornia"
version = "0.8.1"
version = "0.8.2"
requires_python = ">=3.9"
summary = "Open Source Differentiable Computer Vision Library for PyTorch"
groups = ["default"]
dependencies = [
"kornia-rs>=0.1.9",
"packaging",
"torch>=1.9.1",
"torch>=2.0.0",
]
files = [
{file = "kornia-0.8.1-py2.py3-none-any.whl", hash = "sha256:5dcb00faa795dfb45a3630d771387290bc4f40473451352ca250e5bcc81af3d1"},
{file = "kornia-0.8.1.tar.gz", hash = "sha256:9ce5a54a11df661794934a293f89f8b8d49e83dd09b0b9419f6082ab07afe433"},
{file = "kornia-0.8.2-py2.py3-none-any.whl", hash = "sha256:32dfe77c9c74a87a2de49395aa3c2c376a1b63c27611a298b394d02d13905819"},
{file = "kornia-0.8.2.tar.gz", hash = "sha256:5411b2ce0dd909d1608016308cd68faeef90f88c47f47e8ecd40553fd4d8b937"},
]
[[package]]
name = "kornia-rs"
version = "0.1.9"
version = "0.1.10"
requires_python = ">=3.8"
summary = "Low level implementations for computer vision in Rust"
groups = ["default"]
files = [
{file = "kornia_rs-0.1.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a0f45987702e816f34bc0fcac253c504932d8ca877c9ab644d8445e7de737aec"},
{file = "kornia_rs-0.1.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9bb863f3ff42919749b7db4a56f2adb076a10d3c57907305898c72e643fa3d5d"},
{file = "kornia_rs-0.1.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54604bc8eb7d4d703eac19963378b4d6a72432a3f0da765edb1b0396d10def01"},
{file = "kornia_rs-0.1.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cdda9133297c4cff2c2c54be44d5c39bce715306d0bccb8ab1fae7c0dc7cf63"},
{file = "kornia_rs-0.1.9-cp311-cp311-win_amd64.whl", hash = "sha256:689929d8dab80928feedbcdc2375060a3fe02b32fbf0dba12ae3fefb605fd089"},
{file = "kornia_rs-0.1.9-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:889b4121f830d8827260f0246554f8bd722137d98db0bf3c2b0f5b1812cf5c63"},
{file = "kornia_rs-0.1.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a0834f6aa44a35b486fe9802516dde24ec5d8b3b51563f18b488098062074671"},
{file = "kornia_rs-0.1.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e52ead233c9d0b924eee4b906f26f32fde1e236a30723525dfb2b1a610bd48b"},
{file = "kornia_rs-0.1.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e74a8901843e8e5e47f495927462288c7b7b8dc8a253495051c72a5fbda5f664"},
{file = "kornia_rs-0.1.9-cp312-cp312-win_amd64.whl", hash = "sha256:fdfe0baa04800e541425730d03f3b3d217a1a6f0303926889b443b4562c0fda5"},
{file = "kornia_rs-0.1.9-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e82f5d90ad5b3d02d28535d19bf612e25ca559003d56fad1d12cd173be5d8418"},
{file = "kornia_rs-0.1.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:876f0805ed8d05bd94d6b9a6c43161cdc74bc5c4508f5b737d6975d1dcf9016d"},
{file = "kornia_rs-0.1.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00021bb1941766e1e9e8c2cdbebcf33a08f8de3586e6efc791b9580a7e52b5ed"},
{file = "kornia_rs-0.1.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9feaa6d410bc4d0609f3c1f2c0c010743706c2f5eed6f5ded10f2b8fec32acdf"},
{file = "kornia_rs-0.1.9-cp313-cp313-win_amd64.whl", hash = "sha256:4d063e9d74d2b198f080940cd1679cfb66004cd59bb7cc20e0bcf5874ce3d200"},
{file = "kornia_rs-0.1.9-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f8d03da3dba89fd290f4df012f49262cde128e3682632b5c498b34909d875190"},
{file = "kornia_rs-0.1.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cef15e7db4cd05ebedc25cd62616c38346f71f7e8a2fb751feacc8726e7e417e"},
{file = "kornia_rs-0.1.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d6ea40aa2027f62e90c590112fc4be4a787092359ed041479d2b015c0483c97"},
{file = "kornia_rs-0.1.9-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9282a70c9e81710f04fdb23617c73191324ccc070c7f96d62efb5bf66dc242a"},
{file = "kornia_rs-0.1.9-cp313-cp313t-win_amd64.whl", hash = "sha256:cd6b9860ca2fd6103340f4f977f74fa96562d89563e36c00059f2d96c7cea464"},
{file = "kornia_rs-0.1.9.tar.gz", hash = "sha256:c7e45e84eb3c2454055326f86329e48a68743507460fb7e39315397fa6eeb9a0"},
{file = "kornia_rs-0.1.10-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6757940733f13c52c4f142b9b11e3e9bd12ef9d209e333300602e86e21f5ae2f"},
{file = "kornia_rs-0.1.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68e90101a34ba2bbce920332b25fd4d25c8c546d9a241b2606a6d886df2dd1ed"},
{file = "kornia_rs-0.1.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b0adb81858a8963455f2f0da01fcd6ea3296147b918306488edeeaf6bc2a979"},
{file = "kornia_rs-0.1.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c3e237a8428524ad9f86599c0c47b355bc3007669fe297ea3fbd59cd64bc2f7"},
{file = "kornia_rs-0.1.10-cp311-cp311-win_amd64.whl", hash = "sha256:1d300ea6d4666e47302fba6cc438556d91e37ce41caf291a9a04a8f74c231d0b"},
{file = "kornia_rs-0.1.10-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f0809277e51156d59be3c39605ba9659e94f7a4cf3b0b6c035ec2f06f6067881"},
{file = "kornia_rs-0.1.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ecf2ba0291cc1bb178073d56e46b16296a8864a20272b63af02ee88771cb574"},
{file = "kornia_rs-0.1.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d874ca12dd58871f9849672d9bf9fa998398470a88b52d61223ce2133b196662"},
{file = "kornia_rs-0.1.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f332a2a034cc791006f25c2d85e342a060887145e9236e8e43562badcadededf"},
{file = "kornia_rs-0.1.10-cp312-cp312-win_amd64.whl", hash = "sha256:34111ce1c8abe930079b4b0aeb8d372f876c621a867ed03f77181de685e71a8f"},
{file = "kornia_rs-0.1.10-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:950a943f91c2cff94d80282886b0d48bbc15ef4a7cc4b15ac819724dfdb2f414"},
{file = "kornia_rs-0.1.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:63b802aaf95590276d3426edc6d23ff11caf269d2bc2ec37cb6c679b7b2a8ee0"},
{file = "kornia_rs-0.1.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38087da7cdf2bffe10530c0d53335dd1fc107fae6521f2dd4797c6522b6d11b3"},
{file = "kornia_rs-0.1.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa3464de8f9920d87415721c36840ceea23e054dcb54dd9f69189ba9eabce0c7"},
{file = "kornia_rs-0.1.10-cp313-cp313-win_amd64.whl", hash = "sha256:c57d157bebe64c22e2e44c72455b1c7365eee4d767e0c187dc28f22d072ebaf7"},
{file = "kornia_rs-0.1.10-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:0b375f02422ef5986caed612799b4ddcc91f57f303906868b0a8c397a17e7607"},
{file = "kornia_rs-0.1.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f2bcfa438d6b5dbe07d573afc980f2871f6639b2eac5148b8c0bba4f82357b9a"},
{file = "kornia_rs-0.1.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:021b0a02b2356b12b3954a298f369ed4fe2dd522dcf8b6d72f91bf3bd8eea201"},
{file = "kornia_rs-0.1.10-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d9b07e2ae79e423b3248d94afd092e324c5ddfe3157fafc047531cc8bffa6a3"},
{file = "kornia_rs-0.1.10-cp313-cp313t-win_amd64.whl", hash = "sha256:b80a037e34d63cb021bcd5fc571e41aff804a2981311f66e883768c6b8e5f8de"},
{file = "kornia_rs-0.1.10.tar.gz", hash = "sha256:5fd3fbc65240fa751975f5870b079f98e7fdcaa2885ea577b3da324d8bf01d81"},
]
[[package]]
@ -1881,7 +1878,7 @@ files = [
[[package]]
name = "lightning"
version = "2.5.5"
version = "2.5.6"
requires_python = ">=3.9"
summary = "The Deep Learning framework to train, deploy, and ship AI products Lightning fast."
groups = ["default"]
@ -1897,8 +1894,8 @@ dependencies = [
"typing-extensions<6.0,>4.5.0",
]
files = [
{file = "lightning-2.5.5-py3-none-any.whl", hash = "sha256:69eb248beadd7b600bf48eff00a0ec8af171ec7a678d23787c4aedf12e225e8f"},
{file = "lightning-2.5.5.tar.gz", hash = "sha256:4d3d66c5b1481364a7e6a1ce8ddde1777a04fa740a3145ec218a9941aed7dd30"},
{file = "lightning-2.5.6-py3-none-any.whl", hash = "sha256:25bb2053078c2efc57c082fda89dfbd975dfa76beb08def191947c2b571a8c8a"},
{file = "lightning-2.5.6.tar.gz", hash = "sha256:57b6abe87080895bc237fb7f36b7b4abaa2793760cbca00e3907e56607e0ed27"},
]
[[package]]
@ -3176,7 +3173,7 @@ name = "python-dotenv"
version = "1.1.1"
requires_python = ">=3.9"
summary = "Read key-value pairs from a .env file and set them as environment variables"
groups = ["dev"]
groups = ["default", "dev"]
files = [
{file = "python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc"},
{file = "python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab"},
@ -3198,7 +3195,7 @@ files = [
[[package]]
name = "pytorch-lightning"
version = "2.5.5"
version = "2.5.6"
requires_python = ">=3.9"
summary = "PyTorch Lightning is the lightweight PyTorch wrapper for ML researchers. Scale your models. Write less boilerplate."
groups = ["default"]
@ -3213,8 +3210,8 @@ dependencies = [
"typing-extensions>4.5.0",
]
files = [
{file = "pytorch_lightning-2.5.5-py3-none-any.whl", hash = "sha256:0b533991df2353c0c6ea9ca10a7d0728b73631fd61f5a15511b19bee2aef8af0"},
{file = "pytorch_lightning-2.5.5.tar.gz", hash = "sha256:d6fc8173d1d6e49abfd16855ea05d2eb2415e68593f33d43e59028ecb4e64087"},
{file = "pytorch_lightning-2.5.6-py3-none-any.whl", hash = "sha256:037bad1e2fd94d5eb6c5144f045fd4c1070c3d38fc9c14d9f3774a3a9be54dff"},
{file = "pytorch_lightning-2.5.6.tar.gz", hash = "sha256:c428faaceef74be50b870814d0d7e9f9c6ee748b8769a2afd3366bc69daf3a0f"},
]
[[package]]
@ -3503,7 +3500,7 @@ files = [
[[package]]
name = "rich"
version = "14.1.0"
version = "14.2.0"
requires_python = ">=3.8.0"
summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
groups = ["default", "dev"]
@ -3512,13 +3509,13 @@ dependencies = [
"pygments<3.0.0,>=2.13.0",
]
files = [
{file = "rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f"},
{file = "rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8"},
{file = "rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd"},
{file = "rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4"},
]
[[package]]
name = "rich-argparse"
version = "1.7.1"
version = "1.7.2"
requires_python = ">=3.8"
summary = "Rich help formatters for argparse and optparse"
groups = ["default"]
@ -3526,8 +3523,8 @@ dependencies = [
"rich>=11.0.0",
]
files = [
{file = "rich_argparse-1.7.1-py3-none-any.whl", hash = "sha256:a8650b42e4a4ff72127837632fba6b7da40784842f08d7395eb67a9cbd7b4bf9"},
{file = "rich_argparse-1.7.1.tar.gz", hash = "sha256:d7a493cde94043e41ea68fb43a74405fa178de981bf7b800f7a3bd02ac5c27be"},
{file = "rich_argparse-1.7.2-py3-none-any.whl", hash = "sha256:0559b1f47a19bbeb82bf15f95a057f99bcbbc98385532f57937f9fc57acc501a"},
{file = "rich_argparse-1.7.2.tar.gz", hash = "sha256:64fd2e948fc96e8a1a06e0e72c111c2ce7f3af74126d75c0f5f63926e7289cd1"},
]
[[package]]
@ -3754,7 +3751,7 @@ files = [
[[package]]
name = "scipy"
version = "1.16.2"
version = "1.16.3"
requires_python = ">=3.11"
summary = "Fundamental algorithms for scientific computing in Python"
groups = ["default"]
@ -3762,47 +3759,47 @@ dependencies = [
"numpy<2.6,>=1.25.2",
]
files = [
{file = "scipy-1.16.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:6ab88ea43a57da1af33292ebd04b417e8e2eaf9d5aa05700be8d6e1b6501cd92"},
{file = "scipy-1.16.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c95e96c7305c96ede73a7389f46ccd6c659c4da5ef1b2789466baeaed3622b6e"},
{file = "scipy-1.16.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:87eb178db04ece7c698220d523c170125dbffebb7af0345e66c3554f6f60c173"},
{file = "scipy-1.16.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:4e409eac067dcee96a57fbcf424c13f428037827ec7ee3cb671ff525ca4fc34d"},
{file = "scipy-1.16.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e574be127bb760f0dad24ff6e217c80213d153058372362ccb9555a10fc5e8d2"},
{file = "scipy-1.16.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5db5ba6188d698ba7abab982ad6973265b74bb40a1efe1821b58c87f73892b9"},
{file = "scipy-1.16.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec6e74c4e884104ae006d34110677bfe0098203a3fec2f3faf349f4cb05165e3"},
{file = "scipy-1.16.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:912f46667d2d3834bc3d57361f854226475f695eb08c08a904aadb1c936b6a88"},
{file = "scipy-1.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:91e9e8a37befa5a69e9cacbe0bcb79ae5afb4a0b130fd6db6ee6cc0d491695fa"},
{file = "scipy-1.16.2-cp311-cp311-win_arm64.whl", hash = "sha256:f3bf75a6dcecab62afde4d1f973f1692be013110cad5338007927db8da73249c"},
{file = "scipy-1.16.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:89d6c100fa5c48472047632e06f0876b3c4931aac1f4291afc81a3644316bb0d"},
{file = "scipy-1.16.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ca748936cd579d3f01928b30a17dc474550b01272d8046e3e1ee593f23620371"},
{file = "scipy-1.16.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:fac4f8ce2ddb40e2e3d0f7ec36d2a1e7f92559a2471e59aec37bd8d9de01fec0"},
{file = "scipy-1.16.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:033570f1dcefd79547a88e18bccacff025c8c647a330381064f561d43b821232"},
{file = "scipy-1.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea3421209bf00c8a5ef2227de496601087d8f638a2363ee09af059bd70976dc1"},
{file = "scipy-1.16.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f66bd07ba6f84cd4a380b41d1bf3c59ea488b590a2ff96744845163309ee8e2f"},
{file = "scipy-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e9feab931bd2aea4a23388c962df6468af3d808ddf2d40f94a81c5dc38f32ef"},
{file = "scipy-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03dfc75e52f72cf23ec2ced468645321407faad8f0fe7b1f5b49264adbc29cb1"},
{file = "scipy-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:0ce54e07bbb394b417457409a64fd015be623f36e330ac49306433ffe04bc97e"},
{file = "scipy-1.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a8ffaa4ac0df81a0b94577b18ee079f13fecdb924df3328fc44a7dc5ac46851"},
{file = "scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70"},
{file = "scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9"},
{file = "scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5"},
{file = "scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925"},
{file = "scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9"},
{file = "scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7"},
{file = "scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb"},
{file = "scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e"},
{file = "scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c"},
{file = "scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104"},
{file = "scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1"},
{file = "scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a"},
{file = "scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f"},
{file = "scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4"},
{file = "scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21"},
{file = "scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7"},
{file = "scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8"},
{file = "scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472"},
{file = "scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351"},
{file = "scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d"},
{file = "scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b"},
{file = "scipy-1.16.3-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:40be6cf99e68b6c4321e9f8782e7d5ff8265af28ef2cd56e9c9b2638fa08ad97"},
{file = "scipy-1.16.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:8be1ca9170fcb6223cc7c27f4305d680ded114a1567c0bd2bfcbf947d1b17511"},
{file = "scipy-1.16.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bea0a62734d20d67608660f69dcda23e7f90fb4ca20974ab80b6ed40df87a005"},
{file = "scipy-1.16.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:2a207a6ce9c24f1951241f4693ede2d393f59c07abc159b2cb2be980820e01fb"},
{file = "scipy-1.16.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:532fb5ad6a87e9e9cd9c959b106b73145a03f04c7d57ea3e6f6bb60b86ab0876"},
{file = "scipy-1.16.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0151a0749efeaaab78711c78422d413c583b8cdd2011a3c1d6c794938ee9fdb2"},
{file = "scipy-1.16.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7180967113560cca57418a7bc719e30366b47959dd845a93206fbed693c867e"},
{file = "scipy-1.16.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:deb3841c925eeddb6afc1e4e4a45e418d19ec7b87c5df177695224078e8ec733"},
{file = "scipy-1.16.3-cp311-cp311-win_amd64.whl", hash = "sha256:53c3844d527213631e886621df5695d35e4f6a75f620dca412bcd292f6b87d78"},
{file = "scipy-1.16.3-cp311-cp311-win_arm64.whl", hash = "sha256:9452781bd879b14b6f055b26643703551320aa8d79ae064a71df55c00286a184"},
{file = "scipy-1.16.3-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81fc5827606858cf71446a5e98715ba0e11f0dbc83d71c7409d05486592a45d6"},
{file = "scipy-1.16.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:c97176013d404c7346bf57874eaac5187d969293bf40497140b0a2b2b7482e07"},
{file = "scipy-1.16.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2b71d93c8a9936046866acebc915e2af2e292b883ed6e2cbe5c34beb094b82d9"},
{file = "scipy-1.16.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3d4a07a8e785d80289dfe66b7c27d8634a773020742ec7187b85ccc4b0e7b686"},
{file = "scipy-1.16.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0553371015692a898e1aa858fed67a3576c34edefa6b7ebdb4e9dde49ce5c203"},
{file = "scipy-1.16.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:72d1717fd3b5e6ec747327ce9bda32d5463f472c9dce9f54499e81fbd50245a1"},
{file = "scipy-1.16.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fb2472e72e24d1530debe6ae078db70fb1605350c88a3d14bc401d6306dbffe"},
{file = "scipy-1.16.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c5192722cffe15f9329a3948c4b1db789fbb1f05c97899187dcf009b283aea70"},
{file = "scipy-1.16.3-cp312-cp312-win_amd64.whl", hash = "sha256:56edc65510d1331dae01ef9b658d428e33ed48b4f77b1d51caf479a0253f96dc"},
{file = "scipy-1.16.3-cp312-cp312-win_arm64.whl", hash = "sha256:a8a26c78ef223d3e30920ef759e25625a0ecdd0d60e5a8818b7513c3e5384cf2"},
{file = "scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:d2ec56337675e61b312179a1ad124f5f570c00f920cc75e1000025451b88241c"},
{file = "scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:16b8bc35a4cc24db80a0ec836a9286d0e31b2503cb2fd7ff7fb0e0374a97081d"},
{file = "scipy-1.16.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:5803c5fadd29de0cf27fa08ccbfe7a9e5d741bf63e4ab1085437266f12460ff9"},
{file = "scipy-1.16.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:b81c27fc41954319a943d43b20e07c40bdcd3ff7cf013f4fb86286faefe546c4"},
{file = "scipy-1.16.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0c3b4dd3d9b08dbce0f3440032c52e9e2ab9f96ade2d3943313dfe51a7056959"},
{file = "scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88"},
{file = "scipy-1.16.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:663b8d66a8748051c3ee9c96465fb417509315b99c71550fda2591d7dd634234"},
{file = "scipy-1.16.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eab43fae33a0c39006a88096cd7b4f4ef545ea0447d250d5ac18202d40b6611d"},
{file = "scipy-1.16.3-cp313-cp313-win_amd64.whl", hash = "sha256:062246acacbe9f8210de8e751b16fc37458213f124bef161a5a02c7a39284304"},
{file = "scipy-1.16.3-cp313-cp313-win_arm64.whl", hash = "sha256:50a3dbf286dbc7d84f176f9a1574c705f277cb6565069f88f60db9eafdbe3ee2"},
{file = "scipy-1.16.3-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:fb4b29f4cf8cc5a8d628bc8d8e26d12d7278cd1f219f22698a378c3d67db5e4b"},
{file = "scipy-1.16.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:8d09d72dc92742988b0e7750bddb8060b0c7079606c0d24a8cc8e9c9c11f9079"},
{file = "scipy-1.16.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:03192a35e661470197556de24e7cb1330d84b35b94ead65c46ad6f16f6b28f2a"},
{file = "scipy-1.16.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:57d01cb6f85e34f0946b33caa66e892aae072b64b034183f3d87c4025802a119"},
{file = "scipy-1.16.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:96491a6a54e995f00a28a3c3badfff58fd093bf26cd5fb34a2188c8c756a3a2c"},
{file = "scipy-1.16.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cd13e354df9938598af2be05822c323e97132d5e6306b83a3b4ee6724c6e522e"},
{file = "scipy-1.16.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63d3cdacb8a824a295191a723ee5e4ea7768ca5ca5f2838532d9f2e2b3ce2135"},
{file = "scipy-1.16.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e7efa2681ea410b10dde31a52b18b0154d66f2485328830e45fdf183af5aefc6"},
{file = "scipy-1.16.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2d1ae2cf0c350e7705168ff2429962a89ad90c2d49d1dd300686d8b2a5af22fc"},
{file = "scipy-1.16.3-cp313-cp313t-win_arm64.whl", hash = "sha256:0c623a54f7b79dd88ef56da19bc2873afec9673a48f3b85b18e4d402bdd29a5a"},
{file = "scipy-1.16.3.tar.gz", hash = "sha256:01e87659402762f43bd2fee13370553a17ada367d42e7487800bf2916535aecb"},
]
[[package]]
@ -3918,7 +3915,7 @@ files = [
[[package]]
name = "tifffile"
version = "2025.10.4"
version = "2025.10.16"
requires_python = ">=3.11"
summary = "Read and write TIFF files"
groups = ["default"]
@ -3926,8 +3923,8 @@ dependencies = [
"numpy",
]
files = [
{file = "tifffile-2025.10.4-py3-none-any.whl", hash = "sha256:7687d691e49026053181470cec70fa9250e3a586b2041041297e38b10bbd34e1"},
{file = "tifffile-2025.10.4.tar.gz", hash = "sha256:2e437c16ab211be5bcdc79f71b4907359115f1f83b5d919e7c297c29725d3e38"},
{file = "tifffile-2025.10.16-py3-none-any.whl", hash = "sha256:41463d979c1c262b0a5cdef2a7f95f0388a072ad82d899458b154a48609d759c"},
{file = "tifffile-2025.10.16.tar.gz", hash = "sha256:425179ec7837ac0e07bc95d2ea5bea9b179ce854967c12ba07fc3f093e58efc1"},
]
[[package]]

View File

@ -1,15 +1,16 @@
[project]
name = "dopt-sensor-anomalies"
version = "0.1.0"
version = "0.1.5"
description = "anomaly detection for sensor images for quality assurance processes"
authors = [
{name = "d-opt GmbH", email = "f.foerster@d-opt.com"},
{name = "d-opt GmbH (resp.: Florian Foerster)", email = "f.foerster@d-opt.com"},
]
dependencies = ["imutils>=0.5.4", "dopt-basics>=0.2.0", "numpy>=2.2.6", "anomalib[vlm_clip]>=2.1.0", "open-clip-torch>=3.2.0"]
dependencies = ["imutils>=0.5.4", "dopt-basics>=0.2.4", "numpy>=2.2.6", "open-clip-torch>=3.2.0", "anomalib==2.1.0", "dotenv>=0.9.9"]
requires-python = "<3.14,>=3.11"
readme = "README.md"
license = {text = "LicenseRef-Proprietary"}
[build-system]
requires = ["pdm-backend", "Cython", "setuptools"]
build-backend = "pdm.backend"
@ -76,7 +77,7 @@ directory = "reports/coverage"
[tool.bumpversion]
current_version = "0.1.0"
current_version = "0.1.5"
parse = """(?x)
(?P<major>0|[1-9]\\d*)\\.
(?P<minor>0|[1-9]\\d*)\\.
@ -148,6 +149,7 @@ dev = [
"cython>=3.1.4",
"setuptools>=80.9.0",
"build>=1.3.0",
"rich>=14.2.0",
]
nb = [
"jupyterlab>=4.3.5",

2
scripts/cvt_manual.ps1 Normal file
View File

@ -0,0 +1,2 @@
# covert the manual Markdown file to PDF
pandoc .\docs\manual.md -o .\docs\manual.pdf -V geometry:"a4paper, margin=2.5cm" -V header-includes="\usepackage[none]{hyphenat}" # -V header-includes="\lstset{escapeinside={(*@}{@*)}}" --include-in-header=.\docs\header.tex # --syntax-highlighting=idiomatic

View File

@ -0,0 +1,17 @@
Write-Output "[PWSH] Deleting compiled extension modules..."
Remove-Item ".\src\dopt_sensor_anomalies\*.pyd" -Force
Write-Output "[PWSH] Running tests..."
pdm run pytest --cov --cov-report=html --no-cov-on-fail
if ($? -eq $false){
Write-Output "[PWSH] Exiting script because there were failed tests"
Write-Output "[PWSH] No coverage report was generated"
Exit
}
Write-Output "[PWSH] Opening coverage report..."
Invoke-Item .\reports\coverage\index.html
Write-Output "[PWSH] Installing extension module..."
pdm install
Write-Output "[PWSH] Running test suite against extension module..."
pdm run pytest .\tests\test_detection.py

View File

@ -0,0 +1,44 @@
"""main pipeline interface for external calls"""
from __future__ import annotations
import sys
from typing import TYPE_CHECKING, TextIO
from dopt_sensor_anomalies import detection
if TYPE_CHECKING:
from dopt_basics.result_pattern import Status
def _print_error_state(
state: Status,
out_stream: TextIO,
) -> None:
if state.ExceptionType is None:
raise RuntimeError("Tried to treat state as error, but no exception is registered")
msg = (
f"During the procedure the following exception occurred:"
f"\nType: {state.ExceptionType.__name__}\nDescription: {state.description}\n"
f"Message: {state.message}"
)
print(f"\r{msg}", flush=True, file=out_stream)
def sensor_anomalies_detection(
user_img_path: str,
pixels_per_metric_X: float,
pixels_per_metric_Y: float,
) -> int:
res = detection.pipeline(
user_img_path=user_img_path,
pixels_per_metric_X=pixels_per_metric_X,
pixels_per_metric_Y=pixels_per_metric_Y,
)
if res.status.code != 0:
_print_error_state(res.status, out_stream=sys.stderr)
return 1
res.unwrap()
return 0

View File

@ -6,9 +6,10 @@ STOP_FOLDER_NAME: Final[str] = "python"
MODEL_FOLDER_NAME: Final[str] = "models"
THRESHOLD_BW: Final[int] = 63
BACKBONE: Final[str] = "resnet18"
LAYERS: Final[tuple[str, str]] = ("layer1", "layer2")
RATIO: Final[float] = 0.05
BACKBONE: Final[str] = "wide_resnet50_2"
LAYERS: Final[tuple[str, ...]] = ("layer1", "layer2", "layer3")
RATIO: Final[float] = 0.01
ANOMALY_THRESHOLD: Final[float] = 0.14
NUM_VALID_ELECTRODES: Final[int] = 6
HEATMAP_FILENAME_SUFFIX: Final[str] = "_Heatmap"

File diff suppressed because one or more lines are too long

View File

@ -140,10 +140,10 @@ def measure_length(
f"expected value: count = {num_contours}, expected = {const.NUM_VALID_ELECTRODES}"
)
x_min = min(np.min(c[:, 0, 0]) for c in filtered_cnts) - 20
x_max = max(np.max(c[:, 0, 0]) for c in filtered_cnts) + 20
y_min = min(np.min(c[:, 0, 1]) for c in filtered_cnts) - 20
y_max = max(np.max(c[:, 0, 1]) for c in filtered_cnts) + 20
x_min = max(min(np.min(c[:, 0, 0]) for c in filtered_cnts) - 20, 0)
x_max = min(max(np.max(c[:, 0, 0]) for c in filtered_cnts) + 20, orig.shape[1])
y_min = max(min(np.min(c[:, 0, 1]) for c in filtered_cnts) - 20, 0)
y_max = min(max(np.max(c[:, 0, 1]) for c in filtered_cnts) + 20, orig.shape[0])
rightmost_x_third = max(filtered_cnts[2][:, 0, 0])
leftmost_x_fourth = min(filtered_cnts[3][:, 0, 0])
@ -176,7 +176,7 @@ def infer_image(
output = model(input_tensor)
anomaly_score = output.pred_score.item()
anomaly_label = output.pred_label.item()
anomaly_label = bool(1 if anomaly_score >= const.ANOMALY_THRESHOLD else 0)
anomaly_map = output.anomaly_map.squeeze().cpu().numpy()
img_np = np.array(pil_image)

3
tests/_models/README.md Normal file
View File

@ -0,0 +1,3 @@
**PLACE MODELS IN THIS FOLDER**
The model files are too large. Download the files from our internal distribution channel (primarily cloud).

View File

@ -0,0 +1 @@
1177,318;804,803;947509,0;876,575;808,853;709020,9;952,191;804,781;766305,3;944,223;792,829;748607,2;838,797;804,902;675148,9;1203,187;792,829;953921,4;0;0
1 1177,318 804,803 947509,0 876,575 808,853 709020,9 952,191 804,781 766305,3 944,223 792,829 748607,2 838,797 804,902 675148,9 1203,187 792,829 953921,4 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@ -94,7 +94,7 @@ def test_isolated_pipeline(results_folder, path_img_with_failure_TrainedModel):
pixels_per_metric_X,
pixels_per_metric_Y,
)
print(">>>>>>> Data: ", data_csv)
# measured sizes
assert len(data_csv) == 18
assert sensor_images["left"] is not None
@ -150,6 +150,16 @@ def test_full_pipeline_wrapped_FailElectrodeCount(path_img_with_failure_Electrod
@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "lib")
def test_full_pipeline_wrapped_Success(results_folder, path_img_with_failure_TrainedModel):
# paths: check files for existence and delete because of other tests
root_img = path_img_with_failure_TrainedModel.parent
file_stem = path_img_with_failure_TrainedModel.stem
csv_file = root_img / f"{file_stem}.csv"
heatmap_file = root_img / f"{file_stem}{constants.HEATMAP_FILENAME_SUFFIX}.png"
if csv_file.exists():
csv_file.unlink()
if heatmap_file.exists():
heatmap_file.unlink()
img_path = str(path_img_with_failure_TrainedModel)
pixels_per_metric_X: float = 0.251
pixels_per_metric_Y: float = 0.251
@ -159,11 +169,6 @@ def test_full_pipeline_wrapped_Success(results_folder, path_img_with_failure_Tra
assert ret.status.code == 0
assert ret.status.ExceptionType is None
# check files for existence
root_img = path_img_with_failure_TrainedModel.parent
file_stem = path_img_with_failure_TrainedModel.stem
csv_file = root_img / f"{file_stem}.csv"
heatmap_file = root_img / f"{file_stem}{constants.HEATMAP_FILENAME_SUFFIX}.png"
assert csv_file.exists()
assert heatmap_file.exists()
shutil.copy(csv_file, (results_folder / csv_file.name))

111
tests/test_interface.py Normal file
View File

@ -0,0 +1,111 @@
import shutil
from io import StringIO
from unittest.mock import patch
import pytest
from dopt_basics.result_pattern import wrap_result
from dopt_sensor_anomalies import _interface, constants
def test_print_error_state_WrongState():
from dopt_basics.result_pattern import STATUS_HANDLER
MSG = "to treat state as error"
with pytest.raises(RuntimeError, match=MSG):
_interface._print_error_state(STATUS_HANDLER.SUCCESS, out_stream=StringIO())
def test_print_error_state(tmp_path):
@wrap_result(100)
def error_func() -> None:
# do something
raise RuntimeError("Oops, error occurred")
err_state = error_func().status
output_file = tmp_path / "t_output.txt"
output_file.touch()
with open(output_file, "w") as stream:
_interface._print_error_state(err_state, stream)
lines: list[str]
with open(output_file, "r") as file:
lines = file.readlines()
try:
lines.remove("\n")
except ValueError: # pragma: no cover
pass
assert "following exception" in lines[0]
assert "Type: RuntimeError" in lines[1]
assert "Description:" in lines[2]
assert "Message: Oops, error occurred" in lines[3]
@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "lib")
def test_sensor_anomalies_detection_FailImagePath(setup_temp_dir):
img_path = str(setup_temp_dir / "not-existing.bmp")
pixels_per_metric_X: float = 0.251
pixels_per_metric_Y: float = 0.251
MESSAGE = "The provided path seems not to exist"
with patch("sys.stderr", new_callable=StringIO) as mock_err:
ret = _interface.sensor_anomalies_detection(
img_path, pixels_per_metric_X, pixels_per_metric_Y
)
captured = mock_err.getvalue()
assert ret != 0
assert "FileNotFoundError" in captured
assert MESSAGE in captured
@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "lib")
def test_sensor_anomalies_detection_FailElectrodeCount(path_img_with_failure_ElectrodeCount):
img_path = str(path_img_with_failure_ElectrodeCount)
pixels_per_metric_X: float = 0.251
pixels_per_metric_Y: float = 0.251
MESSAGE = "Number of counted electrodes does not match the"
with patch("sys.stderr", new_callable=StringIO) as mock_err:
ret = _interface.sensor_anomalies_detection(
img_path, pixels_per_metric_X, pixels_per_metric_Y
)
captured = mock_err.getvalue()
assert ret != 0
assert "InvalidElectrodeCount" in captured
assert MESSAGE in captured
@patch("dopt_sensor_anomalies._find_paths.STOP_FOLDER_NAME", "lib")
def test_sensor_anomalies_detection_Success(
results_folder, path_img_with_failure_TrainedModel
):
# paths: check files for existence and delete because of other tests
root_img = path_img_with_failure_TrainedModel.parent
file_stem = path_img_with_failure_TrainedModel.stem
csv_file = root_img / f"{file_stem}.csv"
heatmap_file = root_img / f"{file_stem}{constants.HEATMAP_FILENAME_SUFFIX}.png"
if csv_file.exists():
csv_file.unlink()
if heatmap_file.exists():
heatmap_file.unlink()
img_path = str(path_img_with_failure_TrainedModel)
pixels_per_metric_X: float = 0.251
pixels_per_metric_Y: float = 0.251
ret = _interface.sensor_anomalies_detection(
img_path, pixels_per_metric_X, pixels_per_metric_Y
)
assert ret == 0
assert csv_file.exists()
assert heatmap_file.exists()
target_folder = results_folder / "csharp_interface"
target_folder.mkdir(exist_ok=True)
shutil.copy(csv_file, (target_folder / csv_file.name))
shutil.copy(heatmap_file, (target_folder / heatmap_file.name))