<commit_before>"""
Date of Creation: 28th August 2015.

Description:    Join two data tables using a key field in both

Copyright (C) 2015
Philip J. Uren

Authors: Philip J. Uren

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""

# standard python imports
import sys
import unittest
import StringIO

# for unit tests
import mock

# pyokit imports
from pyokit.io.fastqIterators import fastqIterator
from pyokit.interface.cli import CLI, Option

###############################################################################
#                                  CONSTANTS                                  #
###############################################################################

DEFAULT_VERBOSITY = False

###############################################################################
#                               USER INTERFACE                                #
###############################################################################

def getUI(prog_name, args):
  longDescription = "compute the nucleotide frequency at each position in " +\
                    "a fastq file"
  shortDescription = longDescription

  ui = CLI(prog_name, shortDescription, longDescription)
  ui.minArgs = 1
  ui.maxArgs = 1
  ui.addOption(Option(short="o", long="output", argName="filename",
                      description="output resultant table to this file. " +
                                  "If omitted, output is to stdout",
                      required=False, type=str))
  ui.addOption(Option(short="h", long="help",
                      description="show this help message ", special=True))
  ui.addOption(Option(short="v", long="verbose",
                      description="outputs additional messages to stdout " +
                                  "about run (default: " +
                                  str(DEFAULT_VERBOSITY) + ")",
                      default=DEFAULT_VERBOSITY, required=False))
  ui.addOption(Option(short="u", long="test",
                      description="run unit tests ", special=True))

  ui.parseCommandLine(args)
  return ui

###############################################################################
#                     COMMAND LINE PROCESSING AND DISPATCH                    #
###############################################################################

def _main(args, prog_name):
  # get options and arguments
  ui = getUI(prog_name, args)

  # just run unit tests
  if ui.optionIsSet("test"):
    unittest.main(argv=[sys.argv[0]])
    sys.exit()

  # just show help
  if ui.optionIsSet("help"):
    ui.usage()
    sys.exit()
  verbose = (ui.optionIsSet("verbose") is True) or DEFAULT_VERBOSITY

  # get input handles -- we required one args, so we know these will be here.
  infh = open(ui.getArgument(0))

  # make output handle
  outfh = sys.stdout
  if ui.optionIsSet("output"):
    outfh = open(ui.getValue("output"), "w")

  counts = count(infh, verbose)
  write_output(counts, outfh)

###############################################################################
#                             MAIN PROGRAM LOGIC                              #
###############################################################################

def count(fn, verbose=False):
  res = []
  for read in fastqIterator(fn, verbose=verbose, allowNameMissmatch=True):
    for i in range(0, len(read)):
      nuc = read[i]
      if len(res) <= i:
        res.append({})
      if nuc not in res[i]:
        res[i][nuc] = 0
      res[i][nuc] += 1
  return res

def write_output(counts, outfh):
  for i in range(0, len(counts)):
    kys = counts[i].keys()
    kys.sort()
    for nuc in counts[i]:
      outfh.write(str(i) + "\t" + str(nuc) + "\t" + str(counts[i][nuc]) + "\n")

###############################################################################
#                         UNIT TESTS FOR THIS MODULE                          #
###############################################################################

def build_mock_open_side_effect(string_d, stream_d):
  """
  Build a mock open side effect using a dictionary of content for the files.

  :param string_d: keys are file names, values are string file contents
  :param stream_d: keys are file names, values are stream of contents
  """
  assert(len(set(string_d.keys()).intersection(set(stream_d.keys()))) == 0)

  def mock_open_side_effect(*args, **kwargs):
    if args[0] in string_d:
      return StringIO.StringIO(string_d[args[0]])
    elif args[0] in stream_d:
      return stream_d[args[0]]
    else:
      raise IOError("No such file: " + args[0])
  return mock_open_side_effect

class TestNucDist(unittest.TestCase):

  @mock.patch('__builtin__.open')
  def test_simple(self, mock_open):
    out_strm = StringIO.StringIO()
    f = "@700156R:635:C7RW1ACXX:8:1101:1499:2065 2:N:0:41\n" +\
        "ACGAC\n" +\
        "+\n" +\
        "B<<BB\n" +\
        "@700156R:635:C7RW1ACXX:8:1101:1421:2159 2:N:0:41\n" +\
        "TCGAC\n" +\
        "+\n" +\
        "<B0BF\n"

    f_map = {"in.fq": f}
    streams = {"out.dat": out_strm}
    mock_open.side_effect = build_mock_open_side_effect(f_map, streams)

    _main(["-o", "out.dat", "in.fq"], sys.argv[0])
    expect = "\n".join(["\t".join(["0", "A", "1"]),
                        "\t".join(["0", "T", "1"]),
                        "\t".join(["1", "C", "2"]),
                        "\t".join(["2", "G", "2"]),
                        "\t".join(["3", "A", "2"]),
                        "\t".join(["4", "C", "2"])])
    self.assertEqual(expect + "\n", out_strm.getvalue())

###############################################################################
#              MAIN ENTRY POINT WHEN RUN AS STAND-ALONE MODULE                #
###############################################################################

if __name__ == "__main__":
  try:
    _main(sys.argv[1:], sys.argv[0])
  except Exception as e:
    sys.stderr.write("An unexpected exception occurred. Details: " + str(e) +
                     " \n")
<commit_msg>removed redundant code for mock open from nucDist script<commit_after>"""
Date of Creation: 28th August 2015.

Description:    Join two data tables using a key field in both

Copyright (C) 2015
Philip J. Uren

Authors: Philip J. Uren

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""

# standard python imports
import sys
import unittest
import StringIO

# for unit tests
import mock

# pyokit imports
from pyokit.io.fastqIterators import fastqIterator
from pyokit.interface.cli import CLI, Option
from pyokit.util.testing import build_mock_open_side_effect

###############################################################################
#                                  CONSTANTS                                  #
###############################################################################

DEFAULT_VERBOSITY = False

###############################################################################
#                               USER INTERFACE                                #
###############################################################################

def getUI(prog_name, args):
  longDescription = "compute the nucleotide frequency at each position in " +\
                    "a fastq file"
  shortDescription = longDescription

  ui = CLI(prog_name, shortDescription, longDescription)
  ui.minArgs = 1
  ui.maxArgs = 1
  ui.addOption(Option(short="o", long="output", argName="filename",
                      description="output resultant table to this file. " +
                                  "If omitted, output is to stdout",
                      required=False, type=str))
  ui.addOption(Option(short="h", long="help",
                      description="show this help message ", special=True))
  ui.addOption(Option(short="v", long="verbose",
                      description="outputs additional messages to stdout " +
                                  "about run (default: " +
                                  str(DEFAULT_VERBOSITY) + ")",
                      default=DEFAULT_VERBOSITY, required=False))
  ui.addOption(Option(short="u", long="test",
                      description="run unit tests ", special=True))

  ui.parseCommandLine(args)
  return ui

###############################################################################
#                     COMMAND LINE PROCESSING AND DISPATCH                    #
###############################################################################

def _main(args, prog_name):
  # get options and arguments
  ui = getUI(prog_name, args)

  # just run unit tests
  if ui.optionIsSet("test"):
    unittest.main(argv=[sys.argv[0]])
    sys.exit()

  # just show help
  if ui.optionIsSet("help"):
    ui.usage()
    sys.exit()
  verbose = (ui.optionIsSet("verbose") is True) or DEFAULT_VERBOSITY

  # get input handles -- we required one args, so we know these will be here.
  infh = open(ui.getArgument(0))

  # make output handle
  outfh = sys.stdout
  if ui.optionIsSet("output"):
    outfh = open(ui.getValue("output"), "w")

  counts = count(infh, verbose)
  write_output(counts, outfh)

###############################################################################
#                             MAIN PROGRAM LOGIC                              #
###############################################################################

def count(fn, verbose=False):
  res = []
  for read in fastqIterator(fn, verbose=verbose, allowNameMissmatch=True):
    for i in range(0, len(read)):
      nuc = read[i]
      if len(res) <= i:
        res.append({})
      if nuc not in res[i]:
        res[i][nuc] = 0
      res[i][nuc] += 1
  return res

