Exemplo n.º 1
0
def CUE_cal(t_fin, N, M, t_n,  Tref, Ma, ass, x0, pk, Ea_D, typ):

    # Setted Parameters
    k = 0.0000862 # Boltzman constant
    T_pk = Tref + pk # Peak above Tref, Kelvin
    Ea_D = np.repeat(3.5,N) # Deactivation energy - only used if use Sharpe-Schoolfield temp-dependance
    t = sc.linspace(0,t_fin-1,t_fin) # Time steps

    Ea_U = np.round(np.random.normal(1.5, 0.01, N),3)[0:N] # ?Ea for uptake
    Ea_R = Ea_U - 0.8 # ?Ea for respiration, which should always be lower than Ea_U so 'peaks' later
    B_U = (10**(2.84 + (-4.96 * Ea_U))) + 4 # ?B0 for uptake - ** NB The '+4' term is added so B_U>> B_R, otherwise often the both consumers can die and the resources are consumed
    B_R = (10**(1.29 + (-1.25 * Ea_R))) # ?B0 for respiration

    x = bvm.ass_temp_run(t_fin, N, M, t_n,  Tref, Ma, ass, x0, pk, Ea_D, typ)[0] # Result array
    xc =  x[:,0:N] # consumer
    r =  x[:,N:N+M] # resources

    # Functional response
    if typ == 2:
        xr = r /(K + r) # type 2, monod function
    else:
        xr = r #type 1 


    #uptake rate and maintenance
    CUE_out = np.empty((0,N))

    for i in range(20, t_n):
        T = 273.15 + i
        U = par.params(N, M, T, k, Tref, T_pk, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D)[0] # Uptake
        R = par.params(N, M, T, k, Tref, T_pk, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D)[1] # Respiration
        l = par.params(N, M, T, k, Tref, T_pk, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D)[2] # leakage
        l_sum = np.sum(l, axis=1)
        SL = (1 - l_sum) * xr[t_fin*(i-20)*ass:t_fin*(i-19)*ass,:]
        C = np.einsum('ij,kj->ik', SL, U) - R
        dCdt = xc[t_fin*(i-20)*ass:t_fin*(i-19)*ass,:] * C
        
        CUE = dCdt / np.einsum('ij,kj->ik', xr[t_fin*(i-20)*ass:t_fin*(i-19)*ass,:], U)
        CUE_out = np.append(CUE_out,CUE, axis = 0)

    
    return CUE_out
