Пример #1
0
    def get_dimensions(self):
        dic = self.original_metadata

        reciprocal_name = 'u'
        spatial_name = 'x'

        if 'dimensional_calibrations' in dic:
            dimension_list = dic['dimensional_calibrations']
        elif 'spatial_calibrations' in dic:
            dimension_list = dic['spatial_calibrations']
        else:
            return

        for dim in range(len(dimension_list)):
            dimension_tags = dimension_list[dim]
            units = dimension_tags['units']
            values = (np.arange(self.data_cube.shape[int(dim)]) -
                      dimension_tags['offset']) * dimension_tags['scale']

            if 'eV' == units:
                self.dimensions.append(
                    sidpy.Dimension(values,
                                    name='energy_loss',
                                    units=units,
                                    quantity='energy-loss',
                                    dimension_type='spectral'))
            elif 'eV' in units:
                self.dimensions.append(
                    sidpy.Dimension(values,
                                    name='energy',
                                    units=units,
                                    quantity='energy',
                                    dimension_type='spectral'))
            elif '1/' in units or units in ['mrad', 'rad']:
                self.dimensions.append(
                    sidpy.Dimension(values,
                                    name=reciprocal_name,
                                    units=units,
                                    quantity='reciprocal distance',
                                    dimension_type='reciprocal'))
                reciprocal_name = chr(ord(reciprocal_name) + 1)
            elif 'nm' in units:
                self.dimensions.append(
                    sidpy.Dimension(values,
                                    name=spatial_name,
                                    units=units,
                                    quantity='distance',
                                    dimension_type='spatial'))
                spatial_name = chr(ord(spatial_name) + 1)
            else:
                self.dimensions.append(
                    sidpy.Dimension(values,
                                    name='generic_{}'.format(dim),
                                    units='generic',
                                    quantity='generic',
                                    dimension_type='UNKNOWN'))
Пример #2
0
    def get_image(self):

        scale_x = float(
            self.metadata['BinaryResult']['PixelSize']['width']) * 1e9
        scale_y = float(
            self.metadata['BinaryResult']['PixelSize']['height']) * 1e9

        if self.data_array.shape[2] == 1:
            self.datasets.append(
                sidpy.Dataset.from_array(self.data_array[:, :, 0]))
            self.datasets[-1].data_type = 'image'
            self.datasets[-1].set_dimension(
                0,
                sidpy.Dimension(np.arange(self.data_array.shape[0]) * scale_x,
                                name='x',
                                units='nm',
                                quantity='distance',
                                dimension_type='spatial'))
            self.datasets[-1].set_dimension(
                1,
                sidpy.Dimension(np.arange(self.data_array.shape[1]) * scale_y,
                                name='y',
                                units='nm',
                                quantity='distance',
                                dimension_type='spatial'))
        else:
            self.data_array = np.moveaxis(self.data_array,
                                          source=[0, 1, 2],
                                          destination=[1, 2, 0])
            self.datasets.append(sidpy.Dataset.from_array(self.data_array))
            self.datasets[-1].data_type = 'image_stack'
            self.datasets[-1].set_dimension(
                0,
                sidpy.Dimension(np.arange(self.data_array.shape[0]),
                                name='frame',
                                units='frame',
                                quantity='time',
                                dimension_type='temporal'))
            self.datasets[-1].set_dimension(
                1,
                sidpy.Dimension(np.arange(self.data_array.shape[1]) * scale_x,
                                name='x',
                                units='nm',
                                quantity='distance',
                                dimension_type='spatial'))
            self.datasets[-1].set_dimension(
                2,
                sidpy.Dimension(np.arange(self.data_array.shape[2]) * scale_y,
                                name='y',
                                units='nm',
                                quantity='distance',
                                dimension_type='spatial'))
        self.datasets[-1].original_metadata = self.metadata

        self.datasets[-1].units = 'counts'
        self.datasets[-1].quantity = 'intensity'
