<commit_before>import lib.collection as collection
from collections import OrderedDict

class iperf_veth_tcp(collection.Collection):
    constants = {
        'protocol': 'tcp',
        'topology': 'direct_veth',
    }
    variables = OrderedDict([
        ('parallelism', (1, 2, 3, 4, 5, 6, 7, 8, 12, 16)),

        ('iperf_name', ('iperf2', 'iperf3', 'iperf3m')),
        ('disable_offloading', (False, True)),
        ('packet_size', ('default', 536)),
        ('zerocopy', (False, True)),
        ('affinity', (False, True)),
    ])

    def generation_skip_fn(self, settings):
        if settings['iperf_name'] == 'iperf2' and (settings['zerocopy'] or settings['affinity']):
            return True
        return False

    x_axis = 'parallelism'
    y_axes = ['throughput', 'cpu']
    x_title = '# of parallel flows'

    filters = {
        'iperf3m': lambda r: r['iperf_name'] != 'iperf3m',
    }

    def analysis_row_label_fn(self, r):
        zcpyaff_label_list = []
        for name in ('zerocopy', 'affinity'):
            if r[name]:
                zcpyaff_label_list.append(name)
        return "{iperf_name} {}offloading, pkt: {packet_size} {}".format('no ' if r['disable_offloading'] else '', ', '.join(zcpyaff_label_list), **r)

    def analysis_grouping_fn(self, r):
        iperf_names = list(self.variables['iperf_name'])
        packet_sizes = list(self.variables['packet_size'])
        return (iperf_names.index(r['iperf_name']) * len(packet_sizes) + packet_sizes.index(r['packet_size']),)

    def plot_style_fn(self, r, group_id):
        color = 'black'
        if r['affinity']:
            color = 'red'
        if r['zerocopy']:
            color = 'blue'
        if r['affinity'] and r['zerocopy']:
            color = 'green'

        return {
            'linestyle': '--' if r['disable_offloading'] else '-',
            'color': color,
        }

if __name__ == '__main__':
    iperf_veth_tcp().parse_shell_arguments()
<commit_msg>additional filters<commit_after>import lib.collection as collection
from collections import OrderedDict

class iperf_veth_tcp(collection.Collection):
    constants = {
        'protocol': 'tcp',
        'topology': 'direct_veth',
    }
    variables = OrderedDict([
        ('parallelism', (1, 2, 3, 4, 5, 6, 7, 8, 12, 16)),

        ('iperf_name', ('iperf2', 'iperf3', 'iperf3m')),
        ('disable_offloading', (False, True)),
        ('packet_size', ('default', 536)),
        ('zerocopy', (False, True)),
        ('affinity', (False, True)),
    ])

    def generation_skip_fn(self, settings):
        if settings['iperf_name'] == 'iperf2' and (settings['zerocopy'] or settings['affinity']):
            return True
        return False

    x_axis = 'parallelism'
    y_axes = ['throughput', 'cpu']
    x_title = '# of parallel flows'

    filters = {
        'iperf3m': lambda r: r['iperf_name'] != 'iperf3m',
        'rightsize': lambda r: r['packet_size'] != 'default',
        'paper': lambda r: r['iperf_name'] != 'iperf3m' or r['packet_size'] != 'default' or r['affinity'] or r['disable_offloading'],
    }

    def analysis_row_label_fn(self, r):
        zcpyaff_label_list = []
        for name in ('zerocopy', 'affinity'):
            if r[name]:
                zcpyaff_label_list.append(name)
        return "{iperf_name} {}offloading, pkt: {packet_size} {}".format('no ' if r['disable_offloading'] else '', ', '.join(zcpyaff_label_list), **r)

    def analysis_grouping_fn(self, r):
        iperf_names = list(self.variables['iperf_name'])
        packet_sizes = list(self.variables['packet_size'])
        return (iperf_names.index(r['iperf_name']) * len(packet_sizes) + packet_sizes.index(r['packet_size']),)

    def plot_style_fn(self, r, group_id):
        color = 'black'
        if r['affinity']:
            color = 'red'
        if r['zerocopy']:
            color = 'blue'
        if r['affinity'] and r['zerocopy']:
            color = 'green'

        return {
            'linestyle': '--' if r['disable_offloading'] else '-',
            'color': color,
        }

if __name__ == '__main__':
    iperf_veth_tcp().parse_shell_arguments()
<|endoftext|>


<commit_before>"""
This module is a high-level abstraction to the ipfs.object API.

It provides a pythonic way of interacting with merkledag nodes (a.k.a. objects).

To run the following examples start with::

   >>> from ipfs.api import IpfsApi
   >>> from ipfs.merkledag import Merkledag
   >>> dag = Merkledag(IpfsApi())

"""

from threading import Lock

# jgraef: TODO: Update docs and examples with value instead of data

class Link:
    """
    A link in the merkledag that links another node.

    .. py:attribute:: name

       The link name

    .. py:attribute:: hash

       The linked node's hash

    .. py:attribute:: size

       Size of the node (optional, might be 0)

    """

    def __init__(self, dag, name, hash, size):
        self._dag = dag
        self.name = name
        self.hash = hash
        self.size = size

    def follow(self):
        """
        Return the referenced node.

        Example::

           >>> node = dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
           >>> link = node.get_link("readme")
           >>> readme = link.follow()
           >>> readme
           Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)
           >>> readme.data[5:22].decode()
           'Hello and Welcome'

        Normally you don't have to interact with links. You can directly
        follow links by referencing attributes of a Node.
        """

        return self._dag.get(self.hash)

    def __repr__(self):
        return "Link(name={}, hash={}, size={:d})".format(self.name, self.hash, self.size)

class Node:
    """
    A merkledag node (a.k.a object).

    A merkledag node is a node like in any other graph. It stores some data
    and can have multiple links (or edges) to other nodes.

    To get a merkledag node call ``dag.get(ref)`` or access it via
    ``dag[ref]``, where ``ref`` can be a ipfs or ipns name or a plain
    base58 hash of your node::

       >>> dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
       Node(QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec)

    The data of a node can be accessed via its ``data`` attribute::

       >>> n = dag["QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB"]
       >>> n.data[5:22].decode()
       'Hello and Welcome'

    Links can be followed by directly accessing attributes::

       >>> node = dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
       >>> node.readme
       Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)

    You can also interate over a node's links by::

       >>> node = dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
       >>> for link in node:
               print(link.name, "->", link.hash)

       about -> QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V
       contact -> QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y
       help -> QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7
       quick-start -> QmXifYTiYxz8Nxt3LmjaxtQNLYkjdh324L4r81nZSadoST
       readme -> QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB
       security-notes -> QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ

    .. py:attribute:: hash

       The node's hash

    """

    def __init__(self, dag, hash):
        self._dag = dag
        self.hash = hash
        self._value = None
        self._links = None
        self._links_map = None
        self._loaded = False
        self._lock = Lock()

    def _lazy_load_data(self):
        with self._lock:
            if (self._value != None):
                return

            f = self._dag.ipfs.object.data(self.hash)
            if (self._dag.codec):
                self._value = self._dag.codec.load(f)
            else:
                self._value = f.read()

    def _lazy_load_links(self):
        # jgraef: TODO: How to handle multiple links with the same name?

        with self._lock:
            if (self._links != None):
                return

            links = self._dag.ipfs.object.links(self.hash)["Links"]

            self._links = [Link(self._dag, l["Name"], l["Hash"], l["Size"]) for l in links]
            self._links_map = {}
            for l in self._links:
                self._links_map[l.name] = l

    @property
    def ref(self):
        """ The reference URL, e.g. ``"/ipfs/QmPXME1oRtoT627YKaDPDQ3PwA8tdP9rWuAAweLzqSwAWT"``. """
        return "/ipfs/" + self.hash

    @property
    def data(self):
        """
        The data contained in this node.

        DEPRECATED: Use :py:attr:`value` instead.
        """

        if (self._dag.codec):
            raise AttributeError("The data attribute is not available, when using a codec")
        self._lazy_load_data()
        return self._value

    @property
    def value(self):
        """
        The value contained in this node.
        """

        self._lazy_load_data()
        return self._value

    @property
    def links(self):
        """ A list of the links contained in this node. """
        self._lazy_load_links()
        return self._links

    def get_link(self, name):
        """
        Return a link by its name.

        :param name: The link name
        :return:     The link with that name
        """
        self._lazy_load_links()
        return self._links_map[name]

    def has_link(self, name):
        """
        Return whether this node has a link with the given name.

        :param name: The link name
        :return:     True if a link with that name exists, False otherwise.
        """
        return name in self._links_map

    def get_node(self, name):
        """
        Return a linked node given the link's name.

        :param name: The link name
        :return:     The node linked by this name

        This is a shortcut for ``node.get_link(name).follow()``
        """
        return self.get_link(name).follow()

    """ TODO:
    def add_link(self, name, target):
        if (isinstance(target, Node)):
            ref = target.ref
        elif (isinstance(target, str)):
            ref = "/ipfs/" + target
        else:
            raise ValueError("Invalid link target: {!r}".format(target))

        res = self._dag.ipfs.object_patch_add_link(self.hash, name, ref)
        print(res)

    def rm_link(self, name):
        res = self._dag.ipfs.object_patch_rm_link(self.hash, name)
        print(res)

    def set_data(self, data):
        res = self._dag.ipfs.object_patch_set_data(self.hash, data)
        print(res)

    def append_data(self, data):
        res = self._dag.ipfs.object_patch_append_data(self.hash, data)
        print(res)
    """

    def __getitem__(self, name):
        return self.get_node(name)

    def __contains__(self, name):
        return self.has_link(name)

    def __getattr__(self, name):
        try:
            return self.get_node(name)
        except KeyError:
            raise AttributeError(name)

    def __iter__(self):
        return iter(self.links)

    def __repr__(self):
        return "Node({})".format(self.hash)

    def __str__(self):
        return str(self.data)

    def __hash__(self):
        return hash(self.hash)

    def __eq__(self, other):
        return isinstance(other, Node) and other.hash == self.hash

