def add_hw_component(self, hw_comp, setting_controller, hidden=None): """ Add setting entries for the given hardware component hidden (None or set of str): name of VAs to not show """ hidden = HIDDEN_VAS | (hidden or set()) self.setting_controllers.append(setting_controller) vas_comp = getVAs(hw_comp) vas_config = get_hw_config( hw_comp, self._hw_settings_config) # OrderedDict or dict # Re-order the VAs of the component in the same order as in the config vas_names = util.sorted_according_to(list(vas_comp.keys()), list(vas_config.keys())) for name in vas_names: try: if name in hidden: continue elif name in vas_config: va_conf = vas_config[name] else: logging.debug("No config found for %s: %s", hw_comp.role, name) va_conf = None va = vas_comp[name] setting_controller.add_setting_entry(name, va, hw_comp, va_conf) except TypeError: msg = "Error adding %s setting for: %s" logging.exception(msg, hw_comp.name, name)
def addSettings(self, objWithVA, conf=None): """ Adds settings as one widget on a line for each VigilantAttribute (VA) in the given object. Each setting entry created is added to .entries. objWithVA (object): an object with VAs. conf (None or dict of str->config): allows to override the automatic selection of the VA widget. See odemis.gui.conf.data for documentation. raise: LookupError: if no VA is found on the objWithVA """ vas = getVAs(objWithVA) if not vas: raise LookupError("No VAs found!") if not conf: conf = {} vas_names = util.sorted_according_to(vas.keys(), conf.keys()) for name in vas_names: va = vas[name] self.setting_controller.add_setting_entry(name, va, None, conf=conf.get( name, None))
def addSettings(self, objWithVA, conf=None): """ Adds settings as one widget on a line for each VigilantAttribute (VA) in the given object. Each setting entry created is added to .entries. objWithVA (object): an object with VAs. conf (None or dict of str->config): allows to override the automatic selection of the VA widget. See odemis.gui.conf.data for documentation. raise: LookupError: if no VA is found on the objWithVA """ vas = getVAs(objWithVA) if not vas: raise LookupError("No VAs found!") if not conf: conf = {} vas_names = util.sorted_according_to(vas.keys(), conf.keys()) for name in vas_names: va = vas[name] self.setting_controller.add_setting_entry(name, va, None, conf=conf.get(name, None))
def add_hw_component(self, hw_comp, setting_controller, hidden=None): """ Add setting entries for the given hardware component hidden (None or set of str): name of VAs to not show """ hidden = HIDDEN_VAS | (hidden or set()) self.setting_controllers.append(setting_controller) vas_comp = getVAs(hw_comp) vas_config = get_hw_config(hw_comp, self._hw_settings_config) # OrderedDict or dict # Re-order the VAs of the component in the same order as in the config vas_names = util.sorted_according_to(vas_comp.keys(), vas_config.keys()) for name in vas_names: try: if name in hidden: continue elif name in vas_config: va_conf = vas_config[name] else: logging.debug("No config found for %s: %s", hw_comp.role, name) va_conf = None va = vas_comp[name] setting_controller.add_setting_entry(name, va, hw_comp, va_conf) except TypeError: msg = "Error adding %s setting for: %s" logging.exception(msg, hw_comp.name, name)
def _show_axes(self, sctrl, axes, sclass): """ Show axes in settings panel for a given stream. sctrl (StreamController): stream controller axes (str -> comp): list of axes to display sclass (Stream): stream class of (settings) stream """ stream_configs = get_stream_settings_config() stream_config = stream_configs.get(sclass, {}) # Add Axes (in same order as config) axes_names = util.sorted_according_to(axes.keys(), list(stream_config.keys())) for axisname in axes_names: comp = axes[axisname] if comp is None: logging.debug("Skipping axis %s for non existent component", axisname) continue if axisname not in comp.axes: logging.debug("Skipping non existent axis %s on component %s", axisname, comp.name) continue conf = stream_config.get(axisname) sctrl.add_axis_entry(axisname, comp, conf)
def _show_mn_axes(self, sctrl): main_data = self.main_app.main_data spg = self._getAffectingSpectrograph(main_data.monochromator) axes = {"wavelength": spg, "grating": spg, "slit-in": spg, "slit-monochromator": spg, } stream_configs = get_stream_settings_config() stream_config = stream_configs.get(MonochromatorSettingsStream, {}) # Add Axes (in same order as config) axes_names = util.sorted_according_to(axes.keys(), stream_config.keys()) for axisname in axes_names: comp = axes[axisname] if comp is None: logging.debug("Skipping axis %s for non existent component", axisname) continue if axisname not in comp.axes: logging.debug("Skipping non existent axis %s on component %s", axisname, comp.name) continue conf = stream_config.get(axisname) sctrl.add_axis_entry(axisname, comp, conf)
def test_simple(self): in_exp = ((([1, 2, 3], [3, 2, 1]), [3, 2, 1]), (([1, 2, 3], [4, 2]), [2, 1, 3]), (([], [4, 2]), []), ((["b", "a"], []), ["b", "a"]), ) for i, eo in in_exp: o = util.sorted_according_to(*i) self.assertEqual(o, eo, "Failed to get correct output for %s" % (i,))
def test_simple(self): in_exp = ( (([1, 2, 3], [3, 2, 1]), [3, 2, 1]), (([1, 2, 3], [4, 2]), [2, 1, 3]), (([], [4, 2]), []), ((["b", "a"], []), ["b", "a"]), ) for i, eo in in_exp: o = util.sorted_according_to(*i) self.assertEqual(o, eo, "Failed to get correct output for %s" % (i, ))
def _show_axes(self, sctrl, axes, sclass): """ Show axes in settings panel for a given stream. sctrl (StreamController): stream controller axes (str -> comp): list of axes to display sclass (Stream): stream class of (settings) stream """ stream_configs = get_stream_settings_config() stream_config = stream_configs.get(sclass, {}) # Add Axes (in same order as config) axes_names = util.sorted_according_to(axes.keys(), stream_config.keys()) for axisname in axes_names: comp = axes[axisname] if comp is None: logging.debug("Skipping axis %s for non existent component", axisname) continue if axisname not in comp.axes: logging.debug("Skipping non existent axis %s on component %s", axisname, comp.name) continue conf = stream_config.get(axisname) sctrl.add_axis_entry(axisname, comp, conf)
def __init__(self, name, data, *args, **kwargs): """ :param name: (string) :param data: (model.DataArray(Shadow) of shape (YX) or list of such DataArray(Shadow)). The metadata MD_POS, MD_AR_POLE and MD_POL_MODE should be provided """ if not isinstance(data, collections.Iterable): data = [data] # from now it's just a list of DataArray # TODO: support DAS, as a "delayed loading" by only calling .getData() # when the projection for the particular data needs to be computed (or # .raw needs to be accessed?) # Ensure all the data is a DataArray, as we don't handle (yet) DAS data = [d.getData() if isinstance(d, model.DataArrayShadow) else d for d in data] # find positions of each acquisition # (float, float, str or None)) -> DataArray: position on SEM + polarization -> data self._pos = {} sempositions = set() polpositions = set() for d in data: try: sempos_cur = d.metadata[MD_POS] # When reading data: floating point error (slightly different keys for same ebeam pos) # -> check if there is already a position specified, which is very close by # (and therefore the same ebeam pos) and replace with that ebeam position # (e.g. all polarization positions for the same ebeam positions will have exactly the same ebeam pos) for sempos in sempositions: if almost_equal(sempos_cur[0], sempos[0]) and almost_equal(sempos_cur[1], sempos[1]): sempos_cur = sempos break self._pos[sempos_cur + (d.metadata.get(MD_POL_MODE, None),)] = img.ensure2DImage(d) sempositions.add(sempos_cur) if MD_POL_MODE in d.metadata: polpositions.add(d.metadata[MD_POL_MODE]) except KeyError: logging.info("Skipping DataArray without known position") # SEM position VA # SEM position displayed, (None, None) == no point selected (x, y) self.point = model.VAEnumerated((None, None), choices=frozenset([(None, None)] + list(sempositions))) if self._pos: # Pick one point, e.g., top-left bbtl = (min(x for x, y in sempositions if x is not None), min(y for x, y in sempositions if y is not None)) # top-left point is the closest from the bounding-box top-left def dis_bbtl(v): try: return math.hypot(bbtl[0] - v[0], bbtl[1] - v[1]) except TypeError: return float("inf") # for None, None self.point.value = min(sempositions, key=dis_bbtl) # check if any polarization analyzer data, (None) == no analyzer data (pol) if polpositions: # Check that for every position, all the polarizations are available, # as the GUI expects all the combinations possible, and weird errors # will happen when one is missing. for pos in sempositions: for pol in polpositions: if pos + (pol,) not in self._pos: logging.warning("Polarization data is not complete: missing %s,%s/%s", pos[0], pos[1], pol) # use first entry in acquisition to populate VA (acq could have 1 or 6 pol pos) current_pol = util.sorted_according_to(polpositions, POL_POSITIONS)[0] self.polarization = model.VAEnumerated(current_pol, choices=polpositions) # Add a polarimetry VA containing the polarimetry image results. # Note: Polarimetry analysis are only possible if all 6 images per ebeam pos exist. # Also check if arpolarimetry package can be imported as might not be installed. if polpositions >= set(POL_POSITIONS) and arpolarimetry: self.polarimetry = model.VAEnumerated(MD_POL_S0, choices=set(POL_POSITIONS_RESULTS)) if "acq_type" not in kwargs: kwargs["acq_type"] = model.MD_AT_AR super(StaticARStream, self).__init__(name, list(self._pos.values()), *args, **kwargs)