Пример #3
0
    def _translate_image_stack(self, gwy_data, obj):
        """
        Use this function to write data corresponding to a stack of scan images (most common)
        Returns
        -------
        """

        if obj.endswith('data'):
            data = gwy_data[obj].data
            title = gwy_data[obj + '/title']
            keys = gwy_data[obj].keys()
            meta_data = {}
            for key in keys:
                if 'data' not in key:
                    meta_data[key] = gwy_data[obj][key]

            x_range = gwy_data[obj].get('xreal')
            x_vals = np.linspace(0, x_range, gwy_data[obj]['xres'])

            y_range = gwy_data[obj].get('yreal')
            y_vals = np.linspace(0, y_range, gwy_data[obj]['yres'])

            data_set = sid.Dataset.from_array(data, title=title)
            data_set.data_type = 'Image'

            #Add quantity and units
            data_set.units = gwy_data[obj]['si_unit_z']['unitstr']
            data_set.quantity = title

            #Add dimension info
            data_set.set_dimension(
                0,
                sid.Dimension(x_vals,
                              name='x',
                              units=gwy_data[obj]['si_unit_xy']['unitstr'],
                              quantity='x',
                              dimension_type='spatial'))
            data_set.set_dimension(
                1,
                sid.Dimension(y_vals,
                              name='y',
                              units=gwy_data[obj]['si_unit_xy']['unitstr'],
                              quantity='y',
                              dimension_type='spatial'))

            # append metadata
            data_set.original_metadata = meta_data
            data_set.data_type = 'image'

        return data_set
Пример #4
0
    def set_data_type(self, dataset):

        spectral_dim = False
        for axis in dataset._axes.values():
            if axis.dimension_type == sidpy.DimensionType.SPECTRAL:
                spectral_dim = True

        if len(dataset.shape) > 3:
            raise NotImplementedError('Data_type not implemented yet')
        elif len(dataset.shape) == 3:
            if spectral_dim:
                dataset.data_type = 'spectral_image'
            else:
                dataset.data_type = 'IMAGE_STACK'
                for dim, axis in dataset._axes.items():
                    if axis.dimension_type != sidpy.DimensionType.SPATIAL:
                        dataset.set_dimension(dim, sidpy.Dimension(axis.values,
                                                                   name='frame',
                                                                   units='frame',
                                                                   quantity='stack',
                                                                   dimension_type=sidpy.DimensionType.TEMPORAL))
                        break

        elif len(dataset.shape) == 2:
            if spectral_dim:
                dataset.data_type = sidpy.DataType.SPECTRAL_IMAGE
            else:
                dataset.data_type = sidpy.DataType.IMAGE
        elif len(dataset.shape) == 1:
            if spectral_dim:
                dataset.data_type = sidpy.DataType.SPECTRUM
            else:
                dataset.data_type = sidpy.DataType.LINE_PLOT
Пример #5
0
    def test_complex_valued_dimension(self):
        data_set = sidpy.Dataset.from_array(np.zeros([5, 6], dtype=complex), title='Image')
        h5_file = h5py.File('test.h5', 'w')
        h5_group = h5_file.create_group('MyGroup')
        data_set.set_dimension(0, sidpy.Dimension(np.arange(5, dtype=complex)))

        # with self.assertWarns('ComplexWarning'):
        pyNSID.hdf_io.write_nsid_dataset(data_set, h5_group)
Пример #6
0
    def base_test(self, dims=3, dim_types=['spatial', 'spatial', 'spectral'],
                  data_type='complex', verbose=True):
        h5_f = h5py.File('test.h5', 'w')
        h5_group = h5_f.create_group('MyGroup')
        shape = tuple([np.random.randint(low=2, high=10) for _ in range(dims)])
        data = np.random.normal(size=shape)
        if data_type == 'complex':
            data = np.random.normal(size=tuple(shape)) + 1j * np.random.normal(size=tuple(shape))
        elif data_type == 'int':
            np.random.randint(low=0, high=1000, size=shape, dtype=np.int)
        elif data_type == 'float32':
            data = np.random.normal(size=shape)
            data = np.squeeze(np.array(data, dtype=np.float32))
        else:
            data = np.random.normal(size=shape)
            data = np.squeeze(np.array(data, dtype=np.float64))

        data_set = sidpy.Dataset.from_array(data[:], title='Image')

        for ind in range(dims):
            data_set.set_dimension(ind, sidpy.Dimension(np.linspace(-2, 2, num=data_set.shape[ind], endpoint=True),
                                                        title='x'+str(ind), units='um', quantity='Length',
                                                        dimension_type=dim_types[ind]))
        data_set.units = 'nm'
        data_set.source = 'CypherEast2'
        data_set.quantity = 'Excaliburs'

        h5_dset = hdf_io.write_nsid_dataset(data_set, h5_group, main_data_name='test2', verbose=verbose)

        assert type(h5_dset) == h5py._hl.dataset.Dataset, "Output is not a h5py dataset"
        assert h5_dset.shape == shape, "Output shape is {} but should be {}".format(h5_dset.shape, shape)

        for ind in range(len(sidpy.hdf_utils.get_attr(h5_dset, 'DIMENSION_LABELS'))):

            assert sidpy.hdf_utils.get_attr(h5_dset, 'DIMENSION_LABELS')[ind] == data_set._axes[ind].name, \
                "Dimension name not correctly written, should be {} but is {} in file"\
                    .format(data_set._axes[ind].name, sidpy.hdf_utils.get_attr(h5_dset, 'DIMENSION_LABELS')[ind])

            assert sidpy.hdf_utils.get_attr(h5_dset, 'quantity') == data_set.quantity, \
                "Quantity attribute not correctly written, should be {} but is {} in file"\
                    .format(data_set.quantity, sidpy.hdf_utils.get_attr(h5_dset, 'quantity'))

            assert sidpy.hdf_utils.get_attr(h5_dset, 'source') == data_set.source, \
                "Source attribute not correctly written, should be {} but is {} in file"\
                    .format(data_set.source, sidpy.hdf_utils.get_attr(h5_dset, 'source'))

            assert sidpy.hdf_utils.get_attr(h5_dset, 'units') == data_set.units, \
                "Source attribute not correctly written, should be {} but is {} in file"\
                    .format(data_set.units, sidpy.hdf_utils.get_attr(h5_dset, 'units'))
        h5_f.close()
        remove('test.h5')