class NodeBuilder:
    """
    The NodeBuilder is used to create new nodes.

    Currently it's the only mechanism available to create a node. Soon there
    will be methods to *patch* a node in order to create new nodes.

    Example::

       >>> c1 = dag.builder().data("Child 1").build()
       >>> c2 = dag.builder().data("Child 2").link("sibling", c1).build()
       >>> r = dag.builder().data("Root")\
               .link("child_1", c1).link("child_2", c2).build()
       >>> r
       Node(Qme2Fuk2YRNWwbhQ9G4d3GBAEQ5kL1r8P1b5RVx1HgZsco)

    Try exploring that in your DAG browser:
    http://localhost:5001/ipfs/QmR9MzChjp1MdFWik7NjEjqKQMzVmBkdK3dz14A6B5Cupm/#/objects/object/Qme2Fuk2YRNWwbhQ9G4d3GBAEQ5kL1r8P1b5RVx1HgZsco
    """

    def __init__(self, dag):
        self._dag = dag
        self._value = None
        self._links = {}

    def data(self, data):
        """
        Set the data that will be contained in the new node.

        :param data: A bytes object or string that will be the node's content.
        :return:     The builder itself to allow chaining.

        DEPRECATED: Use :py:meth:`value` instead.
        """

        if (self._dag.codec):
            raise ValueError("Specified raw data with codec")
        self._value = value

    def value(self, value):
        """
        Set the value that will be included in the new node.

        :param value: A value that can be encoded by the coded specified in
                      :py:class:`Merkledag`.
        :return:      The builder itself to allow chaining.
        """

        self._value = value
        return self

    def link(self, name, target, size = 0):
        """
        Set a link that will be added to the node.

        :param name:   The link name
        :param target: The merkledag node or hash to which the link points
        :param size:   The cumulative size of the linked node (optional)
        :return:     The builder itself to allow chaining.
        """

        if (isinstance(target, Node)):
            hash = target.hash
        elif (isinstance(target, str)):
            hash = target
        else:
            raise ValueError("Invalid link target: {!r}".format(target))

        if (name in self._links):
            raise ValueError("Duplicate link name: {}".format(name))

        self._links[name] = (hash, size)

        return self

    def build(self):
        """
        Return the node built by this builder.

        :return: The node with the specified data and links
        """

        if (self._dag.codec):
            data = self._dag.codec.dumps(self._value)
        else:
            if (type(data) == bytes):
                data = self._value
            elif (type(data) == str):
                data = self._value.encode()
            else:
                raise TypeError("Data must be bytes or string")

        links = [{"Name": name, "Hash": l[0], "Size": l[1]} for name, l in self._links.items()]
        node = {"Data": data, "Links": links}
        res = self._dag.ipfs.object.put(node)
        return self._dag.get(res["Hash"])

class Merkledag:
    """
    The root for all merkledag operations.

    To get a node try::

       >>> dag = Merkledag(IpfsApi())
       >>> dag["QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB"]
       Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)

    or::

       >>> dag["/ipfs/QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/readme"]
       Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)

    or::

       >>> dag["/ipns/<your peer ID>"]

    """

    def __init__(self, ipfs, codec = None):
        """
        Create an instance of a merkledage.

        :param ipfs: An IpfsApi instance
        :param codec: The coded used for encoding and decoding node data
        """
        self.ipfs = ipfs
        self.codec = codec

    def get(self, ref):
        """
        Return a merkledag node by it's reference.

        :param ref: Either a IPNS or IPFS name or a plain base58 hash to a node
        :return:    The references node
        """

        if (ref.startswith("/ipns/") or ref.startswith("/ipfs")):
            hash = self.ipfs.resolve(ref)["Path"][6:]
        else:
            hash = ref

        return Node(self, hash)

    def __getitem__(self, hash):
        return self.get(hash)

    def builder(self):
        return NodeBuilder(self)

__all__ = [
    "Link",
    "Node",
    "NodeBuilder",
    "Merkledag"
]

<commit_msg>Raise an RuntimeError when the user tries to access data while using a codec<commit_after>"""
This module is a high-level abstraction to the ipfs.object API.

It provides a pythonic way of interacting with merkledag nodes (a.k.a. objects).

To run the following examples start with::

   >>> from ipfs.api import IpfsApi
   >>> from ipfs.merkledag import Merkledag
   >>> dag = Merkledag(IpfsApi())

"""

from threading import Lock

# jgraef: TODO: Update docs and examples with value instead of data

class Link:
    """
    A link in the merkledag that links another node.

    .. py:attribute:: name

       The link name

    .. py:attribute:: hash

       The linked node's hash

    .. py:attribute:: size

       Size of the node (optional, might be 0)

    """

    def __init__(self, dag, name, hash, size):
        self._dag = dag
        self.name = name
        self.hash = hash
        self.size = size

    def follow(self):
        """
        Return the referenced node.

        Example::

           >>> node = dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
           >>> link = node.get_link("readme")
           >>> readme = link.follow()
           >>> readme
           Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)
           >>> readme.data[5:22].decode()
           'Hello and Welcome'

        Normally you don't have to interact with links. You can directly
        follow links by referencing attributes of a Node.
        """

        return self._dag.get(self.hash)

    def __repr__(self):
        return "Link(name={}, hash={}, size={:d})".format(self.name, self.hash, self.size)

class Node:
    """
    A merkledag node (a.k.a object).

    A merkledag node is a node like in any other graph. It stores some data
    and can have multiple links (or edges) to other nodes.

    To get a merkledag node call ``dag.get(ref)`` or access it via
    ``dag[ref]``, where ``ref`` can be a ipfs or ipns name or a plain
    base58 hash of your node::

       >>> dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
       Node(QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec)

    The data of a node can be accessed via its ``data`` attribute::

       >>> n = dag["QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB"]
       >>> n.data[5:22].decode()
       'Hello and Welcome'

    Links can be followed by directly accessing attributes::

       >>> node = dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
       >>> node.readme
       Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)

    You can also interate over a node's links by::

       >>> node = dag["QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec"]
       >>> for link in node:
               print(link.name, "->", link.hash)

       about -> QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V
       contact -> QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y
       help -> QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7
       quick-start -> QmXifYTiYxz8Nxt3LmjaxtQNLYkjdh324L4r81nZSadoST
       readme -> QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB
       security-notes -> QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ

    .. py:attribute:: hash

       The node's hash

    """

    def __init__(self, dag, hash):
        self._dag = dag
        self.hash = hash
        self._value = None
        self._links = None
        self._links_map = None
        self._loaded = False
        self._lock = Lock()

    def _lazy_load_data(self):
        with self._lock:
            if (self._value != None):
                return

            f = self._dag.ipfs.object.data(self.hash)
            if (self._dag.codec):
                self._value = self._dag.codec.load(f)
            else:
                self._value = f.read()

    def _lazy_load_links(self):
        # jgraef: TODO: How to handle multiple links with the same name?

        with self._lock:
            if (self._links != None):
                return

            links = self._dag.ipfs.object.links(self.hash)["Links"]

            self._links = [Link(self._dag, l["Name"], l["Hash"], l["Size"]) for l in links]
            self._links_map = {}
            for l in self._links:
                self._links_map[l.name] = l

    @property
    def ref(self):
        """ The reference URL, e.g. ``"/ipfs/QmPXME1oRtoT627YKaDPDQ3PwA8tdP9rWuAAweLzqSwAWT"``. """
        return "/ipfs/" + self.hash

    @property
    def data(self):
        """
        The data contained in this node.

        DEPRECATED: Use :py:attr:`value` instead.
        """

        if (self._dag.codec):
            raise RuntimeError("The data attribute is not available, when using a codec")
        self._lazy_load_data()
        return self._value

    @property
    def value(self):
        """
        The value contained in this node.
        """

        self._lazy_load_data()
        return self._value

    @property
    def links(self):
        """ A list of the links contained in this node. """
        self._lazy_load_links()
        return self._links

    def get_link(self, name):
        """
        Return a link by its name.

        :param name: The link name
        :return:     The link with that name
        """
        self._lazy_load_links()
        return self._links_map[name]

    def has_link(self, name):
        """
        Return whether this node has a link with the given name.

        :param name: The link name
        :return:     True if a link with that name exists, False otherwise.
        """
        return name in self._links_map

    def get_node(self, name):
        """
        Return a linked node given the link's name.

        :param name: The link name
        :return:     The node linked by this name

        This is a shortcut for ``node.get_link(name).follow()``
        """
        return self.get_link(name).follow()

    """ TODO:
    def add_link(self, name, target):
        if (isinstance(target, Node)):
            ref = target.ref
        elif (isinstance(target, str)):
            ref = "/ipfs/" + target
        else:
            raise ValueError("Invalid link target: {!r}".format(target))

        res = self._dag.ipfs.object_patch_add_link(self.hash, name, ref)
        print(res)

    def rm_link(self, name):
        res = self._dag.ipfs.object_patch_rm_link(self.hash, name)
        print(res)

    def set_data(self, data):
        res = self._dag.ipfs.object_patch_set_data(self.hash, data)
        print(res)

    def append_data(self, data):
        res = self._dag.ipfs.object_patch_append_data(self.hash, data)
        print(res)
    """

    def __getitem__(self, name):
        return self.get_node(name)

    def __contains__(self, name):
        return self.has_link(name)

    def __getattr__(self, name):
        try:
            return self.get_node(name)
        except KeyError:
            raise AttributeError(name)

    def __iter__(self):
        return iter(self.links)

    def __repr__(self):
        return "Node({})".format(self.hash)

    def __str__(self):
        return str(self.value)

    def __hash__(self):
        return hash(self.hash)

    def __eq__(self, other):
        return isinstance(other, Node) and other.hash == self.hash

