From d6cfb21019d87ea5396a107aeb99b49bce46034b Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Tue, 13 Jan 2026 16:03:19 +0000 Subject: [PATCH 1/3] Set structure format from file extension if provided --- src/vlab4mic/experiments.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vlab4mic/experiments.py b/src/vlab4mic/experiments.py index 0941488..f261eb4 100644 --- a/src/vlab4mic/experiments.py +++ b/src/vlab4mic/experiments.py @@ -37,6 +37,7 @@ class ExperimentParametrisation: experiment_id: str = "vLab4mic_experiment" structure_id: str = "1XI5" + structure_format: str = "CIF" configuration_path: str = "" structure_label: str = "NHS_ester" fluorophore_id: str = "AF647" @@ -194,6 +195,7 @@ def select_structure(self, structure_id="1XI5", build=True, structure_path:str = if structure_path is not None: self.structure_path = structure_path self.structure_id = structure_id + self.structure_format = structure_path.split(".")[-1].upper() else: self.structure_id = structure_id if build: @@ -450,7 +452,7 @@ def _build_structure(self, keep=True): """ if self.structure_id and self.structure_path: struct, struct_param = load_structure( - self.structure_id, self.configuration_path, self.structure_path + self.structure_id, self.configuration_path, self.structure_path, self.structure_format ) self.structure = struct self.objects_created["structure"] = True From b588affc2445a52c8e62e7b4f803c10958d88769 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Tue, 13 Jan 2026 16:04:23 +0000 Subject: [PATCH 2/3] add parameter for structure_format and add exception to create CIFdictionary for PDB format --- src/vlab4mic/generate/molecular_structure.py | 100 ++++++++++--------- src/vlab4mic/workflows.py | 6 +- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/src/vlab4mic/generate/molecular_structure.py b/src/vlab4mic/generate/molecular_structure.py index eea7991..3b66a19 100644 --- a/src/vlab4mic/generate/molecular_structure.py +++ b/src/vlab4mic/generate/molecular_structure.py @@ -254,57 +254,61 @@ def generate_assemmbly_operations(self): """ Parse the rotation/translation operations needed to construct a molecular assembly from an asymmetric unit. """ - if self.CIFdictionary is None: # check if already created - self.generate_MMCIF_dictionary() - if "AlphaFoldDB" in self.CIFdictionary["_database_2.database_id"]: + if self.format == "PDB": + print("Assembly operations are only defined for CIF format files.") self.assymetric_defined = False else: - # get to know how many transformations there are - transformation_ids = self.CIFdictionary["_pdbx_struct_oper_list.id"] - # each element of the list is pair of matrix-vector needed to transform data - # iterate over each of the transformations - assembly_transformations = [] - for tr in range(len(transformation_ids)): - row1 = [ - self.CIFdictionary["_pdbx_struct_oper_list.matrix[1][1]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.matrix[1][2]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.matrix[1][3]"][tr], - ] - - row2 = [ - self.CIFdictionary["_pdbx_struct_oper_list.matrix[2][1]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.matrix[2][2]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.matrix[2][3]"][tr], - ] - - row3 = [ - self.CIFdictionary["_pdbx_struct_oper_list.matrix[3][1]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.matrix[3][2]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.matrix[3][3]"][tr], - ] - rotation_matrix = np.array([row1, row2, row3], dtype="float") - - vector = np.array( - [ - self.CIFdictionary["_pdbx_struct_oper_list.vector[1]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.vector[2]"][tr], - self.CIFdictionary["_pdbx_struct_oper_list.vector[3]"][tr], - ], - dtype="float", - ) - assembly_transformations.append([rotation_matrix, vector]) - struct_oper_dictionary = dict(zip(transformation_ids, assembly_transformations)) - if len(transformation_ids) > 1: - self.assymetric_defined = True - # print( - # "This model is defined with more than one symmetric transformation. - # Will consider the assembly as assymetric defined" - # ) - else: - # when no assembly unit exist, there is only 1 transform expected + if self.CIFdictionary is None: # check if already created + self.generate_MMCIF_dictionary() + if "AlphaFoldDB" in self.CIFdictionary["_database_2.database_id"]: self.assymetric_defined = False - # print("This model is defined with only one symmetric transformation") - self.assembly_operations = struct_oper_dictionary + else: + # get to know how many transformations there are + transformation_ids = self.CIFdictionary["_pdbx_struct_oper_list.id"] + # each element of the list is pair of matrix-vector needed to transform data + # iterate over each of the transformations + assembly_transformations = [] + for tr in range(len(transformation_ids)): + row1 = [ + self.CIFdictionary["_pdbx_struct_oper_list.matrix[1][1]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.matrix[1][2]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.matrix[1][3]"][tr], + ] + + row2 = [ + self.CIFdictionary["_pdbx_struct_oper_list.matrix[2][1]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.matrix[2][2]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.matrix[2][3]"][tr], + ] + + row3 = [ + self.CIFdictionary["_pdbx_struct_oper_list.matrix[3][1]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.matrix[3][2]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.matrix[3][3]"][tr], + ] + rotation_matrix = np.array([row1, row2, row3], dtype="float") + + vector = np.array( + [ + self.CIFdictionary["_pdbx_struct_oper_list.vector[1]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.vector[2]"][tr], + self.CIFdictionary["_pdbx_struct_oper_list.vector[3]"][tr], + ], + dtype="float", + ) + assembly_transformations.append([rotation_matrix, vector]) + struct_oper_dictionary = dict(zip(transformation_ids, assembly_transformations)) + if len(transformation_ids) > 1: + self.assymetric_defined = True + # print( + # "This model is defined with more than one symmetric transformation. + # Will consider the assembly as assymetric defined" + # ) + else: + # when no assembly unit exist, there is only 1 transform expected + self.assymetric_defined = False + # print("This model is defined with only one symmetric transformation") + self.assembly_operations = struct_oper_dictionary def generate_assembly_reference_point(self): """ diff --git a/src/vlab4mic/workflows.py b/src/vlab4mic/workflows.py index 0374003..dbbce08 100644 --- a/src/vlab4mic/workflows.py +++ b/src/vlab4mic/workflows.py @@ -22,7 +22,7 @@ from .utils.data_format.structural_format import label_builder_format from pathlib import Path -def load_structure(structure_id: str = None, config_dir=None, structure_path=None): +def load_structure(structure_id: str = None, config_dir=None, structure_path=None, structure_format="CIF"): """ Initialise a BioPython object for the PDB/CIF ID and retrieve available information about specific labelling. @@ -47,10 +47,10 @@ def load_structure(structure_id: str = None, config_dir=None, structure_path=Non if structure_path is not None: print("Loading structure from local file") structure = build_structure_cif( - cif_file=structure_path, struct_title="", cif_id=structure_id + cif_file=structure_path, struct_title="", cif_id=structure_id, format_type=structure_format ) structure_params = dict( - model = {"ID": structure_id, "format": "CIF", "title": "", "database": ""}, + model = {"ID": structure_id, "format": structure_format, "title": "", "database": ""}, ) print("Structure Loaded!") return structure, structure_params From 6b88da46d4b1841d920b8a42c63225a117e067c1 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Tue, 13 Jan 2026 23:53:50 +0000 Subject: [PATCH 3/3] Return empty list if pdb/cif does not contain protein names --- src/vlab4mic/generate/molecular_structure.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vlab4mic/generate/molecular_structure.py b/src/vlab4mic/generate/molecular_structure.py index 3b66a19..5785142 100644 --- a/src/vlab4mic/generate/molecular_structure.py +++ b/src/vlab4mic/generate/molecular_structure.py @@ -172,7 +172,11 @@ def list_protein_names(self): list of str List of protein names. """ - return list(self.protein_names.keys()) + if self.protein_names is not None: + if len(list(self.protein_names.keys())) > 0: + return list(self.protein_names.keys()) + else: + return [] def _random_substring(string, size=5): """