Пример #1
0
    def _get_metadata(cls, file, file_path):

        first_line, second_line = file.split('\n')[:2]

        name = os.path.splitext(os.path.split(file_path)[1])[0]
        keys = {config.get_key('cube', 'line_one'): first_line.strip(),
                config.get_key('cube', 'line_two'): second_line.strip()}

        return name, keys
Пример #2
0
    def export_to_txt(self):
        if not self.interpolation.interpolation_checkbox.isChecked():
            # Otherwise maps at different energies would be of different size
            print('Only interpolated OrbitalData can be exported.')
            return

        path = config.get_key('paths', 'txt_export_start')
        if path == 'None':
            file_name, _ = QFileDialog.getSaveFileName(
                None, 'Save .itx File (*.itx)')
        else:
            start_path = str(__directory__ / path)
            file_name, _ = QFileDialog.getSaveFileName(
                None, 'Save .itx File (*.itx)', str(start_path))

        if not file_name:
            return

        export_energies = eval(config.get_key('orbital', 'export_energies'))
        if isinstance(export_energies, dict):
            export_energies = np.linspace(export_energies['min'],
                                          export_energies['max'],
                                          export_energies['num'],
                                          endpoint=True)

        kmaps = []
        old_energy = self.cube_options.energy_spinbox.value()
        for energy in export_energies:
            self.cube_options.energy_spinbox.setValue(energy)
            kmaps.append(self.get_displayed_plot_data().data)
        self.cube_options.energy_spinbox.setValue(old_energy)
        kmaps = np.array(kmaps)
        xrange, yrange = self.get_displayed_plot_data().range
        shape = kmaps[0].shape
        xscale = (xrange[1] - xrange[0]) / shape[1]
        yscale = (yrange[1] - yrange[0]) / shape[0]
        name = Path(file_name).stem

        with open(file_name, 'w') as f:
            f.write('IGOR\n')
            f.write(
                f'WAVES/N=({shape[1]},{shape[0]},{len(export_energies)})\t{name}\n'
            )
            f.write('BEGIN\n')
            for data in kmaps:
                f.write('\t')
                np.savetxt(f, data.T, newline='\t')
            f.write('\nEND\n')
            f.write(f'X SetScale/P x {xrange[0]},{xscale}, "A^-1", {name}; ')
            f.write(f'SetScale/P y {yrange[0]},{yscale}, "A^-1", {name}; ')
            f.write(
                f'SetScale/P z {export_energies[0]},{export_energies[1]-export_energies[0]}, "eV", {name}; '
            )
            f.write(f'SetScale d 0,0, "", {name}\n')
Пример #3
0
    def plot(self,
             data,
             title,
             crosshair,
             region,
             phi_sample=720,
             line_sample=500,
             normalized=False):

        index = len(self.plot_item.listDataItems())
        colors = config.get_key('profile_plot', 'colors')
        color = colors.split(',')[index % len(colors)]
        line_width = int(config.get_key('profile_plot', 'line_width'))
        symbols = config.get_key('profile_plot', 'symbols')
        symbol = symbols.split(',')[index % len(symbols)]
        symbol_size = int(config.get_key('profile_plot', 'symbol_size'))

        if isinstance(data, PlotData):
            x, y = self.model.get_plot_data(data, crosshair, region,
                                            phi_sample, line_sample)
        else:
            data, axis = data
            x = np.array(data.axes[axis].axis)
            y = []
            for i in range(len(x)):
                slice_ = data.slice_from_index(i, axis=axis)
                plot_data = crosshair.cut_from_data(slice_, region=region).data

                if np.isnan(plot_data).all():
                    y.append(np.nan)

                else:
                    if config.get_key('crosshair',
                                      'normalized_intensity') == 'True':
                        y.append(normalize(plot_data))

                    else:
                        y.append(np.nansum(plot_data))

            y = np.array(y)

        x = x[~np.isnan(y)]
        y = y[~np.isnan(y)]

        if normalized:
            y = y / max(y)

        self.plot_item.plot(x,
                            y,
                            name=title + self.title_suffixes[region],
                            pen=mkPen(color, width=line_width),
                            symbol=symbol,
                            symbolPen=mkPen(color, width=symbol_size),
                            symbolBrush=mkBrush(color))