class NodeBuilder:
    """
    The NodeBuilder is used to create new nodes.

    Currently it's the only mechanism available to create a node. Soon there
    will be methods to *patch* a node in order to create new nodes.

    Example::

       >>> c1 = dag.builder().data("Child 1").build()
       >>> c2 = dag.builder().data("Child 2").link("sibling", c1).build()
       >>> r = dag.builder().data("Root")\
               .link("child_1", c1).link("child_2", c2).build()
       >>> r
       Node(Qme2Fuk2YRNWwbhQ9G4d3GBAEQ5kL1r8P1b5RVx1HgZsco)

    Try exploring that in your DAG browser:
    http://localhost:5001/ipfs/QmR9MzChjp1MdFWik7NjEjqKQMzVmBkdK3dz14A6B5Cupm/#/objects/object/Qme2Fuk2YRNWwbhQ9G4d3GBAEQ5kL1r8P1b5RVx1HgZsco
    """

    def __init__(self, dag):
        self._dag = dag
        self._value = None
        self._links = {}

    def data(self, data):
        """
        Set the data that will be contained in the new node.

        :param data: A bytes object or string that will be the node's content.
        :return:     The builder itself to allow chaining.

        DEPRECATED: Use :py:meth:`value` instead.
        """

        if (self._dag.codec):
            raise ValueError("Specified raw data with codec")
        self._value = value

    def value(self, value):
        """
        Set the value that will be included in the new node.

        :param value: A value that can be encoded by the coded specified in
                      :py:class:`Merkledag`.
        :return:      The builder itself to allow chaining.
        """

        self._value = value
        return self

    def link(self, name, target, size = 0):
        """
        Set a link that will be added to the node.

        :param name:   The link name
        :param target: The merkledag node or hash to which the link points
        :param size:   The cumulative size of the linked node (optional)
        :return:     The builder itself to allow chaining.
        """

        if (isinstance(target, Node)):
            hash = target.hash
        elif (isinstance(target, str)):
            hash = target
        else:
            raise ValueError("Invalid link target: {!r}".format(target))

        if (name in self._links):
            raise ValueError("Duplicate link name: {}".format(name))

        self._links[name] = (hash, size)

        return self

    def build(self):
        """
        Return the node built by this builder.

        :return: The node with the specified data and links
        """

        if (self._dag.codec):
            data = self._dag.codec.dumps(self._value)
        else:
            if (type(data) == bytes):
                data = self._value
            elif (type(data) == str):
                data = self._value.encode()
            else:
                raise TypeError("Data must be bytes or string")

        links = [{"Name": name, "Hash": l[0], "Size": l[1]} for name, l in self._links.items()]
        node = {"Data": data, "Links": links}
        res = self._dag.ipfs.object.put(node)
        return self._dag.get(res["Hash"])

class Merkledag:
    """
    The root for all merkledag operations.

    To get a node try::

       >>> dag = Merkledag(IpfsApi())
       >>> dag["QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB"]
       Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)

    or::

       >>> dag["/ipfs/QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/readme"]
       Node(QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB)

    or::

       >>> dag["/ipns/<your peer ID>"]

    """

    def __init__(self, ipfs, codec = None):
        """
        Create an instance of a merkledage.

        :param ipfs: An IpfsApi instance
        :param codec: The coded used for encoding and decoding node data
        """
        self.ipfs = ipfs
        self.codec = codec

    def get(self, ref):
        """
        Return a merkledag node by it's reference.

        :param ref: Either a IPNS or IPFS name or a plain base58 hash to a node
        :return:    The references node
        """

        if (ref.startswith("/ipns/") or ref.startswith("/ipfs")):
            hash = self.ipfs.resolve(ref)["Path"][6:]
        else:
            hash = ref

        return Node(self, hash)

    def __getitem__(self, hash):
        return self.get(hash)

    def builder(self):
        return NodeBuilder(self)

__all__ = [
    "Link",
    "Node",
    "NodeBuilder",
    "Merkledag"
]

<|endoftext|>


<commit_before>"""Utilities related to managing nginx."""
import subprocess
import os

from flask import render_template

from ipyproxy import app

def reload():
    subprocess.check_call(('service', 'nginx', 'reload'))
<commit_msg>simplify nginx.py<commit_after>import subprocess

def reload():
    subprocess.check_call(('service', 'nginx', 'reload'))
<|endoftext|>


<commit_before>from typing import Dict

from .contact import Contact
from .util import to_json

class Transaction:
    def __init__(self, id: str, contact: Dict[str, str], type: str,
                 purpose: str, booking_text: str, amount: float) -> None:
        self.id = id
        self.contact = Contact(**contact)
        self.type = type
        self.purpose = purpose
        self.booking_text = booking_text
        self.amount = amount

    def to_json(self):
        return {
            'id': to_json(self.id),
            'contact': to_json(self.contact),
            'type': to_json(self.type),
            'purpose': to_json(self.purpose),
            'booking_text': to_json(self.booking_text),
            'amount': to_json(self.amount)
        }
<commit_msg>added support for multiple types for contact in transaction<commit_after>from typing import Dict

from .contact import Contact
from .util import to_json

class Transaction:
    def __init__(self, id: str, contact, type: str,
                 purpose: str, booking_text: str, amount: float) -> None:
        if isinstance(contact, Dict):
            self.contact = Contact(**contact)
        elif isinstance(contact, Contact):
            self.contact = contact
        else:
            raise Exception('invalid type')

        self.id = id
        self.contact = Contact(**contact)
        self.type = type
        self.purpose = purpose
        self.booking_text = booking_text
        self.amount = amount

    def to_json(self):
        return {
            'id': to_json(self.id),
            'contact': to_json(self.contact),
            'type': to_json(self.type),
            'purpose': to_json(self.purpose),
            'booking_text': to_json(self.booking_text),
            'amount': to_json(self.amount)
        }
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""

Moving data from iRODS server to a Neo4j graphdb.

// DONE:
    * packaging, libraries and class style
    * docker section
    * write graphdb class and OGM models, with entities list
    * PID and rules
    * eudat epic client for PID metadata
    * Replica relation, Collections, Resources
    * neo4j new docker image
// DOING:
    * neo4j backup http://stackoverflow.com/a/25569005/2114395
// TODO:
    * add logs class
    * adjust template for all rules
// TOFIX
    * show counts of irods element vs selected elements
    * irods replica concept
    * switch script to ipython:
        http://click.pocoo.org/5/exceptions/#what-if-i-don-t-want-that
    * python3 irods client? or stick with plumbus?
// NOT SO FAST:
    * Recover PID in production? http://hdl.handle.net/
    * rancher yaml for multi host configuration

"""

import libs.cliinterface as shell_app

# MAIN
if __name__ == '__main__':
    shell_app.cli(obj={})
<commit_msg>The new strategy of the week<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""

Moving data from iRODS server to a Neo4j graphdb.

// DONE:
* packaging, libraries and class style
* docker section
* write graphdb class and OGM models, with entities list
* PID and rules
* Replica relation, Collections, Resources
* eudat epic client for PID metadata
* neo4j new docker image

// DOING:
    * add notebook docker image for executing queries
    NOTE:
    - should use a separate git repo for docker images
        and should also use the matrioska compose of image to separate concepts
    - should track this repo here with git submodules
// TODO:
    * add logs class
    * adjust template for all rules
// TOFIX
    * show counts of irods element vs selected elements
    * irods replica concept
    * switch script to ipython:
        http://click.pocoo.org/5/exceptions/#what-if-i-don-t-want-that
    * python3 irods client? or stick with plumbus?
// LATER:
    * Recover PID in production? http://hdl.handle.net/
    * rancher yaml for multi host configuration

"""

import libs.cliinterface as shell_app

# MAIN
if __name__ == '__main__':
    shell_app.cli(obj={})
<|endoftext|>


<commit_before>#!/usr/bin/python
import sys
import time
from sense_hat import SenseHat
from evdev import InputDevice, list_devices, ecodes

print("Press Ctrl-C to quit")
time.sleep(1)

sense = SenseHat()
sense.clear()  # Blank the LED matrix

found = False;
devices = [InputDevice(fn) for fn in list_devices()]
for dev in devices:
  if dev.name == 'Raspberry Pi Sense HAT Joystick':
    found = True;
    break
if not(found):
  print('Raspberry Pi Sense HAT Joystick not found. Aborting ...')
  exit()

# 0, 0 = Top left
# 7, 7 = Bottom right
UP_PIXELS = [[3, 0], [4, 0]]
DOWN_PIXELS = [[3, 7], [4, 7]]
LEFT_PIXELS = [[0, 3], [0, 4]]
RIGHT_PIXELS = [[7, 3], [7, 4]]
CENTRE_PIXELS = [[3, 3], [4, 3], [3, 4], [4, 4]]

def set_pixels(pixels, col):
    for p in pixels:
        sense.set_pixel(p[0], p[1], col[0], col[1], col[2])

def handle_code(code, colour):
    if code == ecodes.KEY_DOWN:
        set_pixels(DOWN_PIXELS, colour)
    elif code == ecodes.KEY_UP:
        set_pixels(UP_PIXELS, colour)
    elif code == ecodes.KEY_LEFT:
        set_pixels(LEFT_PIXELS, colour)
    elif code == ecodes.KEY_RIGHT:
        set_pixels(RIGHT_PIXELS, colour)
    elif code == ecodes.KEY_ENTER:
        set_pixels(CENTRE_PIXELS, colour)

BLACK = [0, 0, 0]
WHITE = [255, 255, 255]

try:
    for event in dev.read_loop():
        if event.type == ecodes.EV_KEY:
            if event.value == 1:  # key down
                handle_code(event.code, WHITE)
            if event.value == 0:  # key up
                handle_code(event.code, BLACK)
except KeyboardInterrupt:
    sys.exit()
<commit_msg>indentation fix<commit_after>#!/usr/bin/python
import sys
import time
from sense_hat import SenseHat
from evdev import InputDevice, list_devices, ecodes

print("Press Ctrl-C to quit")
time.sleep(1)

sense = SenseHat()
sense.clear()  # Blank the LED matrix

found = False;
devices = [InputDevice(fn) for fn in list_devices()]
for dev in devices:
    if dev.name == 'Raspberry Pi Sense HAT Joystick':
        found = True;
        break

if not(found):
    print('Raspberry Pi Sense HAT Joystick not found. Aborting ...')
    sys.exit()

