diff --git a/etc/6-install_django_app.sh b/etc/6-install_django_app.sh
index 0a4161d..4c0f2d4 100755
--- a/etc/6-install_django_app.sh
+++ b/etc/6-install_django_app.sh
@@ -30,6 +30,7 @@ echo "---- Tables ..."
./manage.py loaddata $ETC/db/configuration.json
./manage.py loaddata $ETC/db/well.json
./manage.py loaddata $ETC/db/multiwell.json
+./manage.py reset_all_well_position --all True
echo "---- start test_tube:*"
echo
diff --git a/test_tube_scanner/home/management/commands/reset_all_well_position.py b/test_tube_scanner/home/management/commands/reset_all_well_position.py
new file mode 100644
index 0000000..6c004b9
--- /dev/null
+++ b/test_tube_scanner/home/management/commands/reset_all_well_position.py
@@ -0,0 +1,36 @@
+'''
+Created on 19 janv. 2026
+
+@author: denis
+'''
+from django.core.management.base import BaseCommand
+#from django.conf import settings
+from scanner.models import MultiWell
+
+class Command(BaseCommand):
+ help = "Recalculer les positions de tous les puits d'un multi-puits"
+
+ def add_arguments(self, parser):
+ super(Command, self).add_arguments(parser)
+ parser.add_argument("--all", type=bool, help=f"Tous les puits de tous les multi-puits", default=False)
+ parser.add_argument("--position", type=str, help=f"Multiwel position: HD, HG, BD, BG", default="HD")
+
+ def handle(self, *args, **options): # @UnusedVariable
+ try:
+ position = options.get('position')
+ _all = options.get('all')
+
+ multiwells = [m for m in MultiWell.objects.filter(active=True).all() ]
+ for m in multiwells:
+ if m.position==position and not _all:
+ m.well_position=False
+ m.save()
+ print("Reset multi-puits position", position)
+ break
+ m.well_position=False
+ m.save()
+ print("Reset multi-puits position", position)
+
+ except Exception as e:
+ print(self.help, 'erreur', e)
+
diff --git a/test_tube_scanner/home/settings.py b/test_tube_scanner/home/settings.py
index 51df51d..d99863b 100644
--- a/test_tube_scanner/home/settings.py
+++ b/test_tube_scanner/home/settings.py
@@ -389,10 +389,9 @@ DATETIME_FORMAT = '%d-%m-%Y-%m %H:%M:%S'
EXPORTS_LOCAL_PATH = config("EXPORTS_LOCAL_PATH")
EXPORT_REMOTE_PATH = config("EXPORT_REMOTE_PATH")
-
EXPORT_DESTINATIONS = ["local", "remote"]
-TEST_VIDEOFILE = True
+TEST_VIDEOFILE = False
TRACKING = True
TRACKER_TUBE_AXIS = "vertical"
diff --git a/test_tube_scanner/scanner/models.py b/test_tube_scanner/scanner/models.py
index 7786d14..741ee72 100644
--- a/test_tube_scanner/scanner/models.py
+++ b/test_tube_scanner/scanner/models.py
@@ -14,12 +14,12 @@ from django.contrib.auth.models import User
# Multi-well positions on the table for calibration and observation
MULTIWELL_POSITION = [
- ('HG', _("Haut gauche")),
- ('HD', _("Haut droit")),
- ('BG', _("Bas gauche")),
- ('BD', _("Bas droit")),
- ('BM', _("Bas milieu")),
- ('HM', _("Haut milieu")),
+ ('HG', _("HG-Haut gauche")),
+ ('HD', _("HD-Haut droit")),
+ ('BG', _("BG-Bas gauche")),
+ ('BD', _("BD-Bas droit")),
+ ('BM', _("BM-Bas milieu")),
+ ('HM', _("HM-Haut milieu")),
]
FOURCC_FORMAT = [
@@ -32,6 +32,12 @@ VIDEO_TYPE = [
('avi', _("AVI")),
]
+CAPTURE_TYPE = [
+ ('rpi', _("Arducam")),
+ ('webcam', _("Webcam")),
+ ('file', _("mp4")),
+]
+
class Configuration(models.Model):
name = models.CharField(_("Nom de la Configuration"), help_text=_("Nom de la configuration"), max_length=100, null=True, blank=False, default=_("Configuration par défaut"))
author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="Auteur", null=True, blank=True)
@@ -44,10 +50,10 @@ class Configuration(models.Model):
# Grbl configuration
grbl_xmax = models.FloatField(_("Grbl Xmax"), help_text=_("CNC Grbl Xmax en mm"), blank=False, default=350.0)
grbl_ymax = models.FloatField(_("Grbl Ymax"), help_text=_("CNC Grbl Ymax en mm"), blank=False, default=250.0)
-
-
# camera configuration
use_rpicam = models.BooleanField(_("Utiliser rpicam"), help_text=_("Par défaaut. Sinon USB webcam"), default=True)
+ capture_type = models.CharField(_("Capture"), help_text=_("Type de capture"), default='rpi', max_length=8, choices=CAPTURE_TYPE, null=True, blank=False)
+
webcam_device_index = models.PositiveSmallIntegerField(_("Index de la webcam"), help_text=_("Index de la webcam (0, 1, ...) si présente"), default=2)
image_quality = models.PositiveSmallIntegerField(_("Qualité JPEG"), help_text=_("Qualité JPEG (1-100) pour les images exportées"), default=90)
video_jpeg_quality = models.PositiveSmallIntegerField(_("Qualité JPEG pour les vidéos"), help_text=_("Qualité JPEG (1-100) pour les images extraites des vidéos"), default=90)
@@ -60,6 +66,10 @@ class Configuration(models.Model):
calibration_default_feed = models.PositiveIntegerField(_("Vitesse de calibration"), help_text=_("Vitesse de déplacement pour la calibration en mm/mn"), default=1000)
calibration_default_step = models.FloatField(_("Pas de calibration"), help_text=_("Pas de déplacement pour la calibration en mm"), default=1.0)
calibration_default_duration = models.FloatField(_("Duruée calibration"), help_text=_("Durée de pose entre chaque puits en s"), default=3.0)
+ # tracking
+ tracking = models.BooleanField(_("Suivi"), help_text=_("Suivi et analyse des planaires"), default=False)
+
+ #
active = models.BooleanField(_("Actif"), default=False)
class Meta:
diff --git a/test_tube_scanner/scanner/process.py b/test_tube_scanner/scanner/process.py
index 5e99cda..dd931a5 100644
--- a/test_tube_scanner/scanner/process.py
+++ b/test_tube_scanner/scanner/process.py
@@ -138,9 +138,8 @@ class CameraRecordManager():
class ScannerProcess(Task):
- def __init__(self, use_tracking=False):
+ def __init__(self):
super().__init__()
- self.use_tracking = use_tracking
self.channel_layer = get_channel_layer()
self.group = f'scanner_proc'
self.stop_event = Event()
@@ -162,6 +161,7 @@ class ScannerProcess(Task):
def start(self, *args, **kwargs):
try:
self.conf = models.Configuration.objects.filter(active=True).first()
+ self.use_tracking = self.conf.tracking
self.video_quality = self.conf.video_jpeg_quality
self.image_quality = self.conf.image_quality
@@ -176,7 +176,9 @@ class ScannerProcess(Task):
self.grbl_ymax = self.conf.grbl_ymax
self.crop = self.set_crop_radius(self.crop_radius)
- if settings.TEST_VIDEOFILE:
+
+ capture_type = self.conf.capture_type
+ if capture_type == 'file':
video_lists = []
wells = models.Well.objects.all()
for wl in wells:
@@ -194,7 +196,7 @@ class ScannerProcess(Task):
parent=self,
video_lists=video_lists,
)
- elif not self.conf.use_rpicam:
+ elif capture_type == 'webcam':
from modules.webcam_capture import WebcamCapture
self.cam = WebcamCapture(
device_index=self.conf.webcam_device_index,
@@ -275,6 +277,7 @@ class ScannerProcess(Task):
try:
(uuid, ts, frame, metrics) = self.record_queue.get()
labels = dict(fps=self.video_fps, session=self.data.session, detected="1" if metrics.get("detected") else "0")
+
if metrics.get("detected"):
labels.update({
"cx" : str(metrics["cx"]),
@@ -283,7 +286,8 @@ class ScannerProcess(Task):
"speed_px_s" : str(metrics["speed_px_s"]),
"axial_pos" : str(metrics["axial_pos"]),
"axial_speed" : str(metrics["axial_speed"]),
- })
+ })
+
self.recordDB.write(uuid, frame, labels, ts=ts)
self.record_queue.task_done()
except Exception as e:
diff --git a/test_tube_scanner/scanner/tasks.py b/test_tube_scanner/scanner/tasks.py
index bf85812..c1e3b09 100644
--- a/test_tube_scanner/scanner/tasks.py
+++ b/test_tube_scanner/scanner/tasks.py
@@ -3,7 +3,6 @@ import asyncio
from celery import shared_task, group, chord, chain
from celery.utils.log import get_task_logger
from django.utils import timezone
-from django.conf import settings
from .process import ScannerProcess, ReplayProcess
from .export_tasks import shm_download_video, export_images_zip, export_video_mp4
@@ -19,7 +18,7 @@ class ScannerTaskManager:
def start_scanner(self):
if self.scanner is None:
- self.scanner = ScannerProcess(use_tracking=settings.TRACKING)
+ self.scanner = ScannerProcess()
self.scanner.start()
def stop_scanner(self):
diff --git a/test_tube_scanner/scanner/templates/scanner/base.html b/test_tube_scanner/scanner/templates/scanner/base.html
index 24ea541..cfb855c 100644
--- a/test_tube_scanner/scanner/templates/scanner/base.html
+++ b/test_tube_scanner/scanner/templates/scanner/base.html
@@ -74,7 +74,7 @@
{% trans "Administration base de données" %}
-
+
{% trans "Base de données Reductstore" %}
@@ -83,13 +83,13 @@
-
+
{% trans "Supervisor" %}
-
+
{% trans "Logs des planifications" %}
-
+
{% trans "Logs des services" %}
diff --git a/test_tube_scanner/scanner/templates/scanner/calibration.html b/test_tube_scanner/scanner/templates/scanner/calibration.html
index 37b309f..c1587cd 100644
--- a/test_tube_scanner/scanner/templates/scanner/calibration.html
+++ b/test_tube_scanner/scanner/templates/scanner/calibration.html
@@ -133,17 +133,17 @@