From 3dcad0a5e2d52792ac849f6ddbe5cfcf03567586 Mon Sep 17 00:00:00 2001
From: David Hammer <dhammer@mailbox.org>
Date: Sat, 5 Feb 2022 18:04:34 +0100
Subject: [PATCH] Make SimpleAssembler ask for geometry on init

---
 src/calng/SimpleAssembler.py | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/src/calng/SimpleAssembler.py b/src/calng/SimpleAssembler.py
index 3a7708f7..f9df6a2a 100644
--- a/src/calng/SimpleAssembler.py
+++ b/src/calng/SimpleAssembler.py
@@ -1,6 +1,8 @@
 import functools
 import pickle
 import re
+import threading
+import time
 
 import numpy as np
 from karabo.bound import (
@@ -127,6 +129,7 @@ class SimpleAssembler(TrainMatcher.TrainMatcher):
         self.KARABO_ON_DATA("geometryInput", self.receive_geometry)
         self.KARABO_SLOT(self.requestScene)
 
+        self.ask_for_geometry()
         self.start()
 
     def requestScene(self, params):
@@ -156,8 +159,38 @@ class SimpleAssembler(TrainMatcher.TrainMatcher):
     def receive_geometry(self, data, metadata):
         self.log.INFO("Received a new geometry")
         self.geometry = pickle.loads(data.get("pickledGeometry"))
+        # TODO: allow multiple memory cells (extra geom notion of extra dimensions)
         self.input_buffer = np.zeros(self.geometry.expected_data_shape)
 
+    def ask_for_geometry(self):
+        def runner():
+            self.log.INFO("Will ask around for a geometry")
+            max_tries = 10
+            for i in range(max_tries):
+                time.sleep(np.random.random() * 10)
+                if self.geometry is None:
+                    missing_connections = set(
+                        self.get("geometryInput.missingConnections")
+                    )
+                    # note: connectedOutputChannels not necessarily connected...
+                    geometry_device_list = [
+                        channel
+                        for channel in self.get("geometryInput.connectedOutputChannels")
+                        if channel not in missing_connections
+                    ]
+                    if not geometry_device_list:
+                        self.log.INFO("No geometry device connected")
+                        continue
+                    geometry_device = geometry_device_list[0].split(":")[0]
+                    self.log.INFO(f"Asking {geometry_device} for a geometry")
+                    self.signalSlotable.call(geometry_device, "pleaseSendYourGeometry")
+                    time.sleep(1)
+
+                if self.geometry is not None:
+                    return
+            self.log.INFO(f"Failed to get geometry in {max_tries} tries, need help")
+        threading.Thread(target=runner, daemon=True).start()
+
     def _send(self, train_id, sources):
         # TODO: adapt to appropriate hook for new TrainMatcher (no _send)
         if self.geometry is None:
-- 
GitLab