# 0, 0 = Top left
# 7, 7 = Bottom right
UP_PIXELS = [[3, 0], [4, 0]]
DOWN_PIXELS = [[3, 7], [4, 7]]
LEFT_PIXELS = [[0, 3], [0, 4]]
RIGHT_PIXELS = [[7, 3], [7, 4]]
CENTRE_PIXELS = [[3, 3], [4, 3], [3, 4], [4, 4]]

def set_pixels(pixels, col):
    for p in pixels:
        sense.set_pixel(p[0], p[1], col[0], col[1], col[2])

def handle_code(code, colour):
    if code == ecodes.KEY_DOWN:
        set_pixels(DOWN_PIXELS, colour)
    elif code == ecodes.KEY_UP:
        set_pixels(UP_PIXELS, colour)
    elif code == ecodes.KEY_LEFT:
        set_pixels(LEFT_PIXELS, colour)
    elif code == ecodes.KEY_RIGHT:
        set_pixels(RIGHT_PIXELS, colour)
    elif code == ecodes.KEY_ENTER:
        set_pixels(CENTRE_PIXELS, colour)

BLACK = [0, 0, 0]
WHITE = [255, 255, 255]

try:
    for event in dev.read_loop():
        if event.type == ecodes.EV_KEY:
            if event.value == 1:  # key down
                handle_code(event.code, WHITE)
            if event.value == 0:  # key up
                handle_code(event.code, BLACK)
except KeyboardInterrupt:
    sys.exit()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

#  Licensed under the Apache License, Version 2.0 (the "License"); you may
#  not use this file except in compliance with the License. You may obtain
#  a copy of the License at
#
#       https://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#  License for the specific language governing permissions and limitations
#  under the License.

from __future__ import unicode_literals

import os
import sys
import requests, json, configparser
import celeb_db
import image_management

from compliment import Compliment
from argparse import ArgumentParser
from watson_developer_cloud import VisualRecognitionV3

from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookParser
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage, TemplateSendMessage,
    ImageMessage, ImageSendMessage, ImagemapSendMessage,
    ButtonsTemplate, ConfirmTemplate, CarouselTemplate, CarouselColumn,
    TemplateAction, PostbackTemplateAction, MessageTemplateAction, URITemplateAction,
    BaseSize, URIImagemapAction, MessageImagemapAction, ImagemapArea,
    FollowEvent, JoinEvent, PostbackEvent
)

app = Flask(__name__)

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
bluemix_api_key = os.getenv('BLUEMIX_API_KEY', None)

if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)
if bluemix_api_key is None:
    print('Specify BLUEMIX_API_KEY as environment variable.')
    sys.exit(1)

visual_recognition = VisualRecognitionV3('2016-05-20', api_key=bluemix_api_key)
line_bot_api = LineBotApi(channel_access_token)
parser = WebhookParser(channel_secret)
config = configparser.ConfigParser()
config.read('locale.ini')
language = config.get('DEFAULT', 'language')

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(500)

    # if event is MessageEvent and message is TextMessage, then check prefix
    for event in events:
        # For bluemix
        if isinstance(event, FollowEvent):
            # If user just added me, send welcome and confirm message
            sendMessage = []
            sendMessage.append(createWelcomeMessage())
            sendMessage.append(createConfirmMessage())
        elif isinstance(event, JoinEvent):
            # If user invited me to a group, send confirm message
            sendMessage = createConfirmMessage()
        elif isinstance(event, PostbackEvent):
            # For postback events
            sendMessage = analyzePostbackEvent(event)
        elif isinstance(event, MessageEvent) and isinstance(event.message, ImageMessage):
            # If user sends an image, save content
            image_url = saveContentImage(event)
            # classify the image
            classifiers = classifyImageMessage(image_url)

            # After classification reply the following to user
            # 1 no classifier found, send a text message
            if classifiers == 0:
                app.logger.info('no classifier!!')
                sendMessage = TextSendMessage(text='I\'m sorry but your image is out of this world.')
                line_bot_api.reply_message(event.reply_token, sendMessage)
                return 'OK'

            isCelebrity = len(classifiers) > 1
            isPerson = 'person' in json.dumps(classifiers)

            app.logger.info('isCelebrity: ' + str(isCelebrity) + ' isPerson:' + str(isPerson))

            # 2 a person and celebrity look alike, send a template message carousel
            if isCelebrity and isPerson:
                sendMessage = createMessageTemplate(classifiers)
            # 3 a celebrity lookalike but not a person
            elif isCelebrity:
                type_class = classifiers[0]['classes'][1]['class']
                celeb_name = celeb_db.findRecordWithId(classifiers[0]['classes'][0]['class'])
                sendMessage = TextSendMessage(text='Funny, that looks like my friend ' + celeb_name + ' but is a ' + type_class)
            # TODO: 4 a person, call detect_face send a single template message,
            elif isPerson:
                type_class = classifiers[0]['classes'][0]['class']
                sendMessage = TextSendMessage(text='You don\'t look like any celebrities, but you look like a ' + type_class)
                #call v3/classify with
                #call v3/detect_face
            # 5 others. send a text message
            else:
                type_class = classifiers[0]['classes'][0]['class']
                app.logger.info('not human but a type_class: ' + type_class)
                text = "Is that a " + type_class + "? If I'm mistaken, please take a clearer picture of yourself."
                sendMessage = TextSendMessage(text=text)
        else:
            continue

        line_bot_api.reply_message(event.reply_token, sendMessage)

    return 'OK'

# Save image to cloudinary
def saveContentImage(event):
    app.logger.info(str(event))
    message_content = line_bot_api.get_message_content(event.message.id)
    image_binary = message_content.content

    # save image to cloudinary
    fp = open("temp_img", 'wb')
    fp.write(image_binary)
    fp.close()
    image_url, image_id = image_management.upload(event.message.id, 'temp_img')

    return image_url

# Classify image in Bluemix
def classifyImageMessage(image_url):
    #initialize v3/classify
    classifier = config.get('DEFAULT', 'Bluemix_Classifier')
    threshold = config.get('DEFAULT', 'Bluemix_Threshold')
    app.logger.info('classifier: ' + classifier)

    #call v3/classify
    response = visual_recognition.classify(
        images_url=image_url,
        classifier_ids=[classifier, 'default'],
        threshold=threshold
        )
    app.logger.info(json.dumps(response, indent=2))

    # check if a classifier is detected in the image
    if 'classifiers' in json.dumps(response):
        return response['images'][0]['classifiers']
    else:
        return 0

def createMessageTemplate(user, classifiers):
    columns = []
    for index, celeb_class in enumerate(classifiers[0]['classes']):
        celeb = celeb_db.findRecordWithId(celeb_class['class'])
        score = computeScore(celeb_class['score'])
        app.logger.info('Carousel index:' + index + ' for ' + celeb['en_name'] + ' score: ' + score)
        title = user + ' looks like ' + celeb['local_name'] + '(' + celeb['en_name'] + ')'
        temp = CarouselColumn(
            thumbnail_image_url=celeb['image_url'],
            title=title[:40],
            text='Score: ' + score + '%',
            actions=[
                PostbackTemplateAction(
                    label='Agree',
                    text='postback text1',
                    data='action=buy&itemid=1'
                ),
                MessageTemplateAction(
                    label='Disagree',
                    text='I think ' + 'userid' + ' is ' + Compliment.getRandomCompliment(celeb['sex']) + ' than ' + celeb['local_name']
                ),
                URITemplateAction(
                    label='Share',
                    uri='http://example.com/1'
                )
            ]
        )
        columns.append(temp)

    carousel_template_message = TemplateSendMessage(
        alt_text= user + ' has is a celebrity look alike! Please check your smartphone',
        template=CarouselTemplate(columns=columns)
    )
    return carousel_template_message

def createWelcomeMessage():
    text_message = TextSendMessage(text=config.get(language, 'Welcome_Message'))
    return text_message

def createConfirmMessage():
    confirm_template_message = TemplateSendMessage(
        alt_text='Please check message on your smartphone',
        template=ConfirmTemplate(
            text='Do you want to know who you look like?',
            actions=[
                PostbackTemplateAction(
                    label='Yes!',
                    text='Yes!',
                    data='action=y'
                ),
                MessageTemplateAction(
                    label='About Me',
                    text='I\'m a bot that searches for a celebrities who look like you. Try me!'
                )
            ]
        )
    )
    return confirm_template_message

def analyzePostbackEvent(event):
    app.logger.info('postback action: ' + str(event.postback.data))
    if str(event.postback.data) == 'action=y':
        app.logger.info('user id: ' + event.user.user_id)
        text_message = TextSendMessage(text='That\'s great ' + event.user.user_id + '! Please send me a picture of yourself.')
    return text_message

def queryStackOverflow(query):
    query = query[3:]
    url = 'https://api.stackexchange.com/2.2/search/advanced?'
    payload = {
        'site': 'stackoverflow',
        'views':'200',
        'answers':'1',
        'order':'desc',
        'sort':'relevance',
        'pagesize':'4',
        'q':query,
        'body':query
    }
    response = requests.get(url=url, params=payload)
    data = response.json()
    if data['has_more']:
        columns2 = []
        for index, item in enumerate(data['items']):
            app.logger.info(str(index) + ':' + str(item))
            temp = CarouselColumn(
                thumbnail_image_url='https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png',
                title=item['title'][:36] + '...',
                text='Tags: ' + item['tags'][0] + ', '+ item['tags'][1] ,
                actions=[
                    URITemplateAction(
                        label='Go to Article',
                        uri=item['link']
                    ),
                    PostbackTemplateAction(
                        label='Useful',
                        text='Article ' + str(index) + ' is useful',
                        data='action=buy&itemid=1'
                    ),
                    MessageTemplateAction(
                        label='Not useful',
                        text='Article ' + str(index) + ' is not useful'
                    )
                ]
            )
            columns2.append(temp)
        carousel_template_message = TemplateSendMessage(
            alt_text='Test',
            template=CarouselTemplate(
                columns=columns2
            )
        )
        return carousel_template_message
    else:
        text_message = TextSendMessage(text='Not found. Please try other keywords.')
        return text_message

