diff --git a/orangecontrib/spectroscopy/io/agilent.py b/orangecontrib/spectroscopy/io/agilent.py index 316d649c2..c0db47059 100644 --- a/orangecontrib/spectroscopy/io/agilent.py +++ b/orangecontrib/spectroscopy/io/agilent.py @@ -9,6 +9,7 @@ agilentMosaicTiles from orangecontrib.spectroscopy.io.util import SpectralFileFormat, _spectra_from_image, \ TileFileFormat, ConstantBytesVisibleImage +from orangecontrib.spectroscopy.utils import MAP_X_VAR, MAP_Y_VAR def load_visible_images(vis_img_list: list[dict]) -> list[ConstantBytesVisibleImage]: @@ -213,8 +214,8 @@ def read_tile(self): attrs = [Orange.data.ContinuousVariable.make("%f" % f) for f in features] domain = Orange.data.Domain(attrs, None, - metas=[Orange.data.ContinuousVariable.make("map_x"), - Orange.data.ContinuousVariable.make("map_y")] + metas=[Orange.data.ContinuousVariable.make(MAP_X_VAR), + Orange.data.ContinuousVariable.make(MAP_Y_VAR)] ) try: diff --git a/orangecontrib/spectroscopy/io/ascii.py b/orangecontrib/spectroscopy/io/ascii.py index 458b69614..cff0d1d57 100644 --- a/orangecontrib/spectroscopy/io/ascii.py +++ b/orangecontrib/spectroscopy/io/ascii.py @@ -5,6 +5,7 @@ from orangecontrib.spectroscopy.util import getx from orangecontrib.spectroscopy.io.util import SpectralFileFormat +from orangecontrib.spectroscopy.utils import MAP_X_VAR, MAP_Y_VAR class AsciiColReader(FileFormat, SpectralFileFormat): @@ -57,7 +58,7 @@ def read(self): domain = Orange.data.Domain([ContinuousVariable.make("%f" % f) for f in dom_vals], None) tbl = np.loadtxt(f, ndmin=2) data = Table.from_numpy(domain, X=tbl[:, 2:]) - metas = [ContinuousVariable.make('map_x'), ContinuousVariable.make('map_y')] + metas = [ContinuousVariable.make(MAP_X_VAR), ContinuousVariable.make(MAP_Y_VAR)] domain = Orange.data.Domain(domain.attributes, None, metas=metas) data = data.transform(domain) with data.unlocked(data.metas): @@ -68,8 +69,8 @@ def read(self): @staticmethod def write_file(filename, data): wavelengths = getx(data) - map_x = data.domain["map_x"] if "map_x" in data.domain else ContinuousVariable("map_x") - map_y = data.domain["map_y"] if "map_y" in data.domain else ContinuousVariable("map_y") + map_x = data.domain[MAP_X_VAR] if MAP_X_VAR in data.domain else ContinuousVariable(MAP_X_VAR) + map_y = data.domain[MAP_Y_VAR] if MAP_Y_VAR in data.domain else ContinuousVariable(MAP_Y_VAR) ndom = Domain([map_x, map_y] + list(data.domain.attributes)) data = data.transform(ndom) with open(filename, "wb") as f: diff --git a/orangecontrib/spectroscopy/io/opus.py b/orangecontrib/spectroscopy/io/opus.py index fdbcc0562..115d9e835 100644 --- a/orangecontrib/spectroscopy/io/opus.py +++ b/orangecontrib/spectroscopy/io/opus.py @@ -7,6 +7,8 @@ from .util import ConstantBytesVisibleImage +from orangecontrib.spectroscopy.utils import MAP_X_VAR, MAP_Y_VAR + class OPUSReader(FileFormat): """Reader for OPUS files""" @@ -58,8 +60,8 @@ def read(self): if type(data) == opusFC.MultiRegionDataReturn: y_data = [] meta_data = [] - metas.extend([ContinuousVariable.make('map_x'), - ContinuousVariable.make('map_y'), + metas.extend([ContinuousVariable.make(MAP_X_VAR), + ContinuousVariable.make(MAP_Y_VAR), StringVariable.make('map_region'), TimeVariable.make('start_time')]) for region in data.regions: @@ -77,8 +79,8 @@ def read(self): elif type(data) == opusFC.MultiRegionTRCDataReturn: y_data = [] meta_data = [] - metas.extend([ContinuousVariable.make('map_x'), - ContinuousVariable.make('map_y'), + metas.extend([ContinuousVariable.make(MAP_X_VAR), + ContinuousVariable.make(MAP_Y_VAR), StringVariable.make('map_region')]) attrs = [ContinuousVariable.make(repr(data.labels[i])) for i in range(len(data.labels))] @@ -93,8 +95,8 @@ def read(self): meta_data = np.vstack(meta_data) elif type(data) == opusFC.ImageDataReturn: - metas.extend([ContinuousVariable.make('map_x'), - ContinuousVariable.make('map_y')]) + metas.extend([ContinuousVariable.make(MAP_X_VAR), + ContinuousVariable.make(MAP_Y_VAR)]) data_3D = data.spectra @@ -109,8 +111,8 @@ def read(self): meta_data = np.vstack((meta_data, coord)) elif type(data) == opusFC.ImageTRCDataReturn: - metas.extend([ContinuousVariable.make('map_x'), - ContinuousVariable.make('map_y')]) + metas.extend([ContinuousVariable.make(MAP_X_VAR), + ContinuousVariable.make(MAP_Y_VAR)]) attrs = [ContinuousVariable.make(repr(data.labels[i])) for i in range(len(data.labels))] diff --git a/orangecontrib/spectroscopy/io/ptir.py b/orangecontrib/spectroscopy/io/ptir.py index 6ec2ab95d..69c2f5923 100644 --- a/orangecontrib/spectroscopy/io/ptir.py +++ b/orangecontrib/spectroscopy/io/ptir.py @@ -3,6 +3,7 @@ from Orange.data import FileFormat from orangecontrib.spectroscopy.io.util import SpectralFileFormat, _spectra_from_image +from orangecontrib.spectroscopy.utils import MAP_X_VAR, MAP_Y_VAR class PTIRFileReader(FileFormat, SpectralFileFormat): @@ -174,8 +175,8 @@ def read_spectra(self): metas = np.array([x_locs[x_loc], y_locs[y_loc]]).T domain = Orange.data.Domain([], None, - metas=[Orange.data.ContinuousVariable.make("map_x"), - Orange.data.ContinuousVariable.make("map_y")] + metas=[Orange.data.ContinuousVariable.make(MAP_X_VAR), + Orange.data.ContinuousVariable.make(MAP_Y_VAR)] ) data = Orange.data.Table.from_numpy(domain, X=np.zeros((len(spectra), 0)), metas=np.asarray(metas, dtype=object)) diff --git a/orangecontrib/spectroscopy/io/util.py b/orangecontrib/spectroscopy/io/util.py index b355e5821..c38402f71 100644 --- a/orangecontrib/spectroscopy/io/util.py +++ b/orangecontrib/spectroscopy/io/util.py @@ -3,6 +3,8 @@ import numpy as np from Orange.data import Domain, ContinuousVariable, Table +from orangecontrib.spectroscopy.utils import MAP_X_VAR, MAP_Y_VAR + class SpectralFileFormat: @@ -29,8 +31,8 @@ def _metatable_maplocs(x_locs, y_locs): metas = np.vstack((x_locs, y_locs)).T domain = Domain([], None, - metas=[ContinuousVariable.make("map_x"), - ContinuousVariable.make("map_y")] + metas=[ContinuousVariable.make(MAP_X_VAR), + ContinuousVariable.make(MAP_Y_VAR)] ) data = Table.from_numpy(domain, X=np.zeros((len(metas), 0)), metas=np.asarray(metas, dtype=object)) diff --git a/orangecontrib/spectroscopy/utils/__init__.py b/orangecontrib/spectroscopy/utils/__init__.py index 9836e8a8f..9728224a4 100644 --- a/orangecontrib/spectroscopy/utils/__init__.py +++ b/orangecontrib/spectroscopy/utils/__init__.py @@ -1,6 +1,11 @@ import numpy as np -from Orange.data import Domain, Table +from Orange.data import Domain, Table, ContinuousVariable +from Orange.widgets.utils.itemmodels import DomainModel +from orangewidget.utils.itemmodels import PyListModel + +MAP_X_VAR = "map_x" +MAP_Y_VAR = "map_y" def apply_columns_numpy(array, function, selector=None, chunk_size=10 ** 7, callback=None): @@ -145,3 +150,24 @@ def split_to_size(size, interval): intervals.append(slice(pos, pos + min(size - pos, interval))) pos += min(size, interval) return intervals + + +class XYDomainModel(DomainModel): + XY = (DomainModel.METAS, PyListModel.Separator, + DomainModel.CLASSES) + + def __init__(self, order=XY, valid_types=ContinuousVariable, **kwargs): + super().__init__(order=order, valid_types=valid_types, **kwargs) + + def set_domain(self, domain): + restore_order = False + if domain is not None and self.order == self.XY: + attr_x = [domain[var] for var in domain if var.name == MAP_X_VAR] + attr_y = [domain[var] for var in domain if var.name == MAP_Y_VAR] + xy = attr_x + attr_y + if len(xy) == 2: + self.order = (xy, PyListModel.Separator) + self.order + restore_order = True + super().set_domain(domain) + if restore_order: + self.order = self.order[2:] diff --git a/orangecontrib/spectroscopy/widgets/owhyper.py b/orangecontrib/spectroscopy/widgets/owhyper.py index 5b0fb6a35..4e34f838d 100644 --- a/orangecontrib/spectroscopy/widgets/owhyper.py +++ b/orangecontrib/spectroscopy/widgets/owhyper.py @@ -39,7 +39,7 @@ from orangewidget.utils.visual_settings_dlg import VisualSettingsDialog from orangecontrib.spectroscopy.preprocess import Integrate -from orangecontrib.spectroscopy.utils import values_to_linspace, index_values_nan, split_to_size +from orangecontrib.spectroscopy.utils import values_to_linspace, index_values_nan, split_to_size, XYDomainModel from orangecontrib.spectroscopy.widgets.owspectra import InteractiveViewBox, \ MenuFocus, CurvePlot, SELECTONE, SELECTMANY, INDIVIDUAL, AVERAGE, \ @@ -287,8 +287,7 @@ def color_palette_model(palettes, iconsize=QSize(64, 16)): class AxesSettingsMixin: def __init__(self): - self.xy_model = DomainModel(DomainModel.METAS | DomainModel.CLASSES, - valid_types=DomainModel.PRIMITIVE) + self.xy_model = XYDomainModel() def setup_axes_settings_box(self): box = gui.vBox(self)