def ass_temp_run(t, N, M, t_n, Tref, B_r, B_g, Ma, k, ass, Meta_ratio, x0,
                 t_fin, T_pk, Ea_D, Fg_num):
    result_array = np.empty((0, N + M))
    row = np.repeat(sc.linspace(1, ass, ass), N)
    B_n = sc.linspace(1, N, N)
    N_n = np.tile(sc.linspace(1, M, M), rep)
    output_tmp_lrg = np.empty((0, 11))

    for i in range(20, t_n):
        #for i in range(0, len(temp)):
        #for i in range(1,3):

        T = 273.15 + i  # temperature
        Temp = np.repeat(T - 273.15, N)
        Ea_U_tmp2 = np.repeat(np.array([0.6, 0.7, 0.8, 0.9, 1.0]),
                              N)  # Activation energy (same for g and rm)
        Ea_R_tmp2 = np.repeat(np.array([0.7, 0.8, 0.9, 1.0, 1.1]),
                              N)  # Activation energy (same for g and rm)
        #Meta_ratio = np.array([1, 1.1, 1, 0.9, 1])
        Ea_U_tmp3 = shuffle(Ea_U_tmp2, random_state=0)
        Ea_U = Ea_U_tmp3[0:N]
        #print(Ea_U)
        Ea_R_tmp3 = shuffle(Ea_R_tmp2, random_state=0)
        Ea_R = Ea_R_tmp3[0:N]
        #Ea_R = shuffle(Ea_R_tmp2, random_state=0)
        #print(Ea_R)
        #Ea_R=np.repeat(0.3, 10)
        # Varying B0
        #B_g = np.exp(2.5 + (-5 * Ea))
        #B_rm = 0.5 *(np.exp(2.5 + (-5 * Ea))) #(0.5 * (B_g)) #

        output_tmp = np.empty((0, 10))
        print('')
        print('Temperature =', i)

        for j in range(ass):
            print('')
            print('Assembly = ', j)
            t = sc.linspace(0, t_fin - 1, t_fin)
            Ea_1_U = Ea_U  # To fill output dataframe
            Ea_1_R = Ea_R  # To fill output dataframe
            #B_g_1 = B_g # To fill output dataframe when B0 varies
            #B_rm_1 = B_rm # To fill output dataframe when B0 varies
            B_g_1 = np.repeat(B_g,
                              N)  # To fill output dataframe when B0 constant
            B_r_1 = np.repeat(B_r,
                              N)  # To fill output dataframe when B0 constant

            #print('Uptake Ea (C1 - C5)' + str(Ea_U[0:M]))
            #print('Uptake Ea (C6 - C10)' + str(Ea_U[M:N]))
            print('Metabolic ratio between competitors' + str(Meta_ratio))

            # Set up model
            U = par.params(N, M, T, k, Tref, T_pk, B_g, B_r, Ma, Ea_U, Ea_R,
                           Ea_D, Meta_ratio)[0]  # make less than 1
            R = par.params(N, M, T, k, Tref, T_pk, B_g, B_r, Ma, Ea_U, Ea_R,
                           Ea_D, Meta_ratio)[1]  # make less than 1
            l = par.params(N, M, T, k, Tref, T_pk, B_g, B_r, Ma, Ea_U, Ea_R,
                           Ea_D, Meta_ratio)[2]
            p = par.params(N, M, T, k, Tref, T_pk, B_g, B_r, Ma, Ea_U, Ea_R,
                           Ea_D, Meta_ratio)[3]
            l_sum = np.sum(l, axis=1)
            pars = (U, R, l, p, l_sum, Ea_U, Ea_R, Ea_D, N, M, T, Tref, B_r,
                    B_g, Ma, k, ass, Meta_ratio)

            #print('Metabolic ratio (C1 - C5)' + str(np.round(np.diag(U[5:10])/R[5:10], 3)))
            #print('Metabolic ratio (C6 - C10)' + str(np.round(np.diag(U)/R[0:5],3)))
            #print(np.round(U, 3))
            #print(np.round(R, 3))

            # Run model
            pops = odeint(mod.metabolic_model, y0=x0, t=t, args=pars)
            pops = np.round(pops, 3)

            # Steady state test
            ss_test = np.round(
                abs((pops[t_fin - 1, 0:N]) - (pops[t_fin - 50, 0:N])), 3)
            #print((ss_test))
            while True:
                if np.any(ss_test > 0):
                    t = sc.linspace(0, 99, 100)
                    pops2 = odeint(mod.metabolic_model,
                                   y0=pops[t_fin - 1, :],
                                   t=t,
                                   args=pars)
                    pops = np.append(pops, pops2, axis=0)
                    t_fin = t_fin + 100
                    ss_test = np.round(
                        abs((pops[t_fin - 1, 0:N]) - (pops[t_fin - 50, 0:N])),
                        3)
                elif np.all(ss_test == 0):
                    break
                else:
                    pops = pops
            print(t_fin)

            pops = np.round(pops, 3)

            print('Bacteria mass at equilibrium (C1 - C5)' +
                  str(pops[len(pops) - 1, 0:M]))
            print('Bacteria mass at equilibrium (C6 - C10)' +
                  str(pops[len(pops) - 1, M:N]))
            print('Resource mass at equilibrium (S1 - S5)' +
                  str(pops[len(pops) - 1, N:N + M]))

            # Output for analysis in R
            T_fin_B = pops[t_fin - 1, 0:N]
            T_fin_N = np.tile(pops[t_fin - 1, N:N + M], rep)
            T_fin = sc.full([N], t_fin)
            output_tmp = np.append(output_tmp,
                                   np.column_stack(
                                       (T_fin_B, T_fin_N, Ea_1_U, Ea_1_R, Temp,
                                        B_n, N_n, T_fin, B_g_1, B_r_1)),
                                   axis=0)

            # if j == ass-1:
            #     break

            # Assembly
            rem_find = pops[t_fin - 1, 0:N]  # final individuals numbers
            ext = np.where(rem_find < 0.01)  # Eas to keep
            rem_find = np.where(rem_find < 0.01, 0.1,
                                rem_find)  # replace extinct with 0.1
            x0 = np.concatenate(
                (rem_find, pops[t_fin - 1, N:N + M]))  # new x0 with nutrients

            # Varying temp sensitivity
            Ea_tmp_U = np.repeat(np.array(
                [0.6, 0.7, 0.8, 0.9,
                 1.0]), N)  # Create large temporary Ea for new species
            Ea_tmp_U = shuffle(Ea_U_tmp2)  # randomise vector
            Ea_tmp_U = Ea_tmp_U[0:len(
                ext[0])]  # Cut vector so one Ea for each individual
            Ea_U[ext] = Ea_tmp_U  # Replace removed Eas with new Eas
            #Ea_tmp_R = np.repeat(np.array([0.6, 0.7, 0.8, 0.9, 1.0]),N) # Create large temporary Ea for new species
            # shuffle(Ea_R_tmp2, random_state=1) # randomise vector
            # Ea_tmp_R = Ea_R_tmp2[0:len(ext[0])] # Cut vector so one Ea for each individual
            # Ea_R[ext] = Ea_tmp_R # Replace removed Eas with new Eas

            # Change relationship between old B and new one migrating in
            R_ext_tmp = np.array(ext)
            R_ext_tmp[R_ext_tmp > M] = R_ext_tmp[
                R_ext_tmp > M] - M  # - M so find which nut it had
            R_ext = np.unique(
                R_ext_tmp
            )  # remove duplicates, i.e. if both competitors die (wont happen)
            R_func_new = np.repeat(np.array([0.8, 0.9, 1, 1.1, 1.2]),
                                   50)  # new U/Rm conditions
            R_func_new = shuffle(R_func_new)  # shuffle U/Rm conditions
            Meta_ratio[R_ext] = R_func_new[R_ext]

            # Varying temperature sensitivity
            #B_g_tmp_2 = np.exp(2.5 + (-5 * Ea_tmp))
            #B_r_tmp_2 = 0.5 *(np.exp(2.5 + (-5 * Ea_tmp))) #(0.5 * B_g_tmp_2)
            #B_g_tmp_2 = B_g_tmp_2[0:len(ext[0])] # Cut vector so one Ea for each individual
            #B_r_tmp_2 = B_r_tmp_2[0:len(ext[0])] # Cut vector so one Ea for each individual
            #B_g[ext] = B_g_tmp_2 # Replace removed Eas with new Eas
            #B_r[ext] = B_r_tmp_2 # Replace removed Eas with new Eas
            result_array = np.append(result_array, pops, axis=0)

        x0 = np.concatenate((sc.full([N], (0.1)), sc.full([M], (1.0))))
        output = np.column_stack((row, output_tmp))
        output_tmp_lrg = np.append(output_tmp_lrg, output, axis=0)

    #print(result_array[len(result_array)-1,0:N]   )

    #### Save outputs ####
    #np.savetxt('Smith_params_new_temp_size_brm_ss.csv', output_tmp_lrg, delimiter=',')
    #np.savetxt('sens_analysis_B_g-0.7.csv', output_tmp_lrg, delimiter=',')
    #np.savetxt('output_low-peak_traits_size_comp.csv', output_tmp_lrg, delimiter=',')
    #np.savetxt('raw_test_ss.csv', result_array, delimiter=',')
    #result_array = result_array[t_fin:len(result_array),:]
    #   result_array = np.append(result_array, np.column_stack((pops[t_fin,0:N], np.repeat(pops[t_fin,N:N+M], rep))), axis=0)
    # result_array = result_array[N:t_n_output,:]
    # output_array = np.empty((N,3))
    # for i in range(t_n):
    #     T = 273.15 + i # temperature
    #     output = np.column_stack((np.array((np.repeat(T,N ))),Ea, Ea_D))
    #     output_array = np.append(output_array, output, axis=0)
    # output_array = output_array[N:t_n_output,:]

    # final = np.column_stack((output_array, result_array))

    # np.savetxt('final_nov_2019.csv', final, delimiter=',')

    #### Plot output ####
    t_plot = sc.linspace(0, len(result_array), len(result_array))
    plt.plot(t_plot,
             result_array[:, 0:N],
             'g-',
             label='Consumers',
             linewidth=0.7)
    plt.plot(t_plot,
             result_array[:, N:N + M],
             'b-',
             label='Resources',
             linewidth=0.7)
    #plt.plot(t, pops[:,0:N], 'g-', label = 'Consumers', linewidth=0.7)
    #plt.plot(t, pops[:,N:N+M], 'b-', label = 'Resources', linewidth=0.7)
    plt.grid
    plt.ylabel('Population density')
    plt.xlabel('Time')
    plt.title('Bacteria-Resource population dynamics')
    plt.legend([
        Line2D([0], [0], color='green', lw=2),
        Line2D([0], [0], color='blue', lw=2)
    ], ['Bacteria', 'Resources'])
    #plt.legend([Line2D([0], [0], color='green', lw=2)], ['Consumers'])
    #plt.savefig('Figure_ein_exist_2.png')
    #plt.ylim([0, 10])
    plt.show()
