filter_envelope.py 2.43 KB
title = "LowPass"
tip = "applies lower envelope filter to data"
onein = True

TITLE = title
TIP = tip

import numpy as np

from guidata.dataset.datatypes import DataSet
from guidata.dataset.dataitems import (IntItem, FloatArrayItem, StringItem,
                                       ChoiceItem, FloatItem, DictItem,
                                       BoolItem)
from guiqwt.config import _

class NOD3_App:

    def __init__(self, parent):
        self.parent = parent
        self.parent.activateWindow()

    def compute_app(self, **args):
        class FuncParam(DataSet):
            window = IntItem('Window:', min=5, default=9)
        name = title.replace(" ", "")
        if args == {}:
           param = FuncParam(_(title), "Set window for lower envelope:")
        else:
           param = self.parent.ScriptParameter(name, args)
        self.parent.compute_11(name, lambda m, p: self.function(m, p), param, onein) 

    def quarter(self, data, x1, x2, y1, y2, win):
        if x1 == x2 or y1 == y2:
           return 0.0, 0.0
        else:
           #return np.nanmin(data[y1:y2, x1:x2]), 1.0
           amin = np.nanmin(data[y1:y2, x1:x2])
           if np.isnan(amin):
              return 0.0, 0.0
           else:
              return amin, 1.0

    def envelope(self, data, row, rows, cols, win):
        z = []
        for col in range(cols):
            a1, n1 = self.quarter(data, max(0,col-win), col, row, min(rows-1, row+win), win)
            a2, n2 = self.quarter(data, col, min(cols-1,col+win), row, min(rows-1, row+win), win)
            a3, n3 = self.quarter(data, max(0,col-win), col, max(0,row-win), row, win)
            a4, n4 = self.quarter(data, col, min(cols-1,col+win), max(0,row-win), row, win)
            if (n1+n2+n3+n4) == 0.0:
               z.append(np.nan)
            else:
               z.append((a1+a2+a3+a4)/(n1+n2+n3+n4))
        return np.array(z)

    def function(self, m, p):
        rows, cols = m.data.shape
        data = m.data.copy()
        progress = self.parent.imagewidget.Progress
        for row in range(rows):
            if self.parent.STOP:
               self.parent.STOP = False
               progress.showMessage(_("stopped by ^C"), 5000)
               return [], p
            else:
               progress.showMessage(_("progress: %3d %s done") % (int(100*float(row+1)/rows), "%"), 1000)
               data[row] = self.envelope(m.data, row, rows, cols, p.window)
        m.data = data
        return m, p