Пример #1
0
def run():
    input_dir = "../../../../Data/FECs180307/"
    out_dir = "./"
    q_offset_nm = 100
    q_interp, energy_list_arr, _ = FigureUtil.\
        _read_energy_list_and_q_interp(input_dir, q_offset=q_offset_nm,
                                       min_fecs=9)
    # read in some example data
    base_dir_BR = input_dir + "BR+Retinal/"
    names_BR = ["/BR+Retinal/3000nms/170503FEC/landscape_"]
    PEG600 = FigureUtil._read_samples(base_dir_BR,names_BR)[0]
    # read in the FECs
    fecs = FigureUtil._snapsnot(PEG600.base_dir,
                                step=Pipeline.Step.REDUCED).fec_list
    args_mean = (energy_list_arr, q_interp)
    mean_A = mean_A_jarzynski(*args_mean)
    mean_G = mean_G_iwt(*args_mean)
    mean_F_from_dot = mean_A_dot_iwt(*args_mean)[0]
    ex = fecs[0]
    q = q_interp * 1e-9
    # xxx offset q and z... probably a little off!
    z = ex.ZFunc(ex) + q[0]
    k = ex.SpringConstant
    beta = ex.Beta
    A = mean_A[0]
    G = mean_G[0]
    n_iters = 5000
    force =True
    kw_lr = dict(G0=G, A=A, q=q, z=z, k=k, beta=beta,n_iters=n_iters)
    lr = CheckpointUtilities.getCheckpoint("./lr_deconv.pkl",
                                           _deconvoled_lr,force,**kw_lr)
    diff_kT = np.array(lr.mean_diffs) * beta
    min_idx = np.argmin(diff_kT)
    idx_search = np.logspace(start=3,stop=np.floor(np.log2(min_idx)),
                             endpoint=True,num=10,base=2)
    idx_to_use = [int(i) for i in idx_search]
    # fit a spline to the converged G to get the mean restoring force
    fig = PlotUtilities.figure((4,6))
    xlim = [min(q_interp)-5, max(q_interp)]
    fmt_kw = dict(xlim=xlim,ylim=[None,None])
    ax1 = plt.subplot(3,1,1)
    plt.plot(diff_kT)
    plt.axvline(min_idx)
    FigureUtil._plot_fmt(ax1,is_bottom=True,xlabel="iter #",
                         ylabel="diff G (kT)",xlim=[None,None],ylim=[None,None])
    ax2 = plt.subplot(3,1,2)
    plt.plot(q_interp,lr._G0_initial_lr.G0_kT,color='b',linewidth=3)
    plt.plot(q_interp,lr.G0_kT,color='r',linewidth=3)
    FigureUtil._plot_fmt(ax2,is_bottom=False,ylabel="G (kT)",**fmt_kw)
    ax1 = plt.subplot(3,1,3)
    FigureUtil._plot_fec_list(fecs, xlim, ylim=[None,None])
    for i in idx_to_use:
        _plot_f_at_iter_idx(lr, i)
    _plot_f_at_iter_idx(lr, 0,label="F from G0",linewidth=4)
    plt.plot(q_interp,mean_F_from_dot*1e12,label="F from A_z_dot",linewidth=2)
    # also plot the force we expect from the original A_z_dot
    FigureUtil._plot_fmt(ax1,is_bottom=True,xlim=xlim,ylim=[None,None])
    PlotUtilities.legend()
    PlotUtilities.savefig(fig,"FigureS_A_z.png")
    pass