def write_output(counts, outfh):
  for i in range(0, len(counts)):
    kys = counts[i].keys()
    kys.sort()
    for nuc in counts[i]:
      outfh.write(str(i) + "\t" + str(nuc) + "\t" + str(counts[i][nuc]) + "\n")

###############################################################################
#                         UNIT TESTS FOR THIS MODULE                          #
###############################################################################

class TestNucDist(unittest.TestCase):

  @mock.patch('__builtin__.open')
  def test_simple(self, mock_open):
    out_strm = StringIO.StringIO()
    f = "@700156R:635:C7RW1ACXX:8:1101:1499:2065 2:N:0:41\n" +\
        "ACGAC\n" +\
        "+\n" +\
        "B<<BB\n" +\
        "@700156R:635:C7RW1ACXX:8:1101:1421:2159 2:N:0:41\n" +\
        "TCGAC\n" +\
        "+\n" +\
        "<B0BF\n"

    f_map = {"in.fq": f}
    streams = {"out.dat": out_strm}
    mock_open.side_effect = build_mock_open_side_effect(f_map, streams)

    _main(["-o", "out.dat", "in.fq"], sys.argv[0])
    expect = "\n".join(["\t".join(["0", "A", "1"]),
                        "\t".join(["0", "T", "1"]),
                        "\t".join(["1", "C", "2"]),
                        "\t".join(["2", "G", "2"]),
                        "\t".join(["3", "A", "2"]),
                        "\t".join(["4", "C", "2"])])
    self.assertEqual(expect + "\n", out_strm.getvalue())

###############################################################################
#              MAIN ENTRY POINT WHEN RUN AS STAND-ALONE MODULE                #
###############################################################################

if __name__ == "__main__":
  try:
    _main(sys.argv[1:], sys.argv[0])
  except Exception as e:
    sys.stderr.write("An unexpected exception occurred. Details: " + str(e) +
                     " \n")
<|endoftext|>


<commit_before>import unittest

from malcolm.core import Process
from malcolm.modules.system.controllers import ProcessController
from malcolm.modules.system.defines import redirector_iocs

import cothread
from cothread import catools
import time
import os
import subprocess
from math import floor

from malcolm import __version__

class TestProcessController(unittest.TestCase):
    prefix = "unitTest:%s" % floor(time.time()).__repr__()[:-2]

    def setUp(self):
        self.process = Process("proc")
        self.o = ProcessController("MyMRI", self.prefix, "/tmp")
        self.process.add_controller(self.o)
        self.process.start()
        self.b = self.process.block_view("MyMRI")

    def tearDown(self):
        self.process.stop(timeout=2)

    def test_sets_stats(self):
        # In unit tests, this depends on where the test-runner is run from
        assert self.b.pymalcolmVer.value in ["Work", __version__]
        hostname = os.uname()[1]
        hostname = hostname if len(hostname) < 39 else hostname[:35] + '...'
        assert self.b.hostname.value == hostname

    def test_starts_ioc(self):
        cothread.Sleep(5)
        assert catools.caget(self.prefix + ":PYMALCOLM:VER") in ["Work",
                                                                 __version__]

    def test_ioc_ticks(self):
        cothread.Sleep(5)
        uptime = catools.caget(self.prefix + ":UPTIME:RAW")
        assert uptime >= 0
        time.sleep(5)
        assert catools.caget(self.prefix + ":UPTIME:RAW") >= uptime + 5

class TestParseYamlVersion(unittest.TestCase):
    def setUp(self):
        try:
            os.mkdir('/tmp/prod')
        except OSError:
            pass
        self.testArea = '/tmp/prod/testpath-' + \
                        floor(time.time()).__repr__()[:-2]
        os.mkdir(self.testArea)
        self.cwd = os.getcwd()

        self.obj = ProcessController("", "", "/tmp")

    def tearDown(self):
        os.chdir(self.cwd)
        print(['rm', '-rf', self.testArea])
        subprocess.call(['rm', '-rf', self.testArea])
        os.rmdir('/tmp/prod')

    def test_simple_path_parse(self):
        assert self.obj.parse_yaml_version('/not/work/or/prod/something.yaml',
                                  '/tmp/work/',
                                  '/tmp/prod') == 'unknown'
        assert self.obj.parse_yaml_version('/tmp/work/something.yaml', '/tmp/work/',
                                  '/tmp/prod') == 'Work'
        assert self.obj.parse_yaml_version(self.testArea + '/something.yaml',
                                  '/tmp/work/',
                                  self.testArea) == 'Prod (unknown version)'

    def test_git_tag_parse(self):
        os.chdir(self.testArea)
        subprocess.call(['/usr/bin/git', 'init'])
        with open(self.testArea + '/something.yaml', 'w') as test_file:
            test_file.write('''\
- hello.world:
    state: True
    test: 'passing'
''')
        subprocess.call(['/usr/bin/git', 'add', '*'])
        subprocess.call(['/usr/bin/git', 'commit', '-m', 'testing'])
        subprocess.call(['/usr/bin/git', 'tag', 'TEST_VER'])
        assert self.obj.parse_yaml_version(self.testArea + '/something.yaml',
                                  '/tmp/work/',
                                  self.testArea) == 'TEST_VER'

class TestParseRedirectTable(unittest.TestCase):
    def setUp(self):
        try:
            os.mkdir('/tmp/redirector')
        except OSError:
            pass
        self.testArea = '/tmp/redirector/testpath-' + \
                        floor(time.time()).__repr__()[:-2]
        os.mkdir(self.testArea)
        self.cwd = os.getcwd()
        with open(self.testArea + '/redirect_table', 'w') as table:
            table.writelines([
                'TS01I-EA-IOC-01 anyarbitrarystringhere\n',
                'TS01I-gui thisshouldntmatchourregexp\n',
                'ME99P-XX-IOC-99 butthisoneshould\n',
                'TS01I-TS-IOC-69 foobarbaz\n',
                'TS01J-XY-IOC-07 splat\n',
                'TS10I-AB-IOC-01 bang\n'
            ])

    def tearDown(self):
        os.chdir(self.cwd)
        subprocess.call(['rm', '-rf', self.testArea])
        os.rmdir('/tmp/redirector')

    def test_parse(self):
        list0 = redirector_iocs("", 'TS01I-ML-TEST', self.testArea + '/redirect_table').value.split(" ")[:-1]
        list1 = redirector_iocs("", 'ME99P-ML-TEST', self.testArea + '/redirect_table').value.split(" ")[:-1]
        assert len(list0) == 2
        assert list0[0] == "TS01I-EA-IOC-01"
        assert list0[1] == "TS01I-TS-IOC-69"
        assert len(list1) == 1
        assert list1[0] == "ME99P-XX-IOC-99"

<commit_msg>updated unit test<commit_after>import unittest

from malcolm.core import Process
from malcolm.modules.system.controllers import ProcessController
from malcolm.modules.system.defines import redirector_iocs

import cothread
from cothread import catools
import time
import os
import subprocess
from math import floor

from malcolm import __version__

class TestProcessController(unittest.TestCase):
    prefix = "unitTest:%s" % floor(time.time()).__repr__()[:-2]

    def setUp(self):
        self.process = Process("proc")
        self.o = ProcessController("MyMRI", self.prefix, "/tmp")
        self.process.add_controller(self.o)
        self.process.start()
        self.b = self.process.block_view("MyMRI")

    def tearDown(self):
        self.process.stop(timeout=2)

    def test_sets_stats(self):
        # In unit tests, this depends on where the test-runner is run from
        assert self.b.pymalcolmVer.value in ["work", __version__]
        hostname = os.uname()[1]
        hostname = hostname if len(hostname) < 39 else hostname[:35] + '...'
        assert self.b.hostname.value == hostname

    def test_starts_ioc(self):
        cothread.Sleep(5)
        assert catools.caget(self.prefix + ":PYMALCOLM:VER") in ["work",
                                                                 __version__]

    def test_ioc_ticks(self):
        cothread.Sleep(5)
        uptime = catools.caget(self.prefix + ":UPTIME:RAW")
        assert uptime >= 0
        time.sleep(5)
        assert catools.caget(self.prefix + ":UPTIME:RAW") >= uptime + 5