Пример #7
0
    def _translate_spectra(self, gwy_data, obj):
        """
        Use this to translate simple 1D data like force curves
        Returns
        -------
        """
        keys = gwy_data[obj].keys()
        meta_data = {}
        for key in keys:
            if 'data' not in key:
                meta_data[key] = gwy_data[obj][key]

        title = obj['title']
        unitstr = obj['unitstr']
        coords = obj['coords']
        res = obj['data']['res']
        real = obj['data']['real']
        offset = obj['data']['off']
        x_units = obj['data']['si_unit_x']['unitstr']
        y_units = obj['data']['si_unit_y']['unitstr']
        data = obj['data']['data']
        indices = obj['selected']
        x_vals = np.linspace(offset, real, res)

        data_set = sid.Dataset.from_array(data, title=title)
        data_set.data_type = 'line_plot'

        #Add quantity and units
        data_set.units = y_units
        data_set.quantity = title

        #Add dimension info
        data_set.set_dimension(
            0,
            sid.Dimension(x_vals,
                          name='x',
                          units=x_units,
                          quantity='x',
                          dimension_type='spectral'))

        # append metadata
        data_set.original_metadata = meta_data

        return data_set
Пример #8
0
def make_dummy_dataset(value_type):
    """Make a dummy sidpy.Dataset """

    assert isinstance(value_type, sidpy.DataType)
    if type == sidpy.DataType.SPECTRUM:
        dataset = sidpy.Dataset.from_array(np.arange(100))
        dataset.data_type = 'spectrum'
        dataset.units = 'counts'
        dataset.quantity = 'intensity'

        dataset.set_dimension(
            0,
            sidpy.Dimension(np.arange(dataset.shape[0]) + 70,
                            name='energy_scale'))
        dataset.dim_0.dimension_type = 'spectral'
        dataset.dim_0.units = 'eV'
        dataset.dim_0.quantity = 'energy loss'
    else:
        raise NotImplementedError('not implemented')
    return dataset
