From 762b7958cf1da106ba95ffbbee8f2dc9dab75027 Mon Sep 17 00:00:00 2001 From: Yuma Uematsu Date: Sat, 4 Oct 2025 17:25:34 +0200 Subject: [PATCH 1/6] Added OB Loaded Module Cell PDB registration utility --- .../itkpd_interface/ob_loaded_module_cell.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 viewer/functions/itkpd_interface/ob_loaded_module_cell.py diff --git a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py new file mode 100644 index 000000000..de06cf35c --- /dev/null +++ b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +import logging + +from . import module + +logger = logging.getLogger("localdb") + + +class OBLoadedModuleCellRegistration(module.ModuleRegistration): + register_Module = None + + def check_assemble(self, module_type, child_type, serialnumber, look_up_table): + return ( + look_up_table["OB_LOADED_MODULE_CELL_TYPES"][module_type][child_type] + == serialnumber[3:7] + ) + + def make_table(self, config): + look_up_table = {} + look_up_table["OB_LOADED_MODULE_CELL_TYPES"] = {} + look_up_table["FECHIP_VERSION"] = {} + # ob loaded module cell types + for i in range(len(config["types"])): + look_up_table["OB_LOADED_MODULE_CELL_TYPES"][config["types"][i]["code"]] = { + # "XX": config["types"][i]["subprojects"][0]["code"], not defined for each. + "XX": config["subprojects"][0]["code"], + "YY": config["types"][i]["snComponentIdentifier"], + "MODULE": config["children"][ + config["types"][i]["code"].replace(".", "") # 'DUMMY' not supported + ]["MODULE"], + "OB_BARE_MODULE_CELL": config["children"][ + config["types"][i]["code"].replace(".", "") + ]["OB_BARE_MODULE_CELL"], + } + # FE chips + for i in range(len(config["FEchip"])): + look_up_table["FECHIP_VERSION"][config["FEchip"][i]["code"]] = config[ + "FEchip" + ][i]["value"] + return look_up_table + + def register(self, config, look_up_table, location): + data = { + "project": "P", + "subproject": look_up_table["OB_LOADED_MODULE_CELL_TYPES"][config["type"]][ + "XX" + ], + "institution": location, + "componentType": "OB_LOADED_MODULE_CELL", + "type": config["type"], + "properties": {"PRODUCTION_TYPE": config["production_type"]}, + "serialNumber": config["serialNumber"], + } + + module_ins = self.pd_client.post("registerComponent", json=data) + logger.info("Register OB_LOADED_MODULE_CELL!!") + + # assemble children + for child_type in ["MODULE", "OB_BARE_MODULE_CELL"]: + # Retrieve child serial number from web ui input + child_sn = config["child"].get(child_type) + data = { + "parent": module_ins["component"]["code"], + "child": child_sn, + } + if self.check_assemble( + config["type"], child_type, data["child"], look_up_table + ): + self.pd_client.post("assembleComponent", json=data) + logger.info(f"Assembled {child_type}!!") + else: + logger.info( + f"Couldn't assemble {child_type} because the {child_type} and the OB_LOADED_MODULE_CELL are not the correct combination. Please check them and assemble on the Web page." + ) -- GitLab From b2f99823913fe409053251e052b2165428123ec4 Mon Sep 17 00:00:00 2001 From: Yuma Uematsu Date: Wed, 29 Oct 2025 10:37:06 +0100 Subject: [PATCH 2/6] use itksn for parsing serial number --- .../functions/itkpd_interface/ob_loaded_module_cell.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py index de06cf35c..072d4ed97 100644 --- a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py +++ b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py @@ -2,6 +2,8 @@ from __future__ import annotations import logging +import itksn + from . import module logger = logging.getLogger("localdb") @@ -11,9 +13,15 @@ class OBLoadedModuleCellRegistration(module.ModuleRegistration): register_Module = None def check_assemble(self, module_type, child_type, serialnumber, look_up_table): + sn_tokens = itksn.parse(serialnumber.encode("utf-8")) + sn_xxyy = ( + sn_tokens.project_code.bytevalue + + sn_tokens.subproject_code.bytevalue + + sn_tokens.component_code.bytevalue + ).decode("utf-8") return ( look_up_table["OB_LOADED_MODULE_CELL_TYPES"][module_type][child_type] - == serialnumber[3:7] + == sn_xxyy ) def make_table(self, config): -- GitLab From 4cad575e9e0b993d922cb323835528341a456ec4 Mon Sep 17 00:00:00 2001 From: Yuma Uematsu Date: Wed, 29 Oct 2025 16:55:11 +0100 Subject: [PATCH 3/6] add CLI entrypoint --- .../itkpd_interface/ob_loaded_module_cell.py | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py index 072d4ed97..3a0040c85 100644 --- a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py +++ b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py @@ -1,9 +1,13 @@ from __future__ import annotations +import argparse import logging +import os +import traceback import itksn +from ..common import process_request, userdb from . import module logger = logging.getLogger("localdb") @@ -81,3 +85,69 @@ class OBLoadedModuleCellRegistration(module.ModuleRegistration): logger.info( f"Couldn't assemble {child_type} because the {child_type} and the OB_LOADED_MODULE_CELL are not the correct combination. Please check them and assemble on the Web page." ) + + +def main(argv=None): + parser = argparse.ArgumentParser() + parser.add_argument("oblmc_serial_number") + parser.add_argument("module_serial_number") + parser.add_argument("obbmc_serial_number") + args = parser.parse_args(argv) + sn = args.oblmc_serial_number + child_sn = { + "Module": args.module_serial_number, + "OB Bare Module Cell": args.obbmc_serial_number, + } + + sn_tokens = itksn.parse(sn.encode("utf-8")) + sn_yy = sn_tokens.component_code.bytevalue.decode("utf-8") + _type_config = userdb.QC.ob_loaded_module_cell.types.find_one() + for oblmc_type in _type_config["types"]: + if oblmc_type["snComponentIdentifier"] == sn_yy: + oblmc_typename = oblmc_type["code"] + break + else: + logger.error( + f"YY code of given OB Loaded Module Cell serial number ({sn}) is invalid!" + ) + return + + code1 = os.environ.get("ITKDB_ACCESS_CODE1", " ") + code2 = os.environ.get("ITKDB_ACCESS_CODE2", " ") + success, pd_client = process_request(code1, code2) + if success == 0: + logger.error("Failure in getting pd_client!") + return + mod_reg = OBLoadedModuleCellRegistration(pd_client) + + loc = {} + for k, v in child_sn.items(): + try: + componentInfo = mod_reg.get_component(v) + except Exception as exc: + logger.error(traceback.format_exc()) + text = f"{k} {v} does not exist in ITkPD..." + raise RuntimeError(text) from exc + loc[k] = componentInfo["currentLocation"]["code"] + if len(set(loc.values())) > 1: + logger.error("Locations of the child components do not match: %s", loc) + return + + _config = { + "type": oblmc_typename, + "production_type": itksn.parse( + sn.encode("utf-8") + ).identifier.production_type.bytevalue.decode("utf-8"), + "child": { + "MODULE": child_sn["Module"], + "OB_BARE_MODULE_CELL": child_sn["OB Bare Module Cell"], + }, + "serialNumber": sn, + } + mod_reg.register( + _config, mod_reg.make_table(_type_config), next(iter(loc.values())) + ) + + +if __name__ == "__main__": + main() -- GitLab From a074a28de08ddd07542c888029b36bc6bb40bf88 Mon Sep 17 00:00:00 2001 From: Yuma Uematsu Date: Fri, 31 Oct 2025 17:09:34 +0100 Subject: [PATCH 4/6] raise loglevel for check in CLI endpoint --- viewer/functions/itkpd_interface/ob_loaded_module_cell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py index 3a0040c85..633bacf1f 100644 --- a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py +++ b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py @@ -82,7 +82,7 @@ class OBLoadedModuleCellRegistration(module.ModuleRegistration): self.pd_client.post("assembleComponent", json=data) logger.info(f"Assembled {child_type}!!") else: - logger.info( + logger.error( f"Couldn't assemble {child_type} because the {child_type} and the OB_LOADED_MODULE_CELL are not the correct combination. Please check them and assemble on the Web page." ) -- GitLab From f711aa6ffa4d3edf69a4af5079cb8b7cb60d8e6c Mon Sep 17 00:00:00 2001 From: Yuma Uematsu Date: Thu, 6 Nov 2025 13:31:53 +0100 Subject: [PATCH 5/6] safeguard for child already assembled --- .../itkpd_interface/ob_loaded_module_cell.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py index 633bacf1f..d4787a0af 100644 --- a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py +++ b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py @@ -65,13 +65,20 @@ class OBLoadedModuleCellRegistration(module.ModuleRegistration): "serialNumber": config["serialNumber"], } + # safeguard not to use already assembled children + for child_sn in config["child"].values(): + pd_info = self.pd_client.get("getComponent", json={"component": child_sn}) + if pd_info["parents"]: + msg = f"Child {child_sn} already assembled" + logger.error(msg) + raise RuntimeError(msg) + module_ins = self.pd_client.post("registerComponent", json=data) logger.info("Register OB_LOADED_MODULE_CELL!!") # assemble children - for child_type in ["MODULE", "OB_BARE_MODULE_CELL"]: - # Retrieve child serial number from web ui input - child_sn = config["child"].get(child_type) + # Retrieve child serial number from web ui input + for child_type, child_sn in config["child"].items(): data = { "parent": module_ins["component"]["code"], "child": child_sn, -- GitLab From 235776fc14b5944f87d20eaa8f66347f9501c9b7 Mon Sep 17 00:00:00 2001 From: Yuma Uematsu Date: Thu, 6 Nov 2025 13:57:36 +0100 Subject: [PATCH 6/6] cleanup and remove CLI endpoint --- .../itkpd_interface/ob_loaded_module_cell.py | 99 +------------------ 1 file changed, 3 insertions(+), 96 deletions(-) diff --git a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py index d4787a0af..34b2a20e4 100644 --- a/viewer/functions/itkpd_interface/ob_loaded_module_cell.py +++ b/viewer/functions/itkpd_interface/ob_loaded_module_cell.py @@ -1,13 +1,7 @@ from __future__ import annotations -import argparse import logging -import os -import traceback -import itksn - -from ..common import process_request, userdb from . import module logger = logging.getLogger("localdb") @@ -16,18 +10,6 @@ logger = logging.getLogger("localdb") class OBLoadedModuleCellRegistration(module.ModuleRegistration): register_Module = None - def check_assemble(self, module_type, child_type, serialnumber, look_up_table): - sn_tokens = itksn.parse(serialnumber.encode("utf-8")) - sn_xxyy = ( - sn_tokens.project_code.bytevalue - + sn_tokens.subproject_code.bytevalue - + sn_tokens.component_code.bytevalue - ).decode("utf-8") - return ( - look_up_table["OB_LOADED_MODULE_CELL_TYPES"][module_type][child_type] - == sn_xxyy - ) - def make_table(self, config): look_up_table = {} look_up_table["OB_LOADED_MODULE_CELL_TYPES"] = {} @@ -35,7 +17,6 @@ class OBLoadedModuleCellRegistration(module.ModuleRegistration): # ob loaded module cell types for i in range(len(config["types"])): look_up_table["OB_LOADED_MODULE_CELL_TYPES"][config["types"][i]["code"]] = { - # "XX": config["types"][i]["subprojects"][0]["code"], not defined for each. "XX": config["subprojects"][0]["code"], "YY": config["types"][i]["snComponentIdentifier"], "MODULE": config["children"][ @@ -65,7 +46,7 @@ class OBLoadedModuleCellRegistration(module.ModuleRegistration): "serialNumber": config["serialNumber"], } - # safeguard not to use already assembled children + # prevent assembling children that already have a parent for child_sn in config["child"].values(): pd_info = self.pd_client.get("getComponent", json={"component": child_sn}) if pd_info["parents"]: @@ -77,84 +58,10 @@ class OBLoadedModuleCellRegistration(module.ModuleRegistration): logger.info("Register OB_LOADED_MODULE_CELL!!") # assemble children - # Retrieve child serial number from web ui input for child_type, child_sn in config["child"].items(): data = { "parent": module_ins["component"]["code"], "child": child_sn, } - if self.check_assemble( - config["type"], child_type, data["child"], look_up_table - ): - self.pd_client.post("assembleComponent", json=data) - logger.info(f"Assembled {child_type}!!") - else: - logger.error( - f"Couldn't assemble {child_type} because the {child_type} and the OB_LOADED_MODULE_CELL are not the correct combination. Please check them and assemble on the Web page." - ) - - -def main(argv=None): - parser = argparse.ArgumentParser() - parser.add_argument("oblmc_serial_number") - parser.add_argument("module_serial_number") - parser.add_argument("obbmc_serial_number") - args = parser.parse_args(argv) - sn = args.oblmc_serial_number - child_sn = { - "Module": args.module_serial_number, - "OB Bare Module Cell": args.obbmc_serial_number, - } - - sn_tokens = itksn.parse(sn.encode("utf-8")) - sn_yy = sn_tokens.component_code.bytevalue.decode("utf-8") - _type_config = userdb.QC.ob_loaded_module_cell.types.find_one() - for oblmc_type in _type_config["types"]: - if oblmc_type["snComponentIdentifier"] == sn_yy: - oblmc_typename = oblmc_type["code"] - break - else: - logger.error( - f"YY code of given OB Loaded Module Cell serial number ({sn}) is invalid!" - ) - return - - code1 = os.environ.get("ITKDB_ACCESS_CODE1", " ") - code2 = os.environ.get("ITKDB_ACCESS_CODE2", " ") - success, pd_client = process_request(code1, code2) - if success == 0: - logger.error("Failure in getting pd_client!") - return - mod_reg = OBLoadedModuleCellRegistration(pd_client) - - loc = {} - for k, v in child_sn.items(): - try: - componentInfo = mod_reg.get_component(v) - except Exception as exc: - logger.error(traceback.format_exc()) - text = f"{k} {v} does not exist in ITkPD..." - raise RuntimeError(text) from exc - loc[k] = componentInfo["currentLocation"]["code"] - if len(set(loc.values())) > 1: - logger.error("Locations of the child components do not match: %s", loc) - return - - _config = { - "type": oblmc_typename, - "production_type": itksn.parse( - sn.encode("utf-8") - ).identifier.production_type.bytevalue.decode("utf-8"), - "child": { - "MODULE": child_sn["Module"], - "OB_BARE_MODULE_CELL": child_sn["OB Bare Module Cell"], - }, - "serialNumber": sn, - } - mod_reg.register( - _config, mod_reg.make_table(_type_config), next(iter(loc.values())) - ) - - -if __name__ == "__main__": - main() + self.pd_client.post("assembleComponent", json=data) + logger.info(f"Assembled {child_type}!!") -- GitLab