Source code for machinevisiontoolbox.base.data

"""
Locates Machine Vision Toolbox data files within the separately installed ``mvtb-data``
package, sidestepping PyPI size limits by keeping large data independent of code.
"""

from __future__ import annotations

import importlib
from pathlib import Path
from typing import Any, Callable


[docs] def mvtb_load_matfile(filename: str) -> dict[str, Any]: """ Load toolbox mat format data file :param filename: relative pathname of datafile :type filename: str :raises ValueError: File does not exist :return: contents of mat data file :rtype: dict Reads a MATLAB format *mat* file which can contain multiple variables, in a binary or ASCII format. Returns a dict where the keys are the variable names and the values are NumPy arrays. .. note:: - Uses SciPy ``io.loadmat`` to do the work. - If the filename has no path component it will be first be looked for in the folder ``machinevisiontoolbox/data``, then the current working directory. :seealso: :func:`mvtb_path_to_datafile` :func:`scipy.io.loadmat` """ from collections import namedtuple from scipy.io import loadmat from scipy.io.matlab.mio5_params import mat_struct # get results as a dict data = mvtb_load_data(filename, loadmat, squeeze_me=True, struct_as_record=False) # if elements are a scipy.io.matlab.mio5_params.mat_struct, that is, they # were a MATLAB struct, convert them to a namedtuple for key, value in data.items(): if isinstance(value, mat_struct): # scipy private API # type: ignore[arg-type] # print("fixing") nt = namedtuple("matstruct", value._fieldnames) data[key] = nt(*[getattr(value, n) for n in value._fieldnames]) return data
[docs] def mvtb_load_jsonfile(filename: str) -> dict[str, Any]: """ Load toolbox JSON format data file :param filename: relative pathname of datafile :type filename: str :raises ValueError: File does not exist :return: contents of JSON data file :rtype: dict Reads a JSON format file which can contain multiple variables and return a dict where the keys are the variable names and the values are Python data types. .. note:: - If the filename has no path component it will be first be looked for in the folder ``machinevisiontoolbox/data``, then the current working directory. :seealso: :func:`mvtb_path_to_datafile` """ import json return mvtb_load_data(filename, lambda f: json.load(open(f, "r")))
[docs] def mvtb_load_data( filename: str, handler: Callable[..., Any], **kwargs: Any ) -> Any: # type: ignore """ Load toolbox data file :param filename: relative pathname of datafile :type filename: str :param handler: function to read data :type handler: callable :param kwargs: keyword arguments passed to ``handler`` :type kwargs: dict :raises ValueError: File does not exist :return: data object :rtype: Any Resolves the relative pathname to an absolute name and then invokes the data reading function:: handler(abs_file_name, **kwargs) For example:: data = mvtb_load_data('data/foo.dat', lambda f: data_load(open(f, 'r'))) .. note:: If the filename has no path component it will first be looked for in the folder ``machinevisiontoolbox/data``, then the current working directory. :seealso: :func:`mvtb_path_to_datafile` """ path = mvtb_path_to_datafile(filename) return handler(path, **kwargs)
[docs] def mvtb_path_to_datafile( *filename: str | Path, local: bool = True, string: bool = False ) -> Path | str: """ Get absolute path to file in MVTB data package :param filename: pathname components of image file :type filename: str or Path :param local: search for file locally first, default True :type local: bool :param string: return as string, default False :type string: bool :raises FileNotFoundError: File does not exist :return: Absolute path :rtype: Path or str The data associated with the Machine Vision Toolbox for Python is shipped as a separate package. The positional arguments are joined, like ``os.path.join``, for example:: mvtb_path_to_datafile('data', 'solar.dat') # data/solar.dat If ``local`` is True then ``~`` is expanded and if the file exists, the path is made absolute, and symlinks resolved:: mvtb_path_to_datafile("foo.dat") # find ./foo.dat mvtb_path_to_datafile("~/foo.dat") # find $HOME/foo.dat Otherwise, the file is sought within the ``mvtbdata`` package and if found, return that absolute path. Example: .. runblock:: pycon >>> from machinevisiontoolbox import mvtb_path_to_datafile >>> mvtb_path_to_datafile('data', 'solar.dat') # read mvtbdata/data/solar.dat """ path = Path(filename[-1]).expanduser() if path.is_absolute(): # path is absolute path = path.resolve() # make it absolute if path.exists(): if string: return str(path) else: return path else: raise ValueError(f"file {filename} not found locally") # file is either local or in mvtbdata path = Path(filename[-1]).expanduser() if local: # ignore the first element of filename if given, it's only for the mvtbdata case path = path.resolve() # make it absolute if path.exists(): if string: return str(path) else: return path # otherwise, look for it in mvtbdata mvtbdata = importlib.import_module("mvtbdata") root = Path(mvtbdata.__path__[0]) # if folder: # root = root / folder # root = Path(__file__).parent.parent / "images" path = root.joinpath(*filename).resolve() if path.exists(): if string: return str(path) else: return path else: raise ValueError(f"file {filename} not found locally or in mvtbdata ({root})")