Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IO - Object-oriented API? #24

Closed
morganjwilliams opened this issue Sep 7, 2020 · 4 comments
Closed

IO - Object-oriented API? #24

morganjwilliams opened this issue Sep 7, 2020 · 4 comments
Assignees
Labels
enhancement New feature or request

Comments

@morganjwilliams
Copy link
Owner

morganjwilliams commented Sep 7, 2020

One option for developing an API for calibration, transformation and export of points/images would be a class-based interface which allows import and export of 'known/registered' formats

The first part of this might look something along the lines of:

from autopew.io import handler

class Pew(object):

  def __init__(self, *args, **kwargs):
    self._transform = None
    self.transformed = None
    if len(args) == 2: # calibrate using src-dest
      self.calibrate(*args)
    elif len(args) == 1: # pre-defined transform?
      # check that object is a transform or transform matrix
      ...
      self._transform = args[0]
    else:
      raise NotImplementedError('Unrecognised initialization arguments supplied.')

  def calibrate(self, src, dest):
    """
    Calibrate the transformation between two planar coordinate systems given
    two sets of corresponding points.

    Parameters
    -------------
    src : str | pathlib.Path | numpy.ndarray | pandas.DataFrame
    dest: str | pathlib.Path | numpy.ndarray | pandas.DataFrame
    """
    ...
    # check for registered file handlers for importing both sets of points (need not be arrays)
    self.src, self.dest = handler.read(src), handler.read(dest)
    self._transform = affine_transform(
        affine_from_AB(self.src, self.dest)
    )

  def load(self, filepath):
    """
    Import a set of sample coordinates.

    Parameters
    -------------
    filepath: str | pathlib.Path | numpy.ndarray | pandas.DataFrame
    """
    # check for registered file handlers for import
    self.samples = np.array(hander.read(filepath))
    ...
    # return imported coordinates?

  def transform(self, limits=None):
    """
    Transform source coordinates to the destination coordinate system.
    """
    if self._transform is None:
      raise NotCalibratedError("Transform hasn't yet been calibrated.")
    self.transformed= self._transform(self.samples)
    return self.transformed # return values so that quick queries can be make without exporting

  def export(self, filepath):
    """
    Export a set of coordinates.

    Parameters
    -------------
    filepath: str | pathlib.Path
    """
    # make sure the sample inputs have been transformed
    if self.transformed is None:
      self.transform()
    # check for registered file handlers for export
    hander.write(self.transformed, filepath)
@morganjwilliams morganjwilliams added the enhancement New feature or request label Sep 7, 2020
@morganjwilliams morganjwilliams self-assigned this Sep 7, 2020
@morganjwilliams
Copy link
Owner Author

morganjwilliams commented Sep 7, 2020

The second part of this would be the library of registered file formats and their relevant import/export functions (likely to/from pandas.DataFrame). A scaffold for these could be something along the lines of:

import sys, inspect

class PewIOSpecification(object):
  extension = None
  
  def __init__(self, *args, **kwargs):
    pass

class PewCSV(PewIOSpecification):
  extension = '.csv'

  def read(self, filepath):
    ...
    df = pd.read_csv(filepath, ...)
    return df

  def write(self, df, filepath):
    ...
    df.to_csv(filepath.with_suffix(self.extension))

class PewSCANCSV(PewIOSpecification):
  extension = '.scancsv'

  def read(self, filepath):
    ...
    df = read_scancsv(filepath)
    return df

  def write(self, df, filepath):
    ...
    to_scancsv(filepath.with_suffix(self.extension))

def registered_extensions():
  """
  Get a dictionary of registered extensions mapping the relevant IO specifications.
  """
  specs = inspect.getmembers(
    sys.modules[__name__],
    lambda cls: issubclass(cls, PewIOSpecification) if inspect.isclass(cls) else False,
  )
  return {cls.extension: cls for (name, cls) in specs}

@morganjwilliams
Copy link
Owner Author

morganjwilliams commented Sep 11, 2020

This in practice would look like:

map = Pew()
map.calibrate('source_calibration_coords.csv', 'dest_calibration_coords.scancsv')
map.load('sample_coords.csv')
map.export('laserfile.scancsv')

@morganjwilliams
Copy link
Owner Author

Another thing that we'll need for this is a specification for how we store intermediate information (e.g. principally sample coordinates, but also things like sample names, comments and other analytical metadata). One logical way to do this is with dataframes, as in most cases sample analysis involves tabular data.

This would require:

  • x-y sample/calibration points;
  • either sample names or a sampling naming strategy (less important for calibration, but could be useful for verification);

And optionally include things like:

  • z/focus coordinates (see Automatic Z-coordinates. #3)
  • comments
  • analysis configuration parameters per-point or per-dataset (supplied at export time), like spot sizes and dwell times (for systems which allow import of such configurations)

@morganjwilliams
Copy link
Owner Author

morganjwilliams commented Jan 13, 2021

This issue has largely been addressed, so will now be closed.

The autopew.Pew object-oriented API is now live and can be used to succinctly calibrate, import, transform and export sample coordinates from images and stages. The autopew.io.PewIOSpecification class can be used to develop templates for other types of file IO (currently, this includes import/export of generic .csv, Chromium .scancsv, and JEOL .pos files). A function has been added such that any new template added to autopew.io will be automatically discovered and used either where explicitly directed or where a filename with the appropriate extension is provided. Keyword arguments are passed to respective read/write functions of file handlers such that parameters such as z/focus coordinates and comments should be automatically incorporated where the functionality is defined in the file handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant