Example #1
0
def fit_references(data, references, e_ranges, labels=None):
    """Fit 'references' to 'data' in the energy window (x) 'e_range'"""
    # Restrict data to within e_range
    index = []
    for e_range in e_ranges:
        index.append(ct.get_range(data[:, 0], *e_range))
    index = functools.reduce(np.union1d, index)
    #return index
    data = data[index]
    mod_ref = {label: ref[index] for label, ref in references.items()}

    # Define fitting relationship
    def func(x, *args):
        signal = x * 0
        for arg, ref in list(zip(args, mod_ref.values())):
            signal += arg * ref[:, 1]
        return signal

    # Calculate best fit
    ret, _ = curve_fit(func,
                       data[:, 0],
                       data[:, 1],
                       p0=[0.5] * len(references),
                       bounds=(0, np.inf))
    dict_ = {label: ret[i] for i, label in enumerate(references.keys())}
    pretty_dict = dict_as_percent(dict_)
    for label, percent in pretty_dict.items():
        print(label, percent)
    return dict_
Example #2
0
def align_spectra(iss_data, limits=[350, 520], masses=[16, 18], key='oxygen'):
    """Shift the iss data within 'limits' region to snap maximum signal
unto nearest mass in list 'masses'."""

    plt.figure('aligned')
    for data in iss_data:
        # Initialize attributes
        try:
            data.shifted
        except AttributeError:
            data.shifted = {}
        try:
            data.smoothed
        except AttributeError:
            data.smoothed = {}

        # Get index of region of interest
        index = ct.get_range(data.x, *limits)
        # Find maximum in region
        ys = ct.smooth(data.y, width=4)
        data.smoothed[key] = ys
        maximum = max(ys[index])
        if not np.isfinite(maximum):
            data.good = False
            continue  # "Broken" dataset
        data.good = True
        i_max = np.where(ys == maximum)[0]
        x_max = data.x[i_max]

        # Find difference from reference
        energies = data.ConvertEnergy(np.array(masses))
        try:
            distance = np.abs(x_max - energies)
        except ValueError:
            print('ValueError')
            print(data.filename)
            print(data.x)
            print(data.y[np.isfinite(data.y)])
            print(data.smoothed[key])
            print(maximum)
            print(x_max)
            print(energies)
            plt.figure()
            plt.plot(data.x, data.y)
            plt.show()
            raise

        # Snap to nearest line
        data.shifted[key] = data.x - (x_max - energies)[np.where(
            distance == min(distance))[0]]
        plt.plot(data.shifted[key], data.y)
        plt.plot(data.shifted[key], ys)
    data.AddMassLines(masses)

    # Return a nd.array of modified xy data
    return np.vstack((data.shifted[key], data.smoothed[key])).T
Example #3
0
def fit_references_v2(iss, references, e_ranges, labels=None):
    """Fit 'references' to 'data' in the energy window (x) 'e_range'

Subtract background from references to only use peak intensities for fit.
Subtract beckground in the regions you want to fit.
"""
    #plt.show()
    # Restrict data to within e_range
    index = []
    for e_range in e_ranges:
        index.append(ct.get_range(iss.x, *e_range))
    index = functools.reduce(np.union1d, index)

    # Subtract background from references
    modified_references = {}
    for label, (ref, limit) in references.items():

        modified_references[label] = np.copy(ref)
        #modified_references[label][:, 1] -= peak[index]

        background = subtract_single_background(ref, ranges=[limit])
        modified_references[label][:, 1] -= background
        #modified_references[label] = modified_references[label][index]
        #plt.plot(ref[:, 0], ref[:, 1] - background, label=label)

    # Subtract background from data
    subtract_backgrounds(iss_data=[iss], ranges=e_ranges)
    data = iss.xy[index]
    data[:, 1] -= iss.background[index]

    #plt.plot(data[:, 0], data[:, 1], 'ko', label='Data')
    #plt.plot(iss.x, iss.background, label='Data (raw)')

    #plt.legend()
    #plt.show()
    #modified_references = {label: ref[index] for label, ref in references.items()}

    # Define fitting relationship
    def func(x, *args):
        signal = x * 0
        for arg, ref in list(zip(args, modified_references.values())):
            signal += arg * ref[:, 1][index]
        return signal

    # Calculate best fit
    ret, _ = curve_fit(func,
                       data[:, 0],
                       data[:, 1],
                       p0=[0.5] * len(references),
                       bounds=(0, np.inf))
    dict_ = {label: ret[i] for i, label in enumerate(references.keys())}
    #for label, percent in pretty_dict.items(): print(label, percent)
    return dict_, modified_references
