Esempio n. 1
0
    def test(self, pixel_ind=[0, 0]):
        """
        Test the Pixel analysis of a single pixel

        :param pixel_ind: Index of the pixel in the dataset that the process needs to be tested on.
            If a list it is read as [row, column]
        :type pixel_ind: uint or list
            

        :returns: List [inst_freq, tfp, shift]
            WHERE
            array inst_freq is the instantaneous frequency array for that pixel
            float tfp is the time to first peak
            float shift the frequency shift at time t=tfp (i.e. maximum frequency shift)

        """
        # First read the HDF5 dataset to get the deflection for this pixel

        if type(pixel_ind) is not list:
            col = int(pixel_ind % self.parm_dict['num_rows'])
            row = int(np.floor(pixel_ind % self.parm_dict['num_rows']))
            pixel_ind = [row, col]

        # as an array, not an ffta.Pixel
        defl = get_utils.get_pixel(self.h5_main, pixel_ind, array_form=True)

        pix = Pixel(defl, self.parm_dict, **self.pixel_params)

        tfp, shift, inst_freq = pix.analyze()
        pix.plot()

        return self._map_function(defl, self.parm_dict, self.pixel_params,
                                  self.impulse)
Esempio n. 2
0
def analyze_pixel(ibw_file, param_file):
    '''
    Analyzes a single pixel
    
    Parameters
    ----------
    ibw_file : str
        path to \*.ibw file
    param_file : str
        path to parameters.cfg file
        
    Returns
    -------
    pixel : Pixel
        The pixel object read and analyzed
    '''
    signal_array = signal(ibw_file)
    n_pixels, params = configuration(param_file)
    pixel = Pixel(signal_array, params=params)

    pixel.analyze()
    pixel.plot()
    plt.xlabel('Time Step')
    plt.ylabel('Freq Shift (Hz)')

    print('tFP is', pixel.tfp, 's')

    return pixel.tfp
Esempio n. 3
0
    def _map_function(defl, *args, **kwargs):

        parm_dict = args[0]
        pixel_params = args[1]

        pix = Pixel(defl, parm_dict, **pixel_params)

        if parm_dict['if_only']:
            inst_freq, _, _ = pix.generate_inst_freq()
            tfp = 0
            shift = 0
            amplitude = 0
            phase = 0
            pwr_diss = 0
        else:
            tfp, shift, inst_freq = pix.analyze()
            pix.calculate_power_dissipation()
            amplitude = pix.amplitude
            phase = pix.phase
            pwr_diss = pix.power_dissipated

        return [inst_freq, amplitude, phase, tfp, shift, pwr_diss]