Exemplo n.º 3
0
Ma = 1 # Mass
Ea_D = np.repeat(3.5,N) # Deactivation energy - only used if use Sharpe-Schoolfield temp-dependance
Ea_CUE = 0.3
lf = 0.4 # Leakage
k = 0.0000862 # Boltzman constant7

B_U = np.repeat(2, N)
B_R = B_U * (1 - lf) - 0.2 * B_U # B0 for respiration
Ea_U = np.random.beta(25, ((25 - 1/3) / 0.8) + 2/3 - 25, N)
Ea_R = Ea_U - Ea_CUE * (B_U * (1 - lf) - B_R) / B_R
# B_U = (10**(2.84 + (-4.96 * Ea_U))) + 3 # B0 for uptake - ** NB The '+4' term is added so B_U>> B_R, otherwise often the both consumers can die and the resources are consumed
# B_R = (10**(1.29 + (-1.25 * Ea_R))) # B0 for respiration
T_pk_U = Tref + np.random.normal(35, 3, size = N)
T_pk_R = T_pk_U + 3

U0 = par.params(N, M, Tref, k, Tref, T_pk_U, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D, lf)[0]
R0 = par.params(N, M, Tref, k, Tref, T_pk_R, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D, lf)[1]
l = par.params(N, M, Tref, k, Tref, T_pk_U, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D, lf)[2]
l_sum = np.sum(l, axis=1)
B0_CUE = np.mean((U0 @ (1 - l_sum) - R0)/(np.sum(U0, axis = 1)))
np.round(B0_CUE, 3) ## = 0.016

