Example #1
0
def column_of_data(data_file_path, start, column, end="-1", units=""):
    """This function extracts a column of data from a ProCoDA data file.

    Parameters
    ----------
    data_file_path : string
        File path. If the file is in the working directory, then the file name
        is sufficient.

    start : int
        Index of first row of data to extract from the data file

    end : int, optional
        Index of last row of data to extract from the data
        Defaults to -1, which extracts all the data in the file

    column : int or string
        int:
            Index of the column that you want to extract. Column 0 is time.
            The first data column is column 1.
        string:
            Name of the column header that you want to extract

    units : string, optional
        The units you want to apply to the data, e.g. 'mg/L'.
        Defaults to "" which indicates no units

    Returns
    -------
    numpy array
        Experimental data with the units applied.

    Examples
    --------
    column_of_data(Reactor_data.txt, 0, 1, -1, "mg/L")

    """
    if not isinstance(start, int):
        start = int(start)
    if not isinstance(end, int):
        end = int(end)

    df = pd.read_csv(data_file_path, delimiter='\t')
    if units == "":
        if isinstance(column, int):
            data = np.array(pd.to_numeric(df.iloc[start:end, column]))
        else:
            df[column][0:len(df)]
    else:
        if isinstance(column, int):
            data = np.array(pd.to_numeric(df.iloc[start:end,
                                                  column])) * u(units)
        else:
            df[column][0:len(df)] * u(units)
    return data
def Solver_AD_Pe(t_data, C_data, theta_guess, C_bar_guess):
    """Use non-linear least squares to fit the function
    Tracer_AD_Pe(t_seconds, t_bar, C_bar, Pe) to reactor data.

    Parameters
    ----------
    t_data : float list
        Array of times with units

    C_data : float list
        Array of tracer concentration data with units

    theta_guess : float
        Estimate of time spent in one CMFR with units.

    C_bar_guess : float
        Estimate of average concentration with units
        (Mass of tracer)/(volume of one CMFR)

    Returns
    -------
    tuple
        theta : float
            residence time in seconds

        C_bar : float
            average concentration with same units as C_bar_guess

        Pe : float
            peclet number that best fits the data

    Examples
    --------

    """

    C_unitless = C_data.magnitude
    C_units = str(C_bar_guess.units)
    t_seconds = (t_data.to(u.s)).magnitude
    # assume that a guess of 1 reactor in series is close enough to get a solution
    p0 = [theta_guess.to(u.s).magnitude, C_bar_guess.magnitude, 5]
    popt, pcov = curve_fit(Tracer_AD_Pe, t_seconds, C_unitless, p0)
    Solver_theta = popt[0] * u.s
    Solver_C_bar = popt[1] * u(C_units)
    Solver_Pe = popt[2]
    Reactor_results = collections.namedtuple('Reactor_results',
                                             'theta C_bar Pe')
    AD = Reactor_results(theta=Solver_theta, C_bar=Solver_C_bar, Pe=Solver_Pe)
    return AD
Example #3
0
def perform_function_on_state(func,
                              dates,
                              state,
                              column,
                              units="",
                              path="",
                              extension=".xls"):
    """Performs the function given on each state of the data for the given state
    in the given column and outputs the result for each instance of the state

    Parameters
    ----------
    func : function
        A function which will be applied to data from each instance of the state

    dates : string (list)
        A list of dates or single date for which data was recorded, in
        the form "M-D-Y"

    state : int
        The state ID number for which data should be extracted

    column : int or string
        int:
            Index of the column that you want to extract. Column 0 is time.
            The first data column is column 1.
        string:
            Name of the column header that you want to extract

    units : string, optional
        The units you want to apply to the data, e.g. 'mg/L'.
        Defaults to "" which indicates no units

    path : string, optional
        Optional argument of the path to the folder containing your ProCoDA
        files. Defaults to the current directory if no argument is passed in

    extension : string, optional
        The file extension of the tab delimited file. Defaults to ".xls" if
        no argument is passed in

    Returns
    -------
    list
        The outputs of the given function for each instance of the given state

    Requires
    --------
    func takes in a list of data with units and outputs the correct units

    Examples
    --------
    def avg_with_units(lst):
        num = np.size(lst)
        acc = 0
        for i in lst:
            acc = i + acc

        return acc / num

    data_avgs = perform_function_on_state(avg_with_units, ["6-19-2013", "6-20-2013"], 1, 28, "mL/s")

    """
    data_agg = []
    day = 0
    first_day = True
    overnight = False

    if not isinstance(dates, list):
        dates = [dates]

    for d in dates:
        state_file = path + "statelog " + d + extension
        data_file = path + "datalog " + d + extension

        states = pd.read_csv(state_file, delimiter='\t')
        data = pd.read_csv(data_file, delimiter='\t')

        states = np.array(states)
        data = np.array(data)

        # get the start and end times for the state
        state_start_idx = states[:, 1] == state
        state_start = states[state_start_idx, 0]
        state_end_idx = np.append(
            [False], state_start_idx[0:(np.size(state_start_idx) - 1)])
        state_end = states[state_end_idx, 0]

        if overnight:
            state_start = np.insert(state_start, 0, 0)
            state_end = np.insert(state_end, 0, states[0, 0])

        if state_start_idx[-1]:
            state_end.append(data[0, -1])

        # get the corresponding indices in the data array
        data_start = []
        data_end = []
        for i in range(np.size(state_start)):
            add_start = True
            for j in range(np.size(data[:, 0])):
                if (data[j, 0] > state_start[i]) and add_start:
                    data_start.append(j)
                    add_start = False
                if (data[j, 0] > state_end[i]):
                    data_end.append(j - 1)
                    break

        if first_day:
            start_time = data[1, 0]

        # extract data at those times
        for i in range(np.size(data_start)):
            if isinstance(column, int):
                c = data[data_start[i]:data_end[i], column]
            else:
                c = data[column][data_start[i]:data_end[i]]
            if overnight and i == 0:
                data_agg = np.insert(data_agg[-1], np.size(data_agg[-1][:]), c)
            else:
                data_agg.append(c)

        day += 1
        if first_day:
            first_day = False
        if state_start_idx[-1]:
            overnight = True

    output = np.zeros(np.size(data_agg))
    for i in range(np.size(data_agg)):
        if units != "":
            output[i] = func(data_agg[i] * u(units)).magnitude
        else:
            output[i] = func(data_agg[i])

    if units != "":
        return output * func(data_agg[i] * u(units)).units
    else:
        return output