Пример #2
0
def _G0_plot(plot_dir, data_sliced, landscape, fmt):
    # XXX why is this necessary?? screwing up absolute values
    previous_JCP = FigureUtil.read_non_peg_landscape(base="../../FigData/")
    offset_s = np.mean([d.Separation[0] for d in data_sliced])
    G_hao = landscape.G0_kcal_per_mol
    idx_zero = np.where(landscape.q_nm <= 100)
    G_hao = G_hao - landscape.G0_kcal_per_mol[0]
    G_JCP = previous_JCP.G0_kcal_per_mol - previous_JCP.G0_kcal_per_mol[0] + 50
    offset_jcp_nm = min(previous_JCP.q_nm)
    landscape_offset_nm = min(landscape.q_nm)
    q_JCP_nm = previous_JCP.q_nm - offset_jcp_nm + 5
    q_Hao_nm = landscape.q_nm - landscape_offset_nm
    fig = FigureUtil._fig_single(y=6)
    xlim, ylim = FigureUtil._limits(data_sliced)
    ax1 = plt.subplot(2, 1, 1)
    FigureUtil._plot_fec_list(data_sliced, **fmt)
    FigureUtil._plot_fmt(ax1, **fmt)
    ax2 = plt.subplot(2, 1, 2)
    plt.plot(q_Hao_nm, G_hao, label="Aligned, IWT")
    plt.plot(q_JCP_nm, G_JCP, 'r--', label="JCP landscape")
    FigureUtil._plot_fmt(ax2,
                         ylabel="G (kcal/mol)",
                         is_bottom=True,
                         xlim=xlim,
                         ylim=[None, None])
    PlotUtilities.legend(ax=ax2, handlelength=2)
    ax2.set_xlim(fmt['xlim'])
    PlotUtilities.savefig(fig, plot_dir + "FigureSX_LandscapeComparison.png")
def _fec_demo_plot(energy_list, out_dir):
    fecs = []
    energies = []
    N = len(energy_list)
    for e in energy_list:
        data = RetinalUtil.read_fecs(e)
        fecs.append(data)
        energies.append(e)
    n_cols = N
    fig = PlotUtilities.figure((n_cols * 1, 6))
    FigureUtil.data_plot(fecs, energies, xlim=[-20, 100])
    PlotUtilities.savefig(fig,
                          out_dir + "energies.png",
                          subplots_adjust=dict(hspace=0.02, wspace=0.04))
Пример #4
0
def run():
    """
    <Description>

    Args:
        param1: This is the first param.
    
    Returns:
        This is a description of what is returned.
    """
    input_dir = "../../../Data/FECs180307/"
    out_dir = "./"
    force = True
    q_interp, energy_list_arr, q_offset_nm,n_fecs = \
        CheckpointUtilities.getCheckpoint("./cache.pkl",read_data,
                                          force,input_dir)
    G_no_peg = FigureUtil.read_non_peg_landscape()
    #_giant_debugging_plot(out_dir, energy_list_arr)
    base = out_dir + "FigureS6_LandscapeComparison"
    kw_name_arr = [
        [dict(add_annotations=True), base],
        [dict(add_annotations=False), base + "_0"],
        [dict(add_annotations=False, limit_plot=1), base + "_1"],
    ]
    for kw, name in kw_name_arr:
        fig = PlotUtilities.figure(figsize=(3, 3))
        make_comparison_plot(q_interp, energy_list_arr, G_no_peg, **kw)
        base = name
        PlotUtilities.save_twice(fig, base + ".jpeg", base + ".svg")