Пример #9
0
    def gsf_read(self):
        """
        Read a Gwyddion Simple Field 1.0 file format
        http://gwyddion.net/documentation/user-guide-en/gsf.html
        
        Parameters
        ----------
        file_name : string
            path to the file
        Returns
        -------
        metadata : dict)
            Additional metadata to be included in the file
        data : numpy.ndarray
            An arbitrarily sized 2D array of arbitrary numeric type
        """

        gsf_file = open(self._input_file_path, 'rb')

        metadata = {}

        # check if header is OK
        if not (gsf_file.readline().decode('UTF-8')
                == 'Gwyddion Simple Field 1.0\n'):
            gsf_file.close()
            raise ValueError('File has wrong header')

        term = b'00'
        # read metadata header
        while term != b'\x00':
            line_string = gsf_file.readline().decode('UTF-8')
            metadata[line_string.rpartition(' = ')
                     [0]] = line_string.rpartition('=')[2]
            term = gsf_file.read(1)
            gsf_file.seek(-1, 1)

        gsf_file.read(4 - gsf_file.tell() % 4)

        # fix known metadata types from .gsf file specs
        # first the mandatory ones...
        metadata['XRes'] = np.int(metadata['XRes'])
        metadata['YRes'] = np.int(metadata['YRes'])

        # now check for the optional ones
        if 'XReal' in metadata:
            metadata['XReal'] = np.float(metadata['XReal'])

        if 'YReal' in metadata:
            metadata['YReal'] = np.float(metadata['YReal'])

        if 'XOffset' in metadata:
            metadata['XOffset'] = np.float(metadata['XOffset'])

        if 'YOffset' in metadata:
            metadata['YOffset'] = np.float(metadata['YOffset'])

        datasets = []

        data = np.frombuffer(gsf_file.read(),
                             dtype='float32').reshape(metadata['YRes'],
                                                      metadata['XRes'])

        gsf_file.close()
        num_cols, num_rows = data.shape
        data_set = sid.Dataset.from_array(data, title=metadata['Title'])
        data_set.data_type = 'Image'

        #Add quantity and units
        data_set.units = metadata['ZUnits']
        data_set.quantity = metadata['Title']

        #Add dimension info
        data_set.set_dimension(
            0,
            sid.Dimension(np.linspace(0, metadata['XReal'], num_cols),
                          name='x',
                          units=metadata['XYUnits'],
                          quantity='x',
                          dimension_type='spatial'))
        data_set.set_dimension(
            1,
            sid.Dimension(np.linspace(0, metadata['YReal'], num_rows),
                          name='y',
                          units=metadata['XYUnits'],
                          quantity='y',
                          dimension_type='spatial'))

        # append metadata
        data_set.original_metadata = metadata
        data_set.data_type = 'image'

        #Finally, append it
        datasets.append(data_set)

        return datasets
Пример #10
0
    def read(self, verbose=False, parm_encoding='utf-8'):
        """
        Reads the file given in file_path into a sidpy dataset

        Parameters
        ----------
        verbose : Boolean (Optional)
            Whether or not to show  print statements for debugging
        parm_encoding : str, optional
            Codec to be used to decode the bytestrings into Python strings if
            needed. Default 'utf-8'

        Returns
        -------
        sidpy.Dataset : List of sidpy.Dataset objects.
            Multi-channel inputs are separated into individual dataset objects
        """

        file_path = self._input_file_path
        folder_path, file_name = path.split(file_path)
        file_name = file_name[:-4]

        # Extracting the raw data into memory
        file_handle = open(file_path, 'r')
        string_lines = file_handle.readlines()
        file_handle.close()

        # Extract parameters from the first few header lines
        parm_dict, num_headers = self._read_parms(string_lines)

        num_rows = int(parm_dict['Main-y_pixels'])
        num_cols = int(parm_dict['Main-x_pixels'])
        num_pos = num_rows * num_cols
        spectra_length = int(parm_dict['Main-z_points'])

        # Extract the STS data from subsequent lines
        raw_data_2d = self._read_data(string_lines, num_pos, spectra_length,
                                      num_headers)
        raw_data = np.reshape(raw_data_2d,
                              (num_rows, num_cols, spectra_length))

        # Generate the x / voltage / spectroscopic axis:
        volt_vec = np.linspace(parm_dict['Spectroscopy-Device_1_Start [Volt]'],
                               parm_dict['Spectroscopy-Device_1_End [Volt]'],
                               spectra_length)

        # Build row, column vectors
        xvec = np.linspace(0, parm_dict['Main-x_length'], num_cols)
        yvec = np.linspace(0, parm_dict['Main-y_length'], num_rows)

        # now write it to the sidpy dataset object
        data_set = sid.Dataset.from_array(raw_data, name='Omicron_STS')
        data_set.data_type = 'spectral_image'

        # Add quantity and units
        data_set.units = parm_dict['Main-value_unit']
        data_set.quantity = 'Current'

        # Add dimension info
        data_set.set_dimension(
            0,
            sid.Dimension(xvec,
                          name='x',
                          units='nm',
                          quantity='position',
                          dimension_type=sid.DimensionType.SPATIAL))

        data_set.set_dimension(
            1,
            sid.Dimension(yvec,
                          name='y',
                          units='nm',
                          quantity='position',
                          dimension_type=sid.DimensionType.SPATIAL))

        data_set.set_dimension(
            2,
            sid.Dimension(volt_vec,
                          name='I',
                          units=parm_dict['Main-value_unit'],
                          quantity='Current',
                          dimension_type=sid.DimensionType.SPECTRAL))

        # append metadata
        data_set.metadata = parm_dict

        # Return the sidy dataset
        return data_set
