def imp_one_cycle(testdf, cd, cyc_loop, battery, datatype, windowlength,
                      polyorder, lenmax):
        """imports and fits a single charge discharge cycle of a battery
        file_val = directory containing current cycle
        cd = either 'c' for charge or 'd' for discharge
        cyc_loop = cycle number
        battery = battery name
        output: a dictionary of descriptors for a single battery"""

        # make sure this is an Excel spreadsheet by checking the file extension
        # assert file_val.split('.')[-1] == ('xlsx' or 'xls')

        # reads excel file into pandas
        # testdf = pd.read_excel(file_val)

        # extracts charge and discharge from the dataset
        (cycle_ind_col, data_point_col, volt_col, curr_col, dis_cap_col,
         char_cap_col, charge_or_discharge) = ccf.col_variables(datatype)
        charge, discharge = ccf.sep_char_dis(testdf, datatype)

        # determines if the charge, discharge indicator was inputted correctly
        # assigns daframe for fitting accordingly
        if cd == 'c':
            df_run = charge
        elif cd == 'd':
            df_run = discharge
        else:
            raise TypeError(
                "Cycle type must be either 'c' for charge or 'd' for discharge."
            )
        print('Generating descriptors for cycle number: ' + str(cyc_loop) + cd)
        # determines if a cycle should be passed into the descriptor
        # fitting function
        if (len(charge[volt_col].index) >= 10) and (len(
                discharge[volt_col].index) >= 10):
            # generates a dictionary of descriptors
            c = fitters.descriptor_func(df_run, cd, cyc_loop, battery,
                                        windowlength, polyorder, datatype,
                                        lenmax)
            # df_run[volt_col], df_run['Smoothed_dQ/dV']
            #c is the dictionary of descriptors here
        # eliminates cycle number and notifies user of cycle removal
        else:
            notice = 'Cycle ' + str(cyc_loop) + ' in battery ' + battery + \
                ' had fewer than 10 datapoints and was removed from the dataset.'
            print(notice)
            c = 'throw'
        # print('here is the c parameter in the imp_one_cycle: ')
        # print(c)
        return c
Beispiel #2
0
    def imp_one_cycle(file_val, cd, cyc_loop, battery):
        """imports and fits a single charge discharge cycle of a battery

        file_val = directory containing current cycle
        cd = either 'c' for charge or 'd' for discharge
        cyc_loop = cycle number
        battery = battery name

        output: a dictionary of descriptors for a single battery"""

        # make sure this is an Excel spreadsheet by checking the file extension
        assert file_val.split('.')[-1] == ('xlsx' or 'xls')

        # reads excel file into pandas
        testdf = pd.read_excel(file_val)

        # extracts charge and discharge from the dataset
        charge, discharge = ccf.sep_char_dis(testdf)

        # determines if the charge, discharge indicator was inputted correctly
        # assigns daframe for fitting accordingly
        if cd == 'c':
            df_run = charge
        elif cd == 'd':
            df_run = discharge
        else:
            raise TypeError(
                "Cycle type must be either 'c' for charge or 'd' for discharge.")

        # determines if a cycle should be passed into the descriptor
        # fitting function
        if (len(charge['Voltage(V)'].index) >= 10) and (len(discharge['Voltage(V)'].index) >= 10):
            # generates a dictionary of descriptors
            c = fitters.descriptor_func(
                df_run['Voltage(V)'], df_run['Smoothed_dQ/dV'], cd, cyc_loop, battery)
        # eliminates cycle number and notifies user of cycle removal
        else:
            notice = 'Cycle ' + str(cyc_loop) + ' in battery ' + battery + \
                ' had fewer than 10 datapoints and was removed from the dataset.'
            print(notice)
            c = 'throw'
        return c
Beispiel #3
0
def update_figure2(selected_step, contents, filename, date,
                   selected_row_indices):
    data = parse_contents(contents, filename, date)
    (charge, discharge) = ccf.sep_char_dis(data)
    filtered_data = discharge[discharge['Cycle_Index'] == selected_step]
    for i in filtered_data['Cycle_Index'].unique():
        dff = filtered_data[filtered_data['Cycle_Index'] == i]
        fig = plotly.tools.make_subplots(
            rows=2,
            cols=1,
            subplot_titles=('Smoothed dQ/dV Discharge Cycle',
                            'Cleaned dQ/dV Discharge Cycle'),
            shared_xaxes=True)
        marker = {'color': ['#0074D9'] * len(dff)}
        for i in (selected_row_indices or []):
            marker['color'][i] = '#FF851B'
        fig.append_trace(
            {
                'x': dff['Voltage(V)'],
                'y': dff['Smoothed_dQ/dV'],
                'type': 'scatter',
                'marker': marker,
                'name': 'Smoothed Data'
            }, 1, 1)
        fig.append_trace(
            {
                'x': dff['Voltage(V)'],
                'y': dff['dQ/dV'],
                'type': 'scatter',
                'marker': marker,
                'name': 'Raw Data'
            }, 2, 1)
        fig['layout']['showlegend'] = False
        fig['layout']['height'] = 800
        fig['layout']['margin'] = {'l': 40, 'r': 10, 't': 60, 'b': 200}
        fig['layout']['yaxis2']
    return fig
