|
| 1 | +""" |
| 2 | +This script can be used for any purpose without limitation subject to the |
| 3 | +conditions at https://www.ccdc.cam.ac.uk/Community/Pages/Licences/v2.aspx |
| 4 | +This permission notice and the following statement of attribution must be |
| 5 | +included in all copies or substantial portions of this script. |
| 6 | +
|
| 7 | +"07/08/2026": created by the Cambridge Crystallographic Data Centre |
| 8 | +""" |
| 9 | + |
| 10 | +import argparse |
| 11 | +from pathlib import Path |
| 12 | + |
| 13 | +from cluster import cluster_features |
| 14 | +from datastructures import OverlayData |
| 15 | +from overlay import OverlayToPharmFeatures |
| 16 | +from write_query import FeaturesToCrossMinerQuery |
| 17 | + |
| 18 | + |
| 19 | +def str_to_bool(value: str) -> bool: |
| 20 | + return value.lower() in {'t', 'true', '1', 'yes', 'y'} |
| 21 | + |
| 22 | + |
| 23 | +def parse_args(): |
| 24 | + parser = argparse.ArgumentParser( |
| 25 | + description="Create Pharmacophore Features from a Ligand Overlay" |
| 26 | + ) |
| 27 | + parser.add_argument('-i', '--input_folder', type=str, required=True, |
| 28 | + help='Input file(s) path.') |
| 29 | + parser.add_argument('-o', '--output_folder', type=str, default=None, |
| 30 | + help="Output folder path. Defaults to a 'queries' folder in the current directory.") |
| 31 | + parser.add_argument('-f', '--feature_definitions', type=str, required=True, |
| 32 | + help='Path to the directory containing the CrossMiner feature definition (.cpf) files.') |
| 33 | + parser.add_argument('-c', '--cluster', type=str_to_bool, default=False, |
| 34 | + help='Cluster features if they are close together or common across multiple inputs.') |
| 35 | + parser.add_argument('-p', '--projected', type=str_to_bool, default=False, |
| 36 | + help='Use projected acceptor features or point features.') |
| 37 | + parser.add_argument('-id', '--overlay_id', type=int, default=0, |
| 38 | + help='Overlay ID to process. If 0 or not specified, all overlays will be processed.') |
| 39 | + |
| 40 | + return parser.parse_args() |
| 41 | + |
| 42 | + |
| 43 | +def main(): |
| 44 | + args = parse_args() |
| 45 | + |
| 46 | + input_folder = Path(args.input_folder) |
| 47 | + if not input_folder.exists(): |
| 48 | + raise FileNotFoundError(f"Input folder {input_folder} does not exist.") |
| 49 | + |
| 50 | + feature_definitions = Path(args.feature_definitions) |
| 51 | + if not feature_definitions.is_dir(): |
| 52 | + raise FileNotFoundError(f"Feature definitions folder {feature_definitions} does not exist.") |
| 53 | + |
| 54 | + output_folder = Path(args.output_folder) if args.output_folder else Path('queries') |
| 55 | + output_folder.mkdir(parents=True, exist_ok=True) |
| 56 | + |
| 57 | + if (args.overlay_id == 0) or (args.overlay_id is None): |
| 58 | + overlay_files = sorted(input_folder.glob('solution_*.mol2')) |
| 59 | + pharm_files = sorted(input_folder.glob('pharmacophores/solution_pharm_*.mol2')) |
| 60 | + else: |
| 61 | + overlay_files = [input_folder / f'solution_{args.overlay_id:02}.mol2'] |
| 62 | + pharm_files = [input_folder / f'pharmacophores/solution_pharm_{args.overlay_id:02}.mol2'] |
| 63 | + feature_sets = [] |
| 64 | + for pharm_file, overlay_file in zip(pharm_files, overlay_files): |
| 65 | + overlay_data = OverlayData( |
| 66 | + input_folder=input_folder, |
| 67 | + output_folder=output_folder, |
| 68 | + pharm_file=pharm_file, |
| 69 | + overlay_file=overlay_file |
| 70 | + ) |
| 71 | + feature_sets.append(OverlayToPharmFeatures(overlay_data, projected=args.projected).features) |
| 72 | + |
| 73 | + for i, feature_set in enumerate(feature_sets, 1): |
| 74 | + if args.cluster: |
| 75 | + feature_set = cluster_features(feature_set) |
| 76 | + |
| 77 | + query = FeaturesToCrossMinerQuery( |
| 78 | + pharm_feature_points=feature_set, |
| 79 | + feature_definitions=feature_definitions, |
| 80 | + output_file=output_folder / f'features_{i}.cm', |
| 81 | + ) |
| 82 | + query.write_feature_file() |
| 83 | + |
| 84 | + |
| 85 | +if __name__ == '__main__': |
| 86 | + main() |
0 commit comments