def data2Exprate(Csv, low, high):
    # derivative of the actual experimental data
    # get dataframe
    df = pd.read_csv(Csv)
    # data
    conversion, time, temperature = read_filtrated_datafile(df, low, high)
    # numerical derivation of the experimental data
    der = np.diff(conversion) / np.diff(time)
    # new time points
    t = (time[:-1] + time[1:]) / 2.0
    # interpolate the derivative
    f = interpolate.interp1d(t, der, fill_value='extrapolate')
    # calculate the derivative in the old time levels
    dadt = f(time)
    return dadt
def data2PolFit(Csv, low, high, pdeg, npoints):
    # actual experimental conversion to polynomial fit
    # pdeg: degree of polynomial

    # get dataframe
    df = pd.read_csv(Csv)
    # data
    conversion, time, temperature = read_filtrated_datafile(df, low, high)
    # polynomial fit
    z = np.polyfit(time, conversion, pdeg)
    polynomial = np.poly1d(z)
    t_polfit = time
    # t_polfit   = np.linspace(time[0],time[-1],1000) # interpolate to these new points
    a_polfit = polynomial(t_polfit)

    return a_polfit
Example #3
0
def graph_experimental_data(DATA_DIR, OUTPUT_DIR):

    # make output directory
    DIR = os.path.join(OUTPUT_DIR, 'experimental')
    if not os.path.exists(DIR):
        os.makedirs(DIR)

    # concentration range
    low = 0.0
    high = 1.0

    # get the csv data in a list
    Csvs = get_data(DATA_DIR)
    # filnames
    # filnames
    fnames = [f.split('.csv')[0] for f in os.listdir(DATA_DIR)]

    fig = plt.figure()
    # export a graph for the fitting of the integral reaction rate
    Plot = os.path.join(DIR, 'experimental_conversion.' + graph_format)

    for indx, Csv in enumerate(Csvs):
        df = pd.read_csv(Csv)
        # read data file
        conversion, time, temperature = read_filtrated_datafile(df, low, high)
        # read variable units
        timeUnits, tempUnits = read_units(df)
        plt.scatter(time, conversion, s=10, label=str(temperature) + tempUnits)
        # export experimental data
        data = {
            'time': time,
            'conversion': conversion,
            'temperature': temperature,
            'temperature_units': tempUnits
        }
        df = pd.DataFrame(data)
        csv_name = fnames[indx] + '_experimental_conversion.csv'
        df.to_csv(os.path.join(DIR, csv_name), index=False)

    plt.xlim(0, )
    plt.ylim(0, 1.0)
    plt.legend()
    plt.ylabel('conversion')
    plt.xlabel('time [' + timeUnits + ']')
    plt.tight_layout()
    plt.savefig(Plot, format=graph_format, dpi=graph_dpi)
    plt.close()  # to avoid memory warnings
def export_experimental_reaction(DATA_DIR, OUTPUT_DIR, pdeg, npoints):

    # pdeg: degree of the polynomial
    # npoints: numper of polynomial interpolation points

    # make output directory
    DIR = os.path.join(OUTPUT_DIR, 'experimental')
    if not os.path.exists(DIR):
        os.makedirs(DIR)

    # concentration range
    low = 0.0
    high = 1.0

    # get the csv data in a list
    Csvs = get_data(DATA_DIR)
    # filnames
    fnames = [f.split('.csv')[0] for f in os.listdir(DATA_DIR)]

    for indx, Csv in enumerate(Csvs):

        # get experimental conversion
        df = pd.read_csv(Csv)
        conversion, time, temperature = read_filtrated_datafile(df, low, high)
        # experimental reaction rate from polynomial conversion
        dadt_polynomial = data2Polrate(Csv, low, high, pdeg, npoints)
        # experimental reaction rate from actual conversion
        dadt_numerical = data2Exprate(Csv, low, high)

        data = {
            'time': time,
            'dadt_polynomial': dadt_polynomial,
            'dadt_numerical': dadt_numerical,
            'temperature': temperature
        }

        rate_df = pd.DataFrame(data)
        csv_name = fnames[indx] + '_reaction_rate.csv'
        rate_df.to_csv(os.path.join(DIR, csv_name), index=False)