Esempio n. 4
0
def get_pixel(h5_path,
              rc,
              params={},
              pixel_params={},
              array_form=False,
              avg=False,
              transpose=False):
    """
	Gets a pixel of data, returns all the averages within that pixel
	Returns a specific key if requested
	Supplying a direct link to a Dataset is MUCH faster than just the file
	Note that you should supply the deflection data, not instantaneous_frequency
	
	Parameters
	----------
	h5_path : str or h5py or Dataset
		Can pass either an h5_path to a file or a file already in use or specific Dataset
		Again, should pass the deflection data (Rebuilt_Data, or FF_Avg)
	
	rc : list [r, c]
		Pixel location in terms of ROW, COLUMN

	params: dict
		If explicitly changing parameters (to test a feature), you can pass any subset and this will overwrite it
		e.g. parameters  = {'drive_freq': 10} will extract the Pixel, then change Pixel.drive_freq = 10

	pixel_params : dict, optional
		Parameters 'fit', 'pycroscopy', 'method', 'fit_form'
		See ffta.pixel for details. 'pycroscopy' is set to True in this function

	array_form : bool, optional
		Returns the raw array contents rather than Pixel class
	
	avg : bool, optional
		Averages the pixels of n_pnts_per_pixel and then creates Pixel of that
		
	transpose : bool, optional
		For legacy FFtrEFM code, pixel is required in (n_points, n_signals) format
		
	Returns
	-------
	signal_pixel : 1D numpy array, iff array_form == True
		Ndarray of the (n_points) in specific pixel    
	
	pixel_inst : Pixel, iff array_form == False
		Line class containing the signal_array object and parameters
	"""

    # If not a dataset, then find the associated Group
    if 'Dataset' not in str(type(h5_path)):
        p = get_params(h5_path)
        h5_file = px.io.HDFwriter(h5_path).file

        d = usid.hdf_utils.find_dataset(h5_file, 'FF_Raw')[0]
        c = p['num_cols']
        pnts = int(p['pnts_per_pixel'])
        parameters = usid.hdf_utils.get_attributes(d.parent)

    else:

        d = h5_path[()]
        parameters = get_params(h5_path)

        c = parameters['num_cols']
        pnts = parameters['pnts_per_pixel']

    signal_pixel = d[rc[0] * c + rc[1]:rc[0] * c + rc[1] + pnts, :]

    if avg == True:
        signal_pixel = signal_pixel.mean(axis=0)

    if transpose == True:  # this does nothing is avg==True
        signal_pixel = signal_pixel.transpose()

    if array_form == True:
        return signal_pixel

    if signal_pixel.shape[0] == 1:
        signal_pixel = np.reshape(signal_pixel, [signal_pixel.shape[1]])

    if any(params):
        for key, val in params.items():
            parameters[key] = val

    pixel_params.update({'pycroscopy':
                         True})  # must be True in this specific case

    # pixel_inst = Pixel(signal_pixel, parameters, pycroscopy=True)
    pixel_inst = Pixel(signal_pixel, parameters, **pixel_params)

    return pixel_inst
Esempio n. 5
0
def get_pixel(h5_path,
              rc,
              params={},
              pixel_params={},
              array_form=False,
              avg=False,
              transpose=False):
    """
    Gets a pixel of data, returns all the averages within that pixel
    Returns a specific key if requested
    Supplying a direct link to a Dataset is MUCH faster than just the file
    Note that you should supply the deflection data, not instantaneous_frequency
    
    :param h5_path: Can pass either an h5_path to a file or a file already in use or specific Dataset
        Again, should pass the deflection data (Rebuilt_Data, or FF_Avg)
    :type h5_path: str or h5py or Dataset
        
    :param rc: Pixel location in terms of ROW, COLUMN
    :type rc: list [r, c]
        
    :param params: If explicitly changing parameters (to test a feature), you can pass any subset and this will overwrite it
        e.g. parameters  = {'drive_freq': 10} will extract the Pixel, then change Pixel.drive_freq = 10
    :type params: dict
    
    :param pixel_params: Parameters 'fit', 'pycroscopy', 'method', 'fit_form'
        See ffta.pixel for details. 'pycroscopy' is set to True in this function
    :type pixel_params: dict, optional
    
    :param array_form: Returns the raw array contents rather than Pixel class
    :type array_form: bool, optional
        
    :param avg: Averages the pixels of n_pnts_per_pixel and then creates Pixel of that
    :type avg: bool, optional
        
    :param transpose: For legacy FFtrEFM code, pixel is required in (n_points, n_signals) format
    :type transpose: bool, optional
        
        
    :returns: 
    2D numpy array signal_line iff array_form == True, contains hte line 
    OR 
    Line line_inst iff array_form == False, contains signal_array object and parameters

    """

    # If not a dataset, then find the associated Group
    if 'Dataset' not in str(type(h5_path)):
        p = get_params(h5_path)
        h5_file = h5py.File(h5_path)

        d = usid.hdf_utils.find_dataset(h5_file, 'FF_Raw')[0]
        r = p['num_rows']
        c = p['num_cols']
        pnts = int(p['pnts_per_pixel'])
        parameters = usid.hdf_utils.get_attributes(d.parent)

    else:

        d = h5_path[()]
        parameters = get_params(h5_path)
        r = parameters['num_rows']
        c = parameters['num_cols']
        pnts = parameters['pnts_per_pixel']

    if rc[1] > c or rc[0] > r:
        err = 'row and columns must be less than ' + str(r) + ' X ' + str(c)
        raise ValueError(err)

    signal_pixel = d[rc[0] * c + rc[1]:rc[0] * c + rc[1] + pnts, :]

    if avg == True:
        signal_pixel = signal_pixel.mean(axis=0)

    if transpose == True:  # this does nothing is avg==True
        signal_pixel = signal_pixel.transpose()

    if array_form == True:
        return signal_pixel

    if signal_pixel.shape[0] == 1:
        signal_pixel = np.reshape(signal_pixel, [signal_pixel.shape[1]])

    if any(params):
        for key, val in params.items():
            parameters[key] = val

    pixel_params.update({'pycroscopy':
                         True})  # must be True in this specific case

    # pixel_inst = Pixel(signal_pixel, parameters, pycroscopy=True)
    pixel_inst = Pixel(signal_pixel, parameters, **pixel_params)

    return pixel_inst