class TestParseYamlVersion(unittest.TestCase):
    def setUp(self):
        try:
            os.mkdir('/tmp/prod')
        except OSError:
            pass
        self.testArea = '/tmp/prod/testpath-' + \
                        floor(time.time()).__repr__()[:-2]
        os.mkdir(self.testArea)
        self.cwd = os.getcwd()

        self.obj = ProcessController("", "", "/tmp")

    def tearDown(self):
        os.chdir(self.cwd)
        print(['rm', '-rf', self.testArea])
        subprocess.call(['rm', '-rf', self.testArea])
        os.rmdir('/tmp/prod')

    def test_simple_path_parse(self):
        assert self.obj.parse_yaml_version('/not/work/or/prod/something.yaml',
                                  '/tmp/work/',
                                  '/tmp/prod') == 'unknown'
        assert self.obj.parse_yaml_version('/tmp/work/something.yaml', '/tmp/work/',
                                  '/tmp/prod') == 'work'
        assert self.obj.parse_yaml_version(self.testArea + '/something.yaml',
                                  '/tmp/work/',
                                  self.testArea) == 'Prod (unknown version)'

    def test_git_tag_parse(self):
        os.chdir(self.testArea)
        subprocess.call(['/usr/bin/git', 'init'])
        with open(self.testArea + '/something.yaml', 'w') as test_file:
            test_file.write('''\
- hello.world:
    state: True
    test: 'passing'
''')
        subprocess.call(['/usr/bin/git', 'add', '*'])
        subprocess.call(['/usr/bin/git', 'commit', '-m', 'testing'])
        subprocess.call(['/usr/bin/git', 'tag', 'TEST_VER'])
        assert self.obj.parse_yaml_version(self.testArea + '/something.yaml',
                                  '/tmp/work/',
                                  self.testArea) == 'TEST_VER'

class TestParseRedirectTable(unittest.TestCase):
    def setUp(self):
        try:
            os.mkdir('/tmp/redirector')
        except OSError:
            pass
        self.testArea = '/tmp/redirector/testpath-' + \
                        floor(time.time()).__repr__()[:-2]
        os.mkdir(self.testArea)
        self.cwd = os.getcwd()
        with open(self.testArea + '/redirect_table', 'w') as table:
            table.writelines([
                'TS01I-EA-IOC-01 anyarbitrarystringhere\n',
                'TS01I-gui thisshouldntmatchourregexp\n',
                'ME99P-XX-IOC-99 butthisoneshould\n',
                'TS01I-TS-IOC-69 foobarbaz\n',
                'TS01J-XY-IOC-07 splat\n',
                'TS10I-AB-IOC-01 bang\n'
            ])

    def tearDown(self):
        os.chdir(self.cwd)
        subprocess.call(['rm', '-rf', self.testArea])
        os.rmdir('/tmp/redirector')

    def test_parse(self):
        list0 = redirector_iocs("", 'TS01I-ML-TEST', self.testArea + '/redirect_table').value.split(" ")[:-1]
        list1 = redirector_iocs("", 'ME99P-ML-TEST', self.testArea + '/redirect_table').value.split(" ")[:-1]
        assert len(list0) == 2
        assert list0[0] == "TS01I-EA-IOC-01"
        assert list0[1] == "TS01I-TS-IOC-69"
        assert len(list1) == 1
        assert list1[0] == "ME99P-XX-IOC-99"

<|endoftext|>


<commit_before># -*- encoding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv

class lunch_cashbox_clean(osv.osv_memory):

     _name = "lunch.cashbox.clean"
     _description = "clean cashbox"

     def set_to_zero(self, cr, uid, ids, context):
         """
         clean Cashbox. set active fields False.
         @param cr: the current row, from the database cursor,
         @param uid: the current user’s ID for security checks,
         @param ids: List  Lunch cashbox Clean’s IDs
         @return:Dictionary {}.
         """
         cashmove_ref = self.pool.get('lunch.cashmove')
         cr.execute("select user_cashmove, box,sum(amount) from lunch_cashmove where active = 't' and box in (%s) group by user_cashmove, box" % ','.join(map(str, context['active_ids'])))
         res = cr.fetchall()
         cr.execute("update lunch_cashmove set active = 'f' where active= 't' and box in (%s)" % ','.join(map(str, context['active_ids'])))
##    to_unactive= {}.fromkeys([r[0] for r in cr.fetchall]).keys()
##    print to_unactive
##    cashmove_ref.write(cr,uid,to_unactive,{'active':False})
         for (user_id, box_id, amount) in res:
            cashmove_ref.createcr, uid, {'name': 'Summary for user' + str(user_id),
                        'amount': amount,
                        'user_cashmove': user_id,
                        'box': box_id,
                        'active': True,
                        })
         return {}

lunch_cashbox_clean()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<commit_msg>[IMP]:lunch: Added missing bracket in cashbox clean<commit_after># -*- encoding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields, osv

class lunch_cashbox_clean(osv.osv_memory):

     _name = "lunch.cashbox.clean"
     _description = "clean cashbox"

     def set_to_zero(self, cr, uid, ids, context):
         """
         clean Cashbox. set active fields False.
         @param cr: the current row, from the database cursor,
         @param uid: the current user’s ID for security checks,
         @param ids: List  Lunch cashbox Clean’s IDs
         @return:Dictionary {}.
         """
         cashmove_ref = self.pool.get('lunch.cashmove')
         cr.execute("select user_cashmove, box,sum(amount) from lunch_cashmove where active = 't' and box in (%s) group by user_cashmove, box" % ','.join(map(str, context['active_ids'])))
         res = cr.fetchall()
         cr.execute("update lunch_cashmove set active = 'f' where active= 't' and box in (%s)" % ','.join(map(str, context['active_ids'])))
##    to_unactive= {}.fromkeys([r[0] for r in cr.fetchall]).keys()
##    print to_unactive
##    cashmove_ref.write(cr,uid,to_unactive,{'active':False})
         for (user_id, box_id, amount) in res:
            cashmove_ref.create(cr, uid, {'name': 'Summary for user' + str(user_id),
                        'amount': amount,
                        'user_cashmove': user_id,
                        'box': box_id,
                        'active': True,
                        })
         return {}

lunch_cashbox_clean()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<|endoftext|>


<commit_before>
import base64
import json
import urllib.request
import uuid

import numpy

__all__ = ['URL', 'image', 'images', 'plot']

URL = 'http://localhost:8000/events'

def uid():
  return 'pane_%s' % uuid.uuid4()

def send(**command):
  command = json.dumps(command)
  req = urllib.request.Request(URL, method='POST')
  req.add_header('Content-Type', 'application/json')
  req.data = command.encode('ascii')
  try:
    resp = urllib.request.urlopen(req)
    return resp != None
  except:
    raise
    return False

def encode_png(buf, width, height):
  """ buf: must be bytes or a bytearray in py3, a regular string in py2. formatted RGBRGB... """
  import zlib, struct, itertools
  assert (width * height * 3 == len(buf))
  bpp = 3
  # reverse the vertical line order and add null bytes at the start
  width_bytes = width * bpp
  # TODO: make a generetar
  #raw_data = b''.join(b'\x00' + buf[span:span + width_byte_4]
  #    for span in range((height - 1) * width * 4, -1, - width_byte_4))
  def raw_data():
    for span in range((height - 1) * width * bpp, -1, - width_bytes):
      yield b'\x00'
      yield buf[span:span + width_bytes]

  def png_pack(png_tag, data):
    chunk_head = png_tag + data
    return b''.join([
        struct.pack("!I", len(data)),
        chunk_head,
        struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
      ])

  COLOR_TYPE_RGB = 2
  COLOR_TYPE_RGBA = 6
  bit_depth = 8
  return b''.join([
      b'\x89PNG\r\n\x1a\n',
      png_pack(b'IHDR', struct.pack("!2I5B", width, height, bit_depth, COLOR_TYPE_RGB, 0, 0, 0)),
      png_pack(b'IDAT', zlib.compress(b''.join(raw_data()), 9)),
      png_pack(b'IEND', b'')
    ])

