simulate
This commit is contained in:
@@ -396,8 +396,8 @@ EXPORT_DESTINATIONS = ["local", "remote"]
|
||||
|
||||
|
||||
TRACKER_TUBE_AXIS = "vertical"
|
||||
TRACKER_MIN_AREA = 20 # surface min planaire
|
||||
TRACKER_MAX_AREA_RATIO = 0.05 # 5% de la frame = surface max acceptable
|
||||
TRACKER_MIN_AREA = 8 # surface min planaire px x px
|
||||
TRACKER_MAX_AREA_RATIO = 0.1 # 5% de la frame = surface max acceptable
|
||||
TRACKER_MAX_PLANARIANS = 3
|
||||
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ class MultiWellManager:
|
||||
|
||||
|
||||
#def _grid_scanning_capture(self, uuid, duration):
|
||||
def _grid_scanning_capture(self, experiment, well_position):
|
||||
def _grid_scanning_capture(self, experiment, well_position, simulate=False):
|
||||
well = well_position.well
|
||||
multiwell = experiment.multiwell
|
||||
|
||||
@@ -134,12 +134,15 @@ class MultiWellManager:
|
||||
uuid = f'{self.process.data.session}-{multiwell.position}-{well.name}'
|
||||
## start recording
|
||||
self.process.data.uuid = uuid
|
||||
if not simulate:
|
||||
self.process.data.record = True
|
||||
|
||||
start = time.monotonic()
|
||||
while not self.stop_playing.is_set():
|
||||
if time.monotonic() - start > multiwell.duration:
|
||||
break
|
||||
self.cnc_controller.wait_for(1.0)
|
||||
|
||||
self.process.data.record = False
|
||||
self.process.data.uuid = None
|
||||
|
||||
@@ -148,7 +151,7 @@ class MultiWellManager:
|
||||
self.process._send(scan_state=msg)
|
||||
|
||||
|
||||
def _grid_scanning(self, experiment, xnext=0, ynext=0):
|
||||
def _grid_scanning(self, experiment, xnext=0, ynext=0, simulate=False):
|
||||
multiwell = experiment.multiwell
|
||||
wells = models.WellPosition.objects.filter(multiwell_id=multiwell.id).order_by('order').all()
|
||||
cam = self.process.cam
|
||||
@@ -159,10 +162,7 @@ class MultiWellManager:
|
||||
if self.stop_playing.is_set():
|
||||
break
|
||||
self.cnc_controller.move_to(wl.x, wl.y, feed=wl.multiwell.feed)
|
||||
|
||||
#uuid = f'{self.process.data.session}-{multiwell.position}-{wl.well.name}'
|
||||
#self._grid_scanning_capture(uuid, multiwell.duration)
|
||||
self._grid_scanning_capture(experiment, wl)
|
||||
self._grid_scanning_capture(experiment, wl, simulate=simulate)
|
||||
|
||||
## change file
|
||||
if self.process.conf.capture_type == 'file':
|
||||
@@ -172,7 +172,7 @@ class MultiWellManager:
|
||||
self.cnc_controller.move_to(xnext, ynext, feed=multiwell.feed*2)
|
||||
|
||||
|
||||
def _start_scanning(self, session, experiments):
|
||||
def _start_scanning(self, session, experiments, simulate=False):
|
||||
self.process.cam._aligner.debug = False
|
||||
xynext = []
|
||||
for obs in experiments:
|
||||
@@ -189,7 +189,7 @@ class MultiWellManager:
|
||||
obs.save()
|
||||
xnext, ynext = xynext[pos]
|
||||
pos +=1
|
||||
self._grid_scanning(obs, xnext=xnext, ynext=ynext)
|
||||
self._grid_scanning(obs, xnext=xnext, ynext=ynext, simulate=simulate)
|
||||
obs.finished = timezone.now()
|
||||
obs.save()
|
||||
|
||||
@@ -197,10 +197,12 @@ class MultiWellManager:
|
||||
if self.stop_playing.is_set():
|
||||
msg = f"Session {session.name} abandonnée à {session.finished} après {session.finished - started} secondes."
|
||||
else:
|
||||
if not simulate:
|
||||
session.active = False
|
||||
if session.scanning_task:
|
||||
session.scanning_task.enabled = False
|
||||
session.save()
|
||||
|
||||
msg = f"Session {session.name} terminée à {session.finished} après {session.finished - started} secondes."
|
||||
logger.info(msg)
|
||||
self.process._send(scan_state=msg)
|
||||
@@ -214,13 +216,13 @@ class MultiWellManager:
|
||||
self.process.cam._aligner.debug = False
|
||||
|
||||
|
||||
def scanning(self, sid):
|
||||
def scanning(self, sid, simulate=False):
|
||||
try:
|
||||
if self.scan_thread:
|
||||
return
|
||||
session = models.Session.objects.get(pk=sid)
|
||||
experiments = models.SessionExperiment.experiment_by_session(sid)
|
||||
self.scan_thread = Thread(target=self._start_scanning, args=(session, experiments, ), daemon=True).start()
|
||||
self.scan_thread = Thread(target=self._start_scanning, args=(session, experiments, simulate, ), daemon=True).start()
|
||||
except Exception as e:
|
||||
print("MultiWellManager::scan error", e)
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ class ScannerProcess(Task):
|
||||
if self.data.play:
|
||||
try:
|
||||
jpeg=base64.b64encode(jpeg_bytes).decode()
|
||||
logger.warning(f"{jpeg[:100]}")
|
||||
#logger.warning(f"{jpeg[:100]}")
|
||||
self._send(ts=ts.timestamp(), jpeg=jpeg, frame_count=frame_count)
|
||||
except Exception as e:
|
||||
logger.error(f"----_on_frame: {e}")
|
||||
@@ -289,6 +289,8 @@ class ScannerProcess(Task):
|
||||
while not self.stop_event.is_set():
|
||||
try:
|
||||
(uuid, ts, frame, metrics, frame_count) = 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"):
|
||||
@@ -345,15 +347,15 @@ class ScannerProcess(Task):
|
||||
self.cam._active_median = False
|
||||
self.grbl.go_origin(feed=self.manager.feed)
|
||||
|
||||
elif topic == 'scan':
|
||||
|
||||
elif topic == 'scan' or topic == 'simulate':
|
||||
logger.info(f"==== Scan {cmd}")
|
||||
sid = cmd.get("session", '0')
|
||||
if sid == "0":
|
||||
self._send(state='error', msg=str(_('La session est nulle!...')))
|
||||
else:
|
||||
self.cam._active_median = False
|
||||
self.manager.scanning(sid)
|
||||
self.manager.scanning(sid, simulate=(topic=='simulate'))
|
||||
self._send(state=topic, msg=str(_('Balayage démarré...')))
|
||||
|
||||
elif cmd["type"]=="calibrate":
|
||||
topic = cmd.get("topic")
|
||||
|
||||
@@ -104,12 +104,14 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<a href="{% url 'scanner:main' %}" class="w3-bar-item w3-btn w3-hover-opacity">
|
||||
<a href="{% url 'scanner:scanning' %}" class="w3-bar-item w3-btn w3-hover-opacity">
|
||||
<i class="fa-solid fa-film w3-text-green w3-xlarge""></i> {% trans "Balayage multi-puits" %}
|
||||
</a>
|
||||
{% if conf.tracking %}
|
||||
<a href="{% url 'planarian:experiment-list' %}" class="w3-bar-item w3-btn w3-hover-opacity">
|
||||
<i class="fa-solid fa-vials w3-text-lime w3-xlarge"></i> {% trans "Préparation des expériences" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'scanner:images' %}" class="w3-bar-item w3-btn w3-hover-opacity">
|
||||
<i class="fa-regular fa-images w3-text-cyan w3-xlarge" w3-xlarge""></i> {% trans "Gestionnaire d'images" %}
|
||||
</a>
|
||||
|
||||
+19
-10
@@ -3,7 +3,7 @@
|
||||
|
||||
{% block styles %}
|
||||
{{ block.super }}
|
||||
<link href="/static/scanner/css/main.css" rel="stylesheet">
|
||||
<link href="/static/scanner/css/scanning.css" rel="stylesheet">
|
||||
{% endblock %}
|
||||
{% block columns %}{% endblock %}
|
||||
|
||||
@@ -25,20 +25,27 @@
|
||||
<div class="w3-col w3-padding"><span id="_uuid"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w3-col">
|
||||
<button id="_median" class="w3-button w3-dark-xlight w3-round-large w3-padding-small w3-block">
|
||||
<div class="w3-row w3-row-padding">
|
||||
<div class="w3-half">
|
||||
<button id="_median" class="w3-button w3-dark-xlight w3-round-large w3-block">
|
||||
{% trans 'Axes' %} <br><i class="fa-solid fa-crosshairs w3-text-amber w3-xlarge"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="w3-col">
|
||||
<button id="_crop" class="w3-button w3-dark-xlight w3-round-large w3-padding-top w3-margin-top w3-block">
|
||||
<div class="w3-half">
|
||||
<button id="_crop" class="w3-button w3-dark-xlight w3-round-large w3-block">
|
||||
{% trans 'Recadrer' %}<br><i class="fa-solid fa-crop w3-text-amber w3-xlarge"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="w3-col">
|
||||
</div>
|
||||
<div class="w3-row w3-row-padding">
|
||||
<div class="w3-twothird">
|
||||
<button id="_scan" class="w3-button w3-light-blue w3-round-large w3-margin-top w3-block">
|
||||
{% trans 'Lancer' %}<br>{% trans 'le balayage' %}<br><i class="fa-solid fa-circle-check w3-text-blue w3-xlarge"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="w3-third">
|
||||
<button id="_scan" class="w3-button w3-dark-xlight w3-round-large w3-margin-top w3-block">
|
||||
{% trans 'Lancer le balayage' %}<br><i class="fa-solid fa-circle-check w3-text-orange w3-xlarge"></i>
|
||||
{% trans 'Simuler' %}<br>{% trans 'le balayage' %}<br><i class="fa-solid fa-triangle-exclamation w3-text-orange w3-xlarge"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="w3-col">
|
||||
@@ -46,6 +53,7 @@
|
||||
{% trans 'ARRET' %}<br><i class="fa-solid fa-hand w3-xlarge"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w3-col">
|
||||
<div class="w3-margin-top w3-padding w3-small">
|
||||
<span id="_ts"></span>
|
||||
@@ -85,10 +93,11 @@
|
||||
axial_pos : sId("_axial_pos"),
|
||||
area_px : sId("_area_px"),
|
||||
frame_count : sId("_count"),
|
||||
scan_state: sId("_scan_state")
|
||||
scan_state : sId("_scan_state"),
|
||||
simulate : sId("_simulate")
|
||||
};
|
||||
</script>
|
||||
<script src="/static/scanner/js/main.js"></script>
|
||||
<script src="/static/scanner/js/scanning.js"></script>
|
||||
<script>
|
||||
const manager = new ScannerManager(container, options);
|
||||
const protocol = location.protocol === "https:" ? "wss" : "ws";
|
||||
@@ -14,7 +14,7 @@ urlpatterns = [
|
||||
path('logs/worker', views.supervisor_worker, name='logs_worker'),
|
||||
path('logs/scheduler', views.supervisor_scheduler, name='logs_scheduler'),
|
||||
|
||||
path('main/', views.main_view, name='main'),
|
||||
path('scanning/', views.scanning_view, name='scanning'),
|
||||
path('images/', views.images_view, name='images'),
|
||||
path('replay/', views.replay_view, name='replay'),
|
||||
path('api/stats/', views.stats_view, name='api_stats'),
|
||||
|
||||
@@ -75,14 +75,14 @@ def supervisor_scheduler(request):
|
||||
|
||||
## Mainboard
|
||||
@login_required
|
||||
def main_view(request):
|
||||
def scanning_view(request):
|
||||
ctx = dict(
|
||||
ws_route=settings.SCANNER_WEBSOCKET_ROUTE,
|
||||
columns=1,
|
||||
sessions=models.Session.objects.filter(active=True).all(),
|
||||
choice_title=_("Balayage multi-puits")
|
||||
)
|
||||
return render(request, "scanner/main.html", context=global_context(request, **ctx))
|
||||
return render(request, "scanner/scanning.html", context=global_context(request, **ctx))
|
||||
|
||||
## Calibration
|
||||
@login_required
|
||||
|
||||
Reference in New Issue
Block a user