Пример #11
0
    def read(self):
        if 'ndata' in self.extension:
            try:
                self.__f = open(self.__filename, "rb")
            except FileNotFoundError:
                raise FileNotFoundError('File not found')
            local_files, dir_files, eocd = parse_zip(self.__f)

            contains_data = b"data.npy" in dir_files
            contains_metadata = b"metadata.json" in dir_files
            file_count = contains_data + contains_metadata  # use fact that True is 1, False is 0

            self.__f.seek(local_files[dir_files[b"data.npy"][1]][1])

            self.data_cube = np.load(self.__f)

            json_pos = local_files[dir_files[b"metadata.json"][1]][1]
            json_len = local_files[dir_files[b"metadata.json"][1]][2]
            self.__f.seek(json_pos)
            json_properties = self.__f.read(json_len)

            self.original_metadata = json.loads(
                json_properties.decode("utf-8"))
            self.__f.close()
        elif self.extension == '.h5':
            # TODO: use lazy load for large datasets
            self.__f = h5py.File(self.__filename, 'a')
            if 'data' in self.__f:
                json_properties = self.__f['data'].attrs.get("properties", "")
                self.data_cube = self.__f['data'][:]
                self.original_metadata = json.loads(json_properties)
            self.__f.close()
        self.get_dimensions()
        # Need to switch image dimensions in Nion format
        image_dims = []
        spectral_dims = []
        for dim, axis in enumerate(self.dimensions):
            # print(dim, axis)
            if axis.dimension_type == sidpy.DimensionType.SPATIAL:
                image_dims.append(dim)
            if axis.dimension_type == sidpy.DimensionType.SPECTRAL:
                spectral_dims.append(dim)

        # convert line-scan nxN to spectral_image 1xnxN
        if len(image_dims) == 1:
            if self.data_cube.ndim > 1:
                self.data_cube = self.data_cube.reshape(
                    1, self.data_cube.shape[0], self.data_cube.shape[1])
                new_dims = [
                    sidpy.Dimension([1],
                                    name='x',
                                    units='pixels',
                                    quantity='distance',
                                    dimension_type='spatial'),
                    sidpy.Dimension(np.arange(self.data_cube.shape[0]),
                                    name='y',
                                    units='pixels',
                                    quantity='distance',
                                    dimension_type='spatial'),
                    self.dimensions[spectral_dims[0]]
                ]
                self.dimensions = new_dims

        if len(image_dims) == 2:
            self.data_cube = np.swapaxes(self.data_cube, image_dims[0],
                                         image_dims[1])
            temp = self.dimensions[image_dims[0]].copy()
            self.dimensions[image_dims[0]] = self.dimensions[
                image_dims[1]].copy()
            self.dimensions[image_dims[1]] = temp

        dataset = sidpy.Dataset.from_array(self.data_cube)

        dim_names = []
        for dim, axis in enumerate(self.dimensions):
            dataset.set_dimension(dim, axis)

        dataset.original_metadata = self.original_metadata
        if 'dimensional_calibrations' in dataset.original_metadata:
            for dim in dataset.original_metadata['dimensional_calibrations']:
                if dim['units'] == '':
                    dim['units'] = 'pixels'

        dataset.quantity = 'intensity'
        dataset.units = 'counts'
        if 'description' in dataset.original_metadata:
            dataset.title = dataset.original_metadata['description']['title']
        else:
            if 'title' in dataset.original_metadata:
                dataset.title = dataset.original_metadata['title']
            else:
                path, file_name = os.path.split(self.__filename)
                basename, extension = os.path.splitext(file_name)
                dataset.title = basename

        if 'data_source' in dataset.original_metadata:
            dataset.source = dataset.original_metadata['data_source']
        else:
            dataset.source = 'NionReader'

        self.set_data_type(dataset)
        dataset.modality = 'STEM data'
        dataset.h5_dataset = None

        return dataset
