def read(self, filenames, default_index=':', filetype=None): from ase.utils import basestring if isinstance(default_index, basestring): default_index = string2index(default_index) images = [] names = [] for filename in filenames: from ase.io.formats import parse_filename if '.json@' in filename or '.db@' in filename: # Ugh! How would one deal with this? # The parse_filename and string2index somehow conspire # to cause an error. See parse_filename # in ase.io.formats for this particular # special case. -askhl # # TODO Someone figure out how to see what header # a JSON file should have. imgs = read(filename, default_index, filetype) if hasattr(imgs, 'iterimages'): imgs = list(imgs.iterimages()) names += [filename] * len(imgs) images += imgs continue # Argh! if '@' in filename: actual_filename, index = parse_filename(filename, None) else: actual_filename, index = parse_filename( filename, default_index) imgs = read(filename, default_index, filetype) if hasattr(imgs, 'iterimages'): imgs = list(imgs.iterimages()) images.extend(imgs) # Name each file as filename@index: if isinstance(index, slice): start = index.start or 0 step = index.step or 1 else: start = index # index is just an integer assert len(imgs) == 1 step = 1 for i, img in enumerate(imgs): names.append('{}@{}'.format(actual_filename, start + i * step)) self.initialize(images, names)
def save_dialog(gui): dialog = gtk.FileChooserDialog(_('Save ...'), None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_SAVE, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) dialog.set_current_name('') dialog.set_current_folder(os.getcwd()) text = _('Append name with "@n" in order to write image number "n" ' 'instead of the current image.\n' 'Append "@start:stop" or "@start:stop:step" if you want to write ' 'a range of images.\n' 'You can leave out "start" and "stop" so that "name@:" will ' 'give you all images.\n' 'Negative numbers count from the last image ' '("name@-1": last image, "name@-2:": last two).') dialog.set_extra_widget(gtk.Label(text)) response = dialog.run() if response == gtk.RESPONSE_OK: filename = dialog.get_filename() dialog.destroy() else: dialog.destroy() return filename, index = parse_filename(filename) if index is None: index = slice(gui.frame, gui.frame + 1) if isinstance(index, str): index = string2index(index) format = filetype(filename, read=False) io = get_ioformat(format) extra = {} remove_hidden = False if format in ['png', 'eps', 'pov']: bbox = np.empty(4) size = np.array([gui.width, gui.height]) / gui.scale bbox[0:2] = np.dot(gui.center, gui.axes[:, :2]) - size / 2 bbox[2:] = bbox[:2] + size extra['rotation'] = gui.axes extra['show_unit_cell'] = gui.ui.get_widget( '/MenuBar/ViewMenu/ShowUnitCell').get_active() extra['bbox'] = bbox extra['colors'] = gui.get_colors(rgb=True)[gui.images.visible] remove_hidden = True images = [gui.images.get_atoms(i, remove_hidden=remove_hidden) for i in range(*index.indices(gui.images.nimages))] if len(images) > 1 and io.single: # We want to write multiple images, but the file format does not # support it. The solution is to write multiple files, inserting # a number in the file name before the suffix. j = filename.rfind('.') filename = filename[:j] + '{0:05d}' + filename[j:] for i, atoms in enumerate(images): write(filename.format(i), atoms, **extra) else: write(filename, images, **extra)
def test_parse_filename_do_not_split(): # check if do_not_split_by_at_sign flag works from ase.io.formats import parse_filename filename, index = parse_filename('user@local/file@name', do_not_split_by_at_sign=True) assert filename == 'user@local/file@name' assert index is None
def read(self, filenames, default_index=':', filetype=None): from ase.utils import basestring if isinstance(default_index, basestring): default_index = string2index(default_index) images = [] names = [] for filename in filenames: from ase.io.formats import parse_filename if '@' in filename and 'postgres' not in filename or \ 'postgres' in filename and filename.count('@') == 2: actual_filename, index = parse_filename(filename, None) else: actual_filename, index = parse_filename( filename, default_index) # Read from stdin: if filename == '-': import sys from io import BytesIO buf = BytesIO(sys.stdin.buffer.read()) buf.seek(0) filename = buf filetype = 'traj' imgs = read(filename, index, filetype) if hasattr(imgs, 'iterimages'): imgs = list(imgs.iterimages()) images.extend(imgs) # Name each file as filename@index: if isinstance(index, slice): start = index.start or 0 step = index.step or 1 else: start = index step = 1 for i, img in enumerate(imgs): if isinstance(start, int): names.append('{}@{}'.format(actual_filename, start + i * step)) else: names.append('{}@{}'.format(actual_filename, start)) self.initialize(images, names)
def save_dialog(gui, filename=None): dialog = ui.SaveFileDialog(gui.window.win, _('Save ...')) ui.Text(text).pack(dialog.top) filename = filename or dialog.go() if not filename: return filename, index = parse_filename(filename) if index is None: index = slice(gui.frame, gui.frame + 1) elif isinstance(index, basestring): index = string2index(index) elif isinstance(index, slice): pass else: if index < 0: index += len(gui.images) index = slice(index, index + 1) format = filetype(filename, read=False) io = get_ioformat(format) extra = {} remove_hidden = False if format in ['png', 'eps', 'pov']: bbox = np.empty(4) size = gui.window.size / gui.scale bbox[0:2] = np.dot(gui.center, gui.axes[:, :2]) - size / 2 bbox[2:] = bbox[:2] + size extra['rotation'] = gui.axes extra['show_unit_cell'] = gui.window['toggle-show-unit-cell'] extra['bbox'] = bbox colors = gui.get_colors(rgb=True) extra['colors'] = [ rgb for rgb, visible in zip(colors, gui.images.visible) if visible ] remove_hidden = True images = [ gui.images.get_atoms(i, remove_hidden=remove_hidden) for i in range(*index.indices(len(gui.images))) ] if len(images) > 1 and io.single: # We want to write multiple images, but the file format does not # support it. The solution is to write multiple files, inserting # a number in the file name before the suffix. j = filename.rfind('.') filename = filename[:j] + '{0:05d}' + filename[j:] for i, atoms in enumerate(images): write(filename.format(i), atoms, **extra) else: try: write(filename, images, **extra) except Exception as err: from ase.gui.ui import showerror showerror(_('Error'), err) raise
def test_parse_filename_bad_slice(): # parse filename with malformed @-slice from ase.io.formats import parse_filename import warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') filename, index = parse_filename('path.to/filename@s:4') assert filename == 'path.to/filename' assert len(w) == 1 assert 'Can not parse index' in str(w[-1].message)
def save_dialog(gui, filename=None): dialog = ui.SaveFileDialog(gui.window.win, _('Save ...')) ui.Text(text).pack(dialog.top) filename = filename or dialog.go() if not filename: return filename, index = parse_filename(filename) if index is None: index = slice(gui.frame, gui.frame + 1) elif isinstance(index, basestring): index = string2index(index) elif isinstance(index, slice): pass else: if index < 0: index += len(gui.images) index = slice(index, index + 1) format = filetype(filename, read=False) io = get_ioformat(format) extra = {} remove_hidden = False if format in ['png', 'eps', 'pov']: bbox = np.empty(4) size = gui.window.size / gui.scale bbox[0:2] = np.dot(gui.center, gui.axes[:, :2]) - size / 2 bbox[2:] = bbox[:2] + size extra['rotation'] = gui.axes extra['show_unit_cell'] = gui.window['toggle-show-unit-cell'] extra['bbox'] = bbox colors = gui.get_colors(rgb=True) extra['colors'] = [rgb for rgb, visible in zip(colors, gui.images.visible) if visible] remove_hidden = True images = [gui.images.get_atoms(i, remove_hidden=remove_hidden) for i in range(*index.indices(len(gui.images)))] if len(images) > 1 and io.single: # We want to write multiple images, but the file format does not # support it. The solution is to write multiple files, inserting # a number in the file name before the suffix. j = filename.rfind('.') filename = filename[:j] + '{0:05d}' + filename[j:] for i, atoms in enumerate(images): write(filename.format(i), atoms, **extra) else: write(filename, images, **extra)
def slice_split(filename): if '@' in filename: filename, index = parse_filename(filename, None) else: filename, index = parse_filename(filename, default_index) return filename, index
def save_dialog(gui): dialog = gtk.FileChooserDialog(_('Save ...'), None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_SAVE, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) dialog.set_current_name('') dialog.set_current_folder(os.getcwd()) text = _('Append name with "@n" in order to write image number "n" ' 'instead of the current image.\n' 'Append "@start:stop" or "@start:stop:step" if you want to write ' 'a range of images.\n' 'You can leave out "start" and "stop" so that "name@:" will ' 'give you all images.\n' 'Negative numbers count from the last image ' '("name@-1": last image, "name@-2:": last two).') dialog.set_extra_widget(gtk.Label(text)) response = dialog.run() if response == gtk.RESPONSE_OK: filename = dialog.get_filename() dialog.destroy() else: dialog.destroy() return filename, index = parse_filename(filename) if index is None: index = slice(gui.frame, gui.frame + 1) if isinstance(index, str): index = string2index(index) format = filetype(filename, read=False) io = get_ioformat(format) extra = {} remove_hidden = False if format in ['png', 'eps', 'pov']: bbox = np.empty(4) size = np.array([gui.width, gui.height]) / gui.scale bbox[0:2] = np.dot(gui.center, gui.axes[:, :2]) - size / 2 bbox[2:] = bbox[:2] + size extra['rotation'] = gui.axes extra['show_unit_cell'] = gui.ui.get_widget( '/MenuBar/ViewMenu/ShowUnitCell').get_active() extra['bbox'] = bbox extra['colors'] = gui.get_colors(rgb=True)[gui.images.visible] remove_hidden = True images = [ gui.images.get_atoms(i, remove_hidden=remove_hidden) for i in range(*index.indices(gui.images.nimages)) ] if len(images) > 1 and io.single: # We want to write multiple images, but the file format does not # support it. The solution is to write multiple files, inserting # a number in the file name before the suffix. j = filename.rfind('.') filename = filename[:j] + '{0:05d}' + filename[j:] for i, atoms in enumerate(images): write(filename.format(i), atoms, **extra) else: write(filename, images, **extra)
def test_parse_filename_db_entry(): # parse filename targetting database entry from ase.io.formats import parse_filename filename, index = parse_filename('path.to/filename.db@anything') assert filename == 'path.to/filename.db' assert index == 'anything'
def test_parse_filename_with_at_no_ext(): # parse filename with no extension but with @-slice from ase.io.formats import parse_filename filename, index = parse_filename('path.to/filename@1:4') assert filename == 'path.to/filename' assert index == slice(1, 4, None)
def test_parse_filename_no_ext(): # parse filename with no extension from ase.io.formats import parse_filename filename, index = parse_filename('path.to/filename') assert filename == 'path.to/filename' assert index is None
def test_parse_filename_with_at_in_path(): # parse filename with '@' in path, but not in name from ase.io.formats import parse_filename filename, index = parse_filename('user@local/filename.xyz') assert filename == 'user@local/filename.xyz' assert index is None
def test_parse_filename_with_at_in_ext(): # parse filename with '@' in extension from ase.io.formats import parse_filename filename, index = parse_filename('file_name.traj@1:4:2') assert filename == 'file_name.traj' assert index == slice(1, 4, 2)