### Testing
T = 273.15
U = par.params(N, M, T, k, Tref, T_pk_U, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D, lf)[0] # Uptake
R = par.params(N, M, T, k, Tref, T_pk_R, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D, lf)[1] # Respiration
CUE = (U @ (1 - l_sum) - R)/(np.sum(U, axis = 1))
np.round(np.mean(CUE), 3)


B0_CUE = 0.1 * np.exp((-Ea_CUE/k) * ((1/Tref)-(1/273.15)))
Exemplo n.º 4
0
@author: 10929
"""
# Load Packages
import torch
import torch.nn as nn
from pre_process import Segementation_Dataset, gen_data
from torch.utils.data import DataLoader
from torch.optim import Adam
import numpy as np
import tqdm
import matplotlib.pyplot as plt
import os
from parameters import params

config = params()
#%% Define Model


class FCNN(nn.Module):
    """Input->Conv1->ReLU->Conv2->ReLU->MaxPool->Conv3->ReLU->UpSample->Conv4->Output"""
    def __init__(self, channels, kernels, paddings):
        super(FCNN, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(in_channels=channels[0],
                      out_channels=channels[1],
                      kernel_size=kernels[0],
                      padding=paddings[0]),
            nn.ReLU(inplace=True),
            nn.Conv2d(in_channels=channels[1],
                      out_channels=channels[2],
scripts_root = script_dir.split(script_dir.split(os.sep)[-1])[0]

sys.path.append(script_dir)
sys.path.append(scripts_root + os.sep + "_tools")

from cq_model_generator import All, ModelGenerator

import parameters
reload(parameters)

import cq_socket_strips
reload(cq_socket_strips)

family = All  # set to All to generate all series

series = [
    cq_socket_strips.socket_strip, cq_socket_strips.angled_socket_strip,
    cq_socket_strips.smd_socket_strip
]

options = sys.argv[2:] if len(sys.argv) >= 3 else []
#options = [["list"]]

gen = ModelGenerator(scripts_root, script_dir, saveToKicad=False)
#gen.kicadStepUptools = False
gen.footprints_dir = "\\\MEDIA\MyStuff\Electronics\KiCad\New\genmod"
gen.setLicense(ModelGenerator.alt_license)
gen.makeModels(options, series, family, parameters.params())

### EOF ###
# NOTE: many footprints are based on legacy dimensions which does not have any documented datasheet sources
#       see parameter.yaml for which
#

from parameters import params

import socket_strips

if __name__ == '__main__':

    series = [
        socket_strips.pinSocketVerticalTHT,
        socket_strips.pinSocketHorizontalTHT,
        socket_strips.pinSocketVerticalSMD
    ]

    params = params()
    #    models = params.getSampleModels(series, 4)
    models = params.getAllModels(series)
    i = 0
    for variant in models.keys():
        params = models[variant].params
        model = models[variant].model(params)
        if model.make_me:
            model.make()
        i += 1

    print "\nFootprints made:", i

### EOF ###
def ass_temp_run(t_fin, N, M, T, Tref, Ma, ass, Ea_D, lf, p_value, typ, K, inv,
                 sp):
    '''
    Main function for the simulation of resource uptake and growth of microbial communities.
    '''

    # Setted Parameters
    k = 0.0000862  # Boltzman constant
    a = 15  # The alpha value for beta distribution in Ea
    B_R = 1.70  # Using CUE0 = 0.22, mean growth rate = 0.48
    B_U = 4.47  # CUE0 = 0.22

    ### Creating empty array for storing data ###
    result_array = np.empty((0, N + M))  # Array to store data in for plotting
    rich_series = np.empty((0))
    U_out_total = np.empty((0, M))
    # U_ac_total = np.empty((0,N))
    R_out = np.empty((0, N))
    CUE_out = np.empty((0, N))
    Ea_CUE_out = np.empty((0, N))
    overlap = np.empty((0, N))
    crossf = np.empty((0, N))
    invasion_result = np.empty((0, N + sp + M))
    inv_U = np.empty((0, M))
    inv_R = np.empty((0, sp))

    for i in range(ass):

        ### Resetting values for every assembly ###

        x0 = np.concatenate((np.full([N], (0.1)), np.full(
            [M], (1))))  # Starting concentration for resources and consumers

        # Set up Ea (activation energy) and B0 (normalisation constant) based on Tom Smith's observations
        T_pk_U = 273.15 + np.random.normal(35, 5, size=N)
        T_pk_R = T_pk_U + 3
        Ea_U = np.random.beta(a, ((a - 1 / 3) / (0.82 / 4)) + 2 / 3 - a, N) * 4
        Ea_R = np.random.beta(a, ((a - 1 / 3) / (0.67 / 4)) + 2 / 3 - a, N) * 4
        # Ea_R = Ea_U - Ea_CUE * (B_U * (1 - lf) - B_R) / B_R

        p = np.repeat(p_value, M)  # Resource input

        # Set up model
        U = par.params(N, M, T, k, Tref, T_pk_U, B_U, B_R, Ma, Ea_U, Ea_R,
                       Ea_D, lf)[0]  # Uptake
        R = par.params(N, M, T, k, Tref, T_pk_R, B_U, B_R, Ma, Ea_U, Ea_R,
                       Ea_D, lf)[1]  # Respiration
        l = par.params(N, M, T, k, Tref, T_pk_U, B_U, B_R, Ma, Ea_U, Ea_R,
                       Ea_D, lf)[2]  # Leakage
        l_sum = np.sum(l, axis=1)

        # Integration
        t = np.linspace(
            0, t_fin - 1,
            t_fin)  # resetting 't' if steady state not reached (see below)
        pars = (U, R, l, p, l_sum, N, M, typ, K
                )  # Parameters to pass onto model

        pops = odeint(mod.metabolic_model, y0=x0, t=t, args=pars)  # Integrate
        pops = np.round(pops, 7)

        ### Storing simulation results ###
        result_array = np.append(result_array, pops, axis=0)
        U_out_total = np.append(U_out_total, U, axis=0)
        R_out = np.append(R_out, [R], axis=0)

        ### Analysis ###

        # Competition for resources
        jaccard = np.array([[
            np.sum(np.minimum(U[i, ], U[j, ])) /
            np.sum(np.maximum(U[i, ], U[j, ])) for j in range(N)
        ] for i in range(N)])
        comp = np.mean(jaccard, axis=0)
        overlap = np.append(overlap, [comp], axis=0)
        # U_ac_total = np.append(U_ac_total, [comp*np.sum(U,axis=1)], axis = 0)

        # Cross-feeding
        leak = U @ l
        cf = np.array([[
            np.sum(np.minimum(leak[i], U[j])) /
            np.sum(np.maximum(leak[i], U[j])) for j in range(N)
        ] for i in range(N)])
        np.fill_diagonal(cf, 0)
        crossf = np.append(crossf, [np.mean(cf, axis=1)], axis=0)

        # Richness
        rich_series = np.append(
            rich_series, [len(np.where(pops[t_fin - 1, 0:N])[0])]
        )  # Get the consumer concentrations from last timestep and find out survivors

        # CUE
        CUE = (U @ (1 - l_sum) - R) / (np.sum(U, axis=1))
        CUE_out = np.append(CUE_out, [CUE], axis=0)
        Ea_CUE_out = np.append(Ea_CUE_out,
                               [B_R * (Ea_U - Ea_R) / (B_U * (1 - lf) - B_R)],
                               axis=0)

        # Invasion
        if inv == True:
            x0 = np.concatenate((pops[t_fin - 1,
                                      0:N], np.repeat(0.1, sp), pops[t_fin - 1,
                                                                     N:N + M]))

            T_pk_U = 273.15 + np.random.normal(35, 5, size=sp)
            T_pk_R = T_pk_U + 3
            Ea_U = np.random.beta(a, ((a - 1 / 3) /
                                      (0.82 / 4)) + 2 / 3 - a, sp) * 4
            Ea_R = np.random.beta(a, ((a - 1 / 3) /
                                      (0.67 / 4)) + 2 / 3 - a, sp) * 4
            Ea_D = np.repeat(3.5, sp)

            U_new = par.params(sp, M, T, k, Tref, T_pk_U, B_U, B_R, Ma, Ea_U,
                               Ea_R, Ea_D, lf)[0]  # Uptake
            CUE_new = np.max(CUE) + np.random.normal(0.001, 0.0001, sp)
            R_new = U_new @ (1 - l_sum) - CUE_new * (np.sum(U_new, axis=1))

            U = np.append(U, U_new, axis=0)
            R = np.append(R, R_new)

            pars = (U, R, l, p, l_sum, N + sp, M, typ, K
                    )  # Parameters to pass onto model
            pops = odeint(mod.metabolic_model, y0=x0, t=t,
                          args=pars)  # Integrate
            pops = np.round(pops, 7)

            invasion_result = np.append(invasion_result, pops, axis=0)
            inv_U = np.append(inv_U, U_new, axis=0)
            inv_R = np.append(inv_R, [R_new], axis=0)

    return result_array, rich_series, l, U_out_total, R_out, CUE_out, Ea_CUE_out, overlap, crossf, invasion_result, inv_U, inv_R
Exemplo n.º 8
0
K = 1 # Half saturation constant
k = 0.0000862 # Boltzman constant
result_array = np.empty((0,N+M)) # Array to store data in for plotting
CUE_out = np.empty((0,N))
rich_seires = np.empty((0,tv))
U_out_total = np.empty((0,M))
U_ac_total = np.empty((0,N))
x0 = np.concatenate((np.full([N], (0.1)),np.full([M], (0.1)))) # Starting concentration for resources and consumers
Ea_U = np.round(np.random.normal(1.5, 0.01, N),3)[0:N] # Ea for uptake
Ea_R = Ea_U - 0.4 # Ea for respiration, which should always be lower than Ea_U so 'peaks' later
B_U = (10**(2.84 + (-4.96 * Ea_U))) + 4 # B0 for uptake - ** NB The '+4' term is added so B_U>> B_R, otherwise often the both consumers can die and the resources are consumed
B_R = (10**(1.29 + (-1.25 * Ea_R))) # B0 for respiration
T_pk_U = Tref + np.random.normal(32, 5, size = N)
T_pk_R = T_pk_U + 3
p = np.concatenate((np.array([1]), np.repeat(1, M-1)))  # Resource input
U = par.params(N, M, T, k, Tref, T_pk_U, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D)[0] # Uptake
R = par.params(N, M, T, k, Tref, T_pk_R, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D)[1] # Respiration
l = par.params(N, M, T, k, Tref, T_pk_U, B_U, B_R,Ma, Ea_U, Ea_R, Ea_D)[2] # Leakage
l_sum = np.sum(l, axis=1)
rich = np.empty((0, tv))
t = np.linspace(0,t_fin-1,t_fin) # resetting 't' if steady state not reached (see below)
pars = (U, R, l, p, l_sum, N, M, typ, K) # Parameters to pass onto model
pops = odeint(mod.metabolic_model, y0=x0, t=t, args = pars) # Integrate
pops = np.round(pops, 7)
rem_find = pops[t_fin-1,0:N] # Get the consumer concentrations from last timestep
ext = np.where(rem_find<0.01) # Find which consumers have a concentration < 0.01 g/mL, i.e. are extinct
sur = np.where(rem_find>0.01)
# U_out = np.append(U_out, U[sur[0]], axis = 0)
U_out_total = np.append(U_out_total, U, axis = 0)
jaccard = np.zeros((N,N)) # Competition
np.fill_diagonal(jaccard,1)
def ass_temp_run(t, N, M, t_n, Tref, Ma, k, ass, x0, t_fin, T_pk, Ea_D, typ):
    result_array = np.empty((0, N + M))  # Array to store data in for plotting

    for i in range(
            20, t_n
    ):  # Run model at multiple temperatures, here set to just run at 20 C
        T = 273.15 + i  # Temperature

        # Set up Ea (activation energy) and B0 (normalisation constant)
        # Based on Tom Smith's observations
        Ea_U = np.round(np.random.normal(1.5, 0.01, 10),
                        3)[0:N]  # Ea for uptake
        Ea_R = Ea_U - 0.8  # Ea for respiration, which should always be lower than Ea_U so 'peaks' later
        B_U = (
            10**(2.84 + (-4.96 * Ea_U))
        ) + 4  # B0 for uptake - ** NB The '+4' term is added so B_U>> B_R, otherwise often the both consumers can die and the resources are consumed
        B_R = (10**(1.29 + (-1.25 * Ea_R)))  # B0 for respiration

        #print('')
        #print('Temperature =',i)

        for j in range(ass):

            #print('')
            #print('Assembly = ', j)
            t = sc.linspace(
                0, t_fin - 1,
                t_fin)  # resetting 't' if steady state not reached (see below)

            #print('Uptake Ea (C1 - C5)' + str(Ea_U[0:M]))
            #print('Uptake Ea (C6 - C10)' + str(Ea_U[M:N]))
            #print('Metabolic ratio between competitors' + str(Meta_ratio))

            # Set up model
            U = par.params(N, M, T, k, Tref, T_pk, B_U, B_R, Ma, Ea_U, Ea_R,
                           Ea_D)[0]  # Uptake
            R = par.params(N, M, T, k, Tref, T_pk, B_U, B_R, Ma, Ea_U, Ea_R,
                           Ea_D)[1]  # Respiration
            l = par.params(N, M, T, k, Tref, T_pk, B_U, B_R, Ma, Ea_U, Ea_R,
                           Ea_D)[2]  # Leakage
            p = par.params(N, M, T, k, Tref, T_pk, B_U, B_R, Ma, Ea_U, Ea_R,
                           Ea_D)[3]  # Resource input
            l_sum = np.sum(l, axis=1)
            pars = (U, R, l, p, l_sum, Ea_U, Ea_R, Ea_D, N, M, T, Tref, B_R,
                    B_U, Ma, k, ass, typ, K)  # Parameters to pass onto model

            # Run model
            pops = odeint(mod.metabolic_model, y0=x0, t=t,
                          args=pars)  # Integrate
            #pops = np.round(pops, 5)

            # Steady state test
            ss_test = np.round(
                abs((pops[t_fin - 1, 0:N]) - (pops[t_fin - 50, 0:N])), 3
            )  # Find difference between last timestep and timestep at t_fin - 50 (i.e. 150 if t_fin = 200)
            while True:
                if np.any(
                        ss_test > 0
                ):  # If there is a difference then that consumer not yet reached steady state
                    t = sc.linspace(
                        0, 99, 100)  # reset t so shorter, only 100 timesteps
                    pops2 = odeint(
                        mod.metabolic_model,
                        y0=pops[t_fin - 1, :],
                        t=t,
                        args=pars
                    )  # re-run model using last timestep concentrations of consumers and resources
                    pops = np.append(
                        pops, pops2, axis=0
                    )  # append results of additional run to orginial run
                    t_fin = t_fin + 100  # adjust timesteps number
                    ss_test = np.round(
                        abs((pops[t_fin - 1, 0:N]) - (pops[t_fin - 50, 0:N])),
                        3)  # Find again if consumers reached steady state now
                elif np.all(ss_test == 0):
                    break  # Once no difference in consumer concentration then stop performing additional model runs
                else:
                    pops = pops  # If at steady state then nothing happens

            t_fin = 100

            pops = np.round(pops, 7)
            # if j == ass-1:
            #     break

            ###Assembly###

            # Find which consumers have gone extinct
            rem_find = pops[
                t_fin - 1,
                0:N]  # Get the consumer concentrations from last timestep
            ext = np.where(
                rem_find < 0.01
            )  # Find which consumers have a concentration < 0.01 g/mL, i.e. are extinct
            rem_find = np.where(
                rem_find < 0.01, 0.1, rem_find
            )  # Replace extinct consumers with a new concentration of 0.1
            x0 = np.concatenate(
                (rem_find, pops[t_fin - 1, N:N + M])
            )  # Join new concentrations for consumers with those of resources

            # Create new consumers

            # New Ea_ and Ea_R
            Ea_tmp_U = np.round(np.random.normal(1.5, 0.01, 10), 3)[0:len(
                ext[0]
            )]  # Ea for uptake cut to length(ext),i.e. the number of extinct consumers
            Ea_U[ext] = Ea_tmp_U  # Replace removed Eas with new Eas
            Ea_R = Ea_U - 0.8

            # New B0
            B_U = 10**(2.84 + (-4.96 * Ea_U)) + 4
            B_R = 10**(1.29 + (-1.25 * Ea_R))

            #print(np.round(Ea_U, 3))

            result_array = np.append(result_array, pops, axis=0)

        x0 = np.concatenate((sc.full([N], (0.1)), sc.full([M], (0.1))))

    #### Plot output ####
    t_plot = sc.linspace(0, len(result_array), len(result_array))
    plt.plot(t_plot,
             result_array[:, 0:N],
             'g-',
             label='Consumers',
             linewidth=0.7)
    plt.plot(t_plot,
             result_array[:, N:N + M],
             'b-',
             label='Resources',
             linewidth=0.7)
    plt.grid
    plt.ylabel('Population density')
    plt.xlabel('Time')
    plt.title('Consumer-Resource population dynamics')
    plt.legend([
        Line2D([0], [0], color='green', lw=2),
        Line2D([0], [0], color='blue', lw=2)
    ], ['Consumer', 'Resources'])
    plt.show()

    U_out = (st.temp_growth(k, T, Tref, T_pk, N, B_U, Ma, Ea_U, Ea_D))

    return result_array, U_out, R