def normalize(img, opts):
  minval = opts.get('min')
  if minval is None:
    minval = numpy.amin(img)
  maxval = opts.get('max')
  if maxval is None:
    maxval = numpy.amax(img)

  return numpy.uint8((img - minval) * (255/(maxval - minval)))

def to_rgb(img):
  nchannels = img.shape[2] if img.ndim == 3 else 1
  if nchannels == 3:
    return img
  if nchannels == 1:
    return img[:, :, numpy.newaxis].repeat(3, axis=2)
  raise ValueError('Image must be RGB or gray-scale')

def image(img, **opts):
  assert img.ndim == 2 or img.ndim == 3
  win = opts.get('win') or uid()

  if isinstance(img, list):
    return images(img, opts)
  # TODO: if img is a 3d tensor, then unstack it into a list of images

  img = to_rgb(normalize(img, opts))
  pngbytes = encode_png(img.tostring(), img.shape[1], img.shape[0])
  imgdata = 'data:image/png;base64,' + base64.b64encode(pngbytes).decode('ascii')

  send(command='image', id=win, src=imgdata,
    labels=opts.get('labels'),
    width=opts.get('width'),
    title=opts.get('title'))
  return win

def images(images, **opts):
  # TODO: need to merge images into a single canvas
  raise Exception('Not implemented')

def plot(data, **opts):
  """ Plot data as line chart.
  Params:
    data: either a 2-d numpy array or a list of lists.
    win: pane id
    labels: list of series names, first series is always the X-axis
    see http://dygraphs.com/options.html for other supported options
  """
  win = opts.get('win') or uid()

  dataset = {}
  if type(data).__module__ == numpy.__name__:
    dataset = data.tolist()
  else:
    dataset = data

  # clone opts into options
  options = dict(opts)
  options['file'] = dataset
  if options.get('labels'):
    options['xlabel'] = options['labels'][0]

  # Don't pass our options to dygraphs.
  options.pop('win', None)

  send(command='plot', id=win, title=opts.get('title'), options=options)
  return win

<commit_msg>cleanup<commit_after>
import base64
import json
import urllib.request
import uuid

import numpy

__all__ = ['URL', 'image', 'images', 'plot']

URL = 'http://localhost:8000/events'

def uid():
  return 'pane_%s' % uuid.uuid4()

def send(**command):
  command = json.dumps(command)
  req = urllib.request.Request(URL, method='POST')
  req.add_header('Content-Type', 'application/json')
  req.data = command.encode('ascii')
  try:
    resp = urllib.request.urlopen(req)
    return resp != None
  except:
    raise
    return False

def encode_png(buf, width, height):
  """ buf: must be bytes or a bytearray in py3, a regular string in py2. formatted RGBRGB... """
  import zlib, struct, itertools
  assert (width * height * 3 == len(buf))
  bpp = 3

  def raw_data():
    # reverse the vertical line order and add null bytes at the start
    width_bytes = width * bpp
    for span in range((height - 1) * width * bpp, -1, - width_bytes):
      yield b'\x00'
      yield buf[span:span + width_bytes]

  def png_pack(png_tag, data):
    chunk_head = png_tag + data
    return b''.join([
        struct.pack("!I", len(data)),
        chunk_head,
        struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
      ])

  COLOR_TYPE_RGB = 2
  COLOR_TYPE_RGBA = 6
  bit_depth = 8
  return b''.join([
      b'\x89PNG\r\n\x1a\n',
      png_pack(b'IHDR', struct.pack("!2I5B", width, height, bit_depth, COLOR_TYPE_RGB, 0, 0, 0)),
      png_pack(b'IDAT', zlib.compress(b''.join(raw_data()), 9)),
      png_pack(b'IEND', b'')
    ])

def normalize(img, opts):
  minval = opts.get('min')
  if minval is None:
    minval = numpy.amin(img)
  maxval = opts.get('max')
  if maxval is None:
    maxval = numpy.amax(img)

  return numpy.uint8((img - minval) * (255/(maxval - minval)))

def to_rgb(img):
  nchannels = img.shape[2] if img.ndim == 3 else 1
  if nchannels == 3:
    return img
  if nchannels == 1:
    return img[:, :, numpy.newaxis].repeat(3, axis=2)
  raise ValueError('Image must be RGB or gray-scale')

def image(img, **opts):
  assert img.ndim == 2 or img.ndim == 3
  win = opts.get('win') or uid()

  if isinstance(img, list):
    return images(img, opts)
  # TODO: if img is a 3d tensor, then unstack it into a list of images

  img = to_rgb(normalize(img, opts))
  pngbytes = encode_png(img.tostring(), img.shape[1], img.shape[0])
  imgdata = 'data:image/png;base64,' + base64.b64encode(pngbytes).decode('ascii')

  send(command='image', id=win, src=imgdata,
    labels=opts.get('labels'),
    width=opts.get('width'),
    title=opts.get('title'))
  return win

def images(images, **opts):
  # TODO: need to merge images into a single canvas
  raise Exception('Not implemented')

def plot(data, **opts):
  """ Plot data as line chart.
  Params:
    data: either a 2-d numpy array or a list of lists.
    win: pane id
    labels: list of series names, first series is always the X-axis
    see http://dygraphs.com/options.html for other supported options
  """
  win = opts.get('win') or uid()

  dataset = {}
  if type(data).__module__ == numpy.__name__:
    dataset = data.tolist()
  else:
    dataset = data

  # clone opts into options
  options = dict(opts)
  options['file'] = dataset
  if options.get('labels'):
    options['xlabel'] = options['labels'][0]

  # Don't pass our options to dygraphs.
  options.pop('win', None)

  send(command='plot', id=win, title=opts.get('title'), options=options)
  return win

<|endoftext|>


<commit_before>"""
Django settings for py3learn project.

Generated by 'django-admin startproject' using Django 1.9.6.

For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/
"""

import os

import dj_database_url

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ["SECRET_KEY"]

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ['test-py3learn.herokuapp.com']

# Application definition

INSTALLED_APPS = [
    'learn.apps.LearnConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'py3learn.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'py3learn.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Europe/Paris'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
STATIC_URL = '/static/'

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
    os.path.join(PROJECT_ROOT, '../learn/static'),
)

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

X_FRAME_OPTIONS = 'DENY'
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 1
SECURE_HSTS_INCLUDE_SUBDOMAINS = True

DATABASES['default'] = dj_database_url.config()
<commit_msg>allows staging and production site<commit_after>"""
Django settings for py3learn project.

Generated by 'django-admin startproject' using Django 1.9.6.

For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/
"""

import os

import dj_database_url

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ["SECRET_KEY"]

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ['test-py3learn.herokuapp.com', 'py3learn.herokuapp.com']

# Application definition

INSTALLED_APPS = [
    'learn.apps.LearnConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'py3learn.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'py3learn.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Europe/Paris'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
STATIC_URL = '/static/'

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
    os.path.join(PROJECT_ROOT, '../learn/static'),
)

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

X_FRAME_OPTIONS = 'DENY'
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 1
SECURE_HSTS_INCLUDE_SUBDOMAINS = True

DATABASES['default'] = dj_database_url.config()
<|endoftext|>


<commit_before>from __future__ import division, absolute_import, print_function
from past.builtins import xrange

import esutil
import fitsio
import healpy as hp
import numpy as np
from scipy.special import erf

from .catalog import Catalog,Entry
from .utilities import TOTAL_SQDEG, SEC_PER_DEG, astro_to_sphere, calc_theta_i, apply_errormodels