def querySearchEngine(data, type):
    index = 0
    app.logger.info("type:" + type)
    template = ImageSendMessage(
                original_content_url='https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg',
                preview_image_url='https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg'
                )
    return template

if __name__ == "__main__":
    arg_parser = ArgumentParser(
        usage='Usage: python ' + __file__ + ' [--port <port>] [--help]'
    )
    arg_parser.add_argument('-p', '--port', default=8000, help='port')
    arg_parser.add_argument('-d', '--debug', default=False, help='debug')
    options = arg_parser.parse_args()

    app.run(debug=options.debug, host='0.0.0.0', port=int(options.port))
<commit_msg>add dummy user name first<commit_after># -*- coding: utf-8 -*-

#  Licensed under the Apache License, Version 2.0 (the "License"); you may
#  not use this file except in compliance with the License. You may obtain
#  a copy of the License at
#
#       https://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#  License for the specific language governing permissions and limitations
#  under the License.

from __future__ import unicode_literals

import os
import sys
import requests, json, configparser
import celeb_db
import image_management

from compliment import Compliment
from argparse import ArgumentParser
from watson_developer_cloud import VisualRecognitionV3

from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookParser
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage, TemplateSendMessage,
    ImageMessage, ImageSendMessage, ImagemapSendMessage,
    ButtonsTemplate, ConfirmTemplate, CarouselTemplate, CarouselColumn,
    TemplateAction, PostbackTemplateAction, MessageTemplateAction, URITemplateAction,
    BaseSize, URIImagemapAction, MessageImagemapAction, ImagemapArea,
    FollowEvent, JoinEvent, PostbackEvent
)

app = Flask(__name__)

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
bluemix_api_key = os.getenv('BLUEMIX_API_KEY', None)

if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)
if bluemix_api_key is None:
    print('Specify BLUEMIX_API_KEY as environment variable.')
    sys.exit(1)

visual_recognition = VisualRecognitionV3('2016-05-20', api_key=bluemix_api_key)
line_bot_api = LineBotApi(channel_access_token)
parser = WebhookParser(channel_secret)
config = configparser.ConfigParser()
config.read('locale.ini')
language = config.get('DEFAULT', 'language')

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(500)

    # if event is MessageEvent and message is TextMessage, then check prefix
    for event in events:
        # For bluemix
        if isinstance(event, FollowEvent):
            # If user just added me, send welcome and confirm message
            sendMessage = []
            sendMessage.append(createWelcomeMessage())
            sendMessage.append(createConfirmMessage())
        elif isinstance(event, JoinEvent):
            # If user invited me to a group, send confirm message
            sendMessage = createConfirmMessage()
        elif isinstance(event, PostbackEvent):
            # For postback events
            sendMessage = analyzePostbackEvent(event)
        elif isinstance(event, MessageEvent) and isinstance(event.message, ImageMessage):
            # If user sends an image, save content
            image_url = saveContentImage(event)
            # classify the image
            classifiers = classifyImageMessage(image_url)

            # After classification reply the following to user
            # 1 no classifier found, send a text message
            if classifiers == 0:
                app.logger.info('no classifier!!')
                sendMessage = TextSendMessage(text='I\'m sorry but your image is out of this world.')
                line_bot_api.reply_message(event.reply_token, sendMessage)
                return 'OK'

            isCelebrity = len(classifiers) > 1
            isPerson = 'person' in json.dumps(classifiers)

            app.logger.info('isCelebrity: ' + str(isCelebrity) + ' isPerson:' + str(isPerson))

            # 2 a person and celebrity look alike, send a template message carousel
            if isCelebrity and isPerson:
                sendMessage = createMessageTemplate('marc', classifiers)
            # 3 a celebrity lookalike but not a person
            elif isCelebrity:
                type_class = classifiers[0]['classes'][1]['class']
                celeb_name = celeb_db.findRecordWithId(classifiers[0]['classes'][0]['class'])
                sendMessage = TextSendMessage(text='Funny, that looks like my friend ' + celeb_name + ' but is a ' + type_class)
            # TODO: 4 a person, call detect_face send a single template message,
            elif isPerson:
                type_class = classifiers[0]['classes'][0]['class']
                sendMessage = TextSendMessage(text='You don\'t look like any celebrities, but you look like a ' + type_class)
                #call v3/classify with
                #call v3/detect_face
            # 5 others. send a text message
            else:
                type_class = classifiers[0]['classes'][0]['class']
                app.logger.info('not human but a type_class: ' + type_class)
                text = "Is that a " + type_class + "? If I'm mistaken, please take a clearer picture of yourself."
                sendMessage = TextSendMessage(text=text)
        else:
            continue

        line_bot_api.reply_message(event.reply_token, sendMessage)

    return 'OK'

# Save image to cloudinary
def saveContentImage(event):
    app.logger.info(str(event))
    message_content = line_bot_api.get_message_content(event.message.id)
    image_binary = message_content.content

    # save image to cloudinary
    fp = open("temp_img", 'wb')
    fp.write(image_binary)
    fp.close()
    image_url, image_id = image_management.upload(event.message.id, 'temp_img')

    return image_url

# Classify image in Bluemix
def classifyImageMessage(image_url):
    #initialize v3/classify
    classifier = config.get('DEFAULT', 'Bluemix_Classifier')
    threshold = config.get('DEFAULT', 'Bluemix_Threshold')
    app.logger.info('classifier: ' + classifier)

    #call v3/classify
    response = visual_recognition.classify(
        images_url=image_url,
        classifier_ids=[classifier, 'default'],
        threshold=threshold
        )
    app.logger.info(json.dumps(response, indent=2))

    # check if a classifier is detected in the image
    if 'classifiers' in json.dumps(response):
        return response['images'][0]['classifiers']
    else:
        return 0

def createMessageTemplate(user, classifiers):
    columns = []
    for index, celeb_class in enumerate(classifiers[0]['classes']):
        celeb = celeb_db.findRecordWithId(celeb_class['class'])
        score = computeScore(celeb_class['score'])
        app.logger.info('Carousel index:' + index + ' for ' + celeb['en_name'] + ' score: ' + score)
        title = user + ' looks like ' + celeb['local_name'] + '(' + celeb['en_name'] + ')'
        temp = CarouselColumn(
            thumbnail_image_url=celeb['image_url'],
            title=title[:40],
            text='Score: ' + score + '%',
            actions=[
                PostbackTemplateAction(
                    label='Agree',
                    text='postback text1',
                    data='action=buy&itemid=1'
                ),
                MessageTemplateAction(
                    label='Disagree',
                    text='I think ' + 'userid' + ' is ' + Compliment.getRandomCompliment(celeb['sex']) + ' than ' + celeb['local_name']
                ),
                URITemplateAction(
                    label='Share',
                    uri='http://example.com/1'
                )
            ]
        )
        columns.append(temp)

    carousel_template_message = TemplateSendMessage(
        alt_text= user + ' has is a celebrity look alike! Please check your smartphone',
        template=CarouselTemplate(columns=columns)
    )
    return carousel_template_message

def createWelcomeMessage():
    text_message = TextSendMessage(text=config.get(language, 'Welcome_Message'))
    return text_message

def createConfirmMessage():
    confirm_template_message = TemplateSendMessage(
        alt_text='Please check message on your smartphone',
        template=ConfirmTemplate(
            text='Do you want to know who you look like?',
            actions=[
                PostbackTemplateAction(
                    label='Yes!',
                    text='Yes!',
                    data='action=y'
                ),
                MessageTemplateAction(
                    label='About Me',
                    text='I\'m a bot that searches for a celebrities who look like you. Try me!'
                )
            ]
        )
    )
    return confirm_template_message

def analyzePostbackEvent(event):
    app.logger.info('postback action: ' + str(event.postback.data))
    if str(event.postback.data) == 'action=y':
        app.logger.info('user id: ' + event.user.user_id)
        text_message = TextSendMessage(text='That\'s great ' + event.user.user_id + '! Please send me a picture of yourself.')
    return text_message

def queryStackOverflow(query):
    query = query[3:]
    url = 'https://api.stackexchange.com/2.2/search/advanced?'
    payload = {
        'site': 'stackoverflow',
        'views':'200',
        'answers':'1',
        'order':'desc',
        'sort':'relevance',
        'pagesize':'4',
        'q':query,
        'body':query
    }
    response = requests.get(url=url, params=payload)
    data = response.json()
    if data['has_more']:
        columns2 = []
        for index, item in enumerate(data['items']):
            app.logger.info(str(index) + ':' + str(item))
            temp = CarouselColumn(
                thumbnail_image_url='https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png',
                title=item['title'][:36] + '...',
                text='Tags: ' + item['tags'][0] + ', '+ item['tags'][1] ,
                actions=[
                    URITemplateAction(
                        label='Go to Article',
                        uri=item['link']
                    ),
                    PostbackTemplateAction(
                        label='Useful',
                        text='Article ' + str(index) + ' is useful',
                        data='action=buy&itemid=1'
                    ),
                    MessageTemplateAction(
                        label='Not useful',
                        text='Article ' + str(index) + ' is not useful'
                    )
                ]
            )
            columns2.append(temp)
        carousel_template_message = TemplateSendMessage(
            alt_text='Test',
            template=CarouselTemplate(
                columns=columns2
            )
        )
        return carousel_template_message
    else:
        text_message = TextSendMessage(text='Not found. Please try other keywords.')
        return text_message

def querySearchEngine(data, type):
    index = 0
    app.logger.info("type:" + type)
    template = ImageSendMessage(
                original_content_url='https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg',
                preview_image_url='https://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg'
                )
    return template

if __name__ == "__main__":
    arg_parser = ArgumentParser(
        usage='Usage: python ' + __file__ + ' [--port <port>] [--help]'
    )
    arg_parser.add_argument('-p', '--port', default=8000, help='port')
    arg_parser.add_argument('-d', '--debug', default=False, help='debug')
    options = arg_parser.parse_args()

    app.run(debug=options.debug, host='0.0.0.0', port=int(options.port))
<|endoftext|>


<commit_before>

