Source code for axeap.core.item

from .conventions import PathType
from .signal import Signal

import uuid

# Dev Note: I could try metaclasses but that seems like a rabbit hole of
# abstract typing.
[docs]class DataItem: """Superclass for all data-containing objects. This is the superclass for objects such as :obj:`.core.scan.Scan` or :obj:`.core.spectra.Spectra`. Attributes ---------- TYPE_NAME : :obj:`str` The name of the data item type, for example "Scan". Same across all instances. name : :obj:`str` The name of the data item, not necessarily unique. uuid : :obj:`uuid.UUID` UUID of the data item. Unique. meta : :obj:`dict` Dictionary of metadata describing instance of DataItem. """ TYPE_NAME = "DataItem"
[docs] def __init__(self, name=None, meta=None): """ Parameters ---------- name : :obj:`str`, optional Name to assign to item. Should be human-readable, not necessarily unique. meta : :obj:`dict`, optional Metadata concerning the item. Keys should be strings. """ self.name = name if name else "" self.uuid = uuid.uuid4() self.meta = meta.copy() if meta else {}
[docs]class Saveable: """Superclass for any object that can be saved to a file. Attributes ---------- SAVE_FILE_EXTENTIONS : :obj:`list` List of strings containing file extensions that the object can be saved under. Extensions are lowercase and do not include dots (example "txt" instead of ".TXT"). Should be overwritten in subclass definition. SAVE_PATH_TYPE : :obj:`.core.conventions.PathType` Specifies whether the object can be saved as a file or a directory. Should be overwritten by subclass definition. """ SAVE_FILE_EXTENTIONS = [] SAVE_PATH_TYPE = PathType.FILE
[docs] def saveToPath(self, path): """ Save data stored in object to a given path. Parameters ---------- path : :obj:`pathlib.Path`, :obj:`str` Path to store object data to. Could be file or directory. """ raise NotImplementedError('Saving to path has not been implemented!')
[docs]class Loadable: """Superclass for any object that can be loaded from a file. Attributes ---------- LOAD_FILE_EXTENTIONS : :obj:`list` List of strings containing file extensions that the object can be loaded from. Extensions are lowercase and do not include dots (example "txt" instead of ".TXT"). Should be overwritten by subclass definition. SAVE_PATH_TYPE : :obj:`.core.conventions.PathType` Specifies whether the object can be loaded from a file, multiple files, or a directory. Should be overwritten by subclass but constant across instances. """ LOAD_FILE_EXTENTIONS = [] LOAD_PATH_TYPE = PathType.FILE
[docs] def loadFromFile(path): """Load data from file and use to instantiate class. Parameters ---------- path : :obj:`pathlib.Path`, :obj:`str` Path of file containing data. Returns ------- :obj:`Loadable` Instance of object, populated with data from file. """ raise NotImplementedError('Loading from path has not been implemented!')
[docs]class DataItemSet: """Set of :obj:`DataItem` objects. This is essentially just a list of :obj:`DataItem` objects but with the additional features of allowing items to be "selected" or not and emitting signals when the membership of the :obj:`DataItemSet` changes or the selection status of one of the :obj:`DataItem`'s changes. This is the superclass for :obj:`.core.scan.ScanSet`, :obj:`.core.roi.ROISet`, and :obj:`.core.spectra.SpectraSet`. Note ---- Though this uses a list to store the underlying data, users should not depend on the order of the items in the set. Attributes ---------- itemadded : :obj:`.core.signal.Signal` When item is added, signal is emitted with item as argument. itemremoved : :obj:`.core.signal.Signal` When item is removed, signal emitted with item as argument. selectionchanged : :obj:`.core.signal.Signal` When item selection is changed, signal emitted with signature (item, selection). """
[docs] def __init__(self, items=None, selection_default=True, *args, **kwargs): """ Parameters ---------- items : :obj:`list`, optional List of :obj:`DataItem` objects to initially populate the :obj:`DataItemSet`. selection_default : :obj:`bool`, optional Default selection value for items after being added to set. Default default value is `True`. """ self.itemadded = Signal() self.itemremoved = Signal() self.selectionchanged = Signal() self.items = [] self.selections = {} self.selection_default = selection_default if items is not None: for item in items: self.add(item)
[docs] def add(self, item): """Add :obj:`DataItem` to set.""" self.items.append(item) self.selections[item] = self.selection_default self.itemadded.emit(item)
[docs] def remove(self, item): """Remove :obj:`DataItem` from set.""" self.items.remove(item) self.selections.pop(item) self.itemremoved.emit(item)
[docs] def setSelection(self, item, sel): """Change selection status of :obj:`DataItem` Parameters ---------- item : :obj:`DataItem` Item whose selection status to change. sel : :obj:`bool` New selection status. """ if self.selections[item] != sel: self.selections[item] = sel self.selectionchanged.emit(item, sel)
[docs] def getSelection(self, item): """Get selection status of item.""" return self.selections[item]
[docs] def getSelected(self): """Get list of selected items.""" return [i for i in self if self.getSelection(i)]
def __len__(self): return len(self.items) def __iter__(self): """Get iterator over all items in set (not just selected ones).""" return iter(self.items)