Source code for lightonopu.context

import datetime as dt

from lightonopu import types
from lightonopu.types import IntList, Roi


[docs]def from_epoch(datetime_or_epoch): """Convert to datetime if argument is an epoch, otherwise return same""" if isinstance(datetime_or_epoch, dt.datetime): # already a datetime return datetime_or_epoch if isinstance(datetime_or_epoch, float): return dt.datetime.fromtimestamp(datetime_or_epoch) raise ValueError("Need an epoch or datetime")
[docs]class Context: """Describes the context of an OPU transform Attributes ---------- exposure_us: int Exposure time of the camera (µs) frametime_us: int Exposure time of the DMD (µs) cam_roi: tuple(list(int)) (offset, size) of the camera region of interest dmd_roi: (offset, size) of the DMD region of interest start: float epoch of the start time of the transform end: float epoch of the end time of the transform n_ones: int average number of ones displayed on the DMD self.fmt_type: lightonopu.types.FeaturesFormat type of formatting used to map features to the DMD self.fmt_factor: int size of the macro-pixels used when formatting """ def __init__(self, frametime: int = None, exposure: int = None, cam_roi: Roi = None, start: dt.datetime = None, end: dt.datetime = None, gain: float = None, dmd_roi: Roi = None, n_ones: int = None, fmt_type: types.FeaturesFormat = None, fmt_factor: int = None): self.info = None self.exposure_us = exposure # type: int self.frametime_us = frametime # type: int if cam_roi: self.cam_roi_upper = cam_roi[0] # type: IntList # coordinates of upper camera ROI self.cam_roi_shape = cam_roi[1] # type: IntList # shape of camera ROI else: self.cam_roi_shape = self.cam_roi_upper = None if dmd_roi: self.dmd_roi_upper = dmd_roi[0] # type: IntList # coordinates of upper dmd ROI self.dmd_roi_shape = dmd_roi[1] # type: IntList # shape of camera ROI else: self.dmd_roi_shape = self.dmd_roi_upper = None self.start = start # type: dt.datetime # timestamp at start self.end = end # type: dt.datetime # timestamp at end self.gain = gain # camera gain self.n_ones = n_ones self.fmt_type = fmt_type self.fmt_factor = fmt_factor
[docs] def from_opu(self, opu, start, end=None): """Takes context from an OPU device, namely frametime, exposure, cam_roi and gain. With optional end time""" self.frametime_us = opu.frametime_us self.exposure_us = opu.exposure_us self.cam_roi_upper, self.cam_roi_shape = opu.cam_ROI self.gain = opu.gain_dB self.start = start # type: dt.datetime # timestamp at start self.end = end # type: dt.datetime # timestamp at end
@staticmethod def from_timestamps(start, end=None): if end: end = from_epoch(end) return Context(-1, -1, ([-1, -1], [-1, -1]), from_epoch(start), end)
[docs] @staticmethod def from_dict(d): """Create a context from a dict (flat or not)""" roi = d.get("ROI") if not roi and "roi_position_0" in d.keys(): roi = ([d["roi_position_0"], d["roi_position_1"]], [d["roi_shape_0"], d["roi_shape_1"]]) dmd_roi = d.get("dmd_ROI") if not dmd_roi and "dmd_roi_position_0" in d.keys(): dmd_roi = ([d["dmd_roi_position_0"], d["dmd_roi_position_1"]], [d["dmd_roi_shape_0"], d["dmd_roi_shape_1"]]) context = Context(d['frametime_us'], d['exposure_us'], roi, d["start"], d.get("end"), d.get("gain_db"), dmd_roi, d.get("n_ones"), d.get("fmt_type"), d.get("fmt_factor")) context.add_info(d.get("info")) return context
def add_info(self, info): self.info = info def as_dict(self): result = {"exposure_us": self.exposure_us, "frametime_us": self.frametime_us, "ROI": (self.cam_roi_upper, self.cam_roi_shape), "start": self.start} if self.gain is not None: result["gain_dB"] = self.gain if self.info is not None: result["info"] = self.info if self.end is not None: result["end"] = self.end if self.dmd_roi_shape is not None and self.dmd_roi_upper is not None: result["dmd_ROI"] = (self.dmd_roi_upper, self.dmd_roi_shape) if self.n_ones is not None: result["n_ones"] = self.n_ones if self.fmt_type is not None: result["fmt_type"] = self.fmt_type if self.fmt_factor is not None: result["fmt_factor"] = self.fmt_factor return result def as_flat_dict(self): result = self.as_dict() roi = result.pop("ROI", None) dmd_roi = result.pop("dmd_ROI", None) if roi is not None: result["roi_position_0"] = roi[0][0] result["roi_position_1"] = roi[0][1] result["roi_shape_0"] = roi[1][0] result["roi_shape_1"] = roi[1][1] if dmd_roi is not None: result["dmd_roi_position_0"] = dmd_roi[0][0] result["dmd_roi_position_1"] = dmd_roi[0][1] result["dmd_roi_shape_0"] = dmd_roi[1][0] result["dmd_roi_shape_1"] = dmd_roi[1][1] return result def __str__(self): return str(self.as_dict()) def __eq__(self, other): if not isinstance(other, Context): # don't attempt to compare against unrelated types return NotImplemented return self.__dict__ == other.__dict__