base_adjust.py 3.54 KB
title = "Adjust"
tip = "Corrects baseline effects"
onein = True

import numpy as np
from scipy.ndimage import gaussian_filter1d

from guidata.qt.QtGui import QMessageBox
from guidata.dataset.datatypes import DataSet
from guidata.dataset.dataitems import (IntItem, StringItem, ChoiceItem, FloatItem, BoolItem)
from guiqwt.config import _

def median(x):
    xl = list(x)
    xl.sort()
    return xl[len(xl)/3]

class NOD3_App:

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

    def Error(self, msg):
        QMessageBox.critical(self.parent.parent(), title,
                              _(u"Error:")+"\n%s" % str(msg))

    def compute_app(self, **args):
        class FuncParam(DataSet):
            #s = StringItem('s', default="string")
            #i = IntItem('Iteration', default=10, max=100, min=1)
            proz  = FloatItem('Percent', default=25, max=50, min=5)
            #a = FloatItem('a', default=1.)
            #b = BoolItem("bool", default=True)
            #choice = ChoiceItem("Unit", ("Degree", "Arcmin", "Arcsec"), default=2)
        name = title.replace(" ", "")
        if args == {}:
           param = FuncParam(_(title), "Apply a linear baseline in scanning direction")
        else:
           param = self.parent.ScriptParameter(name, args)

        # if no parameter needed set param to None. activate next line
        #param = None
        self.parent.compute_11(name, lambda m, p: self.function(m, p), param, onein)

    def function(self, m, p):
        rows, cols = m.data.shape
        if "SCANDIR" not in m.header:
           class ScanParam(DataSet):
                 scandir = ChoiceItem("SCANDIR", (("LON", "LON"), ("LAT", "LAT")), 
                           default="LAT")
           param = ScanParam(_(title), "Scan direction")
           if not param.edit():
              return
           m.header['SCANDIR'] = param.scandir
        #if not 'SCANDIR' in m.header:
           #self.Error("sorry: keyword 'SCANDIR' not found in FITS header")
           #return [], None
        if m.header['SCANDIR'] in ("LON", "ALON", "ULON", "GLON", "RA"):
           l = int(cols*p.proz/100.0) - int(cols*p.proz/100.0-1)%2
           for row in range(rows):
               x = m.data[row]
               a = x[:l]
               b = x[-l:]
               amask = np.isnan(a)
               bmask = np.isnan(b)
               if False in amask and False in bmask:
                  am = median(a[~amask]) 
                  bm = median(b[~bmask]) 
                  #ax = list(a).index(am)
                  #bx = len(x[:-l]) + list(b).index(bm)
                  ax = float(l)/2.0
                  bx = len(x)-ax
                  s = (am-bm)/(ax-bx)
                  o = am - s*ax
                  m.data[row] -= o + s*np.arange(cols)
        else:
           l = int(rows*p.proz/100.0) - int(rows*p.proz/100.0-1)%2
           for col in range(cols):
               x = m.data[:,col]
               a = x[:l]
               b = x[-l:]
               amask = np.isnan(a)
               bmask = np.isnan(b)
               if False in amask and False in bmask:
                  am = median(a[~amask]) 
                  bm = median(b[~bmask]) 
                  #ax = list(a).index(am)
                  #bx = len(x[:-l]) + list(b).index(bm)
                  ax = float(l)/2.0
                  bx = len(x)-ax
                  s = (am-bm)/(ax-bx)
                  o = am - s*ax
                  m.data[:,col] -= o + s*np.arange(rows)
        if m.header['SCANDIR'] in ("LON", "LAT"): m.header.__delitem__('SCANDIR')
        return m, p