def _body(self, args): results = self.calculate(subset=(args.lower_bound, args.upper_bound)) keys = ('raw', 'mbar', 'umbrella') # plot titration curves and fitted models self.figures['titration'], ax = plt.subplots() for key in keys: line = results[key].occupancies.plot(ax, fmt='o', show_error=False) results[key].model.plot(ax, color=line.get_color(), label=key, xlabel='B Value', ylabel='Occupancy') ax.legend(loc='best') # plot insertion_pmfs self.figures['insertion_pmf'], ax = plt.subplots() for key in keys: results[key].insertion_pmf.plot(ax, label=key, xlabel='Occupancy') ax.legend(loc='best') # print out binding free energies in table format for key in keys: table = fe.Table( key.upper(), fmts=['%d', '%.3f'], headers=['Number of Waters', 'Binding Free Energy']) for i, dA in enumerate(results[key].insertion_pmf): table.add_row([i, dA]) self.tables.append(table) return results
def state_data_table(results, directories, signs, states, estimator): """Returns a Table object containing the free energy differences for the individual states i.e. bound, free and gas. Parameters ---------- results: dict such that results[root][state][estimator] = Result object The free energy results to tabulate directories: list of strings List of root directories containing calculation data signs: list of '+' or '-' The signs to use when calculating the free energy cycle states: list of strings The thermodynamic states simulated estimator: Estimator Class The estimator to tabulate results of """ table = fe.Table(estimator.__name__, fmts=["%s:", "%.3f", "%.3f", "%.3f"], headers=['', 'dG gas', 'dG free', 'dG bound']) closures = {state: fe.Quantity(0., 0.) for state in states} for root, sign in zip(directories, signs): root_dGs = (root, ) for state in states: dG = results[root][state][estimator] root_dGs += (dG, ) if sign == '+': closures[state] += dG else: closures[state] -= dG table.add_row(root_dGs) table.add_row(['Cycle Closure'] + [closures[state] for state in states]) return table
def solv_bind_table(dG_solvs, dG_binds, directories, signs, estimator): """Returns a Table object containing free energies of solvation and binding. Parameters ---------- dG_solvs: dictionary[root][estimator] = Result object Calculated solvation free energy results dG_binds: dictionary[root][estimator] = Result object Calculated binding free energy results directories: list of strings List of root directories containing calculation data signs: list of '+' or '-' The signs to use when calculating the free energy cycle estimator: Estimator Class The estimator to tabulate results of """ table = fe.Table('', fmts=["%s:", "%.3f", "%.3f"], headers=['', 'ddG Solvation', 'ddG Binding']) closure_solv = fe.Quantity(0., 0.) closure_bind = fe.Quantity(0., 0.) for root, sign in zip(directories, signs): dG_solv = dG_solvs[root][estimator] dG_bind = dG_binds[root][estimator] table.add_row([root, dG_solv, dG_bind]) if sign == '+': closure_solv += dG_solv closure_bind += dG_bind else: closure_solv -= dG_solv closure_bind -= dG_bind table.add_row(["Cycle Closure", closure_solv, closure_bind]) return table
def _body(self, args): """Calculation business logic. Parameters ---------- args: argparse.Namespace object Namespace from argumentparser """ subset = (args.lower_bound, args.upper_bound) results = self.calculate(subset=subset) decomp = results[TI_decomposed] if (args.bound or args.gas) is not None: calc2 = DecomposedCalculation(args.bound or args.gas) results2 = calc2.calculate(subset=subset) decomp2 = results2[TI_decomposed] # iterate over the unique keys from both calc and calc2 for term in set(chain(decomp, decomp2)): try: decomp[term] -= decomp2[term] except KeyError: try: decomp[term] = -decomp2[term] except KeyError: # term is not in decomp2, no furthor action needed pass if args.bound is not None: decomp[term] = -decomp[term] # update standard TI result as well results[fe.TI] -= results2[fe.TI] # swap the sign if this is a binding calculation if args.bound is not None: results[fe.TI] = -results[fe.TI] if args.dualtopology: _consolidate_terms(decomp) self.figures['decomposed'] = plot_terms(decomp) if args.pmf: self.figures['decomposed_pmfs'] = plot_pmfs(decomp) table = fe.Table('', fmts=["%s:", "%.3f"]) table.add_row(["FDTI", results[fe.TI].dG]) table.add_blank_row() for term in sorted(decomp): if args.full and decomp[term].dG.value == 0.0: continue else: table.add_row([term, decomp[term].dG]) table.add_row(['sum of terms', np.sum(list(decomp.values())).dG]) self.tables.append(table) return results
def make_result_tables(directories, results): """Print calculated free energies. If multiple repeats are present the mean and standard error are also printed. Parameters ---------- directories : list of list (or other sequences) of strings the directory name associated with each result results : dict of Estimator class-Result object pairs """ tables = [] for estimator in sorted(results, key=lambda x: x.__name__): table = fe.Table(estimator.__name__, ['%s', "%.2f"]) for i, result in enumerate(results[estimator].data): dGs = [] for j, pmf in enumerate(result): dGs.append(pmf.dG) table.add_row([directories[i][j], pmf.dG.value]) table.add_row(['Mean', fe.Quantity.fromData(dGs)]) table.add_blank_row() table.add_row(['Total Mean', results[estimator].dG]) tables.append(table) return tables