# Path: ifcb/data/adc.py
# class AdcFile(BaseDictlike):
#     """
#     Represents an IFCB ``.adc`` file.
# 
#     Provides a dict-like interface; keys are target numbers,
#     values are target records. Target records are tuples which
#     are indexed according to values in the associated schema
#     (accessible via the ``schema`` property).
# 
#     :Example:
# 
#     >>> adc = AdcFile('IFCB4_2013_007_123423.adc')
#     >>> adc[23][adc.schema.ROI_WIDTH]
#     135
# 
#     """
#     def __init__(self, adc_path, parse=False):
#         """
#         :param adc_path: the path of the ``.adc`` file.
#         :param parse: whether to parse the file
#           (if not, parsing is deferred until data is accessed)
#         """
#         self.path = adc_path
#         self.pid = Pid(adc_path, parse=parse)
#         self.schema_version = self.pid.schema_version
#         self.schema = SCHEMA[self.schema_version]
#         if parse:
#             self.csv
#     def getsize(self):
#         """
#         :return int: the size of the file
#         """
#         return os.path.getsize(self.path)
#     @property
#     def lid(self):
#         """
#         The bin's LID
#         """
#         return self.pid.lid
#     @property
#     @lru_cache()
#     def csv(self):
#         """
#         The underlying CSV data as a ``pandas.DataFrame``
#         """
#         return parse_adc_file(self.path)
#     def to_dataframe(self):
#         """
#         Return the ADC data as a ``pandas.DataFrame``. If the
#         file has not been parsed yet, this opens the file, parses it,
#         and closes it.
#         """
#         return self.csv
#     def to_dict(self):
#         """
#         Return the ADC data as a dictionary
#         """
#         return self.csv.to_dict('series')
#     def to_hdf(self, hdf_file, group=None, replace=True, **kw):
#         """
#         Write the ADC file to an HDF file or group.
# 
#         :param hdf_file: the root HDF file pathname or
#           object (h5py.File or h5py.Group) in which to write
#           the ADC data
#         :param group: a path below the sub-group
#           to use
#         :param replace: whether to replace any existing data
#           at that location in the HDF file
#         """
#         from .hdf import adc2hdf
#         adc2hdf(self, hdf_file, group, replace=replace, **kw)
#     def keys(self):
#         """
#         Yield the target numbers of this ADC file, in order.
#         """
#         yield from self.csv.index
#     def has_key(self, k):
#         return k in self.csv.index
#     def __len__(self):
#         return len(self.csv)
#     def get_target(self, target_number):
#         """
#         Get the ADC data for a given target, as a tuple.
#         """
#         d = tuple(self.csv[c][target_number] for c in self.csv.columns)
#         return d
#     def __getitem__(self, target_number):
#         return self.get_target(target_number)
#     def __repr__(self):
#         return '<ADC file %s>' % self.path
#     def __str__(self):
#         return self.path
# 
# Path: ifcb/data/utils.py
# class BaseDictlike(object):
#     """
#     Provides as complete a readonly dict interface as possible,
#     based on anything that implements ``keys`` and ``__getitem__``.
#     when overriding, override ``has_key`` rather than ```__contains__``.
# 
#     Override any method if a more efficient implementation
#     is available.
#     """
#     def keys(self):
#         """
#         Default implementation raises ``NotImplementedError``.
#         This must be overridden for correct behavior.
#         """
#         raise NotImplementedError
#     def __getitem__(self, k):
#         """
#         Default implementation raises ``NotImplementedError``.
#         This must be overridden for correct behavior.
# 
#         :param k: the key
#         :type k: hashable
#         """
#         raise NotImplementedError
#     def __iter__(self):
#         yield from self.keys()
#     def has_key(self, k):
#         """
#         Iterates over keys and returns first key for
#         which equality test passes. This method is
#         called by the ``__contains__`` special method.
# 
#         :param k: the key to test
#         :type k: hashable
#         """
#         for ek in self.keys():
#             if ek == k:
#                 return True
#         return False
#     def __contains__(self, k):
#         return self.has_key(k)
#     def items(self):
#         """
#         Yields item pairs, based on calling keys
#         and then accessing each item.
#         """
#         for k in self.keys():
#             yield k, self[k]
#     def values(self):
#         """
#         Yields all values. Calls ``items``.
#         """
#         for k, v in self.items():
#             yield v
#     def __len__(self):
#         n = 0
#         for k in self.keys():
#             n += 1
#         return n


