diff --git a/unitpackage/entry.py b/unitpackage/entry.py index 136b0e7..b892dcc 100644 --- a/unitpackage/entry.py +++ b/unitpackage/entry.py @@ -144,7 +144,7 @@ def __dir__(self): >>> dir(entry) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE [... 'bibliography', 'citation', 'create_examples', 'curation', 'dataDescription', 'df', 'experimental', 'field_unit', 'figureDescription', - 'from_csv', 'from_df', 'from_local', 'identifier', 'mutable_resource', 'plot', + 'from_csv', 'from_df', 'from_loader', 'from_local', 'identifier', 'mutable_resource', 'plot', 'rename_fields', 'rescale', 'resource', 'save', 'source', 'system', 'yaml'] """ @@ -847,6 +847,56 @@ def from_df(cls, df, metadata=None, fields=None, outdir=None, *, basename): os.path.join(outdir, csvname), metadata=metadata, fields=fields ) + @classmethod + def from_loader(cls, filename=None, loaderName=None, metadata=None): + r""" + Returns an entry constructed from a loader known to unitpackage in loaders. + + TODO: Shoule be accesible from the loader class. + + available names: + * 'eclab' + + EXAMPLES:: + + >>> from unitpackage.entry import Entry + >>> entry = Entry.from_loader(filename='test/loader_data/eclab_cv.mpt', loaderName='eclab') + >>> entry + Entry('eclab_cv') + + >>> entry.df # doctest: +NORMALIZE_WHITESPACE + mode ox/red error ... (Q-Qo)/C I Range P/W + 0 2 1 0 ... 0.000000e+00 41 0.000001 + 1 2 0 0 ... -3.622761e-08 41 -0.000003 + ... + + """ + from unitpackage.loaders.baseloader import BaseLoader + + from pathlib import Path + + path = Path(filename) + + fields = None + + if metadata: + import yaml + metadata = yaml.load(metadata, Loader=yaml.SafeLoader) + try: + fields = metadata["figure description"]["fields"] + except (KeyError, AttributeError): + logger.warning("No units to the fields provided in the metadata") + + if not loaderName: + csv = BaseLoader(filename) + else: + csv = BaseLoader.create('eclab')(open(filename, 'r')) + + entry = cls.from_df(df=csv.df, metadata=metadata, basename=path.stem, fields=fields) + + return entry + + def save(self, *, outdir, basename=None): r""" Create a Data Package, i.e., a CSV file and a JSON file, in the directory ``outdir``. @@ -930,7 +980,7 @@ def save(self, *, outdir, basename=None): resource = self.resource.to_dict() - # update the fields from the main resource with those from the "MutableResource"resource + # update the fields from the main resource with those from the "MutableResource" resource resource["schema"]["fields"] = self.mutable_resource.schema.fields resource["schema"] = resource["MutableResource"].schema.to_dict() del resource["MutableResource"] diff --git a/unitpackage/loaders/baseloader.py b/unitpackage/loaders/baseloader.py index 51562d3..7ad0eb4 100644 --- a/unitpackage/loaders/baseloader.py +++ b/unitpackage/loaders/baseloader.py @@ -129,8 +129,30 @@ def file(self): return StringIO(self._file) - @staticmethod - def create(device=None): + @classmethod + def _loaders(cls): + r""" + A dictionary of known loaders. + """ + return {"eclab": __import__('unitpackage.loaders.eclabloader').loaders.eclabloader.ECLabLoader, + "gamry": __import__('unitpackage.loaders.gamryloader').loaders.gamryloader.GamryLoader} + + @classmethod + def known_loaders(cls): + r""" + A list of known loaders. Refer to the documentation for details + on supported file types for the individual Loaders. + + EXAMPLES:: + + >>> BaseLoader.known_loaders() + ['eclab', 'gamry'] + + """ + return list(cls._loaders().keys()) + + @classmethod + def create(cls, device=None): r""" Calls a specific `loader` based on a given device. @@ -152,18 +174,19 @@ def create(device=None): 0 2 0 0.1 0 0 1 2 1 1.4 5 1 - """ - if device == "eclab": - from unitpackage.loaders.eclabloader import ECLabLoader + An unknown device loader provides a list with supported Loaders:: - return ECLabLoader + >>> BaseLoader.create('unknown_device') # doctest: +NORMALIZE_WHITESPACE + Traceback (most recent call last): + ... + KeyError: "Device wth name 'unknown_device' is not in the list of supported Loaders (['eclab', 'gamry'])'." - if device == "gamry": - from unitpackage.loaders.gamryloader import GamryLoader + """ + if device in BaseLoader.known_loaders(): - return GamryLoader + return cls._loaders()[device] - raise KeyError(f"Device wth name '{device}' is unknown to the loader'.") + raise KeyError(f"Device wth name '{device}' is not in the list of supported Loaders ({cls.known_loaders()})'.") @property def header_lines(self):