class Board(object):
    num_players = 2

    def starting_state(self):
        # Each of the 9 pairs of player 1 and player 2 board bitmasks
        # plus the win/tie state of the big board for p1 and p2 plus
        # the row and column of the required board for the next action
        # and finally the player number to move.
        return (0, 0) * 10 + (None, None, 1)

    def display(self, state, action, _unicode=True):
        pieces = {
            (slot['outer-row'], slot['outer-column'],
             slot['inner-row'], slot['inner-column']): slot['type']
            for slot in state['pieces']
        }

        sub = u"\u2564".join(u"\u2550" for x in xrange(3))
        top = u"\u2554" + u"\u2566".join(sub for x in xrange(3)) + u"\u2557\n"

        sub = u"\u256a".join(u"\u2550" for x in xrange(3))
        div = u"\u2560" + u"\u256c".join(sub for x in xrange(3)) + u"\u2563\n"

        sub = u"\u253c".join(u"\u2500" for x in xrange(3))
        sep = u"\u255f" + u"\u256b".join(sub for x in xrange(3)) + u"\u2562\n"

        sub = u"\u2567".join(u"\u2550" for x in xrange(3))
        bot = u"\u255a" + u"\u2569".join(sub for x in xrange(3)) + u"\u255d\n"
        if action:
            bot += u"Last played: {0}\n".format(
                self.to_notation(self.to_compact_action(action)))
        bot += u"Player: {0}\n".format(state['player'])

        return (
            top +
            div.join(
                sep.join(
                    u"\u2551" +
                    u"\u2551".join(
                        u"\u2502".join(
                            pieces.get((R, C, r, c), " ") for c in xrange(3)
                        )
                        for C in xrange(3)
                    ) +
                    u"\u2551\n"
                    for r in xrange(3)
                )
                for R in xrange(3)
            ) +
            bot
        )

    def to_compact_state(self, data):
        state = [0] * 20
        state.extend([
            data['constraint']['outer-row'],
            data['constraint']['outer-column'],
            data['player']
        ])

        for item in data['pieces']:
            R, C, player = item['outer-row'], item['outer-column'], item['player']
            r, c = item['inner-row'], item['inner-column']
            state[2*(3*R + C) + player - 1] += 1 << (3 * r + c)

        for item in data['boards']:
            players = (1, 2)
            if item['player'] is not None:
                players = (item['player'],)

            for player in players:
                state[17 + player] += 1 << (3 * item['outer-row'] + item['outer-column'])

        return tuple(state)

    def to_json_state(self, state):
        player = state[-1]
        p1_boards, p2_boards = state[18], state[19]

        pieces, boards = [], []
        for R in xrange(3):
            for C in xrange(3):
                for r in xrange(3):
                    for c in xrange(3):
                        index = 1 << (3 * r + c)

                        if index & state[2*(3*R + C)]:
                            pieces.append({
                                'player': 1, 'type': 'X',
                                'outer-row': R, 'outer-column': C,
                                'inner-row': r, 'inner-column': c,
                            })
                        if index & state[2*(3*R + C) + 1]:
                            pieces.append({
                                'player': 2, 'type': 'O',
                                'outer-row': R, 'outer-column': C,
                                'inner-row': r, 'inner-column': c,
                            })

                board_index = 1 << (3 * R + C)
                if board_index & p1_boards & p2_boards:
                    boards.append({
                        'player': None, 'type': 'full',
                        'outer-row': R, 'outer-column': C,
                    })
                elif board_index & p1_boards:
                    boards.append({
                        'player': 1, 'type': 'X',
                        'outer-row': R, 'outer-column': C,
                    })
                elif board_index & p2_boards:
                    boards.append({
                        'player': 2, 'type': 'O',
                        'outer-row': R, 'outer-column': C,
                    })

        return {
            'pieces': pieces,
            'boards': boards,
            'constraint': {'outer-row': state[20], 'outer-column': state[21]},
            'player': player,
            'previous_player': 3 - player,
        }

    def to_compact_action(self, action):
        return (
            action['outer-row'], action['outer-column'],
            action['inner-row'], action['inner-column']
        )

    def to_json_action(self, action):
        try:
            R, C, r, c = action
            return {
                'outer-row': R, 'outer-column': C,
                'inner-row': r, 'inner-column': c,
            }
        except Exception:
            return {}

    def from_notation(self, notation):
        try:
            R, C, r, c = map(int, notation.split())
        except Exception:
            return
        return R, C, r, c

    def to_notation(self, action):
        return ' '.join(map(str, action))

    def next_state(self, state, action):
        R, C, r, c = action
        player = state[-1]
        board_index = 2 * (3 * R + C)
        player_index = player - 1

        state = list(state)
        state[-1] = 3 - player
        state[board_index + player_index] |= 1 << (3 * r + c)
        updated_board = state[board_index + player_index]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        full = (state[board_index] | state[board_index+1] == 0777)
        if any(updated_board & w == w for w in wins):
            state[18 + player_index] |= 1 << (3 * R + C)
        elif full:
            state[18] |= 1 << (3 * R + C)
            state[19] |= 1 << (3 * R + C)

        if (state[18] | state[19]) & 1 << (3 * r + c):
            state[20], state[21] = None, None
        else:
            state[20], state[21] = r, c

        return tuple(state)

    def is_legal(self, history, action):
        state = history[-1]
        R, C, r, c = action

        # Is action out of bounds?
        if not (0 <= R <= 2):
            return False
        if not (0 <= C <= 2):
            return False
        if not (0 <= r <= 2):
            return False
        if not (0 <= c <= 2):
            return False

        player = state[-1]
        board_index = 2 * (3 * R + C)
        player_index = player - 1

        # Is the square within the sub-board already taken?
        occupied = state[board_index] | state[board_index+1]
        if occupied & 1 << (3 * r + c):
            return False

        # Is our action unconstrained by the previous action?
        if state[20] is None:
            return True

        # Otherwise, we must play in the proper sub-board.
        return (R, C) == (state[20], state[21])

    def legal_actions(self, history):
        state = history[-1]
        R, C = state[20], state[21]
        Rset, Cset = (R,), (C,)
        if R is None:
            Rset = Cset = (0, 1, 2)

        occupied = [
            state[2 * x] | state[2 * x + 1] for x in xrange(9)
        ]
        finished = state[18] | state[19]

        actions = [
            (R, C, r, c)
            for R in Rset
            for C in Cset
            for r in xrange(3)
            for c in xrange(3)
            if not occupied[3 * R + C] & 1 << (3 * r + c)
            and not finished & 1 << (3 * R + C)
        ]

        return actions

    def previous_player(self, state):
        return 3 - state[-1]

    def current_player(self, state):
        return state[-1]

    def is_ended(self, history):
        state = history[-1]
        p1 = state[18] & ~state[19]
        p2 = state[19] & ~state[18]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        if any(w & p1 == w for w in wins):
            return True
        if any(w & p2 == w for w in wins):
            return True
        if state[18] | state[19] == 0777:
            return True

        return False

    def win_values(self, history):
        if not self.is_ended(history):
            return

        state = history[-1]
        p1 = state[18] & ~state[19]
        p2 = state[19] & ~state[18]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        if any(w & p1 == w for w in wins):
            return {1: 1, 2: 0}
        if any(w & p2 == w for w in wins):
            return {1: 0, 2: 1}
        if state[18] | state[19] == 0777:
            return {1: 0.5, 2: 0.5}

    def points_values(self, history):
        if not self.is_ended(history):
            return

        state = history[-1]
        p1 = state[18] & ~state[19]
        p2 = state[19] & ~state[18]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        if any(w & p1 == w for w in wins):
            return {1: 1, 2: -1}
        if any(w & p2 == w for w in wins):
            return {1: -1, 2: 1}
        if state[18] | state[19] == 0777:
            return {1: 0, 2: 0}

    def winner_message(self, winners):
        winners = sorted((v, k) for k, v in winners.iteritems())
        value, winner = winners[-1]
        if value == 0.5:
            return "Draw."
        return "Winner: Player {0}.".format(winner)
<commit_msg>Change next_state to take a history stack, not just a state<commit_after>