Пример #12
0
def set_dimensions(dset, current_channel):
    """Attaches correct dimension from old pyTEMlib style.

    Parameters
    ----------
    dset: sidpy.Dataset
    current_channel: hdf5.Group
    """
    dim = 0
    if dset.data_type == sidpy.DataType.IMAGE_STACK:
        dset.set_dimension(
            dim,
            sidpy.Dimension(np.arange(dset.shape[dim]),
                            name='frame',
                            units='frame',
                            quantity='stack',
                            dimension_type='TEMPORAL'))
        dim += 1
    if 'IMAGE' in dset.data_type:

        if 'spatial_scale_x' in current_channel:
            scale_x = current_channel['spatial_scale_x'][()]
        else:
            scale_x = 1
        if 'spatial_units' in current_channel:
            units_x = current_channel['spatial_units'][()]
            if len(units_x) < 2:
                units_x = 'pixel'
        else:
            units_x = 'generic'
        if 'spatial_scale_y' in current_channel:
            scale_y = current_channel['spatial_scale_y'][()]
        else:
            scale_y = 0
        dset.set_dimension(
            dim,
            sidpy.Dimension('x',
                            np.arange(dset.shape[dim]) * scale_x,
                            units=units_x,
                            quantity='Length',
                            dimension_type='SPATIAL'))
        dim += 1
        dset.set_dimension(
            dim,
            sidpy.Dimension('y',
                            np.arange(dset.shape[dim]) * scale_y,
                            units=units_x,
                            quantity='Length',
                            dimension_type='SPATIAL'))
        dim += 1
    if dset.data_type in [
            sidpy.DataType.SPECTRUM, sidpy.DataType.SPECTRAL_IMAGE
    ]:
        if 'spectral_scale_x' in current_channel:
            scale_s = current_channel['spectral_scale_x'][()]
        else:
            scale_s = 1.0
        if 'spectral_units_x' in current_channel:
            units_s = current_channel['spectral_units_x']
        else:
            units_s = 'eV'

        if 'spectral_offset_x' in current_channel:
            offset = current_channel['spectral_offset_x']
        else:
            offset = 0.0
        dset.set_dimension(
            dim,
            sidpy.Dimension(np.arange(dset.shape[dim]) * scale_s + offset,
                            name='energy',
                            units=units_s,
                            quantity='energy_loss',
                            dimension_type='SPECTRAL'))
Пример #13
0
def fourier_transform(dset):
    """
        Reads information into dictionary 'tags', performs 'FFT', and provides a smoothed FT and reciprocal
        and intensity limits for visualization.

        Parameters
        ----------
        dset: sidpy.Dataset
            image

        Returns
        -------
        fft_dset: sidpy.Dataset
            Fourier transform with correct dimensions

        Example
        -------
        >>> fft_dataset = fourier_transform(sidpy_dataset)
        >>> fft_dataset.plot()
    """

    assert isinstance(dset, sidpy.Dataset), 'Expected a sidpy Dataset'

    selection = []
    image_dim = []
    # image_dim = get_image_dims(sidpy.DimensionTypes.SPATIAL)
    if dset.data_type == sidpy.DataType.IMAGE_STACK:
        for dim, axis in dset._axes.items():
            if axis.dimension_type == sidpy.DimensionType.SPATIAL:
                selection.append(slice(None))
                image_dim.append(dim)
            elif axis.dimension_type == sidpy.DimensionType.TEMPORAL or len(dset) == 3:
                selection.append(slice(None))
                stack_dim = dim
            else:
                selection.append(slice(0, 1))
        if len(image_dim) != 2:
            raise ValueError('need at least two SPATIAL dimension for an image stack')
        image_stack = np.squeeze(np.array(dset)[selection])
        new_image = np.sum(np.array(image_stack), axis=stack_dim)
    elif dset.data_type == sidpy.DataType.IMAGE:
        new_image = np.array(dset)
    else:
        return

    new_image = new_image - new_image.min()
    fft_transform = (np.fft.fftshift(np.fft.fft2(new_image)))

    image_dims = get_image_dims(dset)

    units_x = '1/' + dset._axes[image_dims[0]].units
    units_y = '1/' + dset._axes[image_dims[1]].units

    fft_dset = sidpy.Dataset.from_array(fft_transform)
    fft_dset.quantity = dset.quantity
    fft_dset.units = 'a.u.'
    fft_dset.data_type = 'IMAGE'
    fft_dset.source = dset.title
    fft_dset.modality = 'fft'

    fft_dset.set_dimension(0, sidpy.Dimension(np.fft.fftshift(np.fft.fftfreq(new_image.shape[0],
                                                                             d=get_slope(dset.x.values))),

                                              name='u', units=units_x, dimension_type='RECIPROCAL',
                                              quantity='reciprocal_length'))
    fft_dset.set_dimension(1, sidpy.Dimension(np.fft.fftshift(np.fft.fftfreq(new_image.shape[1],
                                                                             d=get_slope(dset.y.values))),
                                              name='v', units=units_y, dimension_type='RECIPROCAL',
                                              quantity='reciprocal_length'))

    return fft_dset
