def get_salty_Enc(E, salttype, CO2unc=0.0, H2Ounc=0.0): """Get a salty, nominal or less-salty enceladus with the activities as ufloats. """ QE = deepcopy(E)#nc(name='En', pH=ocean_pH, CO2origin='pH', T=T, workoutID=False) CO2salt, H2Osalt = Enc.get_CO2_from_HTHeating(QE.env.T, QE.ocean_pH, salts=True) CO2salt273, H2Osalt273 = Enc.get_CO2_from_HTHeating(273.15, QE.ocean_pH, salts=True) aCO2, aH20, aH2, aCH4 = 0,0,0,0 if salttype == 'nom': aCO2 = CO2salt[0] aH2O = H2Osalt[0] aH2 = QE.calc_mol_H2(CO2salt273[0]) aCH4 = QE.calc_mol_CH4(CO2salt273[0]) elif salttype =='high': aCO2 = CO2salt[1] aH2O = H2Osalt[1] aH2 = QE.calc_mol_H2(CO2salt273[1]) aCH4 = QE.calc_mol_CH4(CO2salt273[1]) elif salttype == 'low': aCO2 = CO2salt[2] aH2O = H2Osalt[2] aH2 = QE.calc_mol_H2(CO2salt273[2]) aCH4 = QE.calc_mol_CH4(CO2salt273[2]) else: raise ValueError('Unknown salt type sent to Q_salty') QE.composition['CO2(aq)'].activity = uf(aCO2, aCO2*CO2unc) QE.composition['H2(aq)'].activity = aH2 QE.composition['Methane(aq)'].activity = aCH4 QE.composition['H2O(l)'].activity = uf(aH2O, aH2O*H2Ounc) return QE
def Q_salty_endmember(E, nATP, k_corr): """ Get growth parameters for a methanogenesis quotient considering the widest endmemebers possible. So, variation across the salt content of the ocean affecting CO2. The 'up' bounds are for a salty ocean with maximised reactants and minimised products. The 'low' bounds are for a less salty ocean with maximised products and minimized reactants. """ QE = deepcopy(E)#nc(name='En', pH=ocean_pH, CO2origin='pH', T=T, workoutID=False) CO2salt, H2Osalt = Enc.get_CO2_from_HTHeating(QE.env.T, QE.ocean_pH, salts=True) CO2salt273, H2Osalt273 = Enc.get_CO2_from_HTHeating(273.15, QE.ocean_pH, salts=True) ######### Nominal parameters ########## QE.composition['CO2(aq)'].activity = CO2salt[0] QE.composition['H2(aq)'].activity = E.calc_mol_H2(CO2salt273[0]).n QE.composition['Methane(aq)'].activity = E.calc_mol_CH4(CO2salt273[0]).n QE.composition['H2O(l)'].activity = H2Osalt[0] # quotient, gibbs, ATPgibbs, PowerSupply, max_k Q, G, GP, PS, mk = MGparams(QE, k_corr=k_corr, nATP=nATP) ######### min products, max reactants ######### QE.composition['CO2(aq)'].activity = (CO2salt[1]) H2 = E.calc_mol_H2(CO2salt273[1]) QE.composition['H2(aq)'].activity = (H2.n + H2.s) CH4 = E.calc_mol_CH4(CO2salt273[1]) QE.composition['Methane(aq)'].activity = (CH4.n - CH4.s) QE.composition['H2O(l)'].activity = (H2Osalt[1]) Q_up, G_up, GP_up, PS_up, mk_up = MGparams(QE, k_corr=k_corr, nATP=nATP) ######### max products, min reactants ######### QE.composition['CO2(aq)'].activity = (CO2salt[2]) H2 = E.calc_mol_H2(CO2salt273[2]) QE.composition['H2(aq)'].activity = (H2.n - H2.s) CH4 = E.calc_mol_CH4(CO2salt273[2]) QE.composition['Methane(aq)'].activity = (CH4.n + CH4.s) QE.composition['H2O(l)'].activity = (H2Osalt[2]) Q_do, G_do, GP_do, PS_do, mk_do = MGparams(QE, k_corr=k_corr, nATP=nATP) return {'Gibbs_Methanogenesis' : np.array([[G, G_do, G_up]]), 'Quotient' : np.array([[Q, Q_do, Q_up]]), 'PowerSupply' : np.array([[PS, PS_do, PS_up]]), 'ATPGibbs': np.array([[GP, GP_do, GP_up]]), 'max_k' : np.array([[mk, mk_do, mk_up]])}
def default_org(): rtr = Enceladus('EncT', nominals=True, T=298) # make an organism, for this example, use the preset methanogen. org = TOM(rtr) org.maintenance.Tdef = 'None' org.maintenance.pHdef = 'FluxPerm' return org
def fluxplot(): # make a reactor object rtr = Enceladus('EncT', nominals=True, T=298) # make an organism, for this example, use the preset methanogen. org = TOM(rtr) org.maintenance.Tdef='None' org.maintenance.pHdef='FluxPerm' def_vals = pH_flux_power(org, -1e-3, 1e-10, 1e-10, org.base_volume) high_phi = pH_flux_power(org, -1e-1, 1e-10, 1e-10, org.base_volume) high_perms = pH_flux_power(org, -1e-3, 1e-5, 1e-5, org.base_volume) bigger = pH_flux_power(org, -1e-3, 1e-10, 1e-10, org.base_volume*100) fig, ax = plt.subplots(figsize=(8,4.5), ncols=2) cols = ['k', 'tab:blue', 'cyan', 'tab:purple'] alphas = [1, 0.8, 0.4, 0.6] ax[0].plot(def_vals['pH'], def_vals['fluxH'], c=cols[0], label=r'NutMEG default values: $\bar{P}_H = 10^{-10},\ \bar{P}_{OH}=10^{-10},\ \Delta\Psi = -10^{-3},\ v = 3.44\times10^{-18}$', alpha=alphas[0]) ax[0].plot(def_vals['pH'], def_vals['fluxOH'], c=cols[0], ls='dashed', alpha=alphas[0]) ax[1].plot(def_vals['pH'], def_vals['pow'], c=cols[0], alpha=alphas[0]) ax[0].plot(high_phi['pH'], high_phi['fluxH'], c=cols[1], label=r'Increase potential: $\bar{P}_H = 10^{-10},\ \bar{P}_{OH}=10^{-10},\ \Delta\Psi = -0.1,\ v = 3.44\times10^{-18}$', alpha=alphas[1]) ax[0].plot(high_phi['pH'], high_phi['fluxOH'], c=cols[1], ls='dashed', alpha=alphas[1]) ax[1].plot(high_phi['pH'], high_phi['pow'], c=cols[1], alpha=alphas[1]) ax[0].plot(high_perms['pH'], high_perms['fluxH'], c=cols[2], label=r'Increase permeabilities: $\bar{P}_H = 10^{-5},\ \bar{P}_{OH}=10^{-5},\ \Delta\Psi = -10^{-3},\ v = 3.44\times10^{-18}$', alpha=alphas[2]) ax[0].plot(high_perms['pH'], high_perms['fluxOH'], c=cols[2], ls='dashed', alpha=alphas[2]) ax[1].plot(high_perms['pH'], high_perms['pow'], c=cols[2], alpha=alphas[2]) ax[0].plot(bigger['pH'], bigger['fluxH'], c=cols[3], label=r'Cell size: $\bar{P}_H = 10^{-10},\ \bar{P}_{OH}=10^{-10},\ \Delta\Psi = -10^{-3},\ v = 3.44\times10^{-16}$', alpha=alphas[3]) ax[0].plot(bigger['pH'], bigger['fluxOH'], c=cols[3], ls='dashed', alpha=alphas[3]) ax[1].plot(bigger['pH'], bigger['pow'], c=cols[3], ls='dashed', alpha=alphas[3]) ax[0].set_title('Goldman-style fluxes for H$^{+}$ and OH$^{-}$') ax[1].set_title('Corresponding power demands') ax[0].set_ylabel('Flux of ions [mol (s cell$^{-1}$)]') ax[1].set_ylabel('Power demand [W cell$^{-1}$]') for a in ax: a.set_yscale('log') a.set_xlabel('external pH') fig.subplots_adjust(wspace=0.25, top=0.65, right=0.995, left=0.1) ax[0].legend(bbox_to_anchor=(0., 1.12, 2.25, 1.4), loc=3, ncol=1, mode="expand", borderaxespad=0.) # plt.show() plt.savefig('fluxplot.pdf')
def add_maintenance_lines(ax, colors=['tab:orange', 'k', 'y', 'c']): T1 = range(273, 375) PT = tem.MaintenanceRange_nATPs( Trange=T1, mCH4=3e-8, Tlst=False, fraction=False, Perform=False, dbpath='../../NutMEG-Implementations/TOM/allMtestc') ax.fill_between(T1, np.log10(PT[1]), np.log10(PT[2]), color=colors[0], alpha=0.6) T2 = range(273, 400) # make a TOM and an Enceladus _Enc = Enceladus('EncT') TOM = getE_TOM(_Enc) TE = es.applications.theory_estimates(TOM, _Enc) Ti, L10, L2 = [], [], [] for t in T2: TE.loc.change_T(t) TE.org.get_ESynth(AA=True) # update the synthesis energy td = TE.temperature_defenses(t) Ti.append(td['TijhuisAnaerobe']) L10.append(td['Lever10pc']) L2.append(td['Lever2pc']) Ti = np.array(Ti) ax.fill_between(T2, np.log10(Ti - (0.32 * Ti)), np.log10(Ti + (0.32 * Ti)), color=colors[1], alpha=0.4, lw=3.) ax.fill_between(T2, np.log10(L10), np.log10(L2), color=colors[2], alpha=0.4) ax.fill_between([T2[0], T2[-1]], [-18, -18], [-21, -21], color=colors[3], alpha=0.4) return ax
def add_pH_maintenance_lines(ax, T, pHrange=[7, 12], colors=['tab:orange', 'k', 'g', 'c']): PT = tem.MaintenanceRange_nATPs( Trange=[T], mCH4=3e-8, Tlst=False, fraction=False, Perform=False, dbpath='../../NutMEG-Implementations/TOM/allMtestc') # pH is only 5--9 as that's as far as the data goes ax.fill_between([5, 9], np.log10(PT[1]), np.log10(PT[2]), color=colors[0], alpha=0.4) _Enc = Enceladus('EncT') TOM = getE_TOM(_Enc) TE = es.applications.theory_estimates(TOM, _Enc) Ti, L10, L2 = [], [], [] td = TE.temperature_defenses(T) Ti.append(td['Tijhuis']) L10.append(td['Lever10pc']) L2.append(td['Lever2pc']) ax.fill_between(pHrange, np.log10(Ti), np.log10(Ti), color=colors[1], alpha=0.8, lw=3.) ax.fill_between(pHrange, np.log10(L10), np.log10(L2), color=colors[2], alpha=0.4) ax.fill_between(pHrange, [-18, -18], [-21, -21], color=colors[3], alpha=0.4) return ax
def pow_perm(): # make a reactor object rtr = Enceladus('EncT', nominals=True, T=298) # make an organism, for this example, use the preset methanogen. org = TOM(rtr) org.maintenance.Tdef='None' org.maintenance.pHdef='FluxPerm' Perm4 = pH_flux_power(org, 1e-3, 1e-6, 1e-6, org.base_volume) Perm8 = pH_flux_power(org, 1e-3, 1e-11, 1e-11, org.base_volume) org.locale.env.T = 400 Perm4_350 = pH_flux_power(org, 1e-3, 1e-6, 1e-6, org.base_volume) Perm8_350 = pH_flux_power(org, 1e-3, 1e-11, 1e-11, org.base_volume) fig, ax = plt.subplots(figsize=(6,3.25), ncols=2, sharey=True) ax[0].fill_between(Perm4['pH'], Perm4['pow'], Perm8['pow']) ax[0].set_title('Variable Permeability') ax[1].fill_between(Perm8['pH'], Perm8_350['pow'], Perm8['pow']) ax[1].fill_between(Perm4['pH'], Perm4_350['pow'], Perm4['pow'], facecolor='g') ax[1].set_title('Variable Temperature') for a in ax: a.set_yscale('log') a.set_xlabel('pH') a.set_xlim(0,14) a.set_ylim(1e-27,1e-9) a.grid(b=True, which='major', color='#666666', linestyle='-', alpha=0.8) ax[0].set_ylabel('Power Demand [W cell$^{-1}$]') ax[0].text(10.,10**(-13.25), r'$\bar{P} = 10^{-6}$', c='C0', rotation=40) ax[0].text(10.,10**(-20.5), r'$\bar{P} = 10^{-11}$', c='C0', rotation=40) ax[1].text(10.,10**(-13), r'$\bar{P} = 10^{-6}$', c='g', rotation=40) ax[1].text(10.,10**(-20.5), r'$\bar{P} = 10^{-11}$', c='C0', rotation=40) fig.subplots_adjust(wspace=0., right=0.995, top=0.905, bottom=0.14) # plt.show() plt.savefig('pH_pow_perm.pdf')
def getEncEnergetics( ocean_pH=8., T=273.15, nATP=1.0, k_corr=0., CO2origin='pH', # change to HTHeating later output=gEE_default_output, quotienttype='salty_endmember'): """ Get the requested parameters in output at the selected parameters of ocean_pH, T, nATP, and k_corr. """ outputbools = boolify_output(output) outputdict = {} E = Enc(name='En', pH=ocean_pH, CO2origin=CO2origin, T=T, workoutID=False) if outputbools['Composition']: _concs = {} for species, rx in E.composition.items(): _concs[species] = np.array([[ rx.activity.n, rx.activity.n + rx.activity.s, rx.activity.n - rx.activity.s ]]) outputdict['Composition'] = _concs if outputbools['CO2Tiger']: CO2T = E.get_tigerstripe_CO2(logform=True) CO2Tiger = 10**CO2T.n CO2Tiger_up = 10**(CO2T.n + CO2T.s) CO2Tiger_down = 10**(CO2T.n - CO2T.s) outputdict['CO2Tiger'] = np.array( [[CO2Tiger, CO2Tiger_do, CO2Tiger_up]]) if outputbools['Gibbs_Methanogenesis'] or outputbools[ 'PowerSupply'] or outputbools['ATPGibbs'] or outputbools[ 'max_k'] or outputbools['Quotient']: # need to do the energetic calculations. This is outsourced to the # QuotientUncertainties class. Qdict = {} # dictionary outputs from Qunc if quotienttype == 'allunc': Qdict = Qunc.Q_allunc(E, nATP, k_corr) elif quotienttype == 'salty_endmember': Qdict = Qunc.Q_salty_endmember(E, nATP, k_corr) elif quotienttype == 'salty_nominal': Qdict = Qunc.Q_salty(E, nATP, k_corr, 'nom') elif quotienttype == 'salty_high': Qdict = Qunc.Q_salty(E, nATP, k_corr, 'high') elif quotienttype == 'salty_low': Qdict = Qunc.Q_salty(E, nATP, k_corr, 'low') else: raise ValueError( 'unrecognised quotienttype, how do you want to consider salt effects?' ) if outputbools['Gibbs_Methanogenesis']: outputdict['Gibbs_Methanogenesis'] = Qdict['Gibbs_Methanogenesis'] if outputbools['Quotient']: outputdict['Quotient'] = Qdict['Quotient'] if outputbools['PowerSupply']: outputdict['PowerSupply'] = Qdict['PowerSupply'] if outputbools['ATPGibbs']: outputdict['ATPGibbs'] = Qdict['ATPGibbs'] if outputbools['max_k']: outputdict['max_k'] = Qdict['max_k'] return outputdict
def complex_fluxes(): rtr = Enceladus('EncT', nominals=True, T=298) # make an organism, for this example, use the preset methanogen. org = TOM(rtr) org.maintenance.Tdef='None' org.maintenance.pHdef='FluxPerm' phidicts, phidicts2, pHdicts, pHdicts2 = [], [], [], [] phis= [1, 1e-1, -1e-3, -1e-1, -1] pHints= [5,6,7,8,9] nomcols = plt.get_cmap('coolwarm', len(phis)+1) phicmaplist = [nomcols(i) for i in range(nomcols.N)][1:] cmap = clr.LinearSegmentedColormap.from_list( 'Custom cmap', phicmaplist, len(phis)+1) nomcols2 = plt.get_cmap('PRGn', len(pHints)+3) pHcmaplist = [nomcols2(i) for i in range(nomcols2.N)][1:-2] pHcmaplist = ['#984ea3', '#fb9a99', '#fdcdac', '#b2df8a', '#33a02c'] cmap2 = clr.LinearSegmentedColormap.from_list( 'Custom cmap2', pHcmaplist, len(pHints)+1) for i, phi in enumerate(phis): phidicts.append(pH_flux_power(org, phi, 1e-10, 1e-10, org.base_volume)) phidicts2.append(pH_flux_power(org, phi, 1e-10, 1e-13, org.base_volume)) for i, pHint in enumerate(pHints): org.pH_interior = pHint pHdicts.append(pH_flux_power(org, -1e-3, 1e-10, 1e-10, org.base_volume)) pHdicts2.append(pH_flux_power(org, -1e-3, 1e-10, 1e-13, org.base_volume)) fig, ax = plt.subplots(figsize=(7,8), ncols=2, nrows=3) for i in range(len(phidicts)): ax[0][0].plot(phidicts[i]['pH'], phidicts[i]['fluxH'], c=phicmaplist[i], linewidth=3) ax[0][0].plot(phidicts[i]['pH'], phidicts[i]['fluxOH'], ls='dashed', c=phicmaplist[i], linewidth=3) ax[1][0].plot(phidicts[i]['pH'], phidicts[i]['pow'], c=phicmaplist[i], linewidth=3) ax[2][0].plot(phidicts2[i]['pH'], phidicts2[i]['pow'], c=phicmaplist[i], linewidth=3) for i in range(len(pHdicts)): ax[0][1].plot(pHdicts[i]['pH'], pHdicts[i]['fluxH'], c=pHcmaplist[i], linewidth=3) ax[0][1].plot(pHdicts[i]['pH'], pHdicts[i]['fluxOH'], ls='dashed', c=pHcmaplist[i], linewidth=3) ax[1][1].plot(pHdicts[i]['pH'], pHdicts[i]['pow'], c=pHcmaplist[i], linewidth=3) ax[2][1].plot(pHdicts2[i]['pH'], pHdicts2[i]['pow'], c=pHcmaplist[i], linewidth=3) for ai in ax: for a in ai: a.set_yscale('log') a.set_xlim(0,14) a.get_xaxis().set_ticks([1,3,5,7,9,11,13]) a.grid(b=True, which='major', color='#666666', linestyle='-', alpha=0.8) for a in ax[-1]: a.set_xlabel('external pH') a.set_ylim(1e-27,1e-12) for a in ax[1]: a.set_ylim(1e-27,1e-12) a.get_xaxis().set_ticklabels([]) for a in ax[0]: a.set_ylim(1e-31, 1e-16) a.get_xaxis().set_ticklabels([]) for a in [ax[0][1], ax[1][1], ax[2][1]]: a.get_yaxis().set_ticklabels([]) ax[0][0].set_ylabel('Flux of ions [mol (s cell$^{-1}$)]') ax[1][0].set_ylabel('Power demand [W cell$^{-1}$]') ax[2][0].set_ylabel('Power demand [W cell$^{-1}$]') ax[0][0].text(0.42,0.9,'(a)', horizontalalignment='center', verticalalignment='center', transform=ax[0][0].transAxes) ax[0][1].text(0.42,0.9, '(b)', horizontalalignment='center', verticalalignment='center', transform=ax[0][1].transAxes) ax[1][0].text(0.42,0.9, '(c)', horizontalalignment='center', verticalalignment='center', transform=ax[1][0].transAxes) ax[1][1].text(0.42,0.9, '(d)', horizontalalignment='center', verticalalignment='center', transform=ax[1][1].transAxes) ax[2][0].text(0.42,0.9, '(e)', horizontalalignment='center', verticalalignment='center', transform=ax[2][0].transAxes) ax[2][1].text(0.42,0.9, '(f)', horizontalalignment='center', verticalalignment='center', transform=ax[2][1].transAxes) cbaxes = fig.add_axes([0.125, 0.91, 0.425, 0.02]) cbaxes2 = fig.add_axes([0.57, 0.91, 0.425, 0.02]) # plt.colorbar(clr.BoundaryNorm(phis, nomcols.N), cax=cbaxes, label='phi', orientation='horizontal', pad=0.5, aspect=7) mpl.colorbar.ColorbarBase(cbaxes, cmap=cmap, norm=clr.BoundaryNorm([0.5,1.5,2.5,3.5,4.5], nomcols.N-1), spacing='proportional', ticks=[0.5,1.5,2.5,3.5,4.5], boundaries=[0,1,2,3,4,5], format='%1i', orientation='horizontal') cbaxes.set_xticklabels(['1','10$^{-1}$', '$-10^{-3}$', '$-10^{-1}$', '-1']) cbaxes.set_xlabel('Membrane potential [V]') cbaxes.xaxis.set_label_position('top') cbaxes.xaxis.tick_top() mpl.colorbar.ColorbarBase(cbaxes2, cmap=cmap2, norm=clr.BoundaryNorm(pHints, nomcols2.N-3), spacing='proportional', ticks=pHints, boundaries=[4.5,5.5,6.5,7.5,8.5,9.5], format='%1i', orientation='horizontal') cbaxes2.set_xlabel('Internal pH') cbaxes2.xaxis.set_label_position('top') cbaxes2.xaxis.tick_top() # cmappable = ScalarMappable(norm=Normalize(0,1), cmap=cmapper.r2a()) # fig.colorbar(clr.BoundaryNorm(pHints, nomcols.N), cax=cbaxes2, label='pH', orientation='horizontal', pad=0.5, aspect=7) fig.subplots_adjust(wspace=0.05, hspace=0.07, right=0.995, left=0.125, bottom=0.062, top=0.9) plt.savefig('complex_fluxes.pdf')
sys.path.append(os.path.dirname(__file__) + '../../NutMEG') import ThesisSetup import NutMEG as nm from NutMEG.reactor.saved_systems.Enceladus import Enceladus from NutMEG.culture.saved_organisms.TypicalOptimalMethanogen import TypicalOptimalMethanogen as TOM import matplotlib.pyplot as plt import numpy as np from uncertainties import unumpy as unp from uncertainties import ufloat as uf Ts = range(270, 400) # make a reactor object rtr = Enceladus('EncT') # make an organism, for this example, use the preset methanogen. org = TOM(rtr) # org.dry_mass=29e-18 # set volume to 1 cubic micron. TE = nm.apps_theory_estimates(org, rtr) Tijhuis, TijhuisAerobe, TijhuisAnaerobe = [], [], [] Lever10pc, Lever2pc, Lever1AA = [], [], [] # in-built energy Lever10pc_ces, Lever2pc_ces, Lever1AA_ces = [], [], [] # constant energy for i, T in enumerate(Ts): TE.loc.change_T(T) TE.org.get_ESynth(AA=True) # update the synthesis energy td = TE.temperature_defenses(T) Tijhuis.append(uf(td['Tijhuis'], 0.29 * td['Tijhuis'])) TijhuisAerobe.append(uf(td['TijhuisAerobe'], 0.41 * td['TijhuisAerobe']))