def data2Polrate(Csv, low, high, pdeg, npoints):
    # actual experimental conversion to polynomial fit
    # then derivative of the polynomial fit on npoints new time data
    # then interpolate of the derivative on original time data
    # pdeg: degree of polynomial

    # get dataframe
    df = pd.read_csv(Csv)
    # data
    conversion, time, temperature = read_filtrated_datafile(df, low, high)
    # polynomial fit
    z = np.polyfit(time, conversion, pdeg)
    polynomial = np.poly1d(z)
    t_polfit = np.linspace(time[0], time[-1],
                           1000)  # interpolate to these new points
    a_polfit = polynomial(t_polfit)
    # get the reaction rate from the polynomial
    dadt = np.array([derivative(polynomial, ti, dx=1e-6) for ti in t_polfit])
    # interpolate the derivative
    f = interpolate.interp1d(t_polfit, dadt, fill_value='extrapolate')
    # calculate the derivative in the old time levels
    dadt = f(time)
    return dadt
def ratedata2Fit(DATA_DIR,OUTPUT_DIR,modelNames,low,high,pdeg,npoints,fitExp):
    # low        : lower limit for conversion fraction
    # high       : upper limit for conversion fraction
    # DATA_DIR   : directory containing data
    # OUTPUT_DIR : output directory

    # make output directory
    DIR = os.path.join(OUTPUT_DIR,'conversion_regression')
    if not os.path.exists(DIR):
        os.makedirs(DIR)

    # get csvs
    Csvs = get_data(DATA_DIR)

    # filnames
    fnames = os.listdir(DATA_DIR)

    for indx, Csv in enumerate(Csvs):
        # get dataframe
        df = pd.read_csv(Csv)

        # get experimental conversion
        conversion, time, temperature = read_filtrated_datafile(df,low,high)
        # read variable units
        timeUnits, tempUnits = read_units(df)
        # experimental reaction rate from polynomial conversion
        dadt_polynomial = data2Polrate(Csv,low,high,pdeg,npoints)
        # experimental reaction rate from actual conversion
        dadt_numerical  = data2Exprate(Csv,low,high)

        # accuracy criteria
        ss_res      = [] # sum of square residuals (ideal = 0)
        mse         = [] # mean square error (ideal = 0)
        res_AEr     = [] # residuals absolute error (ideal = 0)
        res_REr     = [] # residuals relative error (ideal = 0)
        k_arrhenius = [] # Arrhenius rate constant

        # loop over all models
        for modelName in modelNames:
            # pick up a model
            model = Model(modelName)
            if modelName not in ['D2','D4']:
                # experimental integral reaction rate
                y = conversion
                # perform regression
                k, yfit = conversionRegression(time,conversion, modelName)
                # calculate the modeled differential reaction rate
                dadt_model = np.array( [k*model.f(a) for a in yfit] )
                yfit = dadt_model
            else:
                # experimental integral reaction rate
                y = np.array([model.g(c) for c in conversion])
                # perform regression
                k, yfit = integralRateRegression(time,conversion, modelName)
                # calculate the modeled differential reaction rate
                dadt_model = np.array( [k*model.f(a) for a in conversion] )
                yfit = dadt_model
            
            if fitExp:
                y = dadt_numerical
            else:
                y = dadt_polynomial
            # calculate validation errors
            ss_res.append(ssRes(y,yfit))
            mse.append(MSE(y,yfit))
            res_AEr.append(resAEr(y,yfit))
            res_REr.append(resREr(y,yfit))
            k_arrhenius.append(k)
        
        # export regression accuracy data
        error_data = {
            'model'       : modelNames,
            'ss_res'      : ss_res,
            'mse'         : mse,
            'resAEr'      : res_AEr,
            'resREr'      : res_REr,
            'temperature' : temperature,
            'temperature_units': tempUnits
        }
        df = pd.DataFrame(error_data)
        prefix = fnames[indx].split('.csv')[0]
        if fitExp:
            df.to_csv(os.path.join(DIR,prefix + '_experimental_rate_fit_accuracy.csv'),index=False)
        else:
            df.to_csv(os.path.join(DIR,prefix + '_polynomial_rate_fit_accuracy.csv'),index=False)