Пример #4
0
 def _set_misc(self):
     x = int(config.get_key('app', 'x'))
     y = int(config.get_key('app', 'y'))
     w = int(config.get_key('app', 'w'))
     h = int(config.get_key('app', 'h'))
     self.setGeometry(x, y, h, w)
     if config.get_key('app', 'fullscreen') == 'True':
         self.showMaximized()
     self.setWindowTitle('kMap.py')
     self.setWindowIcon(
         QIcon(str(__directory__ / 'resources/images/icon.png')))
     self.show()
Пример #5
0
    def export_to_hdf5(self):
        if not self.interpolation.interpolation_checkbox.isChecked():
            print('Only interpolated OrbitalData can be exported.')
            return

        path = config.get_key('paths', 'hdf5_export_start')
        if path == 'None':
            file_name, _ = QFileDialog.getSaveFileName(
                None, 'Save .hdf5 File (*.hdf5)')
        else:
            start_path = str(__directory__ / path)
            file_name, _ = QFileDialog.getSaveFileName(
                None, 'Save .hdf5 File (*.hdf5)', str(start_path))

        if not file_name:
            return
        else:
            h5file = h5py.File(file_name, 'w')

        export_energies = eval(config.get_key('orbital', 'export_energies'))
        if isinstance(export_energies, dict):
            export_energies = np.linspace(export_energies['min'],
                                          export_energies['max'],
                                          export_energies['num'],
                                          endpoint=True)

        kmaps = []
        old_energy = self.cube_options.energy_spinbox.value()
        for energy in export_energies:
            self.cube_options.energy_spinbox.setValue(energy)
            kmaps.append(self.get_displayed_plot_data().data)
        self.cube_options.energy_spinbox.setValue(old_energy)
        kmaps = np.array(kmaps)
        xrange, yrange = self.get_displayed_plot_data().range

        h5file.create_dataset('name', data='Orbitals')
        h5file.create_dataset('axis_1_label', data='E_kin')
        h5file.create_dataset('axis_2_label', data='kx')
        h5file.create_dataset('axis_3_label', data='ky')
        h5file.create_dataset('axis_1_units', data='eV')
        h5file.create_dataset('axis_2_units', data='1/Å')
        h5file.create_dataset('axis_3_units', data='1/Å')
        h5file.create_dataset('axis_1_range',
                              data=[export_energies[0], export_energies[-1]])
        h5file.create_dataset('axis_2_range', data=xrange)
        h5file.create_dataset('axis_3_range', data=yrange)
        h5file.create_dataset('data',
                              data=kmaps,
                              dtype='f8',
                              compression='gzip',
                              compression_opts=9)
        h5file.close()
Пример #6
0
    def __init__(self, data, ID, name='', meta_data={}, file_format='cube'):

        self.dk3D = float(config.get_key('orbital', 'dk3D'))

        AbstractData.__init__(self, ID, name, meta_data)
        Orbital.__init__(self, data, file_format=file_format, dk3D=self.dk3D,
                         value='abs2', orbital_name=name)
    def get_LUT(self):

        colormap = self.getHistogramWidget().gradient.colorMap()
        nPts = int(config.get_key('pyqtgraph', 'nPts'))
        LUT = colormap.getLookupTable(mode='float', alpha=True, nPts=nPts)

        return LUT
Пример #8
0
    def load_cube_files_locally(self):
        # Load one or more new cube files

        extensions = 'cube files (*.cube);; All Files (*)'

        path = config.get_key('paths', 'cube_start')
        if path == 'None':
            paths, _ = QFileDialog.getOpenFileNames(None,
                                                    'Open file(s)',
                                                    filter=extensions)
        else:
            start_path = str(__directory__ / path)
            paths, _ = QFileDialog.getOpenFileNames(None, 'Open file(s)',
                                                    str(start_path),
                                                    extensions)

        if not paths:
            # No file chosen
            logging.getLogger('kmap').info('No file chosen')
            return

        # Get Tab to load to
        tab = self.tab_widget.get_orbital_tab_to_load_to()

        # Load Data to Tab
        for path in paths:
            tab.add_orbital_from_filepath(path)