class Mask(object):
    """
    A super-class for (pixelized) footprint masks

    This should not be instantiated directly (yet).

    parameters
    ----------
    config: Config object
       configuration
    """

    # note: not sure how to organize this.
    #   We need a routine that looks at the mask_mode and instantiates
    #   the correct type.  How is this typically done?

    def __init__(self, config):
        try:
            self.read_maskgals(config.maskgalfile)
        except:
            # this could throw a ValueError or AttributeError
            self.gen_maskgals()

    def calc_radmask(self, *args, **kwargs): pass
    def read_maskgals(self, maskgalfile):
        self.maskgals = Catalog.from_fits_file(maskgalfile)
    def gen_maskgals(self):
        # this needs to be written to generate maskgals if not from file
        # Tom-where would we generate them from?
        pass

    def set_radmask(self, cluster, mpcscale):
        """
        Assign mask (0/1) values to maskgals for a given cluster

        parameters
        ----------
        cluster: Cluster object
        mpcscale: float
            scaling to go from mpc to degrees (check units) at cluster redshift

        results
        -------
        sets maskgals.mark

        """

        # note this probably can be in the superclass, no?
        ras = cluster.ra + self.maskgals.x/(mpcscale*SEC_PER_DEG)/np.cos(np.radians(cluster.dec))
        decs = cluster.dec + self.maskgals.y/(mpcscale*SEC_PER_DEG)
        self.maskgals.mark = self.compute_radmask(ras,decs)

    def calc_maskcorr(self, mstar, maxmag, limmag):
        """
        Obtain mask correction c parameters. From calclambda_chisq_calc_maskcorr.pro

        parameters
        ----------
        maskgals : Object holding mask galaxy parameters
        mstar    :
        maxmag   : Maximum magnitude
        limmag   : Limiting Magnitude
        config  : Configuration object
                    containing configuration info

        returns
        -------
        cpars

        """

        mag_in = self.maskgals.m + mstar
        self.maskgals.refmag = mag_in

        if self.maskgals.limmag[0] > 0.0:
            mag, mag_err = apply_errormodels(self.maskgals, mag_in)

            self.maskgals.refmag_obs = mag
            self.maskgals.refmag_obs_err = mag_err
        else:
            mag = mag_in
            mag_err = 0*mag_in
            raise ValueError('Survey limiting magnitude <= 0!')
            #Raise error here as this would lead to divide by zero if called.

        #extract object for testing
        #fitsio.write('test_data.fits', self.maskgals._ndarray)

        if (self.maskgals.w[0] < 0) or (self.maskgals.w[0] == 0 and
            np.amax(self.maskgals.m50) == 0):
            theta_i = calc_theta_i(mag, mag_err, maxmag, limmag)
        elif (self.maskgals.w[0] == 0):
            theta_i = calc_theta_i(mag, mag_err, maxmag, self.maskgals.m50)
        else:
            raise Exception('Unsupported mode!')

        p_det = theta_i*self.maskgals.mark
        np.set_printoptions(threshold=np.nan)
        c = 1 - np.dot(p_det, self.maskgals.theta_r) / self.maskgals.nin[0]

        cpars = np.polyfit(self.maskgals.radbins[0], c, 3)

        return cpars

class HPMask(Mask):
    """
    A class to use a healpix mask (mask_mode == 3)

    parameters
    ----------
    config: Config object
        Configuration object with maskfile

    """

    def __init__(self, config):
        # record for posterity
        self.maskfile = config.maskfile
        maskinfo, hdr = fitsio.read(config.maskfile, ext=1, header=True)
        # maskinfo converted to a catalog (array of Entrys)
        maskinfo = Catalog(maskinfo)
        nside_mask = hdr['NSIDE']
        nest = hdr['NEST']

        hpix_ring = maskinfo.hpix if nest != 1 else hp.nest2ring(nside_mask, maskinfo.hpix)

        # if we have a sub-region of the sky, cut down the mask to save memory
        if config.hpix > 0:
            print("I'm here!")
            border = np.radians(config.border) + hp.nside2resol(nside_mask)
            theta, phi = hp.pix2ang(config.nside, config.hpix)
            radius = np.sqrt(2) * (hp.nside2resol(config.nside)/2. + border)
            pixint = hp.query_disc(nside_mask, hp.ang2vec(theta, phi),
                                   radius, inclusive=False)
            suba, subb = esutil.numpy_util.match(pixint, hpix_ring)
            hpix_ring = hpix_ring[subb]
            muse = subb
        else:
            print("No, I'm here.")
            muse = np.arange(hpix_ring.size, dtype='i4')

        offset, ntot = np.min(hpix_ring)-1, np.max(hpix_ring)-np.min(hpix_ring)+3
        self.nside = nside_mask
        self.offset = offset
        self.npix = ntot

        #ntot = np.max(hpix_ring) - np.min(hpix_ring) + 3
        self.fracgood = np.zeros(ntot,dtype='f4')

        # check if we have a fracgood in the input maskinfo
        try:
            self.fracgood_float = 1
            self.fracgood[hpix_ring-offset] = maskinfo[muse].fracgood
        except AttributeError:
            self.fracgood_float = 0
            self.fracgood[hpix_ring-offset] = 1
        super(HPMask, self).__init__(config)

    def compute_radmask(self, ra, dec):
        """
        Determine if a given set of ra/dec points are in or out of mask

        parameters
        ----------
        ra: array of doubles
        dec: array of doubles

        returns
        -------
        radmask: array of booleans

        """
        _ra  = np.atleast_1d(ra)
        _dec = np.atleast_1d(dec)

        if (_ra.size != _dec.size):
            raise ValueError("ra, dec must be same length")

        theta, phi = astro_to_sphere(_ra, _dec)
        ipring = hp.ang2pix(self.nside, theta, phi)
        ipring_offset = np.clip(ipring - self.offset, 0, self.npix-1)
        ref = 0 if self.fracgood_float == 0 else np.random.rand(_ra.size)
        radmask = np.zeros(_ra.size, dtype=np.bool_)
        radmask[np.where(self.fracgood[ipring_offset] > ref)] = True
        return radmask

def get_mask(config):
    """
    Convenience function to look at a config file and load the appropriate type of mask.

    parameters
    ----------
    config: Config object
        Configuration object with maskfile
    """

    if config.mask_mode == 0:
        # This is no mask!
        # Return a bare object with maskgal functionality
        return Mask(config)
    elif config.mask_mode == 3:
        # This is a healpix mask
        #  (don't ask about 1 and 2)
        return HPMask(config)

<commit_msg>Simplify call to set_radmask()<commit_after>from __future__ import division, absolute_import, print_function
from past.builtins import xrange

import esutil
import fitsio
import healpy as hp
import numpy as np
from scipy.special import erf

from .catalog import Catalog,Entry
from .utilities import TOTAL_SQDEG, SEC_PER_DEG, astro_to_sphere, calc_theta_i, apply_errormodels

class Mask(object):
    """
    A super-class for (pixelized) footprint masks

    This should not be instantiated directly (yet).

    parameters
    ----------
    config: Config object
       configuration
    """

    # note: not sure how to organize this.
    #   We need a routine that looks at the mask_mode and instantiates
    #   the correct type.  How is this typically done?

    def __init__(self, config):
        try:
            self.read_maskgals(config.maskgalfile)
        except:
            # this could throw a ValueError or AttributeError
            self.gen_maskgals()

    def calc_radmask(self, *args, **kwargs): pass
    def read_maskgals(self, maskgalfile):
        self.maskgals = Catalog.from_fits_file(maskgalfile)
    def gen_maskgals(self):
        # this needs to be written to generate maskgals if not from file
        # Tom-where would we generate them from?
        pass

    def set_radmask(self, cluster):
        """
        Assign mask (0/1) values to maskgals for a given cluster

        parameters
        ----------
        cluster: Cluster object

        results
        -------
        sets maskgals.mark

        """

        # note this probably can be in the superclass, no?
        ras = cluster.ra + self.maskgals.x/(cluster.mpc_scale*SEC_PER_DEG)/np.cos(np.radians(cluster.dec))
        decs = cluster.dec + self.maskgals.y/(cluster.mpc_scale*SEC_PER_DEG)
        self.maskgals.mark = self.compute_radmask(ras,decs)

    def calc_maskcorr(self, mstar, maxmag, limmag):
        """
        Obtain mask correction c parameters. From calclambda_chisq_calc_maskcorr.pro

        parameters
        ----------
        maskgals : Object holding mask galaxy parameters
        mstar    :
        maxmag   : Maximum magnitude
        limmag   : Limiting Magnitude
        config  : Configuration object
                    containing configuration info

        returns
        -------
        cpars

        """

        mag_in = self.maskgals.m + mstar
        self.maskgals.refmag = mag_in

        if self.maskgals.limmag[0] > 0.0:
            mag, mag_err = apply_errormodels(self.maskgals, mag_in)

            self.maskgals.refmag_obs = mag
            self.maskgals.refmag_obs_err = mag_err
        else:
            mag = mag_in
            mag_err = 0*mag_in
            raise ValueError('Survey limiting magnitude <= 0!')
            #Raise error here as this would lead to divide by zero if called.

        #extract object for testing
        #fitsio.write('test_data.fits', self.maskgals._ndarray)

        if (self.maskgals.w[0] < 0) or (self.maskgals.w[0] == 0 and
            np.amax(self.maskgals.m50) == 0):
            theta_i = calc_theta_i(mag, mag_err, maxmag, limmag)
        elif (self.maskgals.w[0] == 0):
            theta_i = calc_theta_i(mag, mag_err, maxmag, self.maskgals.m50)
        else:
            raise Exception('Unsupported mode!')

        p_det = theta_i*self.maskgals.mark
        np.set_printoptions(threshold=np.nan)
        c = 1 - np.dot(p_det, self.maskgals.theta_r) / self.maskgals.nin[0]

        cpars = np.polyfit(self.maskgals.radbins[0], c, 3)

        return cpars