Example #7
0
def rateFitGraphs(DATA_DIR, OUTPUT_DIR, low, high, pdeg, npoints, fitExp):

    # get names (without format suffix) of the data csv files
    # bnames : base names
    bnames = [f.split('.csv')[0] for f in os.listdir(DATA_DIR)]
    # paths of the experimental data csv files
    data_Csvs = get_data(DATA_DIR)
    # metrics directory
    METRICS_DIR = os.path.join(OUTPUT_DIR, 'conversion_regression')
    # paths of the metrics from the conversion regression
    metrics_Csvs = get_data(METRICS_DIR)
    # filter proper csvs
    metrics_Csvs = [
        f for f in metrics_Csvs if 'conversion_regression_accuracy' in f
    ]

    # zip data files and metrics
    data = sortOnData(bnames, data_Csvs)
    metrics = sortOnData(bnames, metrics_Csvs)
    data_and_metrics = list(zip(data, metrics))

    # loop over all data
    for i_csv, csv in enumerate(data_and_metrics):

        # make directory for the graphs
        DIR = os.path.join(METRICS_DIR, 'png')
        DIR = os.path.join(DIR, 'rate_fit')
        GRAPH_DIR = os.path.join(DIR, bnames[i_csv])
        if not os.path.exists(GRAPH_DIR):
            os.makedirs(GRAPH_DIR)

        # data dataframe
        data_df = pd.read_csv(csv[0])
        # metrics dataframe
        metrics_df = pd.read_csv(csv[1])
        # data
        conversion, time, temperature = read_filtrated_datafile(
            data_df, low, high)
        # read variable units
        timeUnits, tempUnits = read_units(data_df)

        # experimental reaction rate from polynomial conversion
        dadt_polynomial = data2Polrate(csv[0], low, high, pdeg, npoints)
        # experimental reaction rate from actual conversion
        dadt_numerical = data2Exprate(csv[0], low, high)

        modelNames = metrics_df['model'].tolist()
        ks = metrics_df['k_arrhenius'].to_numpy()

        # calculate experimental reaction rate
        if fitExp:
            y = dadt_numerical
        else:
            y = dadt_polynomial

        x = time

        # loop over models
        for i_model, modelName in enumerate(modelNames):
            # pick up a model
            model = Model(modelName)
            # choose the corresponding arrhenius rate constant
            k = ks[i_model]

            if modelName not in ['D2', 'D4']:
                # calculate the modeled differential reaction rate
                tfit = np.linspace(time[0], time[-1], num=npoints)
                yfit = np.array([model.alpha(t, k) for t in tfit])
                dadt_model = np.array([k * model.f(a) for a in yfit])
                yfit = dadt_model
                xfit = tfit
                # export a graph for the fitting of the integral reaction rate
                fig = plt.figure()
                if fitExp:
                    ext = '_experimental_rate_fit.'
                else:
                    ext = '_polynomial_rate_fit.'
                fname = modelName + '_' + bnames[i_csv] + ext + graph_format
                Plot = os.path.join(GRAPH_DIR, fname)
                plt.scatter(x, y, s=10, label='experimental')
                plt.plot(xfit, yfit, lw=lwidth, label=modelName)
                plt.legend()
                plt.ylabel(r'reaction rate')
                plt.xlabel('time [' + timeUnits + ']')
                plt.tight_layout()
                plt.savefig(Plot, format=graph_format, dpi=graph_dpi)
                plt.close()  # to avoid memory warnings
Example #8
0
def integralRegressionGraphs(DATA_DIR, OUTPUT_DIR, low, high, npoints):

    # get names (without format suffix) of the data csv files
    # bnames : base names
    bnames = [f.split('.csv')[0] for f in os.listdir(DATA_DIR)]
    # paths of the experimental data csv files
    data_Csvs = get_data(DATA_DIR)
    # metrics directory
    METRICS_DIR = os.path.join(OUTPUT_DIR, 'integral_regression')
    # paths of the metrics from the integral regression
    metrics_Csvs = get_data(METRICS_DIR)

    # zip data files and metrics
    data = sortOnData(bnames, data_Csvs)
    metrics = sortOnData(bnames, metrics_Csvs)
    data_and_metrics = list(zip(data, metrics))

    # loop over all data
    for i_csv, csv in enumerate(data_and_metrics):

        # make directory for the graphs
        DIR = os.path.join(METRICS_DIR, 'png')
        GRAPH_DIR = os.path.join(DIR, bnames[i_csv])
        if not os.path.exists(GRAPH_DIR):
            os.makedirs(GRAPH_DIR)

        # data dataframe
        data_df = pd.read_csv(csv[0])
        # metrics dataframe
        metrics_df = pd.read_csv(csv[1])
        # data
        conversion, time, temperature = read_filtrated_datafile(
            data_df, low, high)
        # read variable units
        timeUnits, tempUnits = read_units(data_df)

        modelNames = metrics_df['model'].tolist()
        ks = metrics_df['k_arrhenius'].to_numpy()

        # loop over models
        for i_model, modelName in enumerate(modelNames):
            # pick up a model
            model = Model(modelName)
            # choose the corresponding arrhenius rate constant
            k = ks[i_model]
            # calculate experimental integral reaction rate
            y = np.array([model.g(a) for a in conversion])
            x = time
            # fit
            tfit = np.linspace(time[0], time[-1], num=npoints)
            yfit = k * tfit
            xfit = tfit

            # export a graph for the fitting of the integral reaction rate
            fig = plt.figure()
            fname = modelName + '_' + bnames[
                i_csv] + '_integral_regression.' + graph_format
            Plot = os.path.join(GRAPH_DIR, fname)
            plt.scatter(x, y, s=10, label='experimental')
            plt.plot(xfit, yfit, lw=lwidth, label=r'kt')
            plt.legend()
            plt.ylabel(r'g (a)')
            plt.xlabel('time [' + timeUnits + ']')
            plt.tight_layout()
            plt.savefig(Plot, format=graph_format, dpi=graph_dpi)
            plt.close()  # to avoid memory warnings