Пример #9
0
    def update_label(self):

        plot_data = self.plot_item.get_plot_data()

        if plot_data == None:
            intensity = np.nan
            area = np.nan

        elif np.isnan(plot_data.data).all():
            intensity = np.nan
            area = np.nan

        else:
            cut = self.model.cut_from_data(plot_data, region='center')
            area = plot_data.data[~np.isnan(plot_data.data
                                            )].size * plot_data.step_size[
                                                0] * plot_data.step_size[1]
            intensity = np.nansum(cut.data)

        decimals = int(config.get_key('crosshair', 'decimal_places'))
        self.point_value_label.setText(f'{intensity:.{decimals}e}')
        self.total_area_value.setText(f'{area:.{decimals}e}')

        x = self.model.x
        y = self.model.y

        self.distance_value_label.setText('%.2f' % np.sqrt(x**2 + y**2))
Пример #10
0
    def fit(self):
        """Calling this method will trigger a lmfit with the current
        settings.

        Returns:
            (list): A list of MinimizerResults. One for each slice
            fitted.
        """

        lmfit_padding = float(config.get_key('lmfit', 'padding'))

        for parameter in self.parameters.values():
            if parameter.vary and parameter.value <= parameter.min:
                padded_value = parameter.min + lmfit_padding
                print('WARNING: Initial value for parameter \'%s\' had to be corrected to %f (was %f)' % (
                    parameter.name, padded_value, parameter.value))
                parameter.value = padded_value

        results = []
        for index in self.slice_policy[1]:
            slice_ = self.get_sliced_kmap(index)
            result = minimize(self._chi2,
                              copy.deepcopy(self.parameters),
                              kws={'slice_': slice_},
                              nan_policy='omit',
                              method=self.method[0],
                              xtol=self.method[1])

            results.append([index, result])

        return results
Пример #11
0
    def load_hdf5_files(self):
        # Load one or more new hdf5 files

        log = logging.getLogger('kmap')
        log.info('Loading .hdf5 file(s)...')

        extensions = 'hdf5 files (*.hdf5 *.h5);; All Files (*)'

        path = config.get_key('paths', 'hdf5_start')
        if path == 'None':
            paths, _ = QFileDialog.getOpenFileNames(None,
                                                    'Open file(s)',
                                                    filter=extensions)
        else:
            start_path = str(__directory__ / path)
            paths, _ = QFileDialog.getOpenFileNames(None, 'Open file(s)',
                                                    str(start_path),
                                                    extensions)

        if not paths:
            # No file chosen
            log.info('No file chosen')
            return

        for path in paths:
            self.tab_widget.open_sliced_data_tab(path)
Пример #12
0
    def export_to_hdf5(self):
        path = config.get_key('paths', 'hdf5_export_start')
        if path == 'None':
            file_name, _ = QFileDialog.getSaveFileName(
                None, 'Save .hdf5 File (*.hdf5)')
        else:
            start_path = str(__directory__ / path)
            file_name, _ = QFileDialog.getSaveFileName(
                None, 'Save .hdf5 File (*.hdf5)', str(start_path))

        if not file_name:
            return
        else:
            h5file = h5py.File(file_name, 'w')

        kmaps = self.get_residual_kmaps()

        slice_axis = self.slider.data.axes[0]
        x_axis = self.slider.data.axes[1]
        y_axis = self.slider.data.axes[2]

        h5file.create_dataset('name', data='Residual')
        h5file.create_dataset('axis_1_label', data=slice_axis.label)
        h5file.create_dataset('axis_2_label', data=x_axis.label)
        h5file.create_dataset('axis_3_label', data=y_axis.label)
        h5file.create_dataset('axis_1_units', data=slice_axis.units)
        h5file.create_dataset('axis_2_units', data=x_axis.units)
        h5file.create_dataset('axis_3_units', data=y_axis.units)
        h5file.create_dataset('axis_1_range', data=slice_axis.range)
        h5file.create_dataset('axis_2_range', data=x_axis.range)
        h5file.create_dataset('axis_3_range', data=y_axis.range)
        h5file.create_dataset('data', data=kmaps, dtype='f8',
                              compression='gzip', compression_opts=9)
        h5file.close()
