From 58022ffbe20860eadbbf7efbfc0f0416f6601379 Mon Sep 17 00:00:00 2001 From: Nazanin Donyapour Date: Fri, 15 Sep 2023 15:09:11 -0400 Subject: [PATCH] vacuum minimization --- cwl_adapters/combine_structure.cwl | 16 +++- examples/config_ci.json | 6 +- examples/docking/docking.wic | 3 +- examples/docking/docking_stability.wic | 26 ++++++- examples/docking/gen_topol_params.wic | 1 + examples/docking/vs_demo_2.wic | 15 ++-- examples/docking/vs_demo_3.wic | 16 ++-- examples/docking/vs_demo_4.wic | 15 ++-- examples/gromacs/basic.wic | 22 ++++-- examples/gromacs/cg.wic | 63 +++++++++------- examples/gromacs/equil.wic | 4 +- examples/gromacs/min.wic | 14 +++- examples/gromacs/prod.wic | 74 +++++++++---------- examples/gromacs/setup_vac_min.wic | 39 ++++++++-- examples/gromacs/solv_ion.wic | 61 ++++++++------- examples/gromacs/stability.wic | 23 +++--- examples/gromacs/steep.wic | 59 ++++++++------- examples/gromacs/topology.wic | 23 ++++-- examples/gromacs/tutorial.wic | 18 ++--- examples/scripts/Dockerfile_combine_structure | 2 +- examples/scripts/combine_structure.py | 41 ++++++++-- 21 files changed, 352 insertions(+), 189 deletions(-) diff --git a/cwl_adapters/combine_structure.cwl b/cwl_adapters/combine_structure.cwl index 4a8f6d5..98fd777 100644 --- a/cwl_adapters/combine_structure.cwl +++ b/cwl_adapters/combine_structure.cwl @@ -12,7 +12,7 @@ baseCommand: ['python', '/combine_structure.py'] hints: DockerRequirement: - dockerPull: ndonyapour/combine_structure + dockerPull: ndonyapour/combine_structure_zip inputs: input_structure1: @@ -40,6 +40,20 @@ inputs: - edam:format_3877 inputBinding: prefix: --input_structure2 + + input_top_zip_path: + label: Input zip file + doc: |- + Input zip file + Type: string + File type: input + Accepted formats: zip + Example file: https://github.com/bioexcel/biobb_md/blob/master/biobb_md/test/data/gromacs/genion.zip + type: File + format: + - edam:format_3987 + inputBinding: + prefix: --input_top_zip_path output_structure_path: label: Output combined PDB file path diff --git a/examples/config_ci.json b/examples/config_ci.json index 986c70f..9338ffb 100644 --- a/examples/config_ci.json +++ b/examples/config_ci.json @@ -10,7 +10,11 @@ "vs_demo_2_weekly", "vs_demo_3_weekly", "vs_demo_4_weekly", - "docking_rescoring_weekly" + "docking_rescoring_weekly", + "stability", + "docking_stability", + "nmr", + "tutorial" ], // NOTE: Most of the workflows in this list have free variables because they are subworkflows // i.e. if you try to run them, you will get "Missing required input parameter" diff --git a/examples/docking/docking.wic b/examples/docking/docking.wic index 10cf0f0..f285eb8 100644 --- a/examples/docking/docking.wic +++ b/examples/docking/docking.wic @@ -98,8 +98,9 @@ steps: - output_top_zip_path: !& complex_vac.zip combine_structure: in: - input_structure1: !* receptor.xyz # receptor_hydrogens.pdb + input_structure1: !* receptor.xyz # !* receptor_hydrogens.pdb input_structure2: !* pose_ligand.xyz + input_top_zip_path: !* complex_vac.zip out: - output_structure_path: !& complex_vac.pdb diff --git a/examples/docking/docking_stability.wic b/examples/docking/docking_stability.wic index 4f35cc2..9b43679 100644 --- a/examples/docking/docking_stability.wic +++ b/examples/docking/docking_stability.wic @@ -20,6 +20,7 @@ steps: dt: !ii 0.002 temperature: !ii 298.0 pressure: !ii 1.0 + wic: graphviz: label: Docking + MD Stability Analysis @@ -31,12 +32,31 @@ wic: wic: inlineable: False steps: + (1, setup_vac_min.wic): + wic: + steps: + (3, solv_ion.wic): + wic: + steps: + (4, genion): + out: + - output_top_zip_path: !& genion_complex.zip (2, basic.wic): + in: + top_zip_path: !* genion_complex.zip wic: steps: (3, prod.wic): wic: steps: + (2, grompp): + in: + input_top_zip_path: !* genion_complex.zip + (3, mdrun): + out: + - output_crd_path: !& prod_complex.gro # overload prod.gro + - output_trr_path: !& prod.trr + - output_edr_path: !& prod.edr (4, cwl_subinterpreter_analysis.wic): wic: implementation: complex @@ -45,4 +65,8 @@ wic: steps: (1, analysis_realtime.wic): wic: - implementation: complex \ No newline at end of file + implementation: complex + (2, analysis_final.wic): + wic: + implementation: complex + diff --git a/examples/docking/gen_topol_params.wic b/examples/docking/gen_topol_params.wic index 1efb759..57a1a5e 100644 --- a/examples/docking/gen_topol_params.wic +++ b/examples/docking/gen_topol_params.wic @@ -78,6 +78,7 @@ steps: in: input_structure1: input_receptor_xyz_path input_structure2: !* pose_ligand.xyz + input_top_zip_path: !* complex_vac.zip out: - output_structure_path: !& complex_vac.pdb diff --git a/examples/docking/vs_demo_2.wic b/examples/docking/vs_demo_2.wic index 5cec17d..742b6b4 100644 --- a/examples/docking/vs_demo_2.wic +++ b/examples/docking/vs_demo_2.wic @@ -155,14 +155,19 @@ wic: wic: inlineable: False steps: - (1, setup.wic): + (1, setup_vac_min.wic): wic: steps: - (4, genion): - out: - - output_top_zip_path: !& genion_complex.zip + (3, solv_ion.wic): + wic: + steps: + (4, genion): + out: + - output_top_zip_path: !& genion_complex.zip (2, basic.wic): - wic: + in: + top_zip_path: !* genion_complex.zip + wic: steps: (3, prod.wic): wic: diff --git a/examples/docking/vs_demo_3.wic b/examples/docking/vs_demo_3.wic index 8960d93..3e75875 100644 --- a/examples/docking/vs_demo_3.wic +++ b/examples/docking/vs_demo_3.wic @@ -127,18 +127,24 @@ wic: (7, gen_topol_params.wic): wic: inlineable: False + (8, stability.wic): wic: inlineable: False steps: - (1, setup.wic): + (1, setup_vac_min.wic): wic: steps: - (4, genion): - out: - - output_top_zip_path: !& genion_complex.zip + (3, solv_ion.wic): + wic: + steps: + (4, genion): + out: + - output_top_zip_path: !& genion_complex.zip (2, basic.wic): - wic: + in: + top_zip_path: !* genion_complex.zip + wic: steps: (3, prod.wic): wic: diff --git a/examples/docking/vs_demo_4.wic b/examples/docking/vs_demo_4.wic index 658f476..21baacf 100644 --- a/examples/docking/vs_demo_4.wic +++ b/examples/docking/vs_demo_4.wic @@ -206,14 +206,19 @@ wic: wic: inlineable: False steps: - (1, setup.wic): + (1, setup_vac_min.wic): wic: steps: - (4, genion): - out: - - output_top_zip_path: !& genion_complex.zip + (3, solv_ion.wic): + wic: + steps: + (4, genion): + out: + - output_top_zip_path: !& genion_complex.zip (2, basic.wic): - wic: + in: + top_zip_path: !* genion_complex.zip + wic: steps: (3, prod.wic): wic: diff --git a/examples/gromacs/basic.wic b/examples/gromacs/basic.wic index 45ece34..276586a 100644 --- a/examples/gromacs/basic.wic +++ b/examples/gromacs/basic.wic @@ -1,4 +1,8 @@ inputs: + top_zip_path: + type: File + format: + - edam:format_3987 nsteps: type: int dt: @@ -15,14 +19,16 @@ steps: # (i.e. immediately before molecular dynamics) so we can extract &min.tpr # to this level and use the following syntax to pass it to only one call site. # (Moreover, the former will create multiple definitions of &min.tpr, which is not allowed.) - min.wic: - equil.wic: - prod.wic: - in: - nsteps: nsteps - dt: dt - ref-t: ref-t - ref-p: ref-p + min.wic: + in: + top_zip_path: top_zip_path + equil.wic: + prod.wic: + in: + nsteps: nsteps + dt: dt + ref-t: ref-t + ref-p: ref-p # Pass the CWL `in` tag as a parameter through BOTH of the yml DSL tags cg.wic and grompp. # Use (1-based) indexing to uniquely reference (step_number, step_name). diff --git a/examples/gromacs/cg.wic b/examples/gromacs/cg.wic index ae53b9f..e9c1374 100644 --- a/examples/gromacs/cg.wic +++ b/examples/gromacs/cg.wic @@ -1,32 +1,39 @@ +inputs: + top_zip_path: + type: File + format: + - edam:format_3987 + steps: - grompp: - in: - config: !ii - mdp: - integrator: cg - define: -DFLEXIBLE # Defines a flexible water model if it exists in the system - # https://manual.gromacs.org/current/reference-manual/algorithms/energy-minimization.html#conjugate-gradient - rvdw: 1.4 - rcoulomb: 1.4 - #coulombtype: PME - nsteps: 1000 - emstep: 0.01 - emtol: 10 - nstxout: 100 - nstenergy: 1 - mdrun: - in: - nb_terms: !ii cpu # NOTE: Workaround for a bug in gromacs 2022.2, fixed in 2022.3 - # https://manual.gromacs.org/current/release-notes/2022/2022.3.html#energy-minimization-would-not-converge-with-gpu-and-without-dd - bonded_terms: !ii cpu # GPU implementation IS supported for md integrator, is NOT supported for sd integrator, etc. - pme_terms: !ii cpu - pme_fft_terms: !ii cpu - update_terms: !ii cpu - gmx_energy: - in: - config: !ii - terms: [Potential] - output_xvg_path: !ii energy_min_cg.xvg + grompp: + in: + input_top_zip_path: top_zip_path + config: !ii + mdp: + integrator: cg + define: -DFLEXIBLE # Defines a flexible water model if it exists in the system + # https://manual.gromacs.org/current/reference-manual/algorithms/energy-minimization.html#conjugate-gradient + rvdw: 1.4 + rcoulomb: 1.4 + #coulombtype: PME + nsteps: 1000 + emstep: 0.01 + emtol: 10 + nstxout: 100 + nstenergy: 1 + mdrun: + in: + nb_terms: !ii cpu # NOTE: Workaround for a bug in gromacs 2022.2, fixed in 2022.3 + # https://manual.gromacs.org/current/release-notes/2022/2022.3.html#energy-minimization-would-not-converge-with-gpu-and-without-dd + bonded_terms: !ii cpu # GPU implementation IS supported for md integrator, is NOT supported for sd integrator, etc. + pme_terms: !ii cpu + pme_fft_terms: !ii cpu + update_terms: !ii cpu + gmx_energy: + in: + config: !ii + terms: [Potential] + output_xvg_path: !ii energy_min_cg.xvg wic: graphviz: diff --git a/examples/gromacs/equil.wic b/examples/gromacs/equil.wic index fb14575..4fdc5d5 100644 --- a/examples/gromacs/equil.wic +++ b/examples/gromacs/equil.wic @@ -1,6 +1,6 @@ steps: - nvt.wic: - npt.wic: + nvt.wic: + npt.wic: wic: graphviz: diff --git a/examples/gromacs/min.wic b/examples/gromacs/min.wic index 8c8a337..255b698 100644 --- a/examples/gromacs/min.wic +++ b/examples/gromacs/min.wic @@ -1,9 +1,19 @@ +inputs: + top_zip_path: + type: File + format: + - edam:format_3987 + steps: - steep.wic: + steep.wic: + in: + top_zip_path: top_zip_path # Fatal error: # The coordinates could not be constrained. Minimizer 'cg' can not handle # constraint failures, use minimizer 'steep' before using 'cg'. - cg.wic: + cg.wic: + in: + top_zip_path: top_zip_path # Fatal error: # The combination of constraints and L-BFGS minimization is not implemented. # Either do not use constraints, or use another minimizer (e.g. steepest diff --git a/examples/gromacs/prod.wic b/examples/gromacs/prod.wic index 62b814f..9fa6389 100644 --- a/examples/gromacs/prod.wic +++ b/examples/gromacs/prod.wic @@ -11,45 +11,45 @@ inputs: type: float steps: - config_tag_mdp: - in: - nsteps: nsteps #10000 - dt: dt #0.002 - ref-t: ref-t #298.0 - ref-p: ref-p #1.0 - config: !ii - mdp: - integrator: md # Use md for performance so we can update coordinates on GPU. Use sd for proper statistical properties. - rvdw: 1.0 - rcoulomb: 1.0 - coulombtype: PME - tc-grps: system - tau-t: 2 - constraints: h-bonds - nstxout: 1000 - nstenergy: 1000 - pcoupl: Parrinello-Rahman - tau-p: 1 - compressibility: 4.5e-5 - comm-mode: Linear - comm-grps: system - out: - - output_config_string: !& config_tag_mdp_prod - grompp: - in: - config: !* config_tag_mdp_prod - input_top_zip_path: !* genion.zip # Use the original topology file so + config_tag_mdp: + in: + nsteps: nsteps #10000 + dt: dt #0.002 + ref-t: ref-t #298.0 + ref-p: ref-p #1.0 + config: !ii + mdp: + integrator: md # Use md for performance so we can update coordinates on GPU. Use sd for proper statistical properties. + rvdw: 1.0 + rcoulomb: 1.0 + coulombtype: PME + tc-grps: system + tau-t: 2 + constraints: h-bonds + nstxout: 1000 + nstenergy: 1000 + pcoupl: Parrinello-Rahman + tau-p: 1 + compressibility: 4.5e-5 + comm-mode: Linear + comm-grps: system + out: + - output_config_string: !& config_tag_mdp_prod + grompp: + in: + config: !* config_tag_mdp_prod + input_top_zip_path: !* genion.zip # Use the original topology file so # we don't have to question whether the topology gets messed up after file format conversions. # (In fact, it is not exactly identical!) - out: - - output_tpr_path: !& prod.tpr - mdrun: - in: - output_trr_path: !ii prod.trr # Explicitly specify for cwl_subinterpreter - out: - - output_crd_path: !& prod.gro - - output_trr_path: !& prod.trr - - output_edr_path: !& prod.edr + out: + - output_tpr_path: !& prod.tpr + mdrun: + in: + output_trr_path: !ii prod.trr # Explicitly specify for cwl_subinterpreter + out: + - output_crd_path: !& prod.gro + - output_trr_path: !& prod.trr + - output_edr_path: !& prod.edr # - cwl_subinterpreter_analysis.wic: wic: diff --git a/examples/gromacs/setup_vac_min.wic b/examples/gromacs/setup_vac_min.wic index 6ef5249..f8ff94f 100644 --- a/examples/gromacs/setup_vac_min.wic +++ b/examples/gromacs/setup_vac_min.wic @@ -1,8 +1,37 @@ -steps: - topology.wic: - min.wic: # Minimize in vacuum first, then in solvent. - solv_ion.wic: +inputs: + crd_path: + type: File + format: + - edam:format_1476 + - edam:format_2033 + top_zip_path: + type: File + format: + - edam:format_3987 +steps: + topology.wic: + in: + crd_path: crd_path + min.wic: # Minimize in vacuum first, then in solvent. + in: + top_zip_path: top_zip_path + solv_ion.wic: + in: + top_zip_path: top_zip_path wic: graphviz: - label: System Setup \ No newline at end of file + label: System Setup + steps: + (1, topology.wic): + wic: + graphviz: + label: 'Initialize\nPeriodic Box' + (2, min.wic): + wic: + graphviz: + label: 'Vacuum Minimization' + (3, solv_ion.wic): + wic: + graphviz: + label: 'Add Water\nSolvent' \ No newline at end of file diff --git a/examples/gromacs/solv_ion.wic b/examples/gromacs/solv_ion.wic index 7f4e680..483a1b0 100644 --- a/examples/gromacs/solv_ion.wic +++ b/examples/gromacs/solv_ion.wic @@ -1,39 +1,46 @@ +inputs: + top_zip_path: + type: File + format: + - edam:format_3987 + steps: - editconf: - in: - config: !ii - box_type: cubic - distance_to_molecule: 1.0 - solvate: - in: - input_top_zip_path: !* complex_vac.zip - out: - - output_crd_path: !& solvate.gro - - output_top_zip_path: !& solvate.zip - grompp: - in: - input_crd_path: !* solvate.gro - input_top_zip_path: !* solvate.zip - config: !ii - maxwarn: 1 # net charge != 0 - mdp: - integrator: steep - genion: - in: - config: !ii - neutral: True - out: - - output_top_zip_path: !& genion.zip + gmx_editconf: + in: + #input_crd_path: crd_path + align_principal_axes: !ii 0 + box_type: !ii cubic + distance_to_molecule: !ii 1.2 + solvate: + in: + input_top_zip_path: top_zip_path + out: + - output_crd_path: !& solvate.gro + - output_top_zip_path: !& solvate.zip + grompp: + in: + input_crd_path: !* solvate.gro + input_top_zip_path: !* solvate.zip + config: !ii + maxwarn: 1 # net charge != 0 + mdp: + integrator: steep + genion: + in: + config: !ii + neutral: True + out: + - output_top_zip_path: !& genion.zip # Use &filename to create a reference to an output. Inputs in later steps can # use *filename to dereference the filename and create an explicit edge. wic: graphviz: label: Solvation & Ionization ranksame: - - (1, editconf) + - (1, gmx_editconf) - (4, genion) steps: - (1, editconf): + (1, gmx_editconf): wic: graphviz: label: 'Initialize\nPeriodic Box' diff --git a/examples/gromacs/stability.wic b/examples/gromacs/stability.wic index 2c87569..6e97aef 100644 --- a/examples/gromacs/stability.wic +++ b/examples/gromacs/stability.wic @@ -18,17 +18,18 @@ inputs: - edam:format_3987 steps: - setup.wic: - in: - crd_path: crd_path - top_zip_path: top_zip_path - basic.wic: - in: - nsteps: nsteps - dt: dt - ref-t: temperature - ref-p: pressure - analysis.wic: + setup_vac_min.wic: + in: + crd_path: crd_path + top_zip_path: top_zip_path + basic.wic: + in: + top_zip_path: !* genion.zip + nsteps: nsteps + dt: dt + ref-t: temperature + ref-p: pressure + analysis.wic: wic: graphviz: diff --git a/examples/gromacs/steep.wic b/examples/gromacs/steep.wic index e64aeed..9d0eb9c 100644 --- a/examples/gromacs/steep.wic +++ b/examples/gromacs/steep.wic @@ -1,34 +1,41 @@ +inputs: + top_zip_path: + type: File + format: + - edam:format_3987 + # On my machine, 10 iterations of steepest descent is sufficient to prevent # conjugate gradient from crashing. (i.e. pytest works for me!) # But using only 10 iterations is causing the tests on github actions to fail! # 25 seems to work, but let's just set it to 100. steps: - grompp: - in: - config: !ii - mdp: - integrator: steep - rvdw: 1.4 - rcoulomb: 1.4 - #coulombtype: PME - nsteps: 1000 - emstep: 0.0001 - emtol: 100 - nstxout: 100 - nstenergy: 1 - mdrun: - in: - nb_terms: !ii cpu # NOTE: Workaround for a bug in gromacs 2022.2, fixed in 2022.3 - # https://manual.gromacs.org/current/release-notes/2022/2022.3.html#energy-minimization-would-not-converge-with-gpu-and-without-dd - bonded_terms: !ii cpu # GPU implementation IS supported for md integrator, is NOT supported for sd integrator, etc. - pme_terms: !ii cpu - pme_fft_terms: !ii cpu - update_terms: !ii cpu - gmx_energy: - in: - config: !ii - terms: [Potential] - output_xvg_path: !ii energy_min_steep.xvg + grompp: + in: + input_top_zip_path: top_zip_path + config: !ii + mdp: + integrator: steep + rvdw: 1.4 + rcoulomb: 1.4 + #coulombtype: PME + nsteps: 1000 + emstep: 0.0001 + emtol: 100 + nstxout: 100 + nstenergy: 1 + mdrun: + in: + nb_terms: !ii cpu # NOTE: Workaround for a bug in gromacs 2022.2, fixed in 2022.3 + # https://manual.gromacs.org/current/release-notes/2022/2022.3.html#energy-minimization-would-not-converge-with-gpu-and-without-dd + bonded_terms: !ii cpu # GPU implementation IS supported for md integrator, is NOT supported for sd integrator, etc. + pme_terms: !ii cpu + pme_fft_terms: !ii cpu + update_terms: !ii cpu + gmx_energy: + in: + config: !ii + terms: [Potential] + output_xvg_path: !ii energy_min_steep.xvg wic: graphviz: diff --git a/examples/gromacs/topology.wic b/examples/gromacs/topology.wic index cc1727f..2b81095 100644 --- a/examples/gromacs/topology.wic +++ b/examples/gromacs/topology.wic @@ -1,15 +1,22 @@ +inputs: + crd_path: + type: File + format: + - edam:format_1476 + - edam:format_2033 + steps: # We want to perform vacuum minimization first, before solvation and ionization. # NOTE: Gromacs no longer supports non-periodic boundary conditions (!!!), # so we must emulate a vacuum by using a very large (1000 Angstrom) box. - editconf: - in: - input_crd_path: !* complex_vac.pdb - config: !ii - box_type: cubic - distance_to_molecule: 100.0 - out: - - output_crd_path: !& complex_box.g96 + editconf: + in: + input_crd_path: crd_path + config: !ii + box_type: cubic + distance_to_molecule: 100.0 + out: + - output_crd_path: !& complex_box.g96 wic: graphviz: diff --git a/examples/gromacs/tutorial.wic b/examples/gromacs/tutorial.wic index 3e13bf2..31918c8 100644 --- a/examples/gromacs/tutorial.wic +++ b/examples/gromacs/tutorial.wic @@ -1,15 +1,15 @@ # This is based on the excellent gromacs CWL tutorial # https://mmb.irbbarcelona.org/biobb/availability/tutorials/cwl steps: - modeling.wic: - stability.wic: - in: - crd_path: !* complex_vac.pdb - top_zip_path: !* complex_vac.zip - nsteps: !ii 100000 - dt: !ii 0.002 - temperature: !ii 298.0 - pressure: !ii 1.0 + modeling.wic: + stability.wic: + in: + crd_path: !* complex_vac.pdb + top_zip_path: !* complex_vac.zip + nsteps: !ii 100000 + dt: !ii 0.002 + temperature: !ii 298.0 + pressure: !ii 1.0 wic: graphviz: diff --git a/examples/scripts/Dockerfile_combine_structure b/examples/scripts/Dockerfile_combine_structure index b8c746d..8225821 100644 --- a/examples/scripts/Dockerfile_combine_structure +++ b/examples/scripts/Dockerfile_combine_structure @@ -1,7 +1,7 @@ FROM condaforge/mambaforge # NOT mambaforge-pypy3 (rdkit is incompatible with pypy) -RUN mamba install -c conda-forge rdkit +RUN mamba install -c conda-forge rdkit mdanalysis gromacs ADD combine_structure.py . ADD Dockerfile_combine_structure . \ No newline at end of file diff --git a/examples/scripts/combine_structure.py b/examples/scripts/combine_structure.py index f16ed70..516f0f1 100644 --- a/examples/scripts/combine_structure.py +++ b/examples/scripts/combine_structure.py @@ -1,9 +1,15 @@ import sys import os +import zipfile import argparse from typing import Optional from rdkit import Chem +import MDAnalysis as mda + + +GROMACS_INCLUDE_PATH = os.path.realpath('/opt/conda/share/gromacs/top') +TEMP_PATH = os.path.realpath('./') def parse_arguments() -> argparse.Namespace: @@ -15,6 +21,7 @@ def parse_arguments() -> argparse.Namespace: parser = argparse.ArgumentParser() parser.add_argument('--input_structure1', required=True) parser.add_argument('--input_structure2', required=True) + parser.add_argument('--input_top_zip_path', required=True) parser.add_argument('--output_structure_path', required=True) args = parser.parse_args() return args @@ -38,22 +45,43 @@ def read_xyz_rdkit(input_structure_path: str) -> Optional[Chem.rdchem.Mol]: # p return xyz -def combine_structure_rdkit(input_structure1_path: str, input_structure2_path: str, output_structure_path: str) -> None: - """ Combine two structures into a single PDB file using RDKit +def fix_atom_names(input_top_zip_path: str, output_structure_path: str) -> None: + """ Modifies the atom names based on the topology file Args: - input_structure1_path (str): The path to the xyz structure 1 - input_structure2_path (str): The path to the xyz structure 2 + input_top_zip_path (str): The path to the input zip file output_structure_path (str): The path to the output combined structure """ + with zipfile.ZipFile(input_top_zip_path, "r") as zip_read: + zip_read.extractall(path=TEMP_PATH) + + file_list = [str(os.path.join(TEMP_PATH, f)) for f in zip_read.namelist()] + top_file = next(name for name in file_list if name.endswith(".top")) + + u1 = mda.Universe(top_file, topology_format='ITP', include_dir=GROMACS_INCLUDE_PATH) + u2 = mda.Universe(os.path.join(TEMP_PATH, 'temp_out.pdb')) + + u2.atoms.names = u1.atoms.names + all_atoms = u2.select_atoms("all") + all_atoms.write(output_structure_path) + + +def combine_structure_rdkit(input_structure1_path: str, input_structure2_path: str) -> None: + """ Combine two structures into a single PDB file using RDKit and saves it in the temporary PDB file + + Args: + input_structure1_path (str): The path to the xyz structure 1 + input_structure2_path (str): The path to the xyz structure 2 + """ + structure1 = read_xyz_rdkit(input_structure1_path) structure2 = read_xyz_rdkit(input_structure2_path) if structure1 and structure2: combo = Chem.CombineMols(structure1, structure2) # pylint: disable=no-member - with Chem.PDBWriter(output_structure_path) as writer: # pylint: disable=no-member + with Chem.PDBWriter(os.path.join(TEMP_PATH, 'temp_out.pdb')) as writer: writer.write(combo) @@ -70,7 +98,8 @@ def main() -> None: print(f'Error: Can not find file {args.input_structure2}') sys.exit(1) - combine_structure_rdkit(args.input_structure1, args.input_structure2, args.output_structure_path) + combine_structure_rdkit(args.input_structure1, args.input_structure2) + fix_atom_names(args.input_top_zip_path, args.output_structure_path) if __name__ == '__main__':