Esempio n. 6
0
    def _map_function(defl, *args, **kwargs):
        """
        
        :param defl:
        :type defl:
        
        :param args:
        :type args:
        
        :param kwargs:
        :type kwargs:
        
        :returns: List [inst_freq, amplitude, phase, tfp, shift, pwr_diss]
            WHERE
            [type] inst_freq is...
            [type] amplitude is...
            [type] phase is...
            [type] tfp is...
            [type] shift is...
            [type] pwr_diss is...
        """
        parm_dict = args[0]
        pixel_params = args[1]
        impulse = args[2]

        pix = Pixel(defl, parm_dict, **pixel_params)

        if parm_dict['if_only']:
            inst_freq, _, _ = pix.generate_inst_freq()
            tfp = 0
            shift = 0
            amplitude = 0
            phase = 0
            pwr_diss = 0
        elif parm_dict['deconvolve']:
            iterations = parm_dict['conv_iterations']
            impulse = impulse[
                parm_dict['impulse_window'][0]:parm_dict['impulse_window'][1]]
            inst_freq, amplitude, phase = pix.generate_inst_freq()
            conv = restoration.richardson_lucy(inst_freq,
                                               impulse,
                                               clip=False,
                                               num_iter=iterations)
            pix.inst_freq = conv
            pix.find_tfp()
            tfp = pix.tfp
            shift = pix.shift
            pix.calculate_power_dissipation()
            pwr_diss = pix.power_dissipated
        else:
            tfp, shift, inst_freq = pix.analyze()
            pix.calculate_power_dissipation()
            amplitude = pix.amplitude
            phase = pix.phase
            pwr_diss = pix.power_dissipated

        return [inst_freq, amplitude, phase, tfp, shift, pwr_diss]
