From 3bdeeba6052778d0ea7f4fc563d8879e03da637e Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:20:03 -0500 Subject: [PATCH 1/8] links fixed --- docs/introduction.md | 53 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/docs/introduction.md b/docs/introduction.md index e4cdcf56..3cae18df 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -35,39 +35,40 @@ bound state. On the other hand, in the so-called Multiple Trajectory (MT) approx of the species (_i.e._ complex, receptor, and ligand) are extracted from their own trajectory file. This approximation, theoretically more rigorous though, leads to higher standard deviation of the binding free energies. - [1]: https://pubs.acs.org/doi/10.1021/ct300418h - [2]: https://pubs.acs.org/doi/abs/10.1021/jacs.6b02682 ## Literature -Further information can be found in [Amber manual][1]: +Further information can be found in [Amber manual][3]: -* [MMPBSA.py][2] -* [The Generalized Born/Surface Area Model][3] -* [PBSA][4] -* [Reference Interaction Site Model][5] -* [Generalized Born (GB) for QM/MM calculations][6] +* [MMPBSA.py][4] +* [The Generalized Born/Surface Area Model][5] +* [PBSA][6] +* [Reference Interaction Site Model][7] +* [Generalized Born (GB) for QM/MM calculations][8] and the foundational papers: -* [Srinivasan J. et al., 1998][7] -* [Kollman P. A. et al., 2000][8] -* [Gohlke H., Case D. A. 2004][9] +* [Srinivasan J. et al., 1998][9] +* [Kollman P. A. et al., 2000][10] +* [Gohlke H., Case D. A. 2004][11] as well as some reviews: -* [Genheden S., Ryde U. 2015][10] -* [Wang et. al., 2018][11] -* [Wang et. al., 2019][12] +* [Genheden S., Ryde U. 2015][12] +* [Wang et. al., 2018][13] +* [Wang et. al., 2019][14] + + [1]: https://pubs.acs.org/doi/10.1021/ct300418h + [2]: https://pubs.acs.org/doi/abs/10.1021/jacs.6b02682 - [1]: https://ambermd.org/doc12/Amber20.pdf - [2]: https://ambermd.org/doc12/Amber20.pdf#chapter.34 - [3]: https://ambermd.org/doc12/Amber20.pdf#chapter.4 - [4]: https://ambermd.org/doc12/Amber20.pdf#chapter.6 - [5]: https://ambermd.org/doc12/Amber20.pdf#chapter.7 - [6]: https://ambermd.org/doc12/Amber20.pdf#subsection.10.1.3 - [7]: https://pubs.acs.org/doi/abs/10.1021/ja981844+ - [8]: https://pubs.acs.org/doi/abs/10.1021/ar000033j - [9]: https://onlinelibrary.wiley.com/doi/abs/10.1002/jcc.10379 - [10]: https://www.tandfonline.com/doi/full/10.1517/17460441.2015.1032936 - [11]: https://www.frontiersin.org/articles/10.3389/fmolb.2017.00087/full - [12]: https://pubs.acs.org/doi/abs/10.1021/acs.chemrev.9b00055 \ No newline at end of file + [3]: https://ambermd.org/doc12/Amber20.pdf + [4]: https://ambermd.org/doc12/Amber20.pdf#chapter.34 + [5]: https://ambermd.org/doc12/Amber20.pdf#chapter.4 + [6]: https://ambermd.org/doc12/Amber20.pdf#chapter.6 + [7]: https://ambermd.org/doc12/Amber20.pdf#chapter.7 + [8]: https://ambermd.org/doc12/Amber20.pdf#subsection.10.1.3 + [9]: https://pubs.acs.org/doi/abs/10.1021/ja981844+ + [10]: https://pubs.acs.org/doi/abs/10.1021/ar000033j + [11]: https://onlinelibrary.wiley.com/doi/abs/10.1002/jcc.10379 + [12]: https://www.tandfonline.com/doi/full/10.1517/17460441.2015.1032936 + [13]: https://www.frontiersin.org/articles/10.3389/fmolb.2017.00087/full + [14]: https://pubs.acs.org/doi/abs/10.1021/acs.chemrev.9b00055 \ No newline at end of file From 314a439feb656eef7b6d4cf4e9bc3ebe21e39ae7 Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:20:36 -0500 Subject: [PATCH 2/8] Output for Interaction Entropy calculation --- GMXMMPBSA/amber_outputs.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/GMXMMPBSA/amber_outputs.py b/GMXMMPBSA/amber_outputs.py index 884632ef..bbc21ae1 100644 --- a/GMXMMPBSA/amber_outputs.py +++ b/GMXMMPBSA/amber_outputs.py @@ -371,6 +371,38 @@ def fill_composite_terms(self): #-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- +class IEout(object): + """ + Interaction Entropy output + """ + def __init__(self, edata, value, frames, ie_frames, key): + self.data = edata + self.value = value + self.frames = frames + self.ieframes = ie_frames + self.key = key + + def print_summary_csv(self, csvwriter): + """ Output summary of quasi-harmonic results in CSV format """ + csvwriter.writerow([f'Iteration Entropy calculation for {self.key.upper()} from last {self.ieframes} frames...']) + csvwriter.writerow(['Iteration Entropy:', '{:.2f}'.format(self.value)]) + + def print_vectors(self, csvwriter): + """ Prints the energy vectors to a CSV file for easy viewing + in spreadsheets + """ + csvwriter.writerow(['Frame #', 'Interaction Entropy']) + for f, d in zip(self.frames, self.edata): + csvwriter.writerow([f] + [d]) + + def print_summary(self): + """ Formatted summary of quasi-harmonic results """ + ret_str = (f'Iteration Entropy calculation for {self.key.upper()} from last {self.ieframes} frames...\n') + ret_str += 'Iteration Entropy: {:.2f}\n'.format(self.value) + return ret_str + +#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + class QHout(object): """ Quasi-harmonic output file class. QH output files are strange so we won't derive from AmberOutput From ce685891019a3595d1ac8e3b6effa3db8cf3ad6e Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:21:03 -0500 Subject: [PATCH 3/8] new class for IE calculation --- GMXMMPBSA/calculation.py | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/GMXMMPBSA/calculation.py b/GMXMMPBSA/calculation.py index 258202a7..c02913e2 100644 --- a/GMXMMPBSA/calculation.py +++ b/GMXMMPBSA/calculation.py @@ -37,6 +37,8 @@ from GMXMMPBSA.exceptions import GMXMMPBSA_ERROR import os import sys +import numpy as np +import math #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -549,3 +551,58 @@ def run(self, rank, stdout=sys.stdout, stderr=sys.stderr): if rank == 0: stdout.write(self.message + '\n') #+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +class InteractionEntropyCalc: + """ + Class for Interaction Entropy calculation + :return {IE_key: data} + """ + def __init__(self, ggas, key, INPUT, output): + self.ggas = ggas + self.key = key + self.INPUT = INPUT + self.output = output + self.data = {} + + self._calculate() + self.save_output() + + def _calculate(self): + # gases constant in kcal/mol + k = 0.001987 + energy_int = np.array([], dtype=np.float) + a_energy_int = np.array([], dtype=np.float) + d_energy_int = np.array([], dtype=np.float) + exp_energy_int = np.array([], dtype=np.float) + ts = np.array([], dtype=np.float) + + for eint in self.ggas: + energy_int = np.append(energy_int, eint) + aeint = energy_int.mean() + a_energy_int = np.append(a_energy_int, aeint) + deint = eint - aeint + d_energy_int = np.append(d_energy_int, deint) + eceint = math.exp(deint / (k * self.INPUT['entropy_temp'])) + exp_energy_int = np.append(exp_energy_int, eceint) + aeceint = exp_energy_int.mean() + cts = k * self.INPUT['entropy_temp'] * math.log(aeceint) + ts = np.append(ts, cts) + self.IntEnt = ts + self.data['IE_' + self.key] = self.IntEnt + nframes = len(self.IntEnt) + self.ie_frames = math.ceil(nframes * (self.INPUT['entropy_seg'] / 100)) + self.value = self.IntEnt[self.ie_frames:].mean() + self.frames = [x for x in range(self.INPUT['startframe'], self.INPUT['endframe'] + self.INPUT['interval'], + self.INPUT['interval'])] + + def save_output(self): + with open(self.output, 'w') as out: + out.write(f'Calculation for last {self.ie_frames} frames:\n') + out.write(f'Interaction Entropy: {self.value}\n\n') + out.write(f'Interaction Entropy per-frame:\n') + + out.write('Frame # | IE value\n') + for f, d in zip(self.frames, self.IntEnt): + out.write('{:d} {:.2f}\n'.format(f,d)) + +#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ From 7633229eac818fff7e5ad7bca255ee8a0e5e6ebe Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:21:29 -0500 Subject: [PATCH 4/8] code refactor --- GMXMMPBSA/main.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/GMXMMPBSA/main.py b/GMXMMPBSA/main.py index e4a58864..08bff65f 100644 --- a/GMXMMPBSA/main.py +++ b/GMXMMPBSA/main.py @@ -32,14 +32,11 @@ import logging # Import gmx_MMPBSA modules from GMXMMPBSA import utils -from GMXMMPBSA.amber_outputs import (QHout, NMODEout, QMMMout, GBout, PBout, - PolarRISM_std_Out, RISM_std_Out, - PolarRISM_gf_Out, RISM_gf_Out, - SingleTrajBinding, MultiTrajBinding) -from GMXMMPBSA.calculation import (CalculationList, EnergyCalculation, - PBEnergyCalculation, RISMCalculation, - NmodeCalc, QuasiHarmCalc, CopyCalc, - PrintCalc, LcpoCalc, MolsurfCalc) +from GMXMMPBSA.amber_outputs import (QHout, NMODEout, QMMMout, GBout, PBout, PolarRISM_std_Out, RISM_std_Out, + PolarRISM_gf_Out, RISM_gf_Out, SingleTrajBinding, MultiTrajBinding, IEout) +from GMXMMPBSA.calculation import (CalculationList, EnergyCalculation, PBEnergyCalculation, RISMCalculation, + NmodeCalc, QuasiHarmCalc, CopyCalc, PrintCalc, LcpoCalc, MolsurfCalc, + InteractionEntropyCalc) from GMXMMPBSA.commandlineparser import parser from GMXMMPBSA.createinput import create_inputs from GMXMMPBSA.exceptions import (MMPBSA_Error, InternalError, InputError, GMXMMPBSA_ERROR) @@ -48,9 +45,7 @@ from GMXMMPBSA.infofile import InfoFile from GMXMMPBSA.input_parser import input_file as _input_file from GMXMMPBSA.make_trajs import make_trajectories, make_mutant_trajectories -from GMXMMPBSA.output_file import (write_stability_output, - write_binding_output, - write_decomp_stability_output, +from GMXMMPBSA.output_file import (write_stability_output, write_binding_output, write_decomp_stability_output, write_decomp_binding_output) from GMXMMPBSA.parm_setup import MMPBSA_System from GMXMMPBSA.make_top import CheckMakeTop From b8855f45a9a3fa2c0511deaeca50b6370d5367c7 Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:22:00 -0500 Subject: [PATCH 5/8] fuction to calculate IE removed --- GMXMMPBSA/main.py | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/GMXMMPBSA/main.py b/GMXMMPBSA/main.py index 08bff65f..f61c150f 100644 --- a/GMXMMPBSA/main.py +++ b/GMXMMPBSA/main.py @@ -910,39 +910,6 @@ def sync_mpi(self): """ Throws up a barrier """ self.MPI.COMM_WORLD.Barrier() - def calculate_interaction_entropy(self, key, mutant=False): - """ - Calculate the interaction entropy described FIXME: article - :param key: - :return: - """ - # gases constant in kcal/mol - k = 0.001987 - if mutant: - calc_types = self.calc_types['mutant'] - else: - calc_types = self.calc_types - energy_int = np.array([], dtype=np.float) - a_energy_int = np.array([], dtype=np.float) - d_energy_int = np.array([], dtype=np.float) - exp_energy_int = np.array([], dtype=np.float) - ts = np.array([], dtype=np.float) - - ggas = calc_types[key]['delta'].data['DELTA G gas'] - - for eint in ggas: - energy_int = np.append(energy_int, eint) - aeint = energy_int.mean() - a_energy_int = np.append(a_energy_int, aeint) - deint = eint - aeint - d_energy_int = np.append(d_energy_int, deint) - eceint = exp(deint / (k * self.INPUT['entropy_temp'])) - exp_energy_int = np.append(exp_energy_int, eceint) - aeceint = exp_energy_int.mean() - cts = k * self.INPUT['entropy_temp'] * log(aeceint) - ts = np.append(ts, cts) - calc_types[key]['delta'].data['-TDS'] = ts - def parse_output_files(self): """ This parses the output files and loads them into dicts for easy access @@ -958,11 +925,9 @@ def parse_output_files(self): # Quasi-harmonic analysis is a special-case, so handle that separately if INPUT['entropy'] == 1: if not INPUT['mutant_only']: - self.calc_types['qh'] = QHout(self.pre + 'cpptraj_entropy.out', - INPUT['temp']) + self.calc_types['qh'] = QHout(self.pre + 'cpptraj_entropy.out', INPUT['temp']) if INPUT['alarun']: - self.calc_types['mutant']['qh'] = QHout(self.pre + - 'mutant_cpptraj_entropy.out', INPUT['temp']) + self.calc_types['mutant']['qh'] = QHout(self.pre + 'mutant_cpptraj_entropy.out', INPUT['temp']) # Set BindingClass based on whether it's a single or multiple trajectory # analysis if self.traj_protocol == 'STP': From c0f7e4f9fcac1e9e52cb53a2d0720b8246e5c3f0 Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:29:02 -0500 Subject: [PATCH 6/8] fixed IE calculation --- GMXMMPBSA/main.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/GMXMMPBSA/main.py b/GMXMMPBSA/main.py index f61c150f..6b2cd4ad 100644 --- a/GMXMMPBSA/main.py +++ b/GMXMMPBSA/main.py @@ -977,8 +977,11 @@ def parse_output_files(self): self.calc_types[key]['ligand'], self.INPUT['verbose'], self.using_chamber) - if self.INPUT['entropy'] == 2: - self.calculate_interaction_entropy(key) + if self.INPUT['entropy'] == 2 and key != 'nmode': + edata = self.calc_types[key]['delta'].data['DELTA G gas'] + ie = InteractionEntropyCalc(edata, key, self.INPUT, self.pre + 'iteraction_entropy.dat') + self.calc_types['ie'] = IEout(ie.data, ie.value, ie.frames, ie.ie_frames, key) + # self.calc_types[self.key]['delta'].data['DELTA G gas'] else: self.calc_types[key]['complex'].fill_composite_terms() # Time for mutant @@ -998,8 +1001,10 @@ def parse_output_files(self): self.calc_types['mutant'][key]['receptor'], self.calc_types['mutant'][key]['ligand'], self.INPUT['verbose'], self.using_chamber) - if self.INPUT['entropy'] == 2: - self.calculate_interaction_entropy(key, mutant=True) + if self.INPUT['entropy'] == 2 and key != 'nmode': + edata = self.calc_types['mutant'][key]['delta'].data['DELTA G gas'] + mie = InteractionEntropyCalc(edata, key, self.INPUT, self.pre + 'mutant_iteraction_entropy.dat') + self.calc_types['mutant']['ie'] = IEout(mie.data, mie.value, mie.frames, mie.ie_frames, key) else: self.calc_types['mutant'][key]['complex'].fill_composite_terms() From 8aec6f1cc13785adbab1d492238431644c89d7b2 Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:30:27 -0500 Subject: [PATCH 7/8] added IE to gmx_MMPBSA output file --- GMXMMPBSA/output_file.py | 58 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/GMXMMPBSA/output_file.py b/GMXMMPBSA/output_file.py index 6c224d83..46abb643 100644 --- a/GMXMMPBSA/output_file.py +++ b/GMXMMPBSA/output_file.py @@ -279,6 +279,10 @@ def write_binding_output(app): if INPUT['nmoderun']: final_output.add_comment('NMODE calculations performed using %s frames.' % app.numframes_nmode) + if INPUT['entropy'] == 2: + final_output.add_comment('Interaction Entropy calculations performed using last %s frames.' % + ceil(app.numframes * (INPUT['entropy_seg']/100))) + if INPUT['pbrun']: if INPUT['sander_apbs']: @@ -318,20 +322,32 @@ def write_binding_output(app): if INPUT['entropy'] == 1: if not INPUT['mutant_only']: qhnorm = app.calc_types['qh'] - final_output.writeline('ENTROPY RESULTS (QUASI-HARMONIC ' - 'APPROXIMATION) CALCULATED WITH PTRAJ:') + final_output.writeline('ENTROPY RESULTS (QUASI-HARMONIC APPROXIMATION) CALCULATED WITH PTRAJ:') final_output.add_section(qhnorm.print_summary()) if INPUT['alarun']: qhmutant = app.calc_types['mutant']['qh'] final_output.writeline(mut_str + ' MUTANT') - final_output.writeline('ENTROPY RESULTS (QUASI-' + - 'HARMONIC APPROXIMATION) CALCULATED WITH PTRAJ:') + final_output.writeline('ENTROPY RESULTS (QUASI-HARMONIC APPROXIMATION) CALCULATED WITH PTRAJ:') final_output.add_section(qhmutant.print_summary()) if INPUT['alarun'] and not INPUT['mutant_only']: final_output.add_section(('\nRESULT OF ALANINE SCANNING: (%s) DELTA ' + 'DELTA S binding = %9.4f\n') % (mut_str, qhnorm.total_avg() - qhmutant.total_avg())) # end if INPUT['entropy'] + if INPUT['entropy'] == 2: + if not INPUT['mutant_only']: + ienorm = app.calc_types['ie'] + final_output.writeline('ENTROPY RESULTS (INTERACTION ENTROPY):') + final_output.add_section(ienorm.print_summary()) + if INPUT['alarun']: + iemutant = app.calc_types['mutant']['ie'] + final_output.writeline(mut_str + ' MUTANT') + final_output.writeline('ENTROPY RESULTS (INTERACTION ENTROPY):') + final_output.add_section(iemutant.print_summary()) + if INPUT['alarun'] and not INPUT['mutant_only']: + final_output.add_section(('\nRESULT OF ALANINE SCANNING: (%s) DELTA ' + + 'DELTA S binding = %9.4f\n') % (mut_str, ienorm.value - iemutant.value)) + # Now print out the normal mode results if INPUT['nmoderun']: @@ -396,24 +412,18 @@ def write_binding_output(app): 'Approximation: DELTA G binding = %9.4f\n' % (sys_norm.data['DELTA TOTAL'][0] - qhnorm.total_avg())) elif INPUT['entropy'] == 2: - b = 0 - if len(sys_norm.data['-TDS']) * app.INPUT['entropy_seg']/100 > 1: - b = ceil(len(sys_norm.data['-TDS']) * (1 - app.INPUT['entropy_seg']/100)) - norm_ts = sys_norm.data['-TDS'][b:].mean() if isinstance(sys_norm.data['DELTA TOTAL'], EnergyVector): - final_output.add_section('Interaction Entropy (-TDS): %9.4f\n' % norm_ts + - 'Using Interaction Entropy ' + + final_output.add_section('Using Interaction Entropy ' + 'Approximation: DELTA G binding = %9.4f\n' % - (sys_norm.data['DELTA TOTAL'].avg() + norm_ts)) + (sys_norm.data['DELTA TOTAL'].avg() + ienorm.value)) else: - final_output.add_section('Interaction Entropy (-TDS): %9.4f\n' % norm_ts + - 'Using Interaction Entropy ' + + final_output.add_section('Using Interaction Entropy ' + 'Approximation: DELTA G binding = %9.4f\n' % - (sys_norm.data['DELTA TOTAL'][0] + norm_ts)) + (sys_norm.data['DELTA TOTAL'][0] + ienorm.value)) if INPUT['nmoderun']: davg, dstdev = sys_norm.diff(nm_sys_norm, 'DELTA TOTAL', 'Total') - final_output.add_section('Using Normal Mode Entropy Approxima' + - 'tion: DELTA G binding = %9.4f +/- %7.4f\n' % (davg, dstdev)) + final_output.add_section('Using Normal Mode Entropy ' + 'Approximation: DELTA G binding = %9.4f +/- %7.4f\n' % (davg, dstdev)) if INPUT['alarun']: sys_mut = app.calc_types['mutant'][key]['delta'] @@ -436,20 +446,14 @@ def write_binding_output(app): 'Approximation: DELTA G binding = %9.4f\n' % (sys_mut.data['DELTA TOTAL'][0] - qhmutant.total_avg())) elif INPUT['entropy'] == 2: - b = 0 - if len(sys_mut.data['-TDS']) * app.INPUT['entropy_seg']/100 > 1: - b = ceil(len(sys_mut.data['-TDS']) * app.INPUT['entropy_seg']/100 > 1) - mut_ts = sys_mut.data['-TDS'][b:].mean() if isinstance(sys_mut.data['DELTA TOTAL'], EnergyVector): - final_output.add_section('Interaction Entropy (-TDS): %9.4f\n' % mut_ts + - 'Using Interaction Entropy ' + + final_output.add_section('Using Interaction Entropy ' + 'Approximation: DELTA G binding = %9.4f\n' % - (sys_mut.data['DELTA TOTAL'].avg() + mut_ts)) + (sys_mut.data['DELTA TOTAL'].avg() + iemutant.value)) else: - final_output.add_section('Interaction Entropy (-TDS): %9.4f\n' % mut_ts + - 'Using Interaction Entropy ' + + final_output.add_section('Using Interaction Entropy ' + 'Approximation: DELTA G binding = %9.4f\n' % - (sys_mut.data['DELTA TOTAL'][0] + mut_ts)) + (sys_mut.data['DELTA TOTAL'][0] + iemutant.value)) if INPUT['nmoderun']: davg, dstdev = sys_mut.diff(nm_sys_mut, 'DELTA TOTAL', 'Total') final_output.add_section('Using Normal Mode Entropy Approxima' + @@ -465,7 +469,7 @@ def write_binding_output(app): davg + qhnorm.total_avg() - qhmutant.total_avg())) elif INPUT['entropy'] == 2: final_output.write(('\n (interaction entropy) (%s) DELTA ' + - 'DELTA G binding = %9.4f\n') % (mut_str, davg + norm_ts - mut_ts)) + 'DELTA G binding = %9.4f\n') % (mut_str, davg + ienorm.value - iemutant.value)) if INPUT['nmoderun']: davg1, dstdev1 = nm_sys_norm.diff(nm_sys_mut, 'Total', 'Total') final_output.write(('\n (normal mode entropy) (%s) DELTA ' + From e6e665252f090107f823f1b6c296e53f17ecd68b Mon Sep 17 00:00:00 2001 From: MARIO Date: Mon, 1 Mar 2021 01:31:40 -0500 Subject: [PATCH 8/8] Error when ligand and/or receptor are discontinuous and non-consecutive numbered --- GMXMMPBSA/make_top.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/GMXMMPBSA/make_top.py b/GMXMMPBSA/make_top.py index dc2b1342..19761bde 100644 --- a/GMXMMPBSA/make_top.py +++ b/GMXMMPBSA/make_top.py @@ -98,13 +98,6 @@ def __init__(self, FILES, INPUT, external_programs): self.receptor_str_file = self.FILES.prefix + 'REC.pdb' self.ligand_str_file = self.FILES.prefix + 'LIG.pdb' - self.rec_ions_pdb = self.FILES.prefix + 'REC_IONS.pdb' - self.lig_ions_pdb = self.FILES.prefix + 'LIG_IONS.pdb' - - self.mutant_complex_pdb = self.FILES.prefix + 'MUT_COM.pdb' - self.mutant_receptor_pdb = self.FILES.prefix + 'MUT_REC.pdb' - self.mutant_ligand_pdb = self.FILES.prefix + 'MUT_LIG.pdb' - if self.FILES.reference_structure: self.ref_str = parmed.read_PDB(self.FILES.reference_structure) @@ -598,30 +591,31 @@ def res2map(self): res_list = {'REC': [], 'LIG': []} com_ndx = ndx['GMXMMPBSA_REC_GMXMMPBSA_LIG'] com_len = len(ndx['GMXMMPBSA_REC_GMXMMPBSA_LIG']) - dif = 0 + resnum = 1 + current_res = None for i in range(com_len): - if i == 0: - dif = com_str.atoms[i].residue.number - 1 # AMBER mask must be start at 1 # We check who owns the residue corresponding to this atom if com_ndx[i] in ndx['GMXMMPBSA_REC']: current = 'R' # save residue number in the rec list - resnum = com_str.atoms[i].residue.number - dif - if not resnum in res_list['REC']: + if com_str.atoms[i].residue.number != current_res and not resnum in res_list['REC']: res_list['REC'].append(resnum) + resnum += 1 + current_res = com_str.atoms[i].residue.number else: current = 'L' # save residue number in the lig list - resnum = com_str.atoms[i].residue.number - dif - if not resnum in res_list['LIG']: + if com_str.atoms[i].residue.number != current_res and not resnum in res_list['LIG']: res_list['LIG'].append(resnum) + resnum += 1 + current_res = com_str.atoms[i].residue.number # check for end if previous and current != previous: - end = com_str.atoms[i-1].residue.number - dif + end = resnum - 2 # when i is the last index if i == com_len - 1: - end = com_str.atoms[i].residue.number - dif + end = resnum - 1 if end: if previous == 'R': masks['REC'].append([start, end])