Пример #5
0
def _heatmap_alignment(gs, alignment, col_idx):
    xlim, ylim = FigureUtil._limits(alignment._all_fecs)
    max_x = xlim[1]
    bin_step_nm = 1
    bin_step_pN = 5
    bins_x = np.arange(xlim[0], xlim[1] + bin_step_nm, step=bin_step_nm)
    bins_y = np.arange(ylim[0], ylim[1] + bin_step_pN, step=bin_step_pN)
    common_kw = dict(separation_max=max_x,
                     use_colorbar=False,
                     title="",
                     bins=(bins_x, bins_y))
    ax1 = plt.subplot(gs[0, col_idx])
    FEC_Plot.heat_map_fec(alignment.zeroed.fec_list, **common_kw)
    FigureUtil._plot_fmt(ax1, xlim, ylim, color=True)
    ax2 = plt.subplot(gs[1, col_idx])
    FEC_Plot.heat_map_fec(alignment.polished.fec_list, **common_kw)
    FigureUtil._plot_fmt(ax2, xlim, ylim, color=True)
    title_kw = dict(color='b', y=0.95, loc='left', fontsize=6)
    downarrow = "$\Downarrow$"
    title_sub = downarrow + " Subtract $X_{\mathbf{PEG3400}}(F)$ + " + \
                "$L_{\mathbf{0,C-term}}$"
    PlotUtilities.title(title_sub, **title_kw)
    PlotUtilities.no_x_label(ax=ax2)
    ax3 = plt.subplot(gs[2, col_idx])
    FEC_Plot.heat_map_fec(alignment.blacklisted.fec_list, **common_kw)
    FigureUtil._plot_fmt(ax3, xlim, ylim, is_bottom=True, color=True)
    PlotUtilities.title(downarrow + " Remove poorly-fit FECs", **title_kw)
    return [ax1, ax2, ax3]
Пример #6
0
def _giant_debugging_plot(out_dir, energy_list_arr):
    fig = PlotUtilities.figure((8, 12))
    gs = gridspec.GridSpec(nrows=2, ncols=1, hspace=0.15)
    n_cols = max([len(list_v) for list_v in energy_list_arr])
    for i, energy_list in enumerate(energy_list_arr):
        fecs = []
        energies = []
        for e in energy_list:
            data = RetinalUtil.read_fecs(e)
            fecs.append(data)
            energies.append(e)
        gs_tmp = gridspec.GridSpecFromSubplotSpec(nrows=3,
                                                  ncols=n_cols,
                                                  subplot_spec=gs[i])
        FigureUtil.data_plot(fecs, energies, gs1=gs_tmp, xlim=[-20, 100])
    PlotUtilities.savefig(fig,
                          out_dir + "FigureS_Mega_Debug.png",
                          subplots_adjust=dict(hspace=0.02, wspace=0.04))
Пример #7
0
def _plot_comparison(plot_dir, heatmap_jcp, iwt_obj, data_sliced_plot):
    fmt = dict(xlim=[-20, 55], ylim=[-20, 150])
    _G0_plot(plot_dir, data_sliced_plot, iwt_obj, fmt=fmt)
    fig = FigureUtil._fig_single(y=6)
    ax1 = plt.subplot(2, 1, 1)
    extent = heatmap_jcp._extent_nm_and_pN(offset_x_nm=0)
    plt.imshow(heatmap_jcp.heatmap,
               origin='lower',
               aspect='auto',
               extent=extent,
               cmap=plt.cm.afmhot)
    FigureUtil._plot_fmt(is_bottom=False, ax=ax1, **fmt)
    PlotUtilities.title("Top: JCP.\n Bottom: New data, - PEG3400")
    ax2 = plt.subplot(2, 1, 2)
    FEC_Plot.heat_map_fec(data_sliced_plot,
                          use_colorbar=False,
                          num_bins=(150, 75),
                          separation_max=fmt['xlim'][1])
    FigureUtil._plot_fmt(is_bottom=True, ax=ax2, **fmt)
    out_name = plot_dir + "FigureSX_jcp_fec_comparison.png"
    PlotUtilities.savefig(fig, out_name, tight=True)