def integral_isoconversional(DATA_DIR, OUTPUT_DIR, low, high):
    def interpolate_time(y, x, interpolated_x):
        # arguments
        # x (numpy array) : conversion
        # y (numpy array) : time

        # returns
        # the time for the interpolated points

        y = time
        x = conversion
        interpol = interp1d(x, y, kind='nearest', fill_value="extrapolate")
        return interpol(interpolated_x)

    def isoconversional_enthalpy(time, temperature):
        # arguments
        # time (numpy array)
        # temperature (numpy array)

        # returns
        # the activation enthalpy (Ea) in a list like [activation enthalpy, mean square error]
        # and the ln[g(a)A] factor

        # gas constant
        R = 8.31446261815324  # J K-1 mol-1

        x = 1.0 / temperature
        y = np.log(time)

        x = x.reshape((-1, 1))

        # linear regression for the logarithmic Arrhenius equation
        regr = LinearRegression()
        regr.fit(x, y)
        y_pred = regr.predict(x)

        Ea = regr.coef_[0] * R * 1.0e-3  # in kJ mol-1
        gA = regr.intercept_
        MSE = mean_squared_error(y, y_pred)
        R2 = r2_score(y_pred, y)

        return [Ea, MSE], gA

    Csvs = get_data(DATA_DIR)

    npoints = 10
    interpolated_conversion = np.linspace(low, high, npoints)

    isoconversional_data = {'conversion': interpolated_conversion}

    for csv in Csvs:
        df = pd.read_csv(csv)
        # read a data file
        conversion, time, temperature = read_filtrated_datafile(df, low, high)
        if df['temperature units'][0] == 'C':
            theta = df['temperature'].to_numpy()
            T = Celsius2Kelvin(theta)
        else:
            T = df['temperature'].to_numpy()
        temperature = T[0]
        # get time in the specified interpolated_conversion points
        interpolated_time = interpolate_time(time, conversion,
                                             interpolated_conversion)
        isoconversional_data.update({str(temperature): interpolated_time})

    df = pd.DataFrame.from_dict(isoconversional_data)

    # linear regression

    y = df['conversion'].to_numpy()

    temperature = [float(i) for i in df.columns.values if i != 'conversion']
    temperature = np.array(temperature)

    Ea = []  # Activation energy (kJ/mol)
    intercept = []  # Intercept ln[A g(a)]
    MSE = []  # Standard deviation
    R2 = []  # Determination coefficient

    dfSize = df.shape[0]
    for i in range(dfSize):
        time = df.iloc[i, 1::].to_numpy()
        enthalpy, gA = isoconversional_enthalpy(time, temperature)
        Ea.append(enthalpy[0])
        MSE.append(enthalpy[1])
        intercept.append(gA)

    isoconversional_data = {
        'activation_enthalpy': Ea,
        'std': MSE,
        'intercept': intercept,
        'conversion': y
    }
    df = pd.DataFrame.from_dict(isoconversional_data)

    # make output directory
    DIR = os.path.join(OUTPUT_DIR, 'isoconversional')
    if not os.path.exists(DIR):
        os.makedirs(DIR)

    df.to_csv(os.path.join(DIR, 'isoconversional_energy.csv'), index=False)

    pass