Beispiel #4
0
def update_slider_value(contents, filename, date):
    data = parse_contents(contents, filename, date)
    charge, discharge = ccf.sep_char_dis(data)
    return charge['Cycle_Index'].max()
Beispiel #5
0
def update_table2(contents, filename, date):
    data = parse_contents(contents, filename, date)
    charge, discharge = ccf.sep_char_dis(data)
    return discharge.to_dict('records')
Beispiel #6
0
import dash_table_experiments as dt
import pandas as pd
import io
import json
import plotly
import base64

##########################################
#Load Data
##########################################
#eventually add everything in folder and create a dropdown that loads that data into data

#for now just use some data we have
data = pd.read_excel('data/Clean_Whole_Sets/CS2_33_12_16_10CleanSet.xlsx')

charge, discharge = ccf.sep_char_dis(data)

#df_dqdv = ccf.calc_dv_dqdv('data/CS2_33/CS2_33_10_04_10.xlsx')
#df_dqdv = ccf.calc_dv_dqdv(data)
#charge, discharge = ccf.sep_char_dis(data)

##########################################
#App Layout
##########################################
app = dash.Dash()  #initialize dash

Introduction = dcc.Markdown('''
        # ChaChi
        ## Interface for visualizing battery cycle data
        #'''),  #Add some Markdown
def get_model_dfs_for_jupyter(df_clean, datatype, cyc, lenmax, peak_thresh):
    # this function is analagous to the get_model_dfs function in the app.py file
    (cycle_ind_col, data_point_col, volt_col, curr_col, dis_cap_col,
     char_cap_col, charge_or_discharge) = ccf.col_variables(datatype)
    clean_charge, clean_discharge = ccf.sep_char_dis(
        df_clean[df_clean[cycle_ind_col] == cyc], datatype)
    windowlength = 75
    polyorder = 3
    # speed this up by moving the initial peak finder out of this, and just have those two things passed to it
    i_charge, volts_i_ch, peak_heights_c = descriptors.fitters.peak_finder(
        clean_charge, 'c', windowlength, polyorder, datatype, lenmax,
        peak_thresh)

    V_series_c = clean_charge[volt_col]
    dQdV_series_c = clean_charge['Smoothed_dQ/dV']
    par_c, mod_c, indices_c = descriptors.fitters.model_gen(
        V_series_c, dQdV_series_c, 'c', i_charge, cyc, peak_thresh)
    model_c = descriptors.fitters.model_eval(V_series_c, dQdV_series_c, 'c',
                                             par_c, mod_c)
    if model_c is not None:
        mod_y_c = mod_c.eval(params=model_c.params, x=V_series_c)
        myseries_c = pd.Series(mod_y_c)
        myseries_c = myseries_c.rename('Model')
        model_c_vals = model_c.values
        new_df_mody_c = pd.concat([
            myseries_c, V_series_c, dQdV_series_c, clean_charge[cycle_ind_col]
        ],
                                  axis=1)
    else:
        mod_y_c = None
        new_df_mody_c = None
        model_c_vals = None
    # now the discharge:
    i_discharge, volts_i_dc, peak_heights_d = descriptors.fitters.peak_finder(
        clean_discharge, 'd', windowlength, polyorder, datatype, lenmax,
        peak_thresh)
    V_series_d = clean_discharge[volt_col]
    dQdV_series_d = clean_discharge['Smoothed_dQ/dV']
    par_d, mod_d, indices_d = descriptors.fitters.model_gen(
        V_series_d, dQdV_series_d, 'd', i_discharge, cyc, peak_thresh)
    model_d = descriptors.fitters.model_eval(V_series_d, dQdV_series_d, 'd',
                                             par_d, mod_d)
    if model_d is not None:
        mod_y_d = mod_d.eval(params=model_d.params, x=V_series_d)
        myseries_d = pd.Series(mod_y_d)
        myseries_d = myseries_d.rename('Model')
        new_df_mody_d = pd.concat([
            -myseries_d, V_series_d, dQdV_series_d,
            clean_discharge[cycle_ind_col]
        ],
                                  axis=1)
        model_d_vals = model_d.values
    else:
        mod_y_d = None
        new_df_mody_d = None
        model_d_vals = None
    # save the model parameters in the database with the data
    if new_df_mody_c is not None or new_df_mody_d is not None:
        new_df_mody = pd.concat([new_df_mody_c, new_df_mody_d], axis=0)
    else:
        new_df_mody = None
    # combine the charge and discharge
    # update model_c_vals and model_d_vals with peak heights

    return new_df_mody, model_c_vals, model_d_vals, peak_heights_c, peak_heights_d