Пример #8
0
def _make_work_plot(fec_list,x_arr,works_kcal,gs,col,color,title):
    # get the interpolated work
    x_interp, mean_W, std_W = _mean_work(x_arr, works_kcal)
    # use Davids function
    shift_david_nm_plot = 10
    L0_david = 11e-9
    max_david = L0_david * 0.95
    x_david = np.linspace(0,max_david,num=100)
    style_david = dict(color='b',linestyle='--',label="David")
    legend_kw = dict(handlelength=1.5,handletextpad=0.3,fontsize=6)
    david_F = _f_david(kbT=4.1e-21, L0=L0_david, Lp=0.4e-9, x=x_david)
    david_W = _single_work(x=x_david,f=david_F)
    x_david_plot = x_david * 1e9 - shift_david_nm_plot
    W_david_plot = david_W * kcal_per_mol_per_J()
    f_david_plot = david_F * 1e12
    is_left = (col == 0)
    fmt_kw = dict(is_left=is_left)
    label_work = "$W$ (kcal/mol)"
    # interpolate each work onto a grid
    xlim, ylim, ylim_work = xlim_ylim()
    fudge_work = max(std_W)
    ax1 = plt.subplot(gs[0,col])
    FigureUtil._plot_fec_list(fec_list,xlim,ylim)
    plt.plot(x_david_plot,f_david_plot,**style_david)
    if is_left:
        PlotUtilities.legend(**legend_kw)
    FigureUtil._plot_fmt(ax1, xlim, ylim,**fmt_kw)
    PlotUtilities.title(title,color=color)
    ax2 = plt.subplot(gs[1,col])
    for x,w in zip(x_arr,works_kcal):
        plt.plot(x * 1e9,w,linewidth=0.75)
    FigureUtil._plot_fmt(ax2, xlim, ylim_work,ylabel=label_work,**fmt_kw)
    ax3 = plt.subplot(gs[2,col])
    _plot_mean_works(x_interp, mean_W, std_W, color, title)
    style_lower_david = dict(**style_david)
    if (not is_left):
        style_lower_david['label'] = None
    plt.plot(x_david_plot,W_david_plot,'b--',zorder=5,**style_lower_david)
    PlotUtilities.legend(**legend_kw)
    FigureUtil._plot_fmt(ax3, xlim, ylim_work,is_bottom=True,
                         ylabel=label_work,**fmt_kw)
Пример #9
0
def run():
    """
    <Description>

    Args:
        param1: This is the first param.
    
    Returns:
        This is a description of what is returned.
    """
    base_dir = "../../../../Data/FECs180307/"
    read_f = FigureUtil.read_sample_landscapes
    gallery = CheckpointUtilities.getCheckpoint("./caches.pkl",
                                                read_f,False,base_dir)
    lab_plot = [ ["BR-PEG3400",gallery.PEG3400],
                 ["BO-PEG3400",gallery.BO_PEG3400] ]
    fig = PlotUtilities.figure(figsize=(4,6))
    gs = gridspec.GridSpec(ncols=1,nrows=2,height_ratios=[3,1])
    gs_pipeline= gridspec.GridSpecFromSubplotSpec(ncols=2,nrows=3,hspace=0.03,
                                                  subplot_spec=gs[0,:])
    colors = ['r','rebeccapurple']
    xlim,_,ylm_W = xlim_ylim()

    mean_works_info = []
    for i,(label,to_use) in enumerate(lab_plot):
        pipeline = FigureUtil._alignment_pipeline(to_use)
        fecs = pipeline.blacklisted.fec_list
        # calculate all the works
        x_arr = [f.Separation for f in fecs]
        f_arr = [f.Force for f in fecs]
        works = _calculate_work(x_arr,f_arr)
        works_kcal = np.array(works) * kcal_per_mol_per_J()
        c = colors[i]
        _make_work_plot(fecs, x_arr, works_kcal,gs_pipeline,col=i,color=c,
                         title=label)
        x_interp, mean_W, std_W= _mean_work(x_arr,works_kcal)
        plt.subplot(gs[-1, :])
        _plot_mean_works(x_interp, mean_W, std_W, color=c, title=label)
        plt.xlim(xlim)
        plt.ylim(ylm_W)
        PlotUtilities.lazyLabel("Extension (nm)" , "$W$ (kcal/mol)","",
                                useLegend=False)
    PlotUtilities.savefig(fig, "FigureS_Work.png".format(label))