Esempio n. 7
0
    def test_deconv(self, window, pixel_ind=[0, 0], iterations=10):
        """
        Tests the deconvolution by bracketing the impulse around window
        A reasonable window size might be 100 us pre-trigger to 500 us post-trigger
        
        :param window: List of format [left_index, right_index] for impulse
        :type window: list
        
        :param pixel_ind: Index of the pixel in the dataset that the process needs to be tested on.
            If a list it is read as [row, column]
        :type pixel_ind: uint or list
            
        
        :param iterations: Number of Richardson-Lucy deconvolution iterations
        :type iterations: int

        """
        if len(window) != 2 or not isinstance(window, list):
            raise ValueError('window must be specified[left, right]')

        if isinstance(window[0], float):  # passed a time index
            window = np.array(window) / self.parm_dict['sampling_rate']
            window = int(window)

        if type(pixel_ind) is not list:
            col = int(pixel_ind % self.parm_dict['num_rows'])
            row = int(np.floor(pixel_ind % self.parm_dict['num_rows']))
            pixel_ind = [row, col]

        # as an array, not an ffta.Pixel
        defl = get_utils.get_pixel(self.h5_main, pixel_ind, array_form=True)

        pixraw = Pixel(defl, self.parm_dict, **self.pixel_params)
        tfp, shift, inst_freq = pixraw.analyze()

        impulse = self.impulse[window[0]:window[1]]
        self.parm_dict['impulse_window'] = window
        self.parm_dict['conv_iterations'] = iterations

        pixconv = restoration.richardson_lucy(inst_freq,
                                              impulse,
                                              clip=False,
                                              num_iter=iterations)

        pixrl = pixraw
        tfp_raw = pixraw.tfp
        fit_raw = pixraw.best_fit
        if_raw = pixraw.inst_freq

        pixrl.inst_freq = pixconv
        pixrl.find_tfp()
        tfp_conv = pixrl.tfp
        fit_conv = pixrl.best_fit
        if_conv = pixrl.inst_freq

        print(tfp_raw, tfp_conv)

        # Plot the results of the original+fit compared to deconvolution+fit
        ridx = int(self.parm_dict['roi'] * self.parm_dict['sampling_rate'])
        fidx = int(pixraw.tidx)
        ifx = np.array([fidx - 1100, fidx + ridx
                        ]) * 1e3 / self.parm_dict['sampling_rate']
        windx = np.array(window) * 1e3 / self.parm_dict['sampling_rate']
        yl0 = [
            if_raw[fidx:(fidx + ridx)].min(), if_raw[fidx:(fidx + ridx)].max()
        ]
        yl1 = [
            if_conv[fidx:(fidx + ridx)].min(),
            if_conv[fidx:(fidx + ridx)].max()
        ]
        yl2 = [
            self.impulse[fidx:(fidx + ridx)].min(),
            self.impulse[fidx:(fidx + ridx)].max()
        ]

        fig, ax = plt.subplots(nrows=2,
                               ncols=2,
                               facecolor='white',
                               figsize=(12, 8))
        tx = np.arange(0, pixraw.total_time, 1 / pixraw.sampling_rate) * 1e3

        ax[0][0].plot(tx, if_raw, 'b', label='Pre-Conv')
        ax[0][0].plot(tx[fidx:(fidx + ridx)],
                      fit_raw,
                      'r--',
                      label='Pre-Conv, fit')
        ax[0][0].set_title('Raw')

        ax[1][0].plot(tx, if_conv, 'b', label='Conv')
        ax[1][0].plot(tx[fidx:(fidx + ridx)],
                      fit_conv,
                      'r--',
                      label='Conv, fit')
        ax[1][0].set_title('Deconvolved')

        ax[0][1].plot(tx, self.impulse, 'k')
        ax[0][1].axvspan(windx[0], windx[1], alpha=0.5, color='red')
        ax[0][1].set_title('Impulse response')

        ax[1][1].plot(tx[fidx:(fidx + ridx)],
                      fit_raw,
                      'r--',
                      label='Pre-Conv, fit')
        ax[1][1].plot(tx[fidx:(fidx + ridx)],
                      fit_conv,
                      'k--',
                      label='Conv, fit')
        ax[1][1].set_title('Comparing fits')
        ax[1][1].legend()

        ax[0][0].set_xlim(ifx)
        ax[0][0].set_ylim(yl0)
        ax[1][0].set_xlim(ifx)
        ax[1][0].set_ylim(yl1)
        ax[0][1].set_xlim(ifx)
        ax[0][1].set_ylim(yl2)
        ax[1][1].set_xlim(ifx)
        ax[1][0].set_xlabel('Time (ms)')
        ax[1][1].set_xlabel('Time (ms)')

        plt.tight_layout()

        return pixrl