Пример #13
0
    def update_label(self):

        plot_data = self.plot_item.get_plot_data()

        if plot_data == None:
            intensity = 0

        elif np.isnan(plot_data.data).all():
            intensity = np.nan

        else:
            cut = self.model.cut_from_data(plot_data, region='center')

            # Normalize by dividing by the number of non nan elements
            if config.get_key('crosshair', 'normalized_intensity') == 'True':
                intensity = normalize(cut.data)

            else:
                intensity = np.nansum(cut.data)

        if abs(intensity) > 1000:
            self.point_value_label.setText('%.2fk' % (intensity / 1000))

        else:
            self.point_value_label.setText('%.2f' % intensity)

        x = self.model.x
        y = self.model.y

        self.distance_value_label.setText('%.2f' % np.sqrt(x**2 + y**2))
Пример #14
0
    def _setup(self):

        s_share = config.get_key('orbital', 's_share_default')
        self.s_share_spinbox.setValue(float(s_share))

        self.s_share_label.setVisible(False)
        self.s_share_spinbox.setVisible(False)
Пример #15
0
    def __init__(self, mode, *args, **kwargs):

        super(SlicedDatabaseWindow, self).__init__(*args, **kwargs)
        self.setupUi(self)
        self._setup_tree()
        self._connect()

        # Setup database
        path = __directory__ / config.get_key('paths', 'database')
        self.database = Database(str(path))

        # Open Options Window
        if mode == 'binding-energy':
            self.options = SlicedDataBaseOptions()

        elif mode == 'photon-energy':
            self.options = SlicedDataBaseOptions2()

        elif mode == 'cubefile':
            self.options = SlicedCubefileOptions()

        # URLs (with extra information if available) chosen
        self.URLs = []

        self.fill_tree()

        self.show()
        self.options.show()
    def set_range(self, range_):

        padding = float(config.get_key('pyqtgraph', 'padding'))
        self.view.setRange(xRange=range_[0],
                           yRange=range_[1],
                           update=True,
                           padding=padding)
Пример #17
0
    def plot(self, x, y, title):
        index = len(self.plot_item.listDataItems())
        colors = config.get_key('profile_plot', 'colors')
        colors = colors.split(',')
        color = colors[index % len(colors)]
        line_width = int(config.get_key('profile_plot', 'line_width'))
        symbols = config.get_key('profile_plot', 'symbols')
        symbols = symbols.split(',')
        symbol = symbols[index % len(symbols)]
        symbol_size = int(config.get_key('profile_plot', 'symbol_size'))

        self.plot_item.plot(x, y,
                            name=title,
                            pen=mkPen(color, width=line_width),
                            symbol=symbol,
                            symbolPen=mkPen(color, width=symbol_size),
                            symbolBrush=mkBrush(color))
Пример #18
0
    def get_plot(self):

        image = self.plot_data.data
        scale = self.plot_data.step_size
        pixel_center = config.get_key('pyqtgraph', 'pixel_center') == 'True'
        pos = self._calculate_pos(scale, pixel_center=pixel_center)
        range_ = self._calculate_range(scale, pixel_center=pixel_center)

        return image, pos, scale, range_