class HPMask(Mask):
    """
    A class to use a healpix mask (mask_mode == 3)

    parameters
    ----------
    config: Config object
        Configuration object with maskfile

    """

    def __init__(self, config):
        # record for posterity
        self.maskfile = config.maskfile
        maskinfo, hdr = fitsio.read(config.maskfile, ext=1, header=True)
        # maskinfo converted to a catalog (array of Entrys)
        maskinfo = Catalog(maskinfo)
        nside_mask = hdr['NSIDE']
        nest = hdr['NEST']

        hpix_ring = maskinfo.hpix if nest != 1 else hp.nest2ring(nside_mask, maskinfo.hpix)

        # if we have a sub-region of the sky, cut down the mask to save memory
        if config.hpix > 0:
            border = np.radians(config.border) + hp.nside2resol(nside_mask)
            theta, phi = hp.pix2ang(config.nside, config.hpix)
            radius = np.sqrt(2) * (hp.nside2resol(config.nside)/2. + border)
            pixint = hp.query_disc(nside_mask, hp.ang2vec(theta, phi),
                                   radius, inclusive=False)
            suba, subb = esutil.numpy_util.match(pixint, hpix_ring)
            hpix_ring = hpix_ring[subb]
            muse = subb
        else:
            muse = np.arange(hpix_ring.size, dtype='i4')

        offset, ntot = np.min(hpix_ring)-1, np.max(hpix_ring)-np.min(hpix_ring)+3
        self.nside = nside_mask
        self.offset = offset
        self.npix = ntot

        #ntot = np.max(hpix_ring) - np.min(hpix_ring) + 3
        self.fracgood = np.zeros(ntot,dtype='f4')

        # check if we have a fracgood in the input maskinfo
        try:
            self.fracgood_float = 1
            self.fracgood[hpix_ring-offset] = maskinfo[muse].fracgood
        except AttributeError:
            self.fracgood_float = 0
            self.fracgood[hpix_ring-offset] = 1
        super(HPMask, self).__init__(config)

    def compute_radmask(self, ra, dec):
        """
        Determine if a given set of ra/dec points are in or out of mask

        parameters
        ----------
        ra: array of doubles
        dec: array of doubles

        returns
        -------
        radmask: array of booleans

        """
        _ra  = np.atleast_1d(ra)
        _dec = np.atleast_1d(dec)

        if (_ra.size != _dec.size):
            raise ValueError("ra, dec must be same length")

        theta, phi = astro_to_sphere(_ra, _dec)
        ipring = hp.ang2pix(self.nside, theta, phi)
        ipring_offset = np.clip(ipring - self.offset, 0, self.npix-1)
        ref = 0 if self.fracgood_float == 0 else np.random.rand(_ra.size)
        radmask = np.zeros(_ra.size, dtype=np.bool_)
        radmask[np.where(self.fracgood[ipring_offset] > ref)] = True
        return radmask

def get_mask(config):
    """
    Convenience function to look at a config file and load the appropriate type of mask.

    parameters
    ----------
    config: Config object
        Configuration object with maskfile
    """

    if config.mask_mode == 0:
        # This is no mask!
        # Return a bare object with maskgal functionality
        return Mask(config)
    elif config.mask_mode == 3:
        # This is a healpix mask
        #  (don't ask about 1 and 2)
        return HPMask(config)

<|endoftext|>


<commit_before>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  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 inspect

from robot import utils
from robot.errors import DataError
from robot.common import BaseLibrary
from robot.output import LOGGER

from handlers import Handler, InitHandler, DynamicHandler

if utils.is_jython:
    from org.python.core import PyReflectedFunction, PyReflectedConstructor
    from java.lang import Object
else:
    Object = None

def TestLibrary(name, args=None, variables=None, create_handlers=True):
    libcode, source = utils.import_(name)
    libclass = _get_lib_class(libcode)
    lib = libclass(libcode, source, name, args or [], variables)
    if create_handlers:
        lib.create_handlers()
    return lib

def _get_lib_class(libcode):
    if inspect.ismodule(libcode):
        return _ModuleLibrary
    if _DynamicMethod(libcode, 'get_keyword_names'):
        if _DynamicMethod(libcode, 'run_keyword'):
            return _DynamicLibrary
        else:
            return _HybridLibrary
    return _ClassLibrary

class _DynamicMethod(object):

    def __init__(self, libcode, underscore_name, default=None):
        self._method = self._get_method(libcode, underscore_name)
        self._default = default

    def __call__(self, *args):
        return self._method(*args) if self._method else self._default

    def __nonzero__(self):
        return self._method is not None

    def _get_method(self, libcode, underscore_name):
        for name in underscore_name, self._getCamelCaseName(underscore_name):
            method = getattr(libcode, name, None)
            if callable(method):
                return method
            return None

    def _getCamelCaseName(self, underscore_name):
        tokens = underscore_name.split('_')
        return ''.join([tokens[0]] + [t.capitalize() for t in tokens[1:]])