Example #4
0
def read_state(dates, state, column, units="", path="", extension=".xls"):
    """Reads a ProCoDA file and outputs the data column and time vector for
    each iteration of the given state.

    Parameters
    ----------
    dates : string (list)
        A list of dates or single date for which data was recorded, in
        the form "M-D-Y"

    state : int
        The state ID number for which data should be extracted

    column : int or string
        int:
            Index of the column that you want to extract. Column 0 is time.
            The first data column is column 1.
        string:
            Name of the column header that you want to extract

    units : string, optional
        The units you want to apply to the data, e.g. 'mg/L'.
        Defaults to "" which indicates no units

    path : string, optional
        Optional argument of the path to the folder containing your ProCoDA
        files. Defaults to the current directory if no argument is passed in

    extension : string, optional
        The file extension of the tab delimited file. Defaults to ".xls" if
        no argument is passed in

    Returns
    -------
    time : numpy array
        Times corresponding to the data (with units)

    data : numpy array
        Data in the given column during the given state with units

    Examples
    --------
    time, data = read_state(["6-19-2013", "6-20-2013"], 1, 28, "mL/s")

    """
    data_agg = []
    day = 0
    first_day = True
    overnight = False

    if not isinstance(dates, list):
        dates = [dates]

    for d in dates:
        state_file = path + "statelog " + d + extension
        data_file = path + "datalog " + d + extension

        states = pd.read_csv(state_file, delimiter='\t')
        data = pd.read_csv(data_file, delimiter='\t')

        states = np.array(states)
        data = np.array(data)

        # get the start and end times for the state
        state_start_idx = states[:, 1] == state
        state_start = states[state_start_idx, 0]
        state_end_idx = np.append(
            [False], state_start_idx[0:(np.size(state_start_idx) - 1)])
        state_end = states[state_end_idx, 0]

        if overnight:
            state_start = np.insert(state_start, 0, 0)
            state_end = np.insert(state_end, 0, states[0, 0])

        if state_start_idx[-1]:
            state_end.append(data[0, -1])

        # get the corresponding indices in the data array
        data_start = []
        data_end = []
        for i in range(np.size(state_start)):
            add_start = True
            for j in range(np.size(data[:, 0])):
                if (data[j, 0] > state_start[i]) and add_start:
                    data_start.append(j)
                    add_start = False
                if (data[j, 0] > state_end[i]):
                    data_end.append(j - 1)
                    break

        if first_day:
            start_time = data[1, 0]

        # extract data at those times
        for i in range(np.size(data_start)):
            t = data[data_start[i]:data_end[i], 0] + day - start_time
            if isinstance(column, int):
                c = data[data_start[i]:data_end[i], column]
            else:
                c = data[column][data_start[i]:data_end[i]]
            if overnight and i == 0:
                data_agg = np.insert(data_agg[-1], np.size(data_agg[-1][:, 0]),
                                     np.vstack((t, c)).T)
            else:
                data_agg.append(np.vstack((t, c)).T)

        day += 1
        if first_day:
            first_day = False
        if state_start_idx[-1]:
            overnight = True

    data_agg = np.vstack(data_agg)
    if units != "":
        return data_agg[:, 0] * u.day, data_agg[:, 1] * u(units)
    else:
        return data_agg[:, 0] * u.day, data_agg[:, 1]