Skip to content

Commit

Permalink
Merge pull request #625 from markotoplak/fix-warn
Browse files Browse the repository at this point in the history
[ENH] Implement equivalence of (some) spectral tranformations
  • Loading branch information
markotoplak authored Nov 14, 2023
2 parents 9909379 + 0526c65 commit f851772
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 45 deletions.
12 changes: 6 additions & 6 deletions conda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ requirements:
run:
- python >=3.8
- numpy >=1.20.0
- orange3 >=3.32.0
- orange-canvas-core >=0.1.24
- orange-widget-base >=4.16.1
- scipy >=1.4.0
- orange3 >=3.34.0
- orange-canvas-core >=0.1.28
- orange-widget-base >=4.19.0
- scipy >=1.9.0
- scikit-learn>=1.0.1
- spectral >=0.22.3,!=0.23
- serverfiles >=0.2
- AnyQt >=0.0.6
- pyqtgraph >=0.11.1,!=0.12.4
- AnyQt >=0.1.0
- pyqtgraph >=0.12.2,!=0.12.4
- colorcet
- h5py
- extranormal3 >=0.0.3
Expand Down
57 changes: 45 additions & 12 deletions orangecontrib/spectroscopy/preprocess/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@


class PCADenoisingFeature(SelectColumn):
pass
InheritEq = True


class _PCAReconstructCommon(CommonDomain):
Expand Down Expand Up @@ -79,7 +79,7 @@ def __call__(self, data):


class GaussianFeature(SelectColumn):
pass
InheritEq = True


class _GaussianCommon(CommonDomainOrderUnknowns):
Expand Down Expand Up @@ -131,7 +131,7 @@ def __call__(self, data):


class SavitzkyGolayFeature(SelectColumn):
pass
InheritEq = True


class _SavitzkyGolayCommon(CommonDomainOrderUnknowns):
Expand All @@ -147,6 +147,15 @@ def transformed(self, X, wavenumbers):
polyorder=self.polyorder,
deriv=self.deriv, mode="nearest")

def __eq__(self, other):
return super().__eq__(other) \
and self.window == other.window \
and self.polyorder == other.polyorder \
and self.deriv == other.deriv

def __hash__(self):
return hash((super().__hash__(), self.window, self.polyorder, self.deriv))


class SavitzkyGolayFiltering(Preprocess):
"""
Expand All @@ -169,7 +178,7 @@ def __call__(self, data):


class RubberbandBaselineFeature(SelectColumn):
pass
InheritEq = True


class _RubberbandBaselineCommon(CommonDomainOrder):
Expand Down Expand Up @@ -233,7 +242,7 @@ def __call__(self, data):


class LinearBaselineFeature(SelectColumn):
pass
InheritEq = True


class _LinearBaselineCommon(CommonDomainOrderUnknowns):
Expand Down Expand Up @@ -276,7 +285,7 @@ def __call__(self, data):


class NormalizeFeature(SelectColumn):
pass
InheritEq = True


class _NormalizeCommon(CommonDomain):
Expand Down Expand Up @@ -333,6 +342,18 @@ def transformed(self, data):
replace_infs(data.X)
return data.X

def __eq__(self, other):
return super().__eq__(other) \
and self.method == other.method \
and self.lower == other.lower \
and self.upper == other.upper \
and self.int_method == other.int_method \
and self.attr == other.attr

def __hash__(self):
return hash((super().__hash__(), self.method, self.lower,
self.upper, self.int_method, self.attr))


class Normalize(Preprocess):
# Normalization methods
Expand Down Expand Up @@ -412,7 +433,7 @@ def features_with_interpolation(points, kind="linear", domain=None, handle_nans=


class InterpolatedFeature(SelectColumn):
pass
InheritEq = True


class _InterpolateCommon:
Expand Down Expand Up @@ -449,6 +470,18 @@ def __call__(self, data):
interpfn = interp1d_wo_unknowns_scipy
return interpfn(x, ys, self.points, kind=self.kind)

def __eq__(self, other):
return type(self) is type(other) \
and np.all(self.points == other.points) \
and self.kind == other.kind \
and self.domain == other.domain \
and self.handle_nans == other.handle_nans \
and self.interpfn == other.interpfn

def __hash__(self):
return hash((type(self), tuple(self.points[:5]), self.kind,
self.domain, self.handle_nans, self.interpfn))


class Interpolate(Preprocess):
"""
Expand Down Expand Up @@ -512,7 +545,7 @@ def __call__(self, data):

######################################### XAS normalization ##########
class XASnormalizationFeature(SelectColumn):
pass
InheritEq = True


class _XASnormalizationCommon(CommonDomainOrderUnknowns):
Expand Down Expand Up @@ -574,7 +607,7 @@ class NoEdgejumpProvidedException(PreprocessException):


class ExtractEXAFSFeature(SelectColumn):
pass
InheritEq = True


class EdgeJumpException(PreprocessException):
Expand Down Expand Up @@ -698,7 +731,7 @@ def __call__(self, data):


class CurveShiftFeature(SelectColumn):
pass
InheritEq = True


class _CurveShiftCommon(CommonDomain):
Expand Down Expand Up @@ -726,7 +759,7 @@ def __call__(self, data):


class DespikeFeature(SelectColumn):
pass
InheritEq = True


class _DespikeCommon(CommonDomainOrderUnknowns):
Expand Down Expand Up @@ -804,7 +837,7 @@ def __call__(self, data):