class _BaseTestLibrary(BaseLibrary):
    supports_named_arguments = False # this attribute is for libdoc
    _log_success = LOGGER.debug
    _log_failure = LOGGER.info
    _log_failure_details = LOGGER.debug

    def __init__(self, libcode, source, name, args, variables):
        if os.path.exists(name):
            name = os.path.splitext(os.path.basename(os.path.normpath(name)))[0]
        self.source = source
        self.version = self._get_version(libcode)
        self.name = name
        self.orig_name = name # Stores original name also after copying
        self.positional_args = []
        self.named_args = {}
        self._instance_cache = []
        self._libinst = None
        if libcode is not None:
            self.doc = inspect.getdoc(libcode) or ''
            self.scope = self._get_scope(libcode)
            self._libcode = libcode
            self.init =  self._create_init_handler(libcode)
            self.positional_args, self.named_args = self.init.arguments.resolve(args, variables)

    def create_handlers(self):
        if self._libcode:
            self._libinst = self.get_instance()
            self.handlers = self._create_handlers(self._libinst)
            self.init_scope_handling()

    def start_suite(self):
        pass

    def end_suite(self):
        pass

    def start_test(self):
        pass

    def end_test(self):
        pass

    def _get_version(self, code):
        try:
            return str(code.ROBOT_LIBRARY_VERSION)
        except AttributeError:
            try:
                return str(code.__version__)
            except AttributeError:
                return '<unknown>'

    def _create_init_handler(self, libcode):
        init_method =  getattr(libcode, '__init__', None)
        if not self._valid_init(init_method):
            init_method = None
        return InitHandler(self, init_method)

    def _valid_init(self, init_method):
        if inspect.ismethod(init_method):
            return True
        if utils.is_jython and isinstance(init_method, PyReflectedConstructor):
            return True
        return False

    def init_scope_handling(self):
        if self.scope == 'GLOBAL':
            return
        self._libinst = None
        self.start_suite = self._caching_start
        self.end_suite = self._restoring_end
        if self.scope == 'TESTCASE':
            self.start_test = self._caching_start
            self.end_test = self._restoring_end

    def _caching_start(self):
        self._instance_cache.append(self._libinst)
        self._libinst = None

    def _restoring_end(self):
        self._libinst = self._instance_cache.pop()

    def _get_scope(self, libcode):
        try:
            scope = libcode.ROBOT_LIBRARY_SCOPE
            scope = utils.normalize(scope, ignore=['_']).upper()
        except (AttributeError, TypeError):
            scope = 'TESTCASE'
        return scope if scope in ['GLOBAL','TESTSUITE'] else 'TESTCASE'

    def get_instance(self):
        if self._libinst is None:
            self._libinst = self._get_instance()
        return self._libinst

    def _get_instance(self):
        try:
            return self._libcode(*self.positional_args, **self.named_args)
        except:
            self._raise_creating_instance_failed()

    def _create_handlers(self, libcode):
        handlers = utils.NormalizedDict(ignore=['_'])
        for name in self._get_handler_names(libcode):
            method = self._try_to_get_handler_method(libcode, name)
            if method:
                handler = self._try_to_create_handler(name, method)
                if handler:
                    handlers[name] = handler
                    self._log_success("Created keyword '%s'" % handler.name)
        return handlers

    def _get_handler_names(self, libcode):
        return [name for name in dir(libcode)
                if not name.startswith(('_', 'ROBOT_LIBRARY_'))]

    def _try_to_get_handler_method(self, libcode, name):
        pre = "Adding keyword '%s' to library '%s' failed: " % (name, self.name)
        try:
            return self._get_handler_method(libcode, name)
        except DataError, err:
            self._log_failure(pre + unicode(err))
        except:
            msg, details = utils.get_error_details()
            self._log_failure(pre + 'Getting handler method failed: ' + msg)
            self._log_failure_details('Details:\n' + details)

    def _get_handler_method(self, libcode, name):
        method = getattr(libcode, name)
        if not inspect.isroutine(method):
            raise DataError('Not a method or function')
        return method

    def _try_to_create_handler(self, name, method):
        pre = "Adding keyword '%s' to library '%s' failed: " % (name, self.name)
        try:
            return self._create_handler(name, method)
        except:
            msg, details = utils.get_error_details()
            self._log_failure(pre + 'Creating keyword failed: ' + msg)
            self._log_failure_details('Details:\n%s' % details)

    def _create_handler(self, handler_name, handler_method):
        return Handler(self, handler_name, handler_method)

    def _raise_creating_instance_failed(self):
        msg, details = utils.get_error_details()
        if self.positional_args:
            args = "argument%s %s" % (utils.plural_or_not(self.positional_args),
                                      utils.seq2str(self.positional_args))
        else:
            args = "no arguments"
        raise DataError("Creating an instance of the test library '%s' with %s "
                        "failed: %s\n%s" % (self.name, args, msg, details))

class _ClassLibrary(_BaseTestLibrary):
    supports_named_arguments = True # this attribute is for libdoc

    def _get_handler_method(self, libinst, name):
        # Type is checked before using getattr to avoid calling properties,
        # most importantly bean properties generated by Jython (issue 188).
        for item in (libinst,) + inspect.getmro(libinst.__class__):
            if item in (object, Object):
                continue
            if not (hasattr(item, '__dict__') and name in item.__dict__):
                continue
            self._validate_handler(item.__dict__[name])
            return getattr(libinst, name)
        raise DataError('No non implicit implementation found')

    def _validate_handler(self, handler):
        if not self._is_routine(handler):
            raise DataError('Not a method or function')
        if self._is_implicit_java_or_jython_method(handler):
            raise DataError('Implicit methods are ignored')

    def _is_routine(self, handler):
        # inspect.isroutine doesn't work with methods from Java classes
        # prior to Jython 2.5.2: http://bugs.jython.org/issue1223
        return inspect.isroutine(handler) or self._is_java_method(handler)

    def _is_java_method(self, handler):
        return utils.is_jython and isinstance(handler, PyReflectedFunction)

    def _is_implicit_java_or_jython_method(self, handler):
        if not self._is_java_method(handler):
            return False
        for signature in handler.argslist[:handler.nargs]:
            cls = signature.declaringClass
            if not (cls is Object or self._is_created_by_jython(handler, cls)):
                return False
        return True

    def _is_created_by_jython(self, handler, cls):
        proxy_methods = getattr(cls, '__supernames__', []) + ['classDictInit']
        return handler.__name__ in proxy_methods

class _ModuleLibrary(_BaseTestLibrary):
    supports_named_arguments = True # this attribute is for libdoc

    def _get_scope(self, libcode):
        return 'GLOBAL'

    def _get_handler_method(self, libcode, name):
        method = _BaseTestLibrary._get_handler_method(self, libcode, name)
        if hasattr(libcode, '__all__') and name not in libcode.__all__:
            raise DataError('Not exposed as keyword')
        return method

    def get_instance(self):
        self.init.arguments.check_arg_limits(self.positional_args)
        return self._libcode

    def _create_init_handler(self, libcode):
        return InitHandler(self, None)

class _HybridLibrary(_BaseTestLibrary):
    _log_failure = LOGGER.warn

    def _get_handler_names(self, instance):
        try:
            return instance.get_keyword_names()
        except AttributeError:
            return instance.getKeywordNames()

class _DynamicLibrary(_BaseTestLibrary):

    def __init__(self, libcode, source, name, args, variables=None):
        _BaseTestLibrary.__init__(self, libcode, source, name, args, variables)
        self._get_kw_doc = \
            _DynamicMethod(libcode, 'get_keyword_documentation', default='')
        self._get_kw_args = \
            _DynamicMethod(libcode, 'get_keyword_arguments', default=None)

    def _get_handler_names(self, instance):
        try:
            return instance.get_keyword_names()
        except AttributeError:
            return instance.getKeywordNames()

    def _get_handler_method(self, instance, name_is_ignored):
        try:
            return instance.run_keyword
        except AttributeError:
            return instance.runKeyword

    def _create_handler(self, handler_name, handler_method):
        doc = self._get_kw_doc(self._libinst, handler_name)
        argspec = self._get_kw_args(self._libinst, handler_name)
        return DynamicHandler(self, handler_name, handler_method, doc, argspec)
<commit_msg>Refactored reporting errors when creating keywords fail and made failures when creating dynamic keywords warnings.<commit_after>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  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 inspect

from robot import utils
from robot.errors import DataError
from robot.common import BaseLibrary
from robot.output import LOGGER

from handlers import Handler, InitHandler, DynamicHandler

if utils.is_jython:
    from org.python.core import PyReflectedFunction, PyReflectedConstructor
    from java.lang import Object
else:
    Object = None

def TestLibrary(name, args=None, variables=None, create_handlers=True):
    libcode, source = utils.import_(name)
    libclass = _get_lib_class(libcode)
    lib = libclass(libcode, source, name, args or [], variables)
    if create_handlers:
        lib.create_handlers()
    return lib

def _get_lib_class(libcode):
    if inspect.ismodule(libcode):
        return _ModuleLibrary
    if _DynamicMethod(libcode, 'get_keyword_names'):
        if _DynamicMethod(libcode, 'run_keyword'):
            return _DynamicLibrary
        else:
            return _HybridLibrary
    return _ClassLibrary

class _DynamicMethod(object):

    def __init__(self, libcode, underscore_name, default=None):
        self._method = self._get_method(libcode, underscore_name)
        self._default = default

    def __call__(self, *args):
        if not self._method:
            return self._default
        try:
            return self._method(*args)
        except:
            raise DataError("Calling dynamic method '%s' failed: %s"
                            % (self._method.__name__, utils.get_error_message()))

    def __nonzero__(self):
        return self._method is not None

    def _get_method(self, libcode, underscore_name):
        for name in underscore_name, self._getCamelCaseName(underscore_name):
            method = getattr(libcode, name, None)
            if callable(method):
                return method
        return None

    def _getCamelCaseName(self, underscore_name):
        tokens = underscore_name.split('_')
        return ''.join([tokens[0]] + [t.capitalize() for t in tokens[1:]])

