Source code for afmformats.afm_group

import pathlib

from .afm_data import AFMData
from .formats import load_data


__all__ = ["AFMGroup"]


[docs]class AFMGroup(object): """Container for :class:`afmformats.afm_data.AFMData`""" def __init__(self, path=None, meta_override=None, callback=None, modality=None, data_classes_by_modality=None): """ Parameters ---------- path: str or pathlib.Path or None If this option is specified, then an AFMGroup is generated directly from a datafile. meta_override: dict Dictionary with metadata that is used when loading the data in `path`. callback: callable or None A method that accepts a float between 0 and 1 to externally track the process of loading the data. data_classes_by_modality: dict Override the default AFMData class to use for managing the data (see :data:`default_data_classes_by_modality`): This is e.g. used by :ref:`nanite:index` to pass `Indentation` (which is a subclass of the default `AFMForceDistance`) for handling "force-indentation" data. """ if path is not None: path = pathlib.Path(path) self._mmlist = [] if path is not None: self += load_data( path, callback=callback, meta_override=meta_override, modality=modality, data_classes_by_modality=data_classes_by_modality ) elif meta_override is not None: raise ValueError("Specifying `meta_override` without specifying " "`path` is meaningless.") self.path = path def __add__(self, grp): out = AFMGroup() out += self out += grp return out def __iadd__(self, grp): if not isinstance(grp, (AFMGroup, list)): raise ValueError("Please specify list or AFMGroup for iadd!") for afmdata in grp: self.append(afmdata) self.path = None return self def __iter__(self): return iter(self._mmlist) def __getitem__(self, idx): return self._mmlist[idx] def __len__(self): return len(self._mmlist) def __repr__(self): return f"<{self.__class__.__name__}: '{self.path}' at {hex(id(self))}>" def __str__(self): rep = [f"{self.__class__.__name__}: '{self.path}'"] for afmdata in self._mmlist: rep.append("- {}".format(afmdata)) return "\n".join(rep)
[docs] def append(self, afmdata): """Append an AFMData instance Parameters ---------- afmdata: afmformats.afm_data.AFMData AFM data """ if not isinstance(afmdata, AFMData): raise ValueError("`afmdata` must be an instance of `AFMData`!") self._mmlist.append(afmdata)
[docs] def get_enum(self, enum): """Return the AFMData curve with this enum value Raises ------ ValueError if multiple curves with the same enum value exist. KeyError if the enum value is not found """ curves = [] for afmdata in self._mmlist: if afmdata.enum == enum: curves.append(afmdata) if len(curves) == 0: raise KeyError(f"Could not find dataset with enum '{enum}'!") elif len(curves) == 1: return curves[0] else: raise ValueError( f"Multiple curves with the enum value '{enum}' exist!")
def index(self, afmdata): return self._mmlist.index(afmdata)
[docs] def subgroup_with_path(self, path): """Return a subgroup with AFMData matching `path`""" path = pathlib.Path(path) subgroup = AFMGroup() for afmdata in self: if afmdata.path.samefile(path): subgroup.append(afmdata) subgroup.path = path return subgroup