diff --git a/manual.md b/manual.md index c7746806..a45a7f8b 100644 --- a/manual.md +++ b/manual.md @@ -407,7 +407,7 @@ If a parameter is `None`, it will not be swept and will use default values. - peptide_motif - probe_distance_to_epitope - probe_steric_hindrance -- probe_conjugation_efficiency +- probe_DoL - probe_wobble_theta - labelling_efficiency - defect @@ -449,7 +449,7 @@ If a parameter is `None`, it will not be swept and will use default values. | **probe_fluorophore** | Fluorophore name for emitters (e.g., "AF647") | | **probe_paratope** | If probe_model is defined, the paratope defines the anchor point of the probe | | **probe_conjugation_target_info** | If probe_model is defined, this dictionary specifies the sites to use as probe emitters | -| **probe_conjugation_efficiency** | Efficiency of conjugation of emitters (float) | +| **probe_DoL** | Efficiency of conjugation of emitters (float) | | **probe_seconday_epitope** | If probe is secondary, this amino acid sequence defines the epitope on the primary antibody model | | **probe_wobble_theta** | Enable probe wobbling (float or None) | | **probe_steric_hindrance** | Steric hindrance value or configuration (distance between epitopes) | diff --git a/src/vlab4mic/analysis/sweep.py b/src/vlab4mic/analysis/sweep.py index 92b94e85..489f501f 100644 --- a/src/vlab4mic/analysis/sweep.py +++ b/src/vlab4mic/analysis/sweep.py @@ -868,7 +868,7 @@ def probe_parameters_sweep( probe_fluorophore: str = None, probe_paratope: str = None, probe_conjugation_target_info=None, - probe_conjugation_efficiency: list[float] = None, + probe_DoL: list[float] = None, probe_seconday_epitope=None, probe_wobbling=None, labelling_efficiency: list[float] = None, @@ -885,7 +885,7 @@ def probe_parameters_sweep( probe_fluorophore : str, optional probe_paratope : str, optional probe_conjugation_target_info : any, optional - probe_conjugation_efficiency : list of float, optional + probe_DoL : list of float, optional probe_seconday_epitope : any, optional probe_wobbling : any, optional labelling_efficiency : list of float, optional diff --git a/src/vlab4mic/configs/probes/Antibody.yaml b/src/vlab4mic/configs/probes/Antibody.yaml index c7f8fc55..e331adf7 100644 --- a/src/vlab4mic/configs/probes/Antibody.yaml +++ b/src/vlab4mic/configs/probes/Antibody.yaml @@ -26,7 +26,7 @@ conjugation_sites: - CA residues: - LYS - efficiency: 1 + DoL: epitope: # for secondary target: type: Sequence diff --git a/src/vlab4mic/configs/probes/CCP_heavy_chain_Cterminal.yaml b/src/vlab4mic/configs/probes/CCP_heavy_chain_Cterminal.yaml index 66cdbc82..5e7b8a75 100644 --- a/src/vlab4mic/configs/probes/CCP_heavy_chain_Cterminal.yaml +++ b/src/vlab4mic/configs/probes/CCP_heavy_chain_Cterminal.yaml @@ -22,5 +22,5 @@ conjugation_sites: target: type: value: - efficiency: + DoL: diff --git a/src/vlab4mic/configs/probes/GFP.yaml b/src/vlab4mic/configs/probes/GFP.yaml index 0edf47d5..775ecce0 100644 --- a/src/vlab4mic/configs/probes/GFP.yaml +++ b/src/vlab4mic/configs/probes/GFP.yaml @@ -26,7 +26,7 @@ conjugation_sites: - C1 residues: - CRO - efficiency: 1 + DoL: epitope: # for secondary target: type: diff --git a/src/vlab4mic/configs/probes/GFP_w_nanobody.yaml b/src/vlab4mic/configs/probes/GFP_w_nanobody.yaml index 05911a35..c4ce345c 100644 --- a/src/vlab4mic/configs/probes/GFP_w_nanobody.yaml +++ b/src/vlab4mic/configs/probes/GFP_w_nanobody.yaml @@ -28,7 +28,7 @@ conjugation_sites: - LYS chains: - B - efficiency: 1 + DoL: epitope: # for secondary target: type: diff --git a/src/vlab4mic/configs/probes/HIV_capsid_p24_direct.yaml b/src/vlab4mic/configs/probes/HIV_capsid_p24_direct.yaml index 6aa21910..fca8d6f5 100644 --- a/src/vlab4mic/configs/probes/HIV_capsid_p24_direct.yaml +++ b/src/vlab4mic/configs/probes/HIV_capsid_p24_direct.yaml @@ -22,5 +22,5 @@ conjugation_sites: target: type: value: - efficiency: + DoL: diff --git a/src/vlab4mic/configs/probes/Linker.yaml b/src/vlab4mic/configs/probes/Linker.yaml index 29710601..6ba3e50c 100644 --- a/src/vlab4mic/configs/probes/Linker.yaml +++ b/src/vlab4mic/configs/probes/Linker.yaml @@ -22,5 +22,5 @@ conjugation_sites: target: type: value: - efficiency: + DoL: diff --git a/src/vlab4mic/configs/probes/NHS_ester.yaml b/src/vlab4mic/configs/probes/NHS_ester.yaml index 4bb9d836..8ca5cdd1 100644 --- a/src/vlab4mic/configs/probes/NHS_ester.yaml +++ b/src/vlab4mic/configs/probes/NHS_ester.yaml @@ -26,5 +26,5 @@ conjugation_sites: target: type: value: - efficiency: + DoL: diff --git a/src/vlab4mic/configs/probes/NPC_Nup96_Cterminal_direct.yaml b/src/vlab4mic/configs/probes/NPC_Nup96_Cterminal_direct.yaml index a50e625f..ecaa87ba 100644 --- a/src/vlab4mic/configs/probes/NPC_Nup96_Cterminal_direct.yaml +++ b/src/vlab4mic/configs/probes/NPC_Nup96_Cterminal_direct.yaml @@ -22,5 +22,5 @@ conjugation_sites: target: type: value: - efficiency: + DoL: diff --git a/src/vlab4mic/configs/probes/Nanobody.yaml b/src/vlab4mic/configs/probes/Nanobody.yaml index cedcc923..05d8c018 100644 --- a/src/vlab4mic/configs/probes/Nanobody.yaml +++ b/src/vlab4mic/configs/probes/Nanobody.yaml @@ -26,7 +26,7 @@ conjugation_sites: - CA residues: - LYS - efficiency: 1 + DoL: epitope: # for secondary target: type: diff --git a/src/vlab4mic/configs/probes/SNAP-tag.yaml b/src/vlab4mic/configs/probes/SNAP-tag.yaml index 2410cb62..ee635ad5 100644 --- a/src/vlab4mic/configs/probes/SNAP-tag.yaml +++ b/src/vlab4mic/configs/probes/SNAP-tag.yaml @@ -26,7 +26,7 @@ conjugation_sites: - CAA residues: - OGQ - efficiency: 1 + DoL: epitope: # for secondary target: type: diff --git a/src/vlab4mic/configs/probes/_template_.yaml b/src/vlab4mic/configs/probes/_template_.yaml index 53cbbc1e..e3c7cef5 100644 --- a/src/vlab4mic/configs/probes/_template_.yaml +++ b/src/vlab4mic/configs/probes/_template_.yaml @@ -21,7 +21,7 @@ conjugation_sites: target: type: value: - efficiency: + DoL: fluorophore: epitope: target: diff --git a/src/vlab4mic/configs/probes/anti-p24_primary_antibody_HIV.yaml b/src/vlab4mic/configs/probes/anti-p24_primary_antibody_HIV.yaml index c1921308..639ab90b 100644 --- a/src/vlab4mic/configs/probes/anti-p24_primary_antibody_HIV.yaml +++ b/src/vlab4mic/configs/probes/anti-p24_primary_antibody_HIV.yaml @@ -26,5 +26,5 @@ conjugation_sites: - CA residues: - LYS - efficiency: 0.2 + DoL: diff --git a/src/vlab4mic/configs/probes/mMaple.yaml b/src/vlab4mic/configs/probes/mMaple.yaml index 8b1e2dd0..d7dcc9e5 100644 --- a/src/vlab4mic/configs/probes/mMaple.yaml +++ b/src/vlab4mic/configs/probes/mMaple.yaml @@ -26,7 +26,7 @@ conjugation_sites: - C1 residues: - PIA - efficiency: 1 + DoL: epitope: # for secondary target: type: diff --git a/src/vlab4mic/experiments.py b/src/vlab4mic/experiments.py index f261eb40..4d5882a5 100644 --- a/src/vlab4mic/experiments.py +++ b/src/vlab4mic/experiments.py @@ -934,7 +934,7 @@ def add_probe( probe_steric_hindrance=None, probe_paratope: str = None, probe_conjugation_target_info=None, - probe_conjugation_efficiency: float = None, + probe_DoL: float = None, probe_seconday_epitope=None, probe_wobble_theta: float = None, labelling_efficiency: float = 1.0, @@ -972,7 +972,7 @@ def add_probe( Paratope identifier or information. :param probe_conjugation_target_info : Any, optional Information about the conjugation target. - :param probe_conjugation_efficiency : float, optional + :param probe_DoL : float, optional Efficiency of the probe conjugation. :param probe_seconday_epitope : Any, optional Information about a secondary epitope target. @@ -1063,10 +1063,13 @@ def add_probe( probe_configuration["conjugation_sites"]["target"]["value"] = ( probe_conjugation_target_info["value"] ) - if probe_conjugation_efficiency is not None: - probe_configuration["conjugation_efficiency"] = ( - probe_conjugation_efficiency + if probe_DoL is not None: + print(f"Setting probe DoL to: {probe_DoL}") + probe_configuration["conjugation_sites"]["DoL"] = ( + probe_DoL ) + else: + print("Add_probe: Using default probe DoL from template") if probe_seconday_epitope is not None: probe_configuration["epitope_target_info"] = probe_seconday_epitope if probe_wobble_theta is not None: @@ -1328,7 +1331,7 @@ def generate_virtual_sample( probe_fluorophore: str = "AF647", probe_paratope: str = None, probe_conjugation_target_info=None, - probe_conjugation_efficiency: float = None, + probe_DoL: float = None, probe_seconday_epitope=None, probe_wobble_theta=None, labelling_efficiency: float = 1.0, @@ -1381,7 +1384,7 @@ def generate_virtual_sample( Sequence of the paratope site for when probe includes a model. :param probe_conjugation_target_info : Any, optional Information about the probe conjugation target. - :param probe_conjugation_efficiency : float, optional + :param probe_DoL : float, optional Efficiency of conjugation of emitters. :param probe_seconday_epitope : str, optional Sequence within probe model to be used as epitope for a secondary. @@ -1421,6 +1424,21 @@ def generate_virtual_sample( myexperiment = ExperimentParametrisation() if clear_experiment: myexperiment.clear_experiment() + # select structure + if structure_is_path: + print(f"Selecting structure from path: {structure}") + myexperiment.select_structure( + structure_id=structure.split(".")[0], + structure_path=structure, + build=True + ) + else: + print("Selecting structure from ID:", structure) + myexperiment.select_structure( + structure_id=structure, + structure_path=None, + build=True + ) # load default configuration for probe if (primary_probe is not None) and (secondary_probe is not None): print("Adding primary and secondary probes") @@ -1462,9 +1480,9 @@ def generate_virtual_sample( probe_configuration["conjugation_target_info"] = ( probe_conjugation_target_info ) - if probe_conjugation_efficiency is not None: - probe_configuration["conjugation_efficiency"] = ( - probe_conjugation_efficiency + if probe_DoL is not None: + probe_configuration["probe_DoL"] = ( + probe_DoL ) if probe_seconday_epitope is not None: probe_configuration["epitope_target_info"] = probe_seconday_epitope @@ -1478,22 +1496,7 @@ def generate_virtual_sample( virtual_sample_template + ".yaml", ) vsample_configuration = load_yaml(virtual_sample_template) - myexperiment.configuration_path - if structure_is_path: - print(f"Selecting structure from path: {structure}") - myexperiment.select_structure( - structure_id=structure.split(".")[0], - structure_path=structure, - build=False - ) - else: - print("Selecting structure from ID:", structure) - myexperiment.select_structure( - structure_id=structure, - structure_path=None, - build=False - ) - + #myexperiment.configuration_path if defect and defect_large_cluster and defect_small_cluster: myexperiment.defect_eps["eps1"] = defect_small_cluster myexperiment.defect_eps["eps2"] = defect_large_cluster @@ -1518,7 +1521,10 @@ def generate_virtual_sample( vsample_configuration["yz_orientations"] = yz_orientations vsample_configuration["axial_offset"] = axial_offset myexperiment.virtualsample_params = vsample_configuration - myexperiment.build(use_locals=True) + myexperiment.build(modules=[ + "particle", + "coordinate_field", + "imager"], use_locals=True) if expansion_factor > 1: myexperiment.expand_virtual_sample(factor=expansion_factor) # myexperiment.coordinate_field_id = virtual_sample @@ -1579,7 +1585,7 @@ def image_vsample( probe_fluorophore: str = "AF647", probe_paratope: str = None, probe_conjugation_target_info = None, - probe_conjugation_efficiency: float = None, + probe_DoL: float = None, probe_seconday_epitope = None, probe_wobble_theta = None, labelling_efficiency: float = 1.0, @@ -1649,7 +1655,7 @@ def image_vsample( Sequence of the paratope site for when probe includes a model. :param probe_conjugation_target_info : any, optional Information about the probe conjugation target. - :param probe_conjugation_efficiency : float, optional + :param probe_DoL : float, optional Efficiency of conjugation of emitters. :param probe_seconday_epitope : str, optional Sequence within probe model to be used as epitope for a secondary. @@ -1710,7 +1716,7 @@ def image_vsample( probe_fluorophore=probe_fluorophore, probe_paratope=probe_paratope, probe_conjugation_target_info=probe_conjugation_target_info, - probe_conjugation_efficiency=probe_conjugation_efficiency, + probe_DoL=probe_DoL, probe_seconday_epitope=probe_seconday_epitope, probe_wobble_theta=probe_wobble_theta, labelling_efficiency=labelling_efficiency, diff --git a/src/vlab4mic/generate/labels.py b/src/vlab4mic/generate/labels.py index 97501540..d488f0c6 100644 --- a/src/vlab4mic/generate/labels.py +++ b/src/vlab4mic/generate/labels.py @@ -52,9 +52,9 @@ def _set_model_params(self, ID=None, format=None, database=None, **kwargs): for key, value in kwargs.items(): self.model[key] = value - def _set_conjugation_params(self, target: dict, efficiency, **kwargs): + def _set_conjugation_params(self, target: dict, DoL=None, **kwargs): self.conjugation["target"] = target - self.conjugation["efficiency"] = efficiency + self.conjugation["DoL"] = DoL for key, value in kwargs.items(): self.conjugation[key] = value @@ -265,10 +265,12 @@ def construct_label( label_params["conjugation_sites"]["target"] = kwargs[ "conjugation_target_info" ] - if "conjugation_efficiency" in kwargs.keys(): - label_params["conjugation_sites"]["efficiency"] = kwargs[ - "conjugation_efficiency" - ] + #if "probe_DoL" in label_params.keys(): + # label_params["conjugation_sites"]["DoL"] = kwargs[ + # "probe_DoL" + # ] + #else: + # print("No DoL provided, using default value. ########################") if "epitope_target_info" in kwargs.keys(): label_params["epitope"]["target"] = kwargs["epitope_target_info"] if "wobble_theta" in label_params.keys(): diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index a57ee402..627790a3 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -537,7 +537,7 @@ def set_sweep_parameters( peptide_motif: dict = None, probe_distance_to_epitope= None, probe_steric_hindrance= None, - probe_conjugation_efficiency = None, + probe_DoL = None, probe_wobble_theta = None, labelling_efficiency = None, # defects @@ -568,9 +568,9 @@ def set_sweep_parameters( self.set_parameter_values( "probe", "probe_steric_hindrance", values=probe_steric_hindrance ) - if probe_conjugation_efficiency is not None: + if probe_DoL is not None: self.set_parameter_values( - "probe", "probe_conjugation_efficiency", values=probe_conjugation_efficiency + "probe", "probe_DoL", values=probe_DoL ) if probe_wobble_theta is not None: self.set_parameter_values( @@ -1345,7 +1345,7 @@ def run_parameter_sweep( peptide_motif: dict = None, probe_distance_to_epitope = None, probe_steric_hindrance = None, - probe_conjugation_efficiency = None, + probe_DoL = None, probe_wobble_theta = None, labelling_efficiency = None, defect = None, @@ -1424,7 +1424,7 @@ def run_parameter_sweep( - peptide_motif - probe_distance_to_epitope - probe_steric_hindrance - - probe_conjugation_efficiency + - probe_DoL - probe_wobble_theta - labelling_efficiency - defect @@ -1484,7 +1484,7 @@ def run_parameter_sweep( peptide_motif=peptide_motif, probe_distance_to_epitope=probe_distance_to_epitope, probe_steric_hindrance=probe_steric_hindrance, - probe_conjugation_efficiency=probe_conjugation_efficiency, + probe_DoL=probe_DoL, probe_wobble_theta=probe_wobble_theta, labelling_efficiency=labelling_efficiency, defect=defect, diff --git a/src/vlab4mic/utils/transform/cif_builder.py b/src/vlab4mic/utils/transform/cif_builder.py index 41ee4a00..c2824ae7 100644 --- a/src/vlab4mic/utils/transform/cif_builder.py +++ b/src/vlab4mic/utils/transform/cif_builder.py @@ -151,7 +151,13 @@ def indirect_labelling(coords_nomrals, label_data, **kwargs): # select randomly, and according to labelling_efficiency # the places that will be labelled #efficiency = label_data["labelling_efficiency"] - + if label_data["conjugation_sites"]["DoL"] is not None: + if label_data["conjugation_sites"]["DoL"] > 0: + dol=label_data["conjugation_sites"]["DoL"] + else: + dol = None + else: + dol = None epitopes, normals = binomial_epitope_sampling( epitopes=coords_nomrals["coordinates"], p=label_data["labelling_efficiency"], @@ -178,7 +184,7 @@ def indirect_labelling(coords_nomrals, label_data, **kwargs): else: normals_ft_epitopes = [normals, epitopes] indirect_realisation, list_reoriented_points_normals = decorate_epitopes_normals( - normals_ft_epitopes, label_data["emitters"] + normals_ft_epitopes, label_data["emitters"], dol=dol ) else: print("No emitters defined in label. Using direct labelling") diff --git a/src/vlab4mic/utils/transform/points_transforms.py b/src/vlab4mic/utils/transform/points_transforms.py index 478cd989..f54686d3 100644 --- a/src/vlab4mic/utils/transform/points_transforms.py +++ b/src/vlab4mic/utils/transform/points_transforms.py @@ -1,5 +1,5 @@ import numpy as np - +import copy # # Rodrigues Rotation def rotate_point(point, axis, angle): @@ -90,7 +90,7 @@ def rotate_pts_by_vector(pts, current_vector, new_vector, pts_referece_center): # method that takes the epitopes with their corresponding normals # and takes the labeling entity generated with gen_labeling_entity -def decorate_epitopes_normals(normals_ft_epitopes, labeling_entity): +def decorate_epitopes_normals(normals_ft_epitopes, labeling_entity, dol:int = None, **kwargs): """ labeling_entity is assumed to have the pivot and the axis orientation as the first two points, only after that are defined the actual emitters @@ -98,22 +98,45 @@ def decorate_epitopes_normals(normals_ft_epitopes, labeling_entity): output: the new positioned emitters without pivots """ - # + labeling_entity_copy = copy.copy(labeling_entity) pivot_reference_index = 0 axis_defining_index = 1 list_reoriented_points = [] list_reoriented_points_normals = [] for repl in range(np.shape(normals_ft_epitopes)[1]): new_points, rot_axis = labeling_reorient_set( - labeling_entity, + labeling_entity_copy, pivot_reference_index, axis_defining_index, normals_ft_epitopes[0][repl], normals_ft_epitopes[1][repl], ) - # print(new_points, rot_axis) - list_reoriented_points.append(new_points) - list_reoriented_points_normals.append(normals_ft_epitopes[0][repl]) + # model degree of labelling + if dol is not None: + int_dol = np.random.poisson(lam=dol) + print(f"DOL = {int_dol}") + max_emitters = len(new_points) + if int_dol != 0: + if int_dol > max_emitters - 2 : + # use max value + list_reoriented_points.append(new_points) + else: + # take the first two points to keep pivot and axis + new_points_dol = copy.copy(new_points[0:2]) + # then randomly select the rest of the emitters + emitter_indices = np.arange(2, max_emitters) + selected_emitters = np.random.choice( + emitter_indices, size=int_dol, replace=False + ) + for se in selected_emitters: + new_points_dol = np.vstack((new_points_dol, new_points[se])) + list_reoriented_points.append(new_points_dol) + #new_points = new_points[0:(2+int_dol)] + #list_reoriented_points.append(new_points) + else: + # print(new_points, rot_axis) + list_reoriented_points.append(new_points) + list_reoriented_points_normals.append(normals_ft_epitopes[0][repl]) #print(f"before cleaning: {len(list_reoriented_points)}") # cleanup label entities and leave only the true emitters cleaned_up_labels = cleanup_labeling_entities(list_reoriented_points) diff --git a/tests/test_experiment.py b/tests/test_experiment.py index cfb63d2c..9893aebd 100644 --- a/tests/test_experiment.py +++ b/tests/test_experiment.py @@ -75,6 +75,7 @@ def test_vsample_function(): rotation_angles=[0,20,30], yz_orientations=yz_orientations, axial_offset=axial_offset, + probe_DoL=5, number_of_particles=10, clear_experiment=True )