From f863466ac4aaeee98a611280cfe7fe50dde269ea Mon Sep 17 00:00:00 2001 From: Geoffrey Woollard Date: Fri, 12 Jul 2024 10:32:05 -0400 Subject: [PATCH 1/5] res --- .../config_map_to_map_distance_matrix.yaml | 5 ++- .../_commands/run_map2map_pipeline.py | 6 +-- .../_map_to_map/map_to_map_distance_matrix.py | 38 ++++++++++++++++--- .../data/_validation/output_validators.py | 2 + .../config_files/test_config_map_to_map.yaml | 1 + 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/config_files/config_map_to_map_distance_matrix.yaml b/config_files/config_map_to_map_distance_matrix.yaml index be8d55d..d0ea180 100644 --- a/config_files/config_map_to_map_distance_matrix.yaml +++ b/config_files/config_map_to_map_distance_matrix.yaml @@ -18,9 +18,12 @@ analysis: - corr - bioem - fsc + - res chunk_size_submission: 80 chunk_size_gt: 190 normalize: do: true method: median_zscore -output: results/map_to_map_distance_matrix_submission_0.pkl \ No newline at end of file +output: results/map_to_map_distance_matrix_submission_0.pkl +# external: +# res: results/map_to_map_distance_matrix_submission_0.pkl \ No newline at end of file diff --git a/src/cryo_challenge/_commands/run_map2map_pipeline.py b/src/cryo_challenge/_commands/run_map2map_pipeline.py index 0f3d85f..c985f6a 100644 --- a/src/cryo_challenge/_commands/run_map2map_pipeline.py +++ b/src/cryo_challenge/_commands/run_map2map_pipeline.py @@ -6,8 +6,8 @@ import os import yaml -from .._map_to_map.map_to_map_distance_matrix import run -from ..data._validation.config_validators import validate_input_config_mtm +from cryo_challenge._map_to_map.map_to_map_distance_matrix import run +from cryo_challenge.data._validation.config_validators import validate_input_config_mtm def add_args(parser): @@ -46,5 +46,5 @@ def main(args): if __name__ == "__main__": parser = argparse.ArgumentParser(description=__doc__) - args = parser.parse_args() + # args = parser.parse_args() main(add_args(parser).parse_args()) diff --git a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py index f424751..0ba9a27 100644 --- a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py +++ b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py @@ -2,14 +2,15 @@ import pandas as pd import pickle import torch +import numpy as np -from .map_to_map_distance import ( +from cryo_challenge._map_to_map.map_to_map_distance import ( compute_bioem3d_cost, compute_cost_corr, compute_cost_fsc_chunk, compute_cost_l2, ) -from ..data._validation.output_validators import MapToMapResultsValidator +from cryo_challenge.data._validation.output_validators import MapToMapResultsValidator class MapToMapDistance: @@ -30,7 +31,7 @@ def get_distance_matrix(self, maps1, maps2): chunk_size=chunk_size_gt, )(maps1) - return distance_matrix + return distance_matrix.numpy() def get_computed_assets(self, maps1, maps2): return {} @@ -81,10 +82,36 @@ def get_distance_matrix(self, maps1, maps2): # custom method cost_matrix, fsc_matrix = compute_cost_fsc_chunk(maps_gt_flat_cube, maps_user_flat_cube, n_pix) self.stored_computed_assets = {'fsc_matrix': fsc_matrix} - return cost_matrix + return cost_matrix.numpy() def get_computed_assets(self, maps1, maps2): return self.stored_computed_assets # must run get_distance_matrix first + +class ResDistance(MapToMapDistance): + def __init__(self, config): + super().__init__(config) + + def get_distance_matrix(self, maps1, maps2): # custom method + # get fsc matrix + fourier_pixel_max = 120 + psize = 2.146 + fname = 'tests/results/test_map_to_map_distance_matrix_submission_0.pkl' #self.config['external'] + + with open(fname, 'rb') as f: + data = pickle.load(f) + + # fsc_matrix = fscs_sorted = torch.zeros(len(maps1), len(maps2), fourier_pixel_max) + fsc_matrix = data['fsc']['computed_assets']['fsc_matrix'] + units_Angstroms = 2 * psize / (np.arange(1,fourier_pixel_max+1) / fourier_pixel_max) + def res_at_fsc_threshold(fscs, threshold=0.5): + res_fsc_half = np.argmin(fscs > threshold, axis=-1) + fraction_nyquist = 0.5*res_fsc_half / fscs.shape[-1] + return res_fsc_half, fraction_nyquist + res_fsc_half, fraction_nyquist = res_at_fsc_threshold(fsc_matrix) + self.stored_computed_assets = {'fraction_nyquist': fraction_nyquist} + return units_Angstroms[res_fsc_half] + + def run(config): """ @@ -112,6 +139,7 @@ def run(config): "corr": Correlation(config), "l2": L2DistanceSum(config), "bioem": BioEM3dDistance(config), + "res": ResDistance(config), } maps_user_flat = submission[submission_volume_key].reshape( @@ -145,7 +173,7 @@ def run(config): cost_matrix = map_to_map_distance.get_distance_matrix( maps_gt_flat, maps_user_flat - ).numpy() + ) computed_assets = map_to_map_distance.get_computed_assets( maps_gt_flat, maps_user_flat ) diff --git a/src/cryo_challenge/data/_validation/output_validators.py b/src/cryo_challenge/data/_validation/output_validators.py index 35d9791..5f4a14f 100644 --- a/src/cryo_challenge/data/_validation/output_validators.py +++ b/src/cryo_challenge/data/_validation/output_validators.py @@ -29,6 +29,7 @@ class MapToMapResultsValidator: l2: Optional[dict] = None bioem: Optional[dict] = None fsc: Optional[dict] = None + res: Optional[dict] = None def __post_init__(self): validate_input_config_mtm(self.config) @@ -142,6 +143,7 @@ class DistributionToDistributionResultsValidator: id: str fsc: Optional[dict] = None bioem: Optional[dict] = None + res: Optional[dict] = None l2: Optional[dict] = None corr: Optional[dict] = None diff --git a/tests/config_files/test_config_map_to_map.yaml b/tests/config_files/test_config_map_to_map.yaml index 155bd4f..563dd5b 100644 --- a/tests/config_files/test_config_map_to_map.yaml +++ b/tests/config_files/test_config_map_to_map.yaml @@ -18,6 +18,7 @@ analysis: - corr - bioem - fsc + - res chunk_size_submission: 80 chunk_size_gt: 190 normalize: From 2ae38acde490d3707699181b238b477caf3f9d32 Mon Sep 17 00:00:00 2001 From: Geoffrey Woollard Date: Fri, 12 Jul 2024 11:53:47 -0400 Subject: [PATCH 2/5] global_store_of_running_results for res distance from fsc computed assets --- .../_map_to_map/map_to_map_distance_matrix.py | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py index 0ba9a27..528f84d 100644 --- a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py +++ b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py @@ -20,7 +20,7 @@ def __init__(self, config): def get_distance(self, map1, map2): raise NotImplementedError() - def get_distance_matrix(self, maps1, maps2): + def get_distance_matrix(self, maps1, maps2, global_store_of_running_results): chunk_size_submission = self.config["analysis"]["chunk_size_submission"] chunk_size_gt = self.config["analysis"]["chunk_size_gt"] distance_matrix = torch.vmap( @@ -33,7 +33,7 @@ def get_distance_matrix(self, maps1, maps2): return distance_matrix.numpy() - def get_computed_assets(self, maps1, maps2): + def get_computed_assets(self, maps1, maps2, global_store_of_running_results): return {} class L2DistanceNorm(MapToMapDistance): @@ -68,7 +68,7 @@ class FSCDistance(MapToMapDistance): def __init__(self, config): super().__init__(config) - def get_distance_matrix(self, maps1, maps2): # custom method + def get_distance_matrix(self, maps1, maps2, global_store_of_running_results): # custom method maps_gt_flat = maps1 maps_user_flat = maps2 n_pix = self.config["data"]["n_pix"] @@ -84,24 +84,18 @@ def get_distance_matrix(self, maps1, maps2): # custom method self.stored_computed_assets = {'fsc_matrix': fsc_matrix} return cost_matrix.numpy() - def get_computed_assets(self, maps1, maps2): + def get_computed_assets(self, maps1, maps2, global_store_of_running_results): return self.stored_computed_assets # must run get_distance_matrix first class ResDistance(MapToMapDistance): def __init__(self, config): super().__init__(config) - def get_distance_matrix(self, maps1, maps2): # custom method + def get_distance_matrix(self, maps1, maps2, global_store_of_running_results): # custom method # get fsc matrix fourier_pixel_max = 120 psize = 2.146 - fname = 'tests/results/test_map_to_map_distance_matrix_submission_0.pkl' #self.config['external'] - - with open(fname, 'rb') as f: - data = pickle.load(f) - - # fsc_matrix = fscs_sorted = torch.zeros(len(maps1), len(maps2), fourier_pixel_max) - fsc_matrix = data['fsc']['computed_assets']['fsc_matrix'] + fsc_matrix = global_store_of_running_results['fsc']['computed_assets']['fsc_matrix'] units_Angstroms = 2 * psize / (np.arange(1,fourier_pixel_max+1) / fourier_pixel_max) def res_at_fsc_threshold(fscs, threshold=0.5): res_fsc_half = np.argmin(fscs > threshold, axis=-1) @@ -172,10 +166,10 @@ def run(config): print("cost matrix", distance_label) cost_matrix = map_to_map_distance.get_distance_matrix( - maps_gt_flat, maps_user_flat + maps_gt_flat, maps_user_flat, global_store_of_running_results=results_dict, ) computed_assets = map_to_map_distance.get_computed_assets( - maps_gt_flat, maps_user_flat + maps_gt_flat, maps_user_flat, global_store_of_running_results=results_dict, ) computed_assets.update(computed_assets) From a03541752b4ac7c39809bc0a74feae074c748349 Mon Sep 17 00:00:00 2001 From: Geoffrey Woollard Date: Fri, 12 Jul 2024 11:56:10 -0400 Subject: [PATCH 3/5] psize and box size from config --- src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py index 528f84d..dd19c2c 100644 --- a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py +++ b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py @@ -93,8 +93,8 @@ def __init__(self, config): def get_distance_matrix(self, maps1, maps2, global_store_of_running_results): # custom method # get fsc matrix - fourier_pixel_max = 120 - psize = 2.146 + fourier_pixel_max = self.config['data']['npix'] // 2 # TODO: check for odd psizes if this should be +1 + psize = self.config['data']['npix'] fsc_matrix = global_store_of_running_results['fsc']['computed_assets']['fsc_matrix'] units_Angstroms = 2 * psize / (np.arange(1,fourier_pixel_max+1) / fourier_pixel_max) def res_at_fsc_threshold(fscs, threshold=0.5): From 3f86081400677fc7581fd3ead888a3d6cd27a82c Mon Sep 17 00:00:00 2001 From: Geoffrey Woollard Date: Tue, 16 Jul 2024 08:37:23 -0400 Subject: [PATCH 4/5] typo in npix --- src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py index dd19c2c..1f7d2a4 100644 --- a/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py +++ b/src/cryo_challenge/_map_to_map/map_to_map_distance_matrix.py @@ -93,8 +93,8 @@ def __init__(self, config): def get_distance_matrix(self, maps1, maps2, global_store_of_running_results): # custom method # get fsc matrix - fourier_pixel_max = self.config['data']['npix'] // 2 # TODO: check for odd psizes if this should be +1 - psize = self.config['data']['npix'] + fourier_pixel_max = self.config['data']['n_pix'] // 2 # TODO: check for odd psizes if this should be +1 + psize = self.config['data']['psize'] fsc_matrix = global_store_of_running_results['fsc']['computed_assets']['fsc_matrix'] units_Angstroms = 2 * psize / (np.arange(1,fourier_pixel_max+1) / fourier_pixel_max) def res_at_fsc_threshold(fscs, threshold=0.5): From 1cd02250398b86fe25445f6b47000ac7e6a31c03 Mon Sep 17 00:00:00 2001 From: Geoffrey Woollard Date: Mon, 12 Aug 2024 14:59:01 -0400 Subject: [PATCH 5/5] precommit --- config_files/config_map_to_map.yaml | 2 +- .../_map_to_map/map_to_map_distance.py | 30 +++++++++++++------ .../_map_to_map/map_to_map_pipeline.py | 9 ++++-- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/config_files/config_map_to_map.yaml b/config_files/config_map_to_map.yaml index bb66486..aea2059 100644 --- a/config_files/config_map_to_map.yaml +++ b/config_files/config_map_to_map.yaml @@ -24,4 +24,4 @@ analysis: normalize: do: true method: median_zscore -output: results/map_to_map_distance_matrix_submission_0.pkl \ No newline at end of file +output: results/map_to_map_distance_matrix_submission_0.pkl diff --git a/src/cryo_challenge/_map_to_map/map_to_map_distance.py b/src/cryo_challenge/_map_to_map/map_to_map_distance.py index b9f12f5..e89cda8 100644 --- a/src/cryo_challenge/_map_to_map/map_to_map_distance.py +++ b/src/cryo_challenge/_map_to_map/map_to_map_distance.py @@ -215,7 +215,9 @@ def compute_cost_fsc_chunk(self, maps_gt_flat, maps_user_flat, n_pix): return cost_matrix, fsc_matrix @override - def get_distance_matrix(self, maps1, maps2, global_store_of_running_results): # custom method + def get_distance_matrix( + self, maps1, maps2, global_store_of_running_results + ): # custom method maps_gt_flat = maps1 maps_user_flat = maps2 n_pix = self.config["data"]["n_pix"] @@ -245,16 +247,26 @@ def __init__(self, config): super().__init__(config) @override - def get_distance_matrix(self, maps1, maps2, global_store_of_running_results): # custom method + def get_distance_matrix( + self, maps1, maps2, global_store_of_running_results + ): # custom method # get fsc matrix - fourier_pixel_max = self.config['data']['n_pix'] // 2 # TODO: check for odd psizes if this should be +1 - psize = self.config['data']['psize'] - fsc_matrix = global_store_of_running_results['fsc']['computed_assets']['fsc_matrix'] - units_Angstroms = 2 * psize / (np.arange(1,fourier_pixel_max+1) / fourier_pixel_max) + fourier_pixel_max = ( + self.config["data"]["n_pix"] // 2 + ) # TODO: check for odd psizes if this should be +1 + psize = self.config["data"]["psize"] + fsc_matrix = global_store_of_running_results["fsc"]["computed_assets"][ + "fsc_matrix" + ] + units_Angstroms = ( + 2 * psize / (np.arange(1, fourier_pixel_max + 1) / fourier_pixel_max) + ) + def res_at_fsc_threshold(fscs, threshold=0.5): res_fsc_half = np.argmin(fscs > threshold, axis=-1) - fraction_nyquist = 0.5*res_fsc_half / fscs.shape[-1] + fraction_nyquist = 0.5 * res_fsc_half / fscs.shape[-1] return res_fsc_half, fraction_nyquist + res_fsc_half, fraction_nyquist = res_at_fsc_threshold(fsc_matrix) - self.stored_computed_assets = {'fraction_nyquist': fraction_nyquist} - return units_Angstroms[res_fsc_half] \ No newline at end of file + self.stored_computed_assets = {"fraction_nyquist": fraction_nyquist} + return units_Angstroms[res_fsc_half] diff --git a/src/cryo_challenge/_map_to_map/map_to_map_pipeline.py b/src/cryo_challenge/_map_to_map/map_to_map_pipeline.py index 923e42b..823a174 100644 --- a/src/cryo_challenge/_map_to_map/map_to_map_pipeline.py +++ b/src/cryo_challenge/_map_to_map/map_to_map_pipeline.py @@ -2,7 +2,6 @@ import pandas as pd import pickle import torch -import numpy as np from ..data._validation.output_validators import MapToMapResultsValidator from .._map_to_map.map_to_map_distance import ( @@ -79,10 +78,14 @@ def run(config): print("cost matrix", distance_label) cost_matrix = map_to_map_distance.get_distance_matrix( - maps_gt_flat, maps_user_flat, global_store_of_running_results=results_dict, + maps_gt_flat, + maps_user_flat, + global_store_of_running_results=results_dict, ) computed_assets = map_to_map_distance.get_computed_assets( - maps_gt_flat, maps_user_flat, global_store_of_running_results=results_dict, + maps_gt_flat, + maps_user_flat, + global_store_of_running_results=results_dict, ) computed_assets.update(computed_assets)