Пример #14
0
    def get_eds(self, eds_stream=False):
        if 'AcquisitionSettings' not in self.metadata:
            eds_stream = True
        if eds_stream:
            self.datasets.append(sidpy.Dataset.from_array(self.data_array))
        else:
            data_array = self.get_eds_spectrum()
            if data_array.shape[0] == 1 and data_array.shape[1] == 1:
                data_array = np.array(data_array).flatten()
            self.datasets.append(sidpy.Dataset.from_array(data_array))
        # print(self.datasets[-1])

        self.datasets[-1].original_metadata = self.metadata

        detectors = self.datasets[-1].original_metadata['Detectors']
        if eds_stream:
            pass
        else:
            offset = 0.
            dispersion = 1.
            for detector in detectors.values():
                if self.metadata['BinaryResult']['Detector'] in detector[
                        'DetectorName']:
                    if 'OffsetEnergy' in detector:
                        offset = float(detector['OffsetEnergy'])
                    if 'Dispersion' in detector:
                        dispersion = float(detector['Dispersion'])

            self.datasets[-1].units = 'counts'
            self.datasets[-1].quantity = 'intensity'
            energy_scale = np.arange(
                self.datasets[-1].shape[-1]) * dispersion + offset

            if self.datasets[-1].ndim == 1:
                self.datasets[-1].data_type = 'spectrum'

                self.datasets[-1].set_dimension(
                    0,
                    sidpy.Dimension(energy_scale,
                                    name='energy_scale',
                                    units='eV',
                                    quantity='energy',
                                    dimension_type='spectral'))

            else:
                self.datasets[-1].data_type = 'spectral_image'
                self.datasets[-1].set_dimension(
                    2,
                    sidpy.Dimension(energy_scale,
                                    name='energy_scale',
                                    units='eV',
                                    quantity='energy',
                                    dimension_type='spectral'))
                scale_x = float(
                    self.metadata['BinaryResult']['PixelSize']['width']) * 1e9
                scale_y = float(
                    self.metadata['BinaryResult']['PixelSize']['height']) * 1e9

                self.datasets[-1].set_dimension(
                    0,
                    sidpy.Dimension(np.arange(self.datasets[-1].shape[0]) *
                                    scale_x,
                                    name='x',
                                    units='nm',
                                    quantity='distance',
                                    dimension_type='spatial'))
                self.datasets[-1].set_dimension(
                    1,
                    sidpy.Dimension(np.arange(self.datasets[-1].shape[1]) *
                                    scale_y,
                                    name='y',
                                    units='nm',
                                    quantity='distance',
                                    dimension_type='spatial'))