class Board(object):
    num_players = 2

    def starting_state(self):
        # Each of the 9 pairs of player 1 and player 2 board bitmasks
        # plus the win/tie state of the big board for p1 and p2 plus
        # the row and column of the required board for the next action
        # and finally the player number to move.
        return (0, 0) * 10 + (None, None, 1)

    def display(self, state, action, _unicode=True):
        pieces = {
            (slot['outer-row'], slot['outer-column'],
             slot['inner-row'], slot['inner-column']): slot['type']
            for slot in state['pieces']
        }

        sub = u"\u2564".join(u"\u2550" for x in xrange(3))
        top = u"\u2554" + u"\u2566".join(sub for x in xrange(3)) + u"\u2557\n"

        sub = u"\u256a".join(u"\u2550" for x in xrange(3))
        div = u"\u2560" + u"\u256c".join(sub for x in xrange(3)) + u"\u2563\n"

        sub = u"\u253c".join(u"\u2500" for x in xrange(3))
        sep = u"\u255f" + u"\u256b".join(sub for x in xrange(3)) + u"\u2562\n"

        sub = u"\u2567".join(u"\u2550" for x in xrange(3))
        bot = u"\u255a" + u"\u2569".join(sub for x in xrange(3)) + u"\u255d\n"
        if action:
            bot += u"Last played: {0}\n".format(
                self.to_notation(self.to_compact_action(action)))
        bot += u"Player: {0}\n".format(state['player'])

        return (
            top +
            div.join(
                sep.join(
                    u"\u2551" +
                    u"\u2551".join(
                        u"\u2502".join(
                            pieces.get((R, C, r, c), " ") for c in xrange(3)
                        )
                        for C in xrange(3)
                    ) +
                    u"\u2551\n"
                    for r in xrange(3)
                )
                for R in xrange(3)
            ) +
            bot
        )

    def to_compact_state(self, data):
        state = [0] * 20
        state.extend([
            data['constraint']['outer-row'],
            data['constraint']['outer-column'],
            data['player']
        ])

        for item in data['pieces']:
            R, C, player = item['outer-row'], item['outer-column'], item['player']
            r, c = item['inner-row'], item['inner-column']
            state[2*(3*R + C) + player - 1] += 1 << (3 * r + c)

        for item in data['boards']:
            players = (1, 2)
            if item['player'] is not None:
                players = (item['player'],)

            for player in players:
                state[17 + player] += 1 << (3 * item['outer-row'] + item['outer-column'])

        return tuple(state)

    def to_json_state(self, state):
        player = state[-1]
        p1_boards, p2_boards = state[18], state[19]

        pieces, boards = [], []
        for R in xrange(3):
            for C in xrange(3):
                for r in xrange(3):
                    for c in xrange(3):
                        index = 1 << (3 * r + c)

                        if index & state[2*(3*R + C)]:
                            pieces.append({
                                'player': 1, 'type': 'X',
                                'outer-row': R, 'outer-column': C,
                                'inner-row': r, 'inner-column': c,
                            })
                        if index & state[2*(3*R + C) + 1]:
                            pieces.append({
                                'player': 2, 'type': 'O',
                                'outer-row': R, 'outer-column': C,
                                'inner-row': r, 'inner-column': c,
                            })

                board_index = 1 << (3 * R + C)
                if board_index & p1_boards & p2_boards:
                    boards.append({
                        'player': None, 'type': 'full',
                        'outer-row': R, 'outer-column': C,
                    })
                elif board_index & p1_boards:
                    boards.append({
                        'player': 1, 'type': 'X',
                        'outer-row': R, 'outer-column': C,
                    })
                elif board_index & p2_boards:
                    boards.append({
                        'player': 2, 'type': 'O',
                        'outer-row': R, 'outer-column': C,
                    })

        return {
            'pieces': pieces,
            'boards': boards,
            'constraint': {'outer-row': state[20], 'outer-column': state[21]},
            'player': player,
            'previous_player': 3 - player,
        }

    def to_compact_action(self, action):
        return (
            action['outer-row'], action['outer-column'],
            action['inner-row'], action['inner-column']
        )

    def to_json_action(self, action):
        try:
            R, C, r, c = action
            return {
                'outer-row': R, 'outer-column': C,
                'inner-row': r, 'inner-column': c,
            }
        except Exception:
            return {}

    def from_notation(self, notation):
        try:
            R, C, r, c = map(int, notation.split())
        except Exception:
            return
        return R, C, r, c

    def to_notation(self, action):
        return ' '.join(map(str, action))

    def next_state(self, history, action):
        state = history[-1]
        R, C, r, c = action
        player = state[-1]
        board_index = 2 * (3 * R + C)
        player_index = player - 1

        state = list(state)
        state[-1] = 3 - player
        state[board_index + player_index] |= 1 << (3 * r + c)
        updated_board = state[board_index + player_index]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        full = (state[board_index] | state[board_index+1] == 0777)
        if any(updated_board & w == w for w in wins):
            state[18 + player_index] |= 1 << (3 * R + C)
        elif full:
            state[18] |= 1 << (3 * R + C)
            state[19] |= 1 << (3 * R + C)

        if (state[18] | state[19]) & 1 << (3 * r + c):
            state[20], state[21] = None, None
        else:
            state[20], state[21] = r, c

        return tuple(state)

    def is_legal(self, history, action):
        state = history[-1]
        R, C, r, c = action

        # Is action out of bounds?
        if not (0 <= R <= 2):
            return False
        if not (0 <= C <= 2):
            return False
        if not (0 <= r <= 2):
            return False
        if not (0 <= c <= 2):
            return False

        player = state[-1]
        board_index = 2 * (3 * R + C)
        player_index = player - 1

        # Is the square within the sub-board already taken?
        occupied = state[board_index] | state[board_index+1]
        if occupied & 1 << (3 * r + c):
            return False

        # Is our action unconstrained by the previous action?
        if state[20] is None:
            return True

        # Otherwise, we must play in the proper sub-board.
        return (R, C) == (state[20], state[21])

    def legal_actions(self, history):
        state = history[-1]
        R, C = state[20], state[21]
        Rset, Cset = (R,), (C,)
        if R is None:
            Rset = Cset = (0, 1, 2)

        occupied = [
            state[2 * x] | state[2 * x + 1] for x in xrange(9)
        ]
        finished = state[18] | state[19]

        actions = [
            (R, C, r, c)
            for R in Rset
            for C in Cset
            for r in xrange(3)
            for c in xrange(3)
            if not occupied[3 * R + C] & 1 << (3 * r + c)
            and not finished & 1 << (3 * R + C)
        ]

        return actions

    def previous_player(self, state):
        return 3 - state[-1]

    def current_player(self, state):
        return state[-1]

    def is_ended(self, history):
        state = history[-1]
        p1 = state[18] & ~state[19]
        p2 = state[19] & ~state[18]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        if any(w & p1 == w for w in wins):
            return True
        if any(w & p2 == w for w in wins):
            return True
        if state[18] | state[19] == 0777:
            return True

        return False

    def win_values(self, history):
        if not self.is_ended(history):
            return

        state = history[-1]
        p1 = state[18] & ~state[19]
        p2 = state[19] & ~state[18]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        if any(w & p1 == w for w in wins):
            return {1: 1, 2: 0}
        if any(w & p2 == w for w in wins):
            return {1: 0, 2: 1}
        if state[18] | state[19] == 0777:
            return {1: 0.5, 2: 0.5}

    def points_values(self, history):
        if not self.is_ended(history):
            return

        state = history[-1]
        p1 = state[18] & ~state[19]
        p2 = state[19] & ~state[18]

        wins = (07, 070, 0700, 0111, 0222, 0444, 0421, 0124)

        if any(w & p1 == w for w in wins):
            return {1: 1, 2: -1}
        if any(w & p2 == w for w in wins):
            return {1: -1, 2: 1}
        if state[18] | state[19] == 0777:
            return {1: 0, 2: 0}

    def winner_message(self, winners):
        winners = sorted((v, k) for k, v in winners.iteritems())
        value, winner = winners[-1]
        if value == 0.5:
            return "Draw."
        return "Winner: Player {0}.".format(winner)
<|endoftext|>


<commit_before>#!/usr/bin/env python

import argparse
import math

import numpy as np

import galsim
import bashes

def fourierMatrix(n):
    """
    Returns the fourier transform matrix for a square 2d matrix of size n.
    """
    i,j = np.meshgrid(np.arange(n), np.arange(n))
    A = np.multiply.outer(i.flatten(), i.flatten())
    B = np.multiply.outer(j.flatten(), j.flatten())
    omega = np.exp(-2*np.pi*1J/n)
    return np.power(omega, A+B)

def getTSquare(psf):
    """
    Returns the azimuthally averaged square of the fourier transformed psf.
    """
    import scipy.ndimage
    import scipy.interpolate
    # fourier transform and shift
    t = np.fft.fftshift(np.fft.fft2(psf.array))
    tSq = (np.conjugate(t)*t).real
    # average over theta
    sx, sy = tSq.shape
    X, Y = np.ogrid[0:sx, 0:sy]
    r = np.hypot(X - sx/2 + 0.5, Y - sy/2 + 0.5)
    rbin = r.astype(np.int)
    tSqAvg = scipy.ndimage.mean(tSq, labels=rbin, index=np.arange(0, rbin.max()+1))
    # build 2d representation
    tSqAvgInterp = scipy.interpolate.InterpolatedUnivariateSpline(np.arange(len(tSqAvg)),tSqAvg)
    tSq2d = tSqAvgInterp(r.flatten()).reshape(sx,sy)
    # shift and return
    return np.fft.fftshift(tSq2d)

def getFeatures(image, psfModel, sigma):
    """
    Returns the Fourier moment features of the provided image.
    """
    # Get stamp size/scale
    stampSize = image.xmax - image.xmin + 1
    pixelScale = image.scale

    # Fourier transform image
    ftimage = np.fft.fft2(image.array)

    # Render psf and fourier transform
    psf = bashes.utility.render(psfModel,scale=pixelScale,size=stampSize)
    ftpsf = np.fft.fft2(psf.array)

    # k grid
    kx,ky = np.meshgrid(np.fft.fftfreq(stampSize),np.fft.fftfreq(stampSize))
    kxsq = kx*kx
    kysq = ky*ky
    ksq = kxsq + kysq

    # Build weight function
    sigmasqby2 = sigma*sigma/2
    wg = np.exp(-ksq*sigmasqby2)
    tsq = getTSquare(psf)
    weight = wg*tsq

    # Deconvolve image
    ftdeconvolved = ftimage / ftpsf * weight

    # Build moment matrix
    moments = [np.ones((stampSize,stampSize)), 1J*kx, 1J*ky, ksq, kxsq - kysq, 2*kx*ky]
    M = np.array([x.flatten() for x in moments])

    # Integral over ksq is essentially just a dot product between the moment matrix
    # and the deconvolved image
    dk = kx[0,0]-kx[0,1]
    dksq = dk*dk
    return dksq*M.dot(ftdeconvolved.flatten())

def main():

    # Parse command-line args.
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--sigma', type = float, default = 1.,
            help = 'Weight function size')
    bashes.great3.Observation.addArgs(parser)
    args = parser.parse_args()

    # Initialize the GREAT3 observation we will analyze.
    obs = bashes.great3.Observation(**bashes.great3.Observation.fromArgs(args))

    # Load the postage stamps to analyze.
    dataStamps = obs.getImage()
    data = dataStamps.getStamp(0,0)

    # Load the constant PSF stamp to use for the analysis.
    psfModel = obs.createPSF(0)

    features = getFeatures(image=data,psfModel=psfModel,sigma=args.sigma)

    print '%10s %12s %12s' % ('feature', 'real', 'imag')

    def printFeature(label, feature):
        print '%10s %12.6g %12.6g' % (label, feature.real, feature.imag)

    printFeature('M_I', features[0])
    printFeature('M_x', features[1])
    printFeature('M_y', features[2])
    printFeature('M_r', features[3])
    printFeature('M_+', features[4])
    printFeature('M_x', features[5])

if __name__ == '__main__':
    main()
<commit_msg>generalize circularize function<commit_after>#!/usr/bin/env python