Пример #10
0
def _make_plots(galleries_labels):
    alignments = [
        FigureUtil._alignment_pipeline(gallery_tmp[0])
        for gallery_tmp in galleries_labels
    ]
    for i, (_, label) in enumerate(galleries_labels):
        # make the standard aligning plot
        alignment = alignments[i]
        _make_algned_plot(alignment, label)
    # plot the final curves on the same plot
    xlim, ylim = FigureUtil._limits(alignment._all_fecs)
    colors = ['rebeccapurple', 'g']
    fig = PlotUtilities.figure((5, 3))
    gs = gridspec.GridSpec(2, 2)
    # reverse everything, so PEG600 is on top
    galleries_labels = galleries_labels[::-1]
    alignments = alignments[::-1]
    for i, (_, l) in enumerate(galleries_labels):
        ax = plt.subplot(gs[i, 0])
        a = alignments[i]
        FigureUtil._plot_fec_list(a.blacklisted.fec_list,
                                  xlim,
                                  ylim,
                                  label=l,
                                  color=colors[i])
        if (i == 0):
            PlotUtilities.no_x_label(ax)
            PlotUtilities.xlabel("", ax=ax)
    # plot them both on the last column
    plt.subplot(gs[:, 1])
    kw = [dict(), dict(linewidth=0.6)]
    for i, (_, l) in enumerate(galleries_labels):
        a = alignments[i]
        FigureUtil._plot_fec_list(a.blacklisted.fec_list,
                                  xlim,
                                  ylim,
                                  label=l,
                                  color=colors[i],
                                  **kw[i])
    PlotUtilities.savefig(fig, "FigureS_3400vs600.png")
Пример #11
0
def _ensemble_alignment(gs, alignment, col_idx):
    xlim, ylim = FigureUtil._limits(alignment._all_fecs)
    common_kw = dict(xlim=xlim, ylim=ylim)
    kw_fmt = dict(color=False, is_left=(col_idx == 0), **common_kw)
    ax1 = plt.subplot(gs[0, col_idx])
    FigureUtil._plot_fec_list(alignment.zeroed.fec_list, **common_kw)
    FigureUtil._plot_fmt(ax1, **kw_fmt)
    ax2 = plt.subplot(gs[1, col_idx])
    FigureUtil._plot_fec_list(alignment.polished.fec_list, **common_kw)
    FigureUtil._plot_fmt(ax2, **kw_fmt)
    PlotUtilities.no_x_label(ax=ax2)
    ax3 = plt.subplot(gs[2, col_idx])
    FigureUtil._plot_fec_list(alignment.blacklisted.fec_list, **common_kw)
    FigureUtil._plot_fmt(ax3, is_bottom=True, **kw_fmt)
