Source code for glue.core.component_link

from __future__ import absolute_import, division, print_function

import numbers
import logging
import operator

import numpy as np

from glue.external.six import add_metaclass
from glue.core.contracts import contract, ContractsMeta
from glue.core.subset import InequalitySubsetState
from glue.core.util import join_component_view


__all__ = ['ComponentLink', 'BinaryComponentLink']


def identity(x):
    return x

OPSYM = {operator.add: '+', operator.sub: '-',
         operator.truediv: '/', operator.mul: '*',
         operator.pow: '**'}


@add_metaclass(ContractsMeta)



class CoordinateComponentLink(ComponentLink):

    @contract(comp_from='list(isinstance(ComponentID))',
              comp_to='isinstance(ComponentID)',
              coords='isinstance(Coordinates)',
              index=int,
              pixel2world=bool)
    def __init__(self, comp_from, comp_to, coords, index, pixel2world=True):
        self.coords = coords
        self.index = index
        self.pixel2world = pixel2world

        # Some coords don't need all pixel coords
        # to compute a given world coord, and vice versa
        # (e.g., spectral data cubes)
        self.ndim = len(comp_from)
        self.from_needed = coords.dependent_axes(index)
        self._from_all = comp_from

        comp_from = [comp_from[i] for i in self.from_needed]
        super(CoordinateComponentLink, self).__init__(
            comp_from, comp_to, self.using)
        self.hidden = True

    def using(self, *args):
        attr = 'pixel2world' if self.pixel2world else 'world2pixel'
        func = getattr(self.coords, attr)

        args2 = [None] * self.ndim
        for f, a in zip(self.from_needed, args):
            args2[f] = a
        for i in range(self.ndim):
            if args2[i] is None:
                args2[i] = np.zeros_like(args[0])
        args2 = tuple(args2)

        return func(*args2[::-1])[::-1][self.index]

    def __str__(self):
        rep = 'pix2world' if self.pixel2world else 'world2pix'
        sup = super(CoordinateComponentLink, self).__str__()
        return sup.replace('using', rep)