eff_shift.py 3.17 KB
title = "Shift"
tip = "shift a map with given PATLONG and PATLAT"
onein = True

import numpy as np

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 _

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('i', default=0, max=100, min=0)
            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), "description")
        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 yintpn(self, a, b, c, d, y):
        if y == 0.0:
           return b
        e = b-a
        f = b-c
        g = e+f+f+d-c
        g = g*y-e-f-g
        g = g*y-a+c
        return 0.5*g*y+b

    def shiftr(self, m):
        #dlon = m.header['PATLONG']/m.header['CDELT1']
        dlat = m.header['PATLAT']/m.header['CDELT2']
        if abs(dlat) < 0.001: return m
        rows, cols = m.data.shape
        off = int(dlat)
        dx = dlat-off
        for col in range(cols):
            data = 1*m.data[:,col]
            for row in range(rows):
                if row + off < 0 or row + off >= rows:
                   x = np.nan
                else:
                   #r = max(0, min(rows-1, row + off))
                   r = row + off
                   i = max(0, r-1)
                   j = r
                   k = min(rows-2, r+1)
                   l = min(rows-1, r+2)
                   x = self.yintpn(data[i], data[j], data[k], data[l], dx)      
                m.data[row, col] = x
        return m

    def shiftc(self, m):
        dlon = m.header['PATLONG']/m.header['CDELT1']
        #dlat = m.header['PATLAT']/m.header['CDELT2']
        if abs(dlon) < 0.001: return m
        rows, cols = m.data.shape
        off = int(dlon)
        dx = dlon-off
        for row in range(rows):
            data = 1*m.data[row]
            for col in range(cols):
                if col + off < 0 or col + off >= cols:
                   x = np.nan
                else:
                   #c = max(0, min(cols-1, col + off))
                   c = col + off
                   i = max(0, c-1)
                   j = c
                   k = min(cols-2, c+1)
                   l = min(cols-1, c+2)
                   x = self.yintpn(data[i], data[j], data[k], data[l], dx)      
                m.data[row, col] = x
        return m

    def function(self, m, p):
        m = self.shiftc(m)
        m = self.shiftr(m)
        return m, p