Пример #19
0
    def init_from_online(cls, url, ID, meta_data={}):
        
        log = logging.getLogger('kmap')
        cache_dir = Path(config.get_key('paths', 'cache'))
        cache_file = url.split('OrganicMolecule/')[1].replace('/', '_')
        cache_file = str(cache_dir / cache_file)

        if os.path.isfile(cache_file):
            log.info(f'Found file {url} in cache.')
            with open(cache_file, 'r') as f:
                file = f.read()
                
            name, keys = OrbitalData._get_metadata(file, url)
            name = meta_data['name'] if 'name' in meta_data else name
            meta_data.update(keys)
            file_format = 'cube'

        else:
            try:
                log.info(f'Loading from ID{meta_data["ID"]:05d} hdf5 file....')
                molecule, psi = get_remote_hdf5_orbital('143.50.77.12', '5002',
                int(float(meta_data['database ID'])), int(meta_data['ID'])-1)

                if os.path.isdir(cache_dir):
                    log.info(f'Putting {url} into cache {cache_file}')
                    write_cube(psi, molecule, cache_file)

                file = h5py.File('aux.hdf5', 'w', driver='core', backing_store=False)
                file.create_dataset('num_atom', data=molecule['num_atom'])
                file.create_dataset('chemical_numbers', data=molecule['chemical_numbers'])
                file.create_dataset('atomic_coordinates', data=molecule['atomic_coordinates'], dtype="float64")
                file.create_dataset('x', data=psi['x'], dtype="float64")
                file.create_dataset('y', data=psi['y'], dtype="float64")
                file.create_dataset('z', data=psi['z'], dtype="float64")
                file.create_dataset('data', data=psi['data'], dtype="float64")
                name = psi['name']
                file_format = 'hdf5'

            except:
                log.info('HDF5 File not available, loading cube file...')
                log.info('Loading from database: %s' % url)
                with urllib.request.urlopen(url) as f:
                    file = f.read().decode('utf-8')

                    if os.path.isdir(cache_dir):
                        log.info(f'Putting {url} into cache {cache_file}')
                        with open(cache_file, 'w') as f:
                            f.write(file)

                name, keys = OrbitalData._get_metadata(file, url)
                name = meta_data['name'] if 'name' in meta_data else name
                meta_data.update(keys)
                file_format = 'cube'

        return cls(file, ID, name=name, meta_data=meta_data, file_format=file_format)
    def refresh_plot(self, keep_max_level=False):

        self.clear()

        if self.model.plot_data is None:
            return

        image, pos, scale, range_ = self.model.get_plot()

        if np.all(np.isnan(image)) == True:
            return

        old_level = self.get_levels()

        # Plot
        self.setImage(image,
                      autoRange=True,
                      autoLevels=True,
                      pos=pos,
                      scale=scale)

        self.set_range(range_)
        ratio = (range_[1][1] - range_[1][0]) / (range_[0][1] - range_[0][0])

        if config.get_key('pyqtgraph', 'fixed_ratio') == 'True':
            self.set_aspect_ratio(ratio)

        else:
            self.set_aspect_ratio(None)

        if (keep_max_level
                or config.get_key('pyqtgraph', 'keep_max_level') == 'True'):
            levels = [np.nanmin(image.data), np.nanmax(image.data)]

            # Catch empty plots
            if old_level != (0, 1):
                levels[0] = old_level[0] if old_level[0] < levels[0] else \
                levels[0]
                levels[1] = old_level[1] if old_level[1] > levels[1] else \
                levels[1]

            self.set_levels(levels)
Пример #21
0
    def set_default_colormap(self):

        default_colormap = config.get_key('colormap', 'default')

        try:
            self.set_colormap(default_colormap)

        except ValueError:
            log = logging.getLogger('kmap')
            log.error('The colormap set as default does not exist.')
            log.error(traceback.format_exc())
Пример #22
0
    def get_path(self):

        # Path for the .json file containing the colormaps
        temp = __directory__ / config.get_key('paths', 'colormap')
        user = temp / 'colormaps_user.json'

        if not os.path.isfile(user):
            default = temp / 'colormaps_default.json'
            copy(default, user)

        return user