Пример #12
0
def make_retinal_subplot(gs,
                         energy_list_arr,
                         shifts,
                         skip_arrow=True,
                         limit_plot=None):
    q_interp_nm = energy_list_arr[0].q_nm
    means = [e.G0_kcal_per_mol for e in energy_list_arr]
    # fit a second order polynomial and subtract from each point
    q_fit_nm_relative = 7
    max_fit_idx = \
        np.argmin(np.abs((q_interp_nm - q_interp_nm[0]) - q_fit_nm_relative))
    fits = []
    fit_pred_arr = []
    for m in means:
        fit = np.polyfit(x=q_interp_nm[:max_fit_idx], y=m[:max_fit_idx], deg=2)
        fits.append(fit)
        fit_pred = np.polyval(fit, x=q_interp_nm)
        fit_pred_arr.append(fit_pred)
    stdevs = [e.G_err_kcal for e in energy_list_arr]
    ax1 = plt.subplot(gs[0])
    common_error = dict(capsize=0)
    style_dicts = [
        dict(color=FigureUtil.color_BR(), label=r"with retinal"),
        dict(color=FigureUtil.color_BO(), label=r"w/o  retinal")
    ]
    markers = ['v', 'x']
    deltas, deltas_std = [], []
    delta_styles = [
        dict(color=style_dicts[i]['color'],
             markersize=5,
             linestyle='None',
             marker=markers[i],
             **common_error) for i in range(len(energy_list_arr))
    ]
    xlim = [None, 27]
    ylim = [-25, 450]
    q_arr = []
    round_energy = -1
    max_q_nm = max(q_interp_nm)
    # add the 'shifted' energies
    for i, (mean,
            stdev) in enumerate(zip(means[:limit_plot], stdevs[:limit_plot])):
        tmp_style = style_dicts[i]
        style_fit = dict(**tmp_style)
        style_fit['linestyle'] = '--'
        style_fit['label'] = None
        corrected = mean - fit_pred_arr[i]
        plt.plot(q_interp_nm, mean, **tmp_style)
        plt.fill_between(x=q_interp_nm,
                         y1=mean - stdev,
                         y2=mean + stdev,
                         color=tmp_style['color'],
                         linewidth=0,
                         alpha=0.3)
        energy_error = np.mean(stdev)
        max_idx = -1
        q_at_max_energy = q_interp_nm[max_idx]
        max_energy_mean = corrected[max_idx]
        # for the error, use the mean error over all interpolation
        max_energy_std = energy_error
        deltas.append(max_energy_mean)
        deltas_std.append(max_energy_std)
        q_arr.append(q_at_max_energy)
    plt.xlim(xlim)
    plt.ylim(ylim)
    PlotUtilities.lazyLabel("Extension (nm)", "$\mathbf{\Delta}G$ (kcal/mol)",
                            "")
    leg = PlotUtilities.legend(loc='lower right')
    colors_leg = [s['color'] for s in style_dicts]
    PlotUtilities.color_legend_items(leg, colors=colors_leg[:limit_plot])
    return ax1, means, stdevs