class _BaseTestLibrary(BaseLibrary):
    supports_named_arguments = False # this attribute is for libdoc
    _log_success = LOGGER.debug
    _log_failure = LOGGER.info
    _log_failure_details = LOGGER.debug

    def __init__(self, libcode, source, name, args, variables):
        if os.path.exists(name):
            name = os.path.splitext(os.path.basename(os.path.normpath(name)))[0]
        self.source = source
        self.version = self._get_version(libcode)
        self.name = name
        self.orig_name = name # Stores original name also after copying
        self.positional_args = []
        self.named_args = {}
        self._instance_cache = []
        self._libinst = None
        if libcode is not None:
            self.doc = inspect.getdoc(libcode) or ''
            self.scope = self._get_scope(libcode)
            self._libcode = libcode
            self.init =  self._create_init_handler(libcode)
            self.positional_args, self.named_args = self.init.arguments.resolve(args, variables)

    def create_handlers(self):
        if self._libcode:
            self._libinst = self.get_instance()
            self.handlers = self._create_handlers(self._libinst)
            self.init_scope_handling()

    def start_suite(self):
        pass

    def end_suite(self):
        pass

    def start_test(self):
        pass

    def end_test(self):
        pass

    def _get_version(self, code):
        try:
            return str(code.ROBOT_LIBRARY_VERSION)
        except AttributeError:
            try:
                return str(code.__version__)
            except AttributeError:
                return '<unknown>'

    def _create_init_handler(self, libcode):
        init_method =  getattr(libcode, '__init__', None)
        if not self._valid_init(init_method):
            init_method = None
        return InitHandler(self, init_method)

    def _valid_init(self, init_method):
        if inspect.ismethod(init_method):
            return True
        if utils.is_jython and isinstance(init_method, PyReflectedConstructor):
            return True
        return False

    def init_scope_handling(self):
        if self.scope == 'GLOBAL':
            return
        self._libinst = None
        self.start_suite = self._caching_start
        self.end_suite = self._restoring_end
        if self.scope == 'TESTCASE':
            self.start_test = self._caching_start
            self.end_test = self._restoring_end

    def _caching_start(self):
        self._instance_cache.append(self._libinst)
        self._libinst = None

    def _restoring_end(self):
        self._libinst = self._instance_cache.pop()

    def _get_scope(self, libcode):
        try:
            scope = libcode.ROBOT_LIBRARY_SCOPE
            scope = utils.normalize(scope, ignore=['_']).upper()
        except (AttributeError, TypeError):
            scope = 'TESTCASE'
        return scope if scope in ['GLOBAL','TESTSUITE'] else 'TESTCASE'

    def get_instance(self):
        if self._libinst is None:
            self._libinst = self._get_instance()
        return self._libinst

    def _get_instance(self):
        try:
            return self._libcode(*self.positional_args, **self.named_args)
        except:
            self._raise_creating_instance_failed()

    def _create_handlers(self, libcode):
        handlers = utils.NormalizedDict(ignore=['_'])
        for name in self._get_handler_names(libcode):
            method = self._try_to_get_handler_method(libcode, name)
            if method:
                handler = self._try_to_create_handler(name, method)
                if handler:
                    handlers[name] = handler
                    self._log_success("Created keyword '%s'" % handler.name)
        return handlers

    def _get_handler_names(self, libcode):
        return [name for name in dir(libcode)
                if not name.startswith(('_', 'ROBOT_LIBRARY_'))]

    def _try_to_get_handler_method(self, libcode, name):
        try:
            return self._get_handler_method(libcode, name)
        except:
            self._report_adding_keyword_failed(name)

    def _report_adding_keyword_failed(self, name):
        msg, details = utils.get_error_details()
        self._log_failure("Adding keyword '%s' to library '%s' failed: %s"
                          % (name, self.name, msg))
        if details:
            self._log_failure_details('Details:\n%s' % details)

    def _get_handler_method(self, libcode, name):
        method = getattr(libcode, name)
        if not inspect.isroutine(method):
            raise DataError('Not a method or function')
        return method

    def _try_to_create_handler(self, name, method):
        try:
            return self._create_handler(name, method)
        except:
            self._report_adding_keyword_failed(name)

    def _create_handler(self, handler_name, handler_method):
        return Handler(self, handler_name, handler_method)

    def _raise_creating_instance_failed(self):
        msg, details = utils.get_error_details()
        if self.positional_args:
            args = "argument%s %s" % (utils.plural_or_not(self.positional_args),
                                      utils.seq2str(self.positional_args))
        else:
            args = "no arguments"
        raise DataError("Creating an instance of the test library '%s' with %s "
                        "failed: %s\n%s" % (self.name, args, msg, details))

class _ClassLibrary(_BaseTestLibrary):
    supports_named_arguments = True # this attribute is for libdoc

    def _get_handler_method(self, libinst, name):
        # Type is checked before using getattr to avoid calling properties,
        # most importantly bean properties generated by Jython (issue 188).
        for item in (libinst,) + inspect.getmro(libinst.__class__):
            if item in (object, Object):
                continue
            if not (hasattr(item, '__dict__') and name in item.__dict__):
                continue
            self._validate_handler(item.__dict__[name])
            return getattr(libinst, name)
        raise DataError('No non implicit implementation found')

    def _validate_handler(self, handler):
        if not self._is_routine(handler):
            raise DataError('Not a method or function')
        if self._is_implicit_java_or_jython_method(handler):
            raise DataError('Implicit methods are ignored')

    def _is_routine(self, handler):
        # inspect.isroutine doesn't work with methods from Java classes
        # prior to Jython 2.5.2: http://bugs.jython.org/issue1223
        return inspect.isroutine(handler) or self._is_java_method(handler)

    def _is_java_method(self, handler):
        return utils.is_jython and isinstance(handler, PyReflectedFunction)

    def _is_implicit_java_or_jython_method(self, handler):
        if not self._is_java_method(handler):
            return False
        for signature in handler.argslist[:handler.nargs]:
            cls = signature.declaringClass
            if not (cls is Object or self._is_created_by_jython(handler, cls)):
                return False
        return True

    def _is_created_by_jython(self, handler, cls):
        proxy_methods = getattr(cls, '__supernames__', []) + ['classDictInit']
        return handler.__name__ in proxy_methods

class _ModuleLibrary(_BaseTestLibrary):
    supports_named_arguments = True # this attribute is for libdoc

    def _get_scope(self, libcode):
        return 'GLOBAL'

    def _get_handler_method(self, libcode, name):
        method = _BaseTestLibrary._get_handler_method(self, libcode, name)
        if hasattr(libcode, '__all__') and name not in libcode.__all__:
            raise DataError('Not exposed as keyword')
        return method

    def get_instance(self):
        self.init.arguments.check_arg_limits(self.positional_args)
        return self._libcode

    def _create_init_handler(self, libcode):
        return InitHandler(self, None)

class _HybridLibrary(_BaseTestLibrary):
    _log_failure = LOGGER.warn

    def _get_handler_names(self, instance):
        try:
            return instance.get_keyword_names()
        except AttributeError:
            return instance.getKeywordNames()

class _DynamicLibrary(_BaseTestLibrary):
    _log_failure = LOGGER.warn

    def __init__(self, libcode, source, name, args, variables=None):
        _BaseTestLibrary.__init__(self, libcode, source, name, args, variables)
        self._get_kw_doc = \
            _DynamicMethod(libcode, 'get_keyword_documentation', default='')
        self._get_kw_args = \
            _DynamicMethod(libcode, 'get_keyword_arguments', default=None)

    def _get_handler_names(self, instance):
        try:
            return instance.get_keyword_names()
        except AttributeError:
            return instance.getKeywordNames()

    def _get_handler_method(self, instance, name_is_ignored):
        try:
            return instance.run_keyword
        except AttributeError:
            return instance.runKeyword

    def _create_handler(self, handler_name, handler_method):
        doc = self._get_kw_doc(self._libinst, handler_name)
        argspec = self._get_kw_args(self._libinst, handler_name)
        return DynamicHandler(self, handler_name, handler_method, doc, argspec)
<|endoftext|>