Example #4
0
 def get_timesnippet(self, label, limit):
     """Return (time, data) of data set 'label' cropped to fit into time 'limit'"""
     index = ct.get_range(self.data[label][:, 0], limit[0], limit[1])
     return self.data[label][:, 0][index], self.data[label][:, 1][index]
Example #5
0
    def isolate_experiments(self, set_label=None, temp_label='Sample temperature'):
        """
1) Isolate regions of heating ramps
2) Organize into returnable data
3) Convert time to temperature
    - intentionally oversample the temperature
    - collect groups into points of average/std
    - interpolate points to correlate arbitrary time with a temperature
"""

        # 1) Find regions of heating ramps
        if set_label is None:
            for i in self.labels:
                if 'setpoint' in i.lower().split() and 'temperature' in i.lower().split():
                    set_label = i
                    break
        if set_label is None:
            print('Ramp label is not found automatically. Specify "set_label"!')
            raise ValueError()
        if len(self.data[set_label]) == 0:
            raise ValueError('No heat ramps detected')
        marker_start, marker_end = 0, 0
        counter = 0
        regions = []
        for i in self.data[set_label][:,0]:
            if counter == 0:
                last = i
                marker_start = counter
                counter += 1
                continue

            # Main check
            if i - last > 15: # difference of more than 15 seconds
                marker_end = counter
                region = np.arange(marker_start, marker_end)
                regions.append(region)
                marker_start = counter

            # End of loop
            last = i
            counter += 1
        region = np.arange(marker_start, counter)
        regions.append(region)
        number_of_regions = len(regions)
        #print(number_of_regions)

        # 2) Organize into returnable data
        # Get temperature data
        if not temp_label in self.labels:
            for i in self.labels:
                if 'sample' in i.lower() and 'temperature' in i.lower():
                    temp_label = i
                    print('Temperature label deviating from default found: "{}"'.format(temp_label))
                    break
            else:
                print('"Sample temperature" not found in loaded dataset. Please specify "temp_label"!')
                return None
        interpolate_temp = time2temp(self.data[temp_label])
        # Local heating rate
        number = 0
        t_window = 10

        # For fast temperature logging, this seems to work very good. Hasn't been tested on
        # sparse datasets *** OBSOLETE ***
        while number < 3:
            t_window += 1
            number = len(ct.get_range(self.data[temp_label][:, 0], self.data[temp_label][-1, 0]-t_window, self.data[temp_label][-1, 0]))
        self.slope = self.data[temp_label].copy()
        self.slope[:number+1, 1] = np.nan
        for i in range(len(self.slope[:, 0]) -1, number, -1):
            coeff = np.polyfit(self.data[temp_label][i-number:i+1, 0], self.data[temp_label][i-number:i+1, 1], 1)
            self.slope[i, 1] = coeff[0]
        interpolate_slope = time2temp(self.slope)

        # Set up data structure for experiments
        for i in range(number_of_regions):
            self.exps[i] = {}
            region = regions[i]
            time_ref = self.data[set_label][:,0][region]
            for label in self.labels:
                # skip if empty
                #print(self.data[label], label)
                #if self.data[label] == None:
                #if len(self.data[label]) == 0:
                #    continue
                if len(self.data[label]) == 0:
                    continue
                self.exps[i][label] = {}
                local_range = get_range(self.data[label][:, 0], [time_ref[0]-3, time_ref[-1]+3])
                for x in [0, 1]:
                    self.exps[i][label][x] = self.data[label][:, x][local_range]

            # 3) Add temperature axis to each data set
            for label in self.labels:
                # skip if empty
                #if self.data[label] == None:
                #if len(self.data[label]) == 0:
                #    continue
                if len(self.data[label]) == 0:
                    continue
                print(i, label)
                self.exps[i][label][2] = interpolate_temp(self.exps[i][label][0])
                # Extract information about local heating rate
                dat = self.exps[i][label]
                dat[3] = np.empty(len(dat[0]))
                dat[3][0] = np.nan
                dat[3][1:] = ct.smooth(np.diff(dat[2])/np.diff(dat[0]), width=1)

        # Save results in pickle:
        self.save_pickle()