Пример #23
0
    def set_label(self, side, label, units=None, color='k', size=1):

        axis = AxisItem(side, text=label, units=units,
                        **{'color': color, 'font-size': size})

        if config.get_key('pyqtgraph', 'show_axis_label') == 'True':
            axis.showLabel(True)

        else:
            axis.showLabel(False)

        self.view.setAxisItems({side: axis})
    def get_orbital_kmap_by_ID(self, ID, parameters):
        orbital = self.ID_to_orbital(ID)
        if orbital is None:
            raise IndexError('wrong ID')

        weight, *parameters = parameters
        s_share = float(config.get_key('orbital', 's_share'))

        # Get scaled kmap
        kmap = weight * orbital.get_kmap(*parameters, s_share=s_share)

        return kmap
Пример #25
0
    def __init__(self, plot_item):

        # Setup GUI
        super(Colormap, self).__init__()
        self.setupUi(self)
        self._connect()

        # Path for the .json file containing the colormaps
        self.path = __directory__ + config.get_key('paths', 'colormap')
        self.model = ColormapModel(plot_item)

        self.load_colormaps()
    def get_orbital_kmap_by_ID(self, ID):
        orbital = self.ID_to_orbital(ID)
        if orbital is None:
            raise IndexError('wrong ID')

        parameters = self.controller.get_parameters(ID)
        # Split of first element
        weight, *other = parameters
        s_share = float(config.get_key('orbital', 's_share'))
        # Get scaled kmap
        kmap = weight * orbital.get_kmap(*other, s_share=s_share)

        return kmap
    def set_labels(self, x, y):

        color = config.get_key('pyqtgraph', 'axis_color')
        size = config.get_key('pyqtgraph', 'axis_size')

        if isinstance(x, list):
            self.set_label('bottom', x[0], x[1], color, size)

        elif isinstance(x, Axis):
            self.set_label('bottom', x.label, x.units, color, size)

        else:
            self.set_label('bottom', str(x), None, color, size)

        if isinstance(y, list):
            self.set_label('left', y[0], y[1], color, size)

        elif isinstance(y, Axis):
            self.set_label('left', y.label, y.units, color, size)

        else:
            self.set_label('left', str(y), None, color, size)
Пример #28
0
    def init_from_file(cls, path, ID):
        log = logging.getLogger('kmap')
        possible_paths = [path]
        file_name = Path(path).name
        possible_paths.append(Path(config.get_key('paths', 'cube_start')) /
                file_name)
        for path in config.get_key('paths', 'path').split(','):
            possible_paths.append(Path(path) / file_name)

        for path in possible_paths:
            log.info(f'Looking for {file_name} in {path}.')
            if os.path.isfile(path):
                log.info(f'Found.')
                with open(path, 'r') as f:
                    file = f.read()
               
                name, keys = OrbitalData._get_metadata(file, path)
                return cls(file, ID, name=name, meta_data=keys)
            else:
                continue

        print(f'ERROR: File {file_name} wasn\'t found. Please add its location to the search path (general_settings.paths.path')
Пример #29
0
    def _setup(self):

        temp = __directory__ / config.get_key('paths', 'equations')
        default = temp / 'background_equations_default'
        user = temp / 'background_equations_user'
        self.path = user if os.path.isfile(user) else default

        with open(self.path, 'r') as file:
            equations = file.read().split('\n')

        for equation in equations:
            self.background_combobox.addItem(equation)

        self.background_combobox.setCurrentIndex(0)
Пример #30
0
    def update_label(self):

        plot_data = self.plot_item.get_plot_data()

        super().update_label()

        if plot_data == None:
            intensity = np.nan
            area = np.nan

        else:
            cut = self.model.cut_from_data(plot_data, region='ring')
            area = cut.data[~np.isnan(cut.data)].size * plot_data.step_size[
                0] * plot_data.step_size[1]
            intensity = np.nansum(cut.data)

            # Normalize by dividing by area
            if config.get_key('crosshair', 'normalized_intensity') == 'True':
                intensity /= area

        decimals = int(config.get_key('crosshair', 'decimal_places'))
        self.ring_value_label.setText(f'{intensity:.{decimals}e}')
        self.ann_area_value.setText(f'{area:.{decimals}e}')