import os
import numpy as np
from functools import lru_cache
from .adc import AdcFile
from .utils import BaseDictlike
        from .hdf import roi2hdf
    :param height: the height of the image in pixels

    :returns array-like: an 8-bit 2d image
    """
    length = width * height
    inroi.seek(byte_offset)
    pixel_values = inroi.read(length)
    return np.frombuffer(pixel_values, dtype=np.uint8).reshape((width,height))

class RoiFile(BaseDictlike):
    """
    Wraps and provides access to an IFCB ``.roi`` file.
    Provides context manager support for keeping the
    file open while images are read from it. Also
    provides dict-like support including len, iteration,
    and access to images by target number.

    Requires an associated ``.adc`` file or ``AdcFile`` object.
    """
    def __init__(self, adc, roi_path):
        """
        :param adc: the path of the ``.adc`` file, or an ``AdcFile`` object
        :param roi_path: the path to the ``.roi`` file
        """
        # duck type adc argument
        self.adc = None
        try:
            adc.pid # should work for AdcFile objects
            self.adc = adc
        except AttributeError:

# Path: ifcb/data/adc.py
# class AdcFile(BaseDictlike):
#     """
#     Represents an IFCB ``.adc`` file.
# 
#     Provides a dict-like interface; keys are target numbers,
#     values are target records. Target records are tuples which
#     are indexed according to values in the associated schema
#     (accessible via the ``schema`` property).
# 
#     :Example:
# 
#     >>> adc = AdcFile('IFCB4_2013_007_123423.adc')
#     >>> adc[23][adc.schema.ROI_WIDTH]
#     135
# 
#     """
#     def __init__(self, adc_path, parse=False):
#         """
#         :param adc_path: the path of the ``.adc`` file.
#         :param parse: whether to parse the file
#           (if not, parsing is deferred until data is accessed)
#         """
#         self.path = adc_path
#         self.pid = Pid(adc_path, parse=parse)
#         self.schema_version = self.pid.schema_version
#         self.schema = SCHEMA[self.schema_version]
#         if parse:
#             self.csv
#     def getsize(self):
#         """
#         :return int: the size of the file
#         """
#         return os.path.getsize(self.path)
#     @property
#     def lid(self):
#         """
#         The bin's LID
#         """
#         return self.pid.lid
#     @property
#     @lru_cache()
#     def csv(self):
#         """
#         The underlying CSV data as a ``pandas.DataFrame``
#         """
#         return parse_adc_file(self.path)
#     def to_dataframe(self):
#         """
#         Return the ADC data as a ``pandas.DataFrame``. If the
#         file has not been parsed yet, this opens the file, parses it,
#         and closes it.
#         """
#         return self.csv
#     def to_dict(self):
#         """
#         Return the ADC data as a dictionary
#         """
#         return self.csv.to_dict('series')
#     def to_hdf(self, hdf_file, group=None, replace=True, **kw):
#         """
#         Write the ADC file to an HDF file or group.
# 
#         :param hdf_file: the root HDF file pathname or
#           object (h5py.File or h5py.Group) in which to write
#           the ADC data
#         :param group: a path below the sub-group
#           to use
#         :param replace: whether to replace any existing data
#           at that location in the HDF file
#         """
#         from .hdf import adc2hdf
#         adc2hdf(self, hdf_file, group, replace=replace, **kw)
#     def keys(self):
#         """
#         Yield the target numbers of this ADC file, in order.
#         """
#         yield from self.csv.index
#     def has_key(self, k):
#         return k in self.csv.index
#     def __len__(self):
#         return len(self.csv)
#     def get_target(self, target_number):
#         """
#         Get the ADC data for a given target, as a tuple.
#         """
#         d = tuple(self.csv[c][target_number] for c in self.csv.columns)
#         return d
#     def __getitem__(self, target_number):
#         return self.get_target(target_number)
#     def __repr__(self):
#         return '<ADC file %s>' % self.path
#     def __str__(self):
#         return self.path
# 
# Path: ifcb/data/utils.py
# class BaseDictlike(object):
#     """
#     Provides as complete a readonly dict interface as possible,
#     based on anything that implements ``keys`` and ``__getitem__``.
#     when overriding, override ``has_key`` rather than ```__contains__``.
# 
#     Override any method if a more efficient implementation
#     is available.
#     """
#     def keys(self):
#         """
#         Default implementation raises ``NotImplementedError``.
#         This must be overridden for correct behavior.
#         """
#         raise NotImplementedError
#     def __getitem__(self, k):
#         """
#         Default implementation raises ``NotImplementedError``.
#         This must be overridden for correct behavior.
# 
#         :param k: the key
#         :type k: hashable
#         """
#         raise NotImplementedError
#     def __iter__(self):
#         yield from self.keys()
#     def has_key(self, k):
#         """
#         Iterates over keys and returns first key for
#         which equality test passes. This method is
#         called by the ``__contains__`` special method.
# 
#         :param k: the key to test
#         :type k: hashable
#         """
#         for ek in self.keys():
#             if ek == k:
#                 return True
#         return False
#     def __contains__(self, k):
#         return self.has_key(k)
#     def items(self):
#         """
#         Yields item pairs, based on calling keys
#         and then accessing each item.
#         """
#         for k in self.keys():
#             yield k, self[k]
#     def values(self):
#         """
#         Yields all values. Calls ``items``.
#         """
#         for k, v in self.items():
#             yield v
#     def __len__(self):
#         n = 0
#         for k in self.keys():
#             n += 1
#         return n


# Path: ifcb/data/roi.py
import os
import numpy as np
from functools import lru_cache
from .adc import AdcFile
from .utils import BaseDictlike
        from .hdf import roi2hdf

    :param height: the height of the image in pixels

    :returns array-like: an 8-bit 2d image
    """
    length = width * height
    inroi.seek(byte_offset)
    pixel_values = inroi.read(length)
    return np.frombuffer(pixel_values, dtype=np.uint8).reshape((width,height))

class RoiFile(BaseDictlike):
    """
    Wraps and provides access to an IFCB ``.roi`` file.
    Provides context manager support for keeping the
    file open while images are read from it. Also
    provides dict-like support including len, iteration,
    and access to images by target number.

    Requires an associated ``.adc`` file or ``AdcFile`` object.
    """
    def __init__(self, adc, roi_path):
        """
        :param adc: the path of the ``.adc`` file, or an ``AdcFile`` object
        :param roi_path: the path to the ``.roi`` file
        """
        # duck type adc argument
        self.adc = None
        try:
            adc.pid # should work for AdcFile objects
            self.adc = adc
        except AttributeError:

            self.adc = AdcFile(adc)