From dfac7711a389d56388f168fece39f8c37f2606ed Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 9 Jul 2025 10:07:51 +0200 Subject: [PATCH 01/13] Add attributes for components and blocks This way, we can query some of the exp configuration from the AtomiqHERO. --- src/atomiq/heros.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 23f3e80..3548515 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -42,12 +42,16 @@ class AtomiqHERO(LocalHERO): name: str = "" rid: int = -1 chunksize = -1 + components: list = [] + blocks: list = [] def __init__(self, experiment): self.experiment = experiment self.name = experiment.__class__.__name__ self.rid = experiment.scheduler.rid self.chunksize = experiment.CHUNKSIZE + self.components = experiment.components + self.blocks = [str(block) for block in experiment.blocks] super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") -- GitLab From 2ff524e922432cd68ccd2883acd47440a42044f4 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 9 Jul 2025 11:03:52 +0200 Subject: [PATCH 02/13] Initialize empty blocks list --- src/atomiq/atomiq.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/atomiq/atomiq.py b/src/atomiq/atomiq.py index b5606c0..2077554 100644 --- a/src/atomiq/atomiq.py +++ b/src/atomiq/atomiq.py @@ -35,6 +35,7 @@ class AtomiqExperiment(EnvExperiment): CHUNKSIZE = 10 components = ["log"] + blocks = [] arg_provider = default_argument_provider -- GitLab From 50784cc138fa404b34df84e7c68687d31dd91890 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 9 Jul 2025 15:30:20 +0200 Subject: [PATCH 03/13] Add default_arguments attribute to AtomiqHERO --- src/atomiq/heros.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 3548515..423d246 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -44,6 +44,7 @@ class AtomiqHERO(LocalHERO): chunksize = -1 components: list = [] blocks: list = [] + default_arguments: list = [] def __init__(self, experiment): self.experiment = experiment @@ -52,6 +53,7 @@ class AtomiqHERO(LocalHERO): self.chunksize = experiment.CHUNKSIZE self.components = experiment.components self.blocks = [str(block) for block in experiment.blocks] + self.default_arguments = experiment.arguments super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") -- GitLab From 319bf0f8b54233a80a1d0d33d4b6d07f755e3afd Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Mon, 14 Jul 2025 09:57:59 +0200 Subject: [PATCH 04/13] Remove mutable defaults and check via hasattr --- src/atomiq/atomiq.py | 1 - src/atomiq/heros.py | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/atomiq/atomiq.py b/src/atomiq/atomiq.py index 2077554..b5606c0 100644 --- a/src/atomiq/atomiq.py +++ b/src/atomiq/atomiq.py @@ -35,7 +35,6 @@ class AtomiqExperiment(EnvExperiment): CHUNKSIZE = 10 components = ["log"] - blocks = [] arg_provider = default_argument_provider diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 423d246..65ad278 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -42,18 +42,15 @@ class AtomiqHERO(LocalHERO): name: str = "" rid: int = -1 chunksize = -1 - components: list = [] - blocks: list = [] - default_arguments: list = [] def __init__(self, experiment): self.experiment = experiment self.name = experiment.__class__.__name__ self.rid = experiment.scheduler.rid self.chunksize = experiment.CHUNKSIZE - self.components = experiment.components - self.blocks = [str(block) for block in experiment.blocks] - self.default_arguments = experiment.arguments + self.components = experiment.components if hasattr(experiment, "components") else [] + self.blocks = [str(block) for block in experiment.blocks if hasattr(experiment, "blocks")] + self.default_arguments = experiment.arguments if hasattr(experiment, "arguments") else [] super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") -- GitLab From c8ec8b46fe9099664e728a96b9c2237edd083598 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Mon, 14 Jul 2025 13:42:07 +0200 Subject: [PATCH 05/13] Make default arg immutable --- src/atomiq/heros.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 65ad278..3342765 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -42,15 +42,18 @@ class AtomiqHERO(LocalHERO): name: str = "" rid: int = -1 chunksize = -1 + components: tuple[str] = () + blocks: tuple[str] = () + default_arguments: dict[dict] | None = None def __init__(self, experiment): self.experiment = experiment self.name = experiment.__class__.__name__ self.rid = experiment.scheduler.rid self.chunksize = experiment.CHUNKSIZE - self.components = experiment.components if hasattr(experiment, "components") else [] - self.blocks = [str(block) for block in experiment.blocks if hasattr(experiment, "blocks")] - self.default_arguments = experiment.arguments if hasattr(experiment, "arguments") else [] + self.components = tuple(experiment.components) if hasattr(experiment, "components") else () + self.blocks = (str(block) for block in experiment.blocks) if hasattr(experiment, "blocks") else () + self.default_arguments = tuple(experiment.arguments) if hasattr(experiment, "arguments") else () super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") -- GitLab From b573fba9cdf4febc8246cf065fd839030a694911 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Mon, 14 Jul 2025 13:58:40 +0200 Subject: [PATCH 06/13] Fixed default_arguments to be a dict --- src/atomiq/heros.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 3342765..53877dd 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -53,7 +53,7 @@ class AtomiqHERO(LocalHERO): self.chunksize = experiment.CHUNKSIZE self.components = tuple(experiment.components) if hasattr(experiment, "components") else () self.blocks = (str(block) for block in experiment.blocks) if hasattr(experiment, "blocks") else () - self.default_arguments = tuple(experiment.arguments) if hasattr(experiment, "arguments") else () + self.default_arguments = experiment.arguments if hasattr(experiment, "arguments") else {} super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") -- GitLab From 0fbc6ddd7678f70a43efea204443f2712dd2bc62 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Mon, 14 Jul 2025 16:47:49 +0200 Subject: [PATCH 07/13] Let run_timestamp be a float in s --- src/atomiq/atomiq.py | 2 +- src/atomiq/components/basics/datasink.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atomiq/atomiq.py b/src/atomiq/atomiq.py index b5606c0..a7a0861 100644 --- a/src/atomiq/atomiq.py +++ b/src/atomiq/atomiq.py @@ -404,7 +404,7 @@ class AtomiqExperiment(EnvExperiment): self.log.info(f"starting run {exp_identifier}") # get timestamp of the run - self.run_timestamp = int(time.time()*1e6) + self.run_timestamp = float(time.time()) self._prerun_core() diff --git a/src/atomiq/components/basics/datasink.py b/src/atomiq/components/basics/datasink.py index 311f330..51ba1a3 100644 --- a/src/atomiq/components/basics/datasink.py +++ b/src/atomiq/components/basics/datasink.py @@ -20,7 +20,7 @@ class DataSink(Component): env = {s: getattr(point, s) for s in point.attr} env.update({"seqTimestamp": float(identifier)*1e-6, "run_id": point.run_id, - "run_timestamp": int(self.experiment.run_timestamp), + "run_timestamp": float(self.experiment.run_timestamp), "step_counter": point.step_counter, }) names = list(env.keys()) -- GitLab From 5e96af0a569982cd13a4a69051965d540d2123a2 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Mon, 14 Jul 2025 16:49:03 +0200 Subject: [PATCH 08/13] Rename seqTimestamp to timestamp --- src/atomiq/components/basics/datasink.py | 2 +- src/atomiq/components/optoelectronics/camera.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atomiq/components/basics/datasink.py b/src/atomiq/components/basics/datasink.py index 51ba1a3..3b46471 100644 --- a/src/atomiq/components/basics/datasink.py +++ b/src/atomiq/components/basics/datasink.py @@ -18,7 +18,7 @@ class DataSink(Component): if identifier is None: identifier = self.experiment.identifier env = {s: getattr(point, s) for s in point.attr} - env.update({"seqTimestamp": float(identifier)*1e-6, + env.update({"timestamp": float(identifier) * 1e-6, "run_id": point.run_id, "run_timestamp": float(self.experiment.run_timestamp), "step_counter": point.step_counter, diff --git a/src/atomiq/components/optoelectronics/camera.py b/src/atomiq/components/optoelectronics/camera.py index 6b93d14..73051fa 100644 --- a/src/atomiq/components/optoelectronics/camera.py +++ b/src/atomiq/components/optoelectronics/camera.py @@ -108,7 +108,7 @@ class TriggeredRPCCamera(Camera, Triggerable): @rpc(flags={"async"}) def _set_config(self, config: TStr): if config in self.config_dict: - metadata = {"seqTimestamp": float(self.experiment.identifier)*1e-6, + metadata = {"timestamp": float(self.experiment.identifier) * 1e-6, "run_id": self.experiment.run_id, "run_timestamp": self.experiment.run_timestamp, "step_counter": self.experiment.step_counter, -- GitLab From c56256b9afeeb640eaeffea7500b4772c23b5ce0 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Tue, 15 Jul 2025 12:38:01 +0200 Subject: [PATCH 09/13] Add heros realm configuration --- src/atomiq/frontend/atomiq_master.py | 9 ++++++++- src/atomiq/heros.py | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/atomiq/frontend/atomiq_master.py b/src/atomiq/frontend/atomiq_master.py index 474241e..bc5029b 100644 --- a/src/atomiq/frontend/atomiq_master.py +++ b/src/atomiq/frontend/atomiq_master.py @@ -7,6 +7,7 @@ if heros is not None: from heros.zenoh import session_manager _instance_name = None + _heros_realm = "heros" _ArtiqScheduler = artiq.master.scheduler.Scheduler @@ -17,6 +18,7 @@ if heros is not None: def __init__(self, *args, **kwargs): global _instance_name + global _realm _ArtiqScheduler.__init__(self, *args, **kwargs) self._worker_handlers.update({ @@ -26,7 +28,7 @@ if heros is not None: }) postfix = f"-{_instance_name}" if _instance_name is not None else "" - LocalHERO.__init__(self, f"atomiq-scheduler{postfix}") + LocalHERO.__init__(self, f"atomiq-scheduler{postfix}", realm=_heros_realm) @event def run_created(self, rid, metadata={}): @@ -72,6 +74,9 @@ if __name__ == '__main__': parser.add_argument("--heros-connect", help="zenoh host to connect to for discovery" "of heros") + parser.add_argument("--heros-realm", + default="heros", + help='realm under which the atomiq should be exposed') return parser @@ -84,5 +89,7 @@ if __name__ == '__main__': session_manager.update_config({"connect": {"endpoints": [args.heros_connect]}}) if "name" in args: _instance_name = args.name + if "heros_realm" in args: + _heros_realm = args.heros_realm artiq_master.main() diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 53877dd..4d47af4 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -47,6 +47,7 @@ class AtomiqHERO(LocalHERO): default_arguments: dict[dict] | None = None def __init__(self, experiment): + global _heros_realm self.experiment = experiment self.name = experiment.__class__.__name__ self.rid = experiment.scheduler.rid @@ -55,7 +56,7 @@ class AtomiqHERO(LocalHERO): self.blocks = (str(block) for block in experiment.blocks) if hasattr(experiment, "blocks") else () self.default_arguments = experiment.arguments if hasattr(experiment, "arguments") else {} - super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") + super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}", realm=_heros_realm) @property def step_counter(self): -- GitLab From 614e34f20b44b22ca317c98960b03dfe47e81ca6 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Tue, 15 Jul 2025 17:55:58 +0200 Subject: [PATCH 10/13] Setting heros realm only works for scheduler --- src/atomiq/frontend/atomiq_master.py | 2 +- src/atomiq/heros.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atomiq/frontend/atomiq_master.py b/src/atomiq/frontend/atomiq_master.py index bc5029b..cbeb2a5 100644 --- a/src/atomiq/frontend/atomiq_master.py +++ b/src/atomiq/frontend/atomiq_master.py @@ -18,7 +18,7 @@ if heros is not None: def __init__(self, *args, **kwargs): global _instance_name - global _realm + global _heros_realm _ArtiqScheduler.__init__(self, *args, **kwargs) self._worker_handlers.update({ diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 4d47af4..77870d2 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -56,7 +56,7 @@ class AtomiqHERO(LocalHERO): self.blocks = (str(block) for block in experiment.blocks) if hasattr(experiment, "blocks") else () self.default_arguments = experiment.arguments if hasattr(experiment, "arguments") else {} - super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}", realm=_heros_realm) + super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") @property def step_counter(self): -- GitLab From d2e878be20f1014ffb92c248389c85a7e55be576 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Tue, 15 Jul 2025 18:08:01 +0200 Subject: [PATCH 11/13] Fix run_timestamp to identifier conversion --- src/atomiq/atomiq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atomiq/atomiq.py b/src/atomiq/atomiq.py index a7a0861..4d68178 100644 --- a/src/atomiq/atomiq.py +++ b/src/atomiq/atomiq.py @@ -452,7 +452,7 @@ class AtomiqExperiment(EnvExperiment): for point in points: # set the identifier in the master and the running core device - self.identifier = self.run_timestamp + \ + self.identifier = np.int64(self.run_timestamp * 1e6) + \ np.int64((self.core.get_rtio_counter_mu() - self.clock_at_start)*self.core.ref_period*1e6) point.identifier = self.identifier self.step_counter = point.step_counter -- GitLab From 594582293ab2de301b3c6cee88d09652795fbbaf Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Thu, 31 Jul 2025 11:27:16 +0200 Subject: [PATCH 12/13] Revert "Setting heros realm only works for scheduler" This reverts commit 614e34f20b44b22ca317c98960b03dfe47e81ca6. --- src/atomiq/frontend/atomiq_master.py | 2 +- src/atomiq/heros.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atomiq/frontend/atomiq_master.py b/src/atomiq/frontend/atomiq_master.py index cbeb2a5..bc5029b 100644 --- a/src/atomiq/frontend/atomiq_master.py +++ b/src/atomiq/frontend/atomiq_master.py @@ -18,7 +18,7 @@ if heros is not None: def __init__(self, *args, **kwargs): global _instance_name - global _heros_realm + global _realm _ArtiqScheduler.__init__(self, *args, **kwargs) self._worker_handlers.update({ diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 77870d2..4d47af4 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -56,7 +56,7 @@ class AtomiqHERO(LocalHERO): self.blocks = (str(block) for block in experiment.blocks) if hasattr(experiment, "blocks") else () self.default_arguments = experiment.arguments if hasattr(experiment, "arguments") else {} - super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") + super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}", realm=_heros_realm) @property def step_counter(self): -- GitLab From d98637f4f59794e682788edbad50478fe7003c6d Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Thu, 31 Jul 2025 11:27:26 +0200 Subject: [PATCH 13/13] Revert "Add heros realm configuration" This reverts commit c56256b9afeeb640eaeffea7500b4772c23b5ce0. --- src/atomiq/frontend/atomiq_master.py | 9 +-------- src/atomiq/heros.py | 3 +-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/atomiq/frontend/atomiq_master.py b/src/atomiq/frontend/atomiq_master.py index bc5029b..474241e 100644 --- a/src/atomiq/frontend/atomiq_master.py +++ b/src/atomiq/frontend/atomiq_master.py @@ -7,7 +7,6 @@ if heros is not None: from heros.zenoh import session_manager _instance_name = None - _heros_realm = "heros" _ArtiqScheduler = artiq.master.scheduler.Scheduler @@ -18,7 +17,6 @@ if heros is not None: def __init__(self, *args, **kwargs): global _instance_name - global _realm _ArtiqScheduler.__init__(self, *args, **kwargs) self._worker_handlers.update({ @@ -28,7 +26,7 @@ if heros is not None: }) postfix = f"-{_instance_name}" if _instance_name is not None else "" - LocalHERO.__init__(self, f"atomiq-scheduler{postfix}", realm=_heros_realm) + LocalHERO.__init__(self, f"atomiq-scheduler{postfix}") @event def run_created(self, rid, metadata={}): @@ -74,9 +72,6 @@ if __name__ == '__main__': parser.add_argument("--heros-connect", help="zenoh host to connect to for discovery" "of heros") - parser.add_argument("--heros-realm", - default="heros", - help='realm under which the atomiq should be exposed') return parser @@ -89,7 +84,5 @@ if __name__ == '__main__': session_manager.update_config({"connect": {"endpoints": [args.heros_connect]}}) if "name" in args: _instance_name = args.name - if "heros_realm" in args: - _heros_realm = args.heros_realm artiq_master.main() diff --git a/src/atomiq/heros.py b/src/atomiq/heros.py index 4d47af4..53877dd 100644 --- a/src/atomiq/heros.py +++ b/src/atomiq/heros.py @@ -47,7 +47,6 @@ class AtomiqHERO(LocalHERO): default_arguments: dict[dict] | None = None def __init__(self, experiment): - global _heros_realm self.experiment = experiment self.name = experiment.__class__.__name__ self.rid = experiment.scheduler.rid @@ -56,7 +55,7 @@ class AtomiqHERO(LocalHERO): self.blocks = (str(block) for block in experiment.blocks) if hasattr(experiment, "blocks") else () self.default_arguments = experiment.arguments if hasattr(experiment, "arguments") else {} - super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}", realm=_heros_realm) + super().__init__(f"atomiq-run-{self.experiment.scheduler.rid}") @property def step_counter(self): -- GitLab