Пример #15
0
    def read(self, verbose=False):
        """
        Reads the file given in file_path into a sidpy dataset

        Parameters
        ----------
        verbose : Boolean (Optional)
            Whether or not to show  print statements for debugging
        debug : Boolean (Optional)
            Whether or not to print log statements
        Returns
        -------
        sidpy.Dataset : List of sidpy.Dataset objects.
            Multi-channel inputs are separated into individual dataset objects
        """
        file_path = self._input_file_path

        self.notes = None
        self.segments = None
        self.segments_name = []
        self.map_size = {'X': 0, 'Y': 0}
        self.channels_name = []
        self.points_per_sec = None
        self.verbose = verbose

        # Open the datafile
        try:
            data_filepath = os.path.abspath(file_path)
            ARh5_file = h5py.File(data_filepath, 'r')
        except:
            print('Unable to open the file', data_filepath)
            raise

        # Get info from the origin file like Notes and Segments
        self.notes = ARh5_file.attrs['Note'].decode('utf-8')
        self.segments = ARh5_file['ForceMap']['0']['Segments']
        segments_name = list(ARh5_file['ForceMap']['0'].attrs['Segments'])
        self.segments_name = [name.decode('utf-8') for name in segments_name]
        self.map_size['X'] = ARh5_file['ForceMap']['0']['Segments'].shape[0]
        self.map_size['Y'] = ARh5_file['ForceMap']['0']['Segments'].shape[1]
        channels_name = list(ARh5_file['ForceMap']['0'].attrs['Channels'])
        self.channels_name = [name.decode('utf-8') for name in channels_name]
        try:
            self.points_per_sec = np.float(
                self.note_value('ARDoIVPointsPerSec'))
        except NameError:
            self.points_per_sec = np.float(self.note_value('NumPtsPerSec'))

        if self.verbose:
            print('Map size [X, Y]: ', self.map_size)
            print('Channels names: ', self.channels_name)
            print('Name of Segments:', self.segments_name)

        # Only the extension 'Ext' segment can change size
        # so we get the shortest one and we trim all the others

        extension_idx = self.segments_name.index('Ext')
        short_ext = np.amin(np.array(self.segments[:, :, extension_idx]))
        longest_ext = np.amax(np.array(self.segments[:, :, extension_idx]))
        difference = longest_ext - short_ext  # this is a difference between integers
        tot_length = (np.amax(self.segments) - difference) + 1
        # +1 otherwise array(tot_length) will be of 1 position shorter
        points_trimmed = np.array(self.segments[:, :,
                                                extension_idx]) - short_ext

        # Open the output hdf5 file
        x_dim = np.linspace(0, np.float(self.note_value('FastScanSize')),
                            self.map_size['X'])
        y_dim = np.linspace(0, np.float(self.note_value('FastScanSize')),
                            self.map_size['Y'])
        z_dim = np.arange(tot_length) / np.float(self.points_per_sec)

        datasets = []  #list of sidpy datasets

        #Let's get all the metadata
        # Create the new segments that will be stored as attribute
        new_segments = {}
        for seg, name in enumerate(self.segments_name):
            new_segments.update({name: self.segments[0, 0, seg] - short_ext})

        seg_metadata = {
            'Segments': new_segments,
            'Points_trimmed': points_trimmed,
            'Notes': self.notes
        }
        general_metadata = {
            'translator': 'ARhdf5',
            'instrument':
            'Asylum Research ' + self.note_value('MicroscopeModel'),
            'AR sftware version': self.note_value('Version')
        }

        combined_metadata = dict({
            'segments': seg_metadata,
            'general': general_metadata
        })

        for index, channel in enumerate(self.channels_name):
            main_dset = np.empty(
                (self.map_size['X'], self.map_size['Y'], tot_length))
            for column in np.arange(self.map_size['X']):
                for row in np.arange(self.map_size['Y']):
                    AR_pos_string = str(column) + ':' + str(row)
                    seg_start = self.segments[column, row,
                                              extension_idx] - short_ext
                    main_dset[column, row, :] = ARh5_file['ForceMap']['0'][
                        AR_pos_string][index, seg_start:]

            quant_unit = self.get_def_unit(channel)

            data_set = sid.Dataset.from_array(main_dset, name='Image')
            data_set.data_type = sid.DataType.SPECTRAL_IMAGE

            # Add quantity and units
            data_set.units = quant_unit
            data_set.quantity = channel

            # Add dimension info
            data_set.set_dimension(
                0,
                sid.Dimension(x_dim,
                              name='x',
                              units='m',
                              quantity='x',
                              dimension_type='spatial'))
            data_set.set_dimension(
                1,
                sid.Dimension(y_dim,
                              name='y',
                              units='m',
                              quantity='y',
                              dimension_type='spatial'))
            data_set.set_dimension(
                2,
                sid.Dimension(z_dim,
                              name='Time',
                              units='s',
                              quantity='z',
                              dimension_type='spectral'))

            # append metadata
            chan_metadata = dict(ARh5_file['ForceMap']['0'].attrs)
            new_dict = {**chan_metadata, **combined_metadata}
            data_set.metadata = new_dict

            # Finally, append it
            datasets.append(data_set)

        for index, image in enumerate(ARh5_file['Image'].keys()):
            main_dset = np.array(ARh5_file['Image'][image])

            quant_unit = self.get_def_unit(image)

            data_set = sid.Dataset.from_array(main_dset, name='Image')
            data_set.data_type = sid.DataType.IMAGE

            # Add quantity and units
            data_set.units = quant_unit
            data_set.quantity = channel

            # Add dimension info
            data_set.set_dimension(
                0,
                sid.Dimension(x_dim,
                              name='x',
                              units=quant_unit,
                              quantity='x',
                              dimension_type='spatial'))
            data_set.set_dimension(
                1,
                sid.Dimension(y_dim,
                              name='y',
                              units=quant_unit,
                              quantity='y',
                              dimension_type='spatial'))

            # append metadata
            chan_metadata = dict(ARh5_file['Image'].attrs)
            new_dict = {**chan_metadata, **combined_metadata}
            data_set.metadata = new_dict

            # Finally, append it
            datasets.append(data_set)

        # Return the dataset
        return datasets