class SpSubtractFeature(SelectColumn):
pass
InheritEq = True


class _SpSubtractCommon(CommonDomainRef):
Expand Down
6 changes: 3 additions & 3 deletions orangecontrib/spectroscopy/preprocess/als/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


class ALSFeature(SelectColumn):
pass
InheritEq = True


class ALSCommon(CommonDomainOrderUnknowns):
Expand Down Expand Up @@ -54,7 +54,7 @@ def __call__(self, data):


class ARPLSFeature(SelectColumn):
pass
InheritEq = True


class ARPLSCommon(CommonDomainOrderUnknowns):
Expand Down Expand Up @@ -100,7 +100,7 @@ def __call__(self, data):


class AIRPLSFeature(SelectColumn):
pass
InheritEq = True


class AIRPLSCommon(CommonDomainOrderUnknowns):
Expand Down
4 changes: 2 additions & 2 deletions orangecontrib/spectroscopy/preprocess/emsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ def weighted_wavenumbers(weights, wavenumbers):


class EMSCFeature(SelectColumn):
pass
InheritEq = True


class EMSCModel(SelectColumn):
pass
InheritEq = True


class _EMSC(CommonDomainOrderUnknowns):
Expand Down
31 changes: 27 additions & 4 deletions orangecontrib/spectroscopy/preprocess/integrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,25 @@ def compute(self, data, common):
x_s, y_s = self.extract_data(data, common)
return self.compute_integral(x_s, y_s)

def __eq__(self, other):
return super().__eq__(other) \
and self.limits == other.limits

def __hash__(self):
return hash((super().__hash__(), tuple(self.limits)))


class IntegrateFeatureEdgeBaseline(IntegrateFeature):
""" A linear edge-to-edge baseline subtraction. """

name = "Integral from baseline"
InheritEq = True

@staticmethod
def parameters():
return (("Low limit", "Low limit for integration (inclusive)"),
("High limit", "High limit for integration (inclusive)"),
)
)

def compute_baseline(self, x, y):
if np.any(np.isnan(y)):
Expand All @@ -105,6 +113,7 @@ def compute_draw_info(self, x, ys):
class IntegrateFeatureSeparateBaseline(IntegrateFeature):

name = "Integral from separate baseline"
InheritEq = True

@staticmethod
def parameters():
Expand Down Expand Up @@ -148,6 +157,7 @@ class IntegrateFeatureSimple(IntegrateFeatureEdgeBaseline):
""" A simple y=0 integration on the provided data window. """

name = "Integral from 0"
InheritEq = True

def compute_baseline(self, x_s, y_s):
return np.zeros(y_s.shape)
Expand All @@ -157,12 +167,13 @@ class IntegrateFeaturePeakEdgeBaseline(IntegrateFeature):
""" The maximum baseline-subtracted peak height in the provided window. """

name = "Peak from baseline"
InheritEq = True

@staticmethod
def parameters():
return (("Low limit", "Low limit for integration (inclusive)"),
("High limit", "High limit for integration (inclusive)"),
)
)

def compute_baseline(self, x, y):
return edge_baseline(x, y)
Expand All @@ -186,6 +197,7 @@ class IntegrateFeaturePeakSimple(IntegrateFeaturePeakEdgeBaseline):
""" The maximum peak height in the provided data window. """

name = "Peak from 0"
InheritEq = True

def compute_baseline(self, x_s, y_s):
return np.zeros(y_s.shape)
Expand All @@ -195,12 +207,13 @@ class IntegrateFeaturePeakXEdgeBaseline(IntegrateFeature):
""" The X-value of the maximum baseline-subtracted peak height in the provided window. """

name = "X-value of maximum from baseline"
InheritEq = True

@staticmethod
def parameters():
return (("Low limit", "Low limit for integration (inclusive)"),
("High limit", "High limit for integration (inclusive)"),
)
)

def compute_baseline(self, x, y):
return edge_baseline(x, y)
Expand Down Expand Up @@ -231,6 +244,7 @@ class IntegrateFeaturePeakXSimple(IntegrateFeaturePeakXEdgeBaseline):
""" The X-value of the maximum peak height in the provided data window. """

name = "X-value of maximum from 0"
InheritEq = True

def compute_baseline(self, x_s, y_s):
return np.zeros(y_s.shape)
Expand All @@ -240,11 +254,12 @@ class IntegrateFeatureAtPeak(IntegrateFeature):
""" Find the closest x and return the value there. """

name = "Closest value"
InheritEq = True

@staticmethod
def parameters():
return (("Closest to", "Nearest value"),
)
)

def extract_data(self, data, common):
data, x, x_sorter = common
Expand Down Expand Up @@ -275,6 +290,14 @@ def transformed(self, data):
x_sorter = np.argsort(x)
return data, x, x_sorter

def __eq__(self, other):
# pylint: disable=useless-parent-delegation
return super().__eq__(other)

def __hash__(self):
# pylint: disable=useless-parent-delegation
return super().__hash__()


class Integrate(Preprocess):

Expand Down
4 changes: 2 additions & 2 deletions orangecontrib/spectroscopy/preprocess/me_emsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ def cal_ncomp(reference, wavenumbers, explainedVarLim, alpha0, gamma):


class ME_EMSCFeature(SelectColumn):
pass
InheritEq = True


class ME_EMSCModel(SelectColumn):
pass
InheritEq = True


class _ME_EMSC(CommonDomainOrderUnknowns):
Expand Down
Loading

0 comments on commit f851772

Please sign in to comment.