import argparse
import math

import numpy as np

import galsim
import bashes

def fourierMatrix(n):
    """
    Returns the fourier transform matrix for a square 2d matrix of size n.
    """
    i,j = np.meshgrid(np.arange(n), np.arange(n))
    A = np.multiply.outer(i.flatten(), i.flatten())
    B = np.multiply.outer(j.flatten(), j.flatten())
    omega = np.exp(-2*np.pi*1J/n)
    return np.power(omega, A+B)

def circularize(t):
    """
    Returns the azimuthally average of the provided 2d matrix.
    """
    import scipy.ndimage
    import scipy.interpolate
    # average over theta
    sx, sy = t.shape
    X, Y = np.ogrid[0:sx, 0:sy]
    r = np.hypot(X - sx/2 + 0.5, Y - sy/2 + 0.5)
    rbin = r.astype(np.int)
    tAvg = scipy.ndimage.mean(t, labels=rbin, index=np.arange(0, rbin.max()+1))
    # build 2d representation
    tAvgInterp = scipy.interpolate.InterpolatedUnivariateSpline(np.arange(len(tAvg)),tAvg)
    tAvg2d = tAvgInterp(r.flatten()).reshape(sx,sy)
    return tAvg2d

def getFeatures(image, psfModel, sigma):
    """
    Returns the Fourier moment features of the provided image.
    """
    # Get stamp size/scale
    stampSize = image.xmax - image.xmin + 1
    pixelScale = image.scale

    # Fourier transform image
    ftimage = np.fft.fft2(image.array)

    # Render psf and fourier transform
    psf = bashes.utility.render(psfModel,scale=pixelScale,size=stampSize)
    ftpsf = np.fft.fft2(psf.array)

    # k grid
    kx,ky = np.meshgrid(np.fft.fftfreq(stampSize),np.fft.fftfreq(stampSize))
    kxsq = kx*kx
    kysq = ky*ky
    ksq = kxsq + kysq

    # Build weight function
    sigmasqby2 = sigma*sigma/2
    wg = np.exp(-ksq*sigmasqby2)
    tSq = (np.conjugate(ftpsf)*ftpsf).real
    tSqCircle = np.fft.fftshift(circularize(np.fft.fftshift(tSq)))
    weight = wg*tSqCircle

    # Deconvolve image
    ftdeconvolved = ftimage / ftpsf * weight

    # Build moment matrix
    moments = [np.ones((stampSize,stampSize)), 1J*kx, 1J*ky, ksq, kxsq - kysq, 2*kx*ky]
    M = np.array([x.flatten() for x in moments])

    # Integral over ksq is essentially just a dot product between the moment matrix
    # and the deconvolved image
    dk = kx[0,0]-kx[0,1]
    dksq = dk*dk
    return dksq*M.dot(ftdeconvolved.flatten())

def main():

    # Parse command-line args.
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--sigma', type = float, default = 1.,
            help = 'Weight function size')
    bashes.great3.Observation.addArgs(parser)
    args = parser.parse_args()

    # Initialize the GREAT3 observation we will analyze.
    obs = bashes.great3.Observation(**bashes.great3.Observation.fromArgs(args))

    # Load the postage stamps to analyze.
    dataStamps = obs.getImage()
    data = dataStamps.getStamp(0,0)

    # Load the constant PSF stamp to use for the analysis.
    psfModel = obs.createPSF(0)

    features = getFeatures(image=data,psfModel=psfModel,sigma=args.sigma)

    print '%10s %12s %12s' % ('feature', 'real', 'imag')

    def printFeature(label, feature):
        print '%10s %12.6g %12.6g' % (label, feature.real, feature.imag)

    printFeature('M_I', features[0])
    printFeature('M_x', features[1])
    printFeature('M_y', features[2])
    printFeature('M_r', features[3])
    printFeature('M_+', features[4])
    printFeature('M_x', features[5])

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os
import select
import signal
import socket
import sys
import time

from conary.lib import util
from rmake import errors

class LogFile(object):

    def __init__(self, path, mode='a'):
        self.fd = None
        self.tee = None
        self.stdout = None
        self.open(path, mode)

    def __del__(self):
        if self.fd:
            self.close()

    def open(self, path, mode):
        if isinstance(path, int):
            logfd = path
        else:
            util.mkdirChain(os.path.dirname(path))
            logfd = os.open(path, os.O_CREAT | os.O_APPEND | os.O_WRONLY)
        self.fd = logfd

    def write(self, data):
        os.write(self.fd, data)

    def close(self):
        if self.stdout:
            self.restoreOutput()
        if self.fd:
            file = os.fdopen(self.fd, 'w')
            file.flush()
            file.close()
            self.fd = None
        if self.tee:
            self.tee.close()
            self.tee = None

    def teeOutput(self):
        self.tee = Tee()
        outFile = self.tee.tee(self.fd, sys.stdout.fileno())
        os.close(self.fd)
        self.fd = outFile
        self.redirectOutput()

    def redirectOutput(self, close=False):
        sys.stdout.flush()
        sys.stderr.flush()
        if not close:
            self.stdout = os.dup(sys.stdout.fileno())
            self.stderr = os.dup(sys.stderr.fileno())

        os.dup2(self.fd, sys.stdout.fileno())
        os.dup2(self.fd, sys.stderr.fileno())

    def logToPort(self, host, port, key=None):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
        if key:
            s.send(key + '\n')
            status = s.recv(3)
            if status != 'OK\n':
                raise errors.ServerError("Could not connect to socket")
        socketFd = s.fileno()
        self.tee = Tee()
        outFile = self.tee.tee(self.fd, socketFd)
        os.close(self.fd)
        self.fd = outFile
        self.redirectOutput()

    def restoreOutput(self):
        sys.stdout.flush()
        sys.stderr.flush()
        os.dup2(self.stdout, sys.stdout.fileno())
        os.dup2(self.stderr, sys.stderr.fileno())
        os.close(self.stdout)
        os.close(self.stderr)
        self.stdout = None
        self.stderr = None

class Tee(object):
    def __init__(self):
        self.pid = None

    def __del__(self):
        if self.pid:
            self.close()

    def close(self):
        if self.pid:
            pid = self.pid
            self.pid = None
            os.waitpid(pid, 0)

    def tee(self, out1, out2):
        inFile, outFile = os.pipe()
        self.outFile = outFile
        self.pid = os.fork()
        if self.pid:
            os.close(inFile)
            return outFile
        for fd in range(3,256):
            if fd in (inFile, out1, out2):
                continue
            try:
                os.close(fd)
            except OSError, e:
                pass
        try:
            BUFFER = 64 * 1024
            while True:
                try:
                    ready = select.select([inFile], [], [])[0]
                except select.error, e:
                    continue
                rv = os.read(inFile, BUFFER)
                if not rv:
                    break
                os.write(out1, rv)
                os.write(out2, rv)
        finally:
            os._exit(0)
<commit_msg>Add setproctitle call to logfile.Tee<commit_after>#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os
import select
import signal
import socket
import sys
import time

from conary.lib import util
from rmake import errors

class LogFile(object):

    def __init__(self, path, mode='a'):
        self.fd = None
        self.tee = None
        self.stdout = None
        self.open(path, mode)

    def __del__(self):
        if self.fd:
            self.close()

    def open(self, path, mode):
        if isinstance(path, int):
            logfd = path
        else:
            util.mkdirChain(os.path.dirname(path))
            logfd = os.open(path, os.O_CREAT | os.O_APPEND | os.O_WRONLY)
        self.fd = logfd

    def write(self, data):
        os.write(self.fd, data)

    def close(self):
        if self.stdout:
            self.restoreOutput()
        if self.fd:
            file = os.fdopen(self.fd, 'w')
            file.flush()
            file.close()
            self.fd = None
        if self.tee:
            self.tee.close()
            self.tee = None

    def teeOutput(self):
        self.tee = Tee()
        outFile = self.tee.tee(self.fd, sys.stdout.fileno())
        os.close(self.fd)
        self.fd = outFile
        self.redirectOutput()

    def redirectOutput(self, close=False):
        sys.stdout.flush()
        sys.stderr.flush()
        if not close:
            self.stdout = os.dup(sys.stdout.fileno())
            self.stderr = os.dup(sys.stderr.fileno())

        os.dup2(self.fd, sys.stdout.fileno())
        os.dup2(self.fd, sys.stderr.fileno())

    def logToPort(self, host, port, key=None):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
        if key:
            s.send(key + '\n')
            status = s.recv(3)
            if status != 'OK\n':
                raise errors.ServerError("Could not connect to socket")
        socketFd = s.fileno()
        self.tee = Tee()
        outFile = self.tee.tee(self.fd, socketFd)
        os.close(self.fd)
        self.fd = outFile
        self.redirectOutput()

    def restoreOutput(self):
        sys.stdout.flush()
        sys.stderr.flush()
        os.dup2(self.stdout, sys.stdout.fileno())
        os.dup2(self.stderr, sys.stderr.fileno())
        os.close(self.stdout)
        os.close(self.stderr)
        self.stdout = None
        self.stderr = None

class Tee(object):
    def __init__(self):
        self.pid = None

    def __del__(self):
        if self.pid:
            self.close()

    def close(self):
        if self.pid:
            pid = self.pid
            self.pid = None
            os.waitpid(pid, 0)

    def tee(self, out1, out2):
        inFile, outFile = os.pipe()
        self.outFile = outFile
        self.pid = os.fork()
        if self.pid:
            os.close(inFile)
            return outFile
        for fd in range(3,256):
            if fd in (inFile, out1, out2):
                continue
            try:
                os.close(fd)
            except OSError, e:
                pass
        try:
            from rmake.lib import osutil
            osutil.setproctitle('rmake logger')
        except:
            pass
        try:
            BUFFER = 64 * 1024
            while True:
                try:
                    ready = select.select([inFile], [], [])[0]
                except select.error, e:
                    continue
                rv = os.read(inFile, BUFFER)
                if not rv:
                    break
                os.write(out1, rv)
                os.write(out2, rv)
        finally:
            os._exit(0)
<|endoftext|>