Пример #13
0
def make_comparison_plot(q_interp,
                         energy_list_arr,
                         G_no_peg,
                         add_annotations,
                         limit_plot=None):
    landscpes_with_error = \
        FigureUtil._get_error_landscapes(q_interp, energy_list_arr)
    # get the extension grid we wnt...
    ext_grid = np.linspace(0, 25, num=100)
    # read in Hao's energy landscape
    fec_system = WLC._make_plot_inf(ext_grid, WLC.read_haos_data)
    shifts = [fec_system.W_at_f(f) for f in [249, 149]]
    gs = gridspec.GridSpec(nrows=1, ncols=1)
    ax1, means, stdevs = \
        make_retinal_subplot(gs,landscpes_with_error,shifts,
                             limit_plot=limit_plot)
    # get the with-retinal max
    ax1 = plt.subplot(gs[0])
    # get the max of the last point (the retinal energy landscape is greater)
    offsets = [l.G0_kcal_per_mol[-1] for l in landscpes_with_error]
    q_no_PEG_start = max(q_interp)
    q_nm_no_PEG = G_no_peg.q_nm + q_no_PEG_start
    G_err_kcal_no_PEG = G_no_peg.G_err_kcal
    for i, G_offset in enumerate(offsets[:limit_plot]):
        G_kcal = G_no_peg.G0_kcal_per_mol + G_offset
        mean_err = np.mean(G_err_kcal_no_PEG)
        idx_errorbar = q_nm_no_PEG.size // 2
        common_style = dict(color='grey', linewidth=1.5)
        ax1.plot(q_nm_no_PEG, G_kcal, linestyle='--', **common_style)
        if (i != 0):
            continue
        ax1.errorbar(q_nm_no_PEG[idx_errorbar],
                     G_kcal[idx_errorbar],
                     yerr=mean_err,
                     marker=None,
                     markersize=0,
                     capsize=3,
                     **common_style)
    axes = [ax1]
    ylim = [None,
            np.max(offsets) + max(G_no_peg.G0_kcal_per_mol) + \
            G_err_kcal_no_PEG[-1]*4]
    for a in axes:
        a.set_ylim(ylim)
        a.set_xlim([None, max(q_nm_no_PEG)])
    # add in the scale bar
    ax = axes[0]
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
    y_range = (ylim[1] - ylim[0])
    range_scale_kcal = np.round(y_range / 3, -2)
    x_range_scalebar_nm = 20
    min_offset, _, rel_delta = Scalebar. \
        offsets_zero_tick(limits=ylim,range_scalebar=range_scale_kcal)
    min_offset_x, _, rel_delta_x= Scalebar. \
        offsets_zero_tick(limits=xlim,range_scalebar=x_range_scalebar_nm)
    offset_x = 0.25
    offset_y = min_offset + 1 * rel_delta
    common_kw = dict(add_minor=True)
    scalebar_kw = dict(offset_x=offset_x,
                       offset_y=offset_y,
                       ax=ax,
                       x_on_top=True,
                       y_on_right=False,
                       x_kwargs=dict(width=x_range_scalebar_nm,
                                     unit="nm",
                                     **common_kw),
                       y_kwargs=dict(height=range_scale_kcal,
                                     unit="kcal/mol",
                                     **common_kw))
    PlotUtilities.no_x_label(ax=ax)
    PlotUtilities.no_y_label(ax=ax)
    Scalebar.crossed_x_and_y_relative(**scalebar_kw)
    # add the helical boxes
    offset_boxes_nm = -25
    FigureUtil.add_helical_boxes(ax=ax1,
                                 ymax_box=0.97,
                                 box_height=0.07,
                                 constant_offset=offset_boxes_nm,
                                 clip_on=True)
    delta_delta_G_total = np.abs(np.diff(offsets))[0]
    delta_delta_G_linker = np.abs(np.diff(shifts))[0]
    if add_annotations:
        str_text = " $\mathbf{\Delta\Delta}G_{\mathbf{Total}}$"
        min_o = min(offsets)
        xy = q_no_PEG_start, min_o
        xy_end = q_no_PEG_start, min_o + delta_delta_G_total
        labelled_arrow(ax1, str_text, xy, xy_end)
        str_dd = " $\mathbf{\Delta\Delta}G_{\mathbf{Linker}}$"
        xlim = plt.xlim()
        x_range = (xlim[1] - xlim[0])
        x0 = np.mean(xlim) + x_range * 0.05
        y0 = min_o
        y1 = min_o + delta_delta_G_linker
        xy2 = x0, y0
        xy_end2 = x0, y1
        labelled_arrow(ax1,
                       str_dd,
                       xy2,
                       xy_end2,
                       color_arrow='r',
                       y_text_fudge=0.0)
    # # save out the data
    preamble = "FigureS6"
    X = np.array([delta_delta_G_total, delta_delta_G_linker]).reshape((1, -1))
    np.savetxt(fname=preamble + "_ddG.csv",
               X=X,
               fmt=["%.1f", "%.1f"],
               delimiter=",",
               header="ddG_total (kcal/mol), ddG_linker (kcal/mol)")
    # save out the landscapes
    x_y_yerr_name = [[q_interp, landscpes_with_error[0], preamble + "_BR"],
                     [q_interp, landscpes_with_error[1], preamble + "_BO"]]
    for x, l, name in x_y_yerr_name:
        y = l.G0_kcal_per_mol
        yerr = l.G_err_kcal
        Record.save_csv(
            dict(x=x,
                 y=[y, yerr],
                 save_name=name,
                 x_name="q",
                 x_units="nm",
                 y_name=["Energy", "Energy Error"],
                 y_units="kcal/mol"))
    # save out the remainder of the BO
    G_kcal_PEG_tmp = G_no_peg.G0_kcal_per_mol + max(offsets)
    Record.save_csv(
        dict(x=q_nm_no_PEG,
             y=[G_kcal_PEG_tmp, G_err_kcal_no_PEG],
             save_name=preamble + "_JCP_no_PEG",
             x_name="q",
             x_units="nm",
             y_name=["Energy", "Energy Error"],
             y_units="kcal/mol"))