<commit_before>'''Conway's Game of Life
'''

from . import Cell

class World(object):
    '''
    The game world is a two dimensional grid, each coordinate is the
    address of a Cell.

    >>> w = World()
    >>> w[0]
    Cell(location=(0,0),...)

    >>> w[x,y]
    Cell(location=(x,y),...)

    >> w.step()
    >> print(w)

    '''

    def __init__(self,CellClass=None,width=80,height=23):
        '''
        '''
        self.generation = 0
        self.width = int(width)
        self.height = int(height)

        if CellClass is None:
            CellClass = Cell

        if not issubclass(CellClass,Cell):
            msg = 'expecting subclass of Cell, got {klass}'
            raise TypeError(msg.format(klass=CellClass))

        self.cellClass = CellClass
        self.reset()

    @property
    def cells(self):
        try:
            return self._cells
        except AttributeError:
            pass
        self._cells = []
        return self._cells

    def __str__(self):
        '''
        '''
        s = []
        for y in range(self.height):
            r = ''
            for x in range(self.width):
                r += str(self[x,y])
            s.append(r)
        return '\n'.join(s)

    def __repr__(self):
        '''
        '''
        msg = '{klass}(CellClass={cellKlass},width={w},height={h})'
        return msg.format(klass = self.__class__.__name__,
                          cellKlass = self.cellClass.__name__,
                          w = self.width,
                          h = self.height)

    def _clamp(self,key):
        '''
        '''

        x,y = key

        if x < 0:
            x = self.width + x
        if x >= self.width:
            x -= self.width

        if y < 0:
            y = self.height + y
        if y >= self.height:
            y -= self.height
        return x,y

    def __getitem__(self,key):
        '''
        :key: tuple, integer or slice
        :return: Cell or list of Cells

        If tuple, it should be a two entry tuple whose first item is
        the X coordinate and the second is the Y coordinate.

        :tuple: returns the Cell at (X,Y)
        :integer: returns the i-th Cell in the list
        :slice: returns Cells or Cell satisfying the slice.

        '''
        try:
            x,y = self._clamp(key)
            return self.cells[(y * self.width)+x]
        except TypeError:
            pass

        return self.cells[key]

    @property
    def alive(self):
        '''
        Returns a list of Cells that are currently alive.
        '''
        return [c for c in self if c.alive]

    @property
    def dead(self):
        '''
        Returns a list of Cells that are currently not alive.
        '''
        return [c for c in self if not c.alive]

    def reset(self):
        '''
        Resets the simulation to base state.
        '''
        self.generation = 0
        self.cells.clear()
        for y in range(self.height):
            row = []
            for x in range(self.width):
                self.cells.append(self.cellClass(x,y))

    def neighborsFor(self,cell):
        '''
        :param: cell - Cell subclass in
        Assuming a
        '''
        return [self[key] for key in cell.neighbors]

    def step(self):
        '''

        '''
        self.generation += 1

        for c in self:
            c.update(sum(self.neighborsFor(c)))

        for c in self:
            c.commit(self.generation)

    def add(self,pattern,x=0,y=0):
        '''
        '''
        for Y,line in enumerate(pattern.split('\n')):
            for X,c in enumerate(line):
                self[x+X,y+Y].alive = not c.isspace()

class WorldOpt(World):

    def reset(self):
        super(WorldOpt,self).reset()
        self.live = set(self.alive)

    def add(self,pattern,x=0,y=0):
        super(WorldOpt,self).add(pattern,x,y)
        self.live = set(self.alive)

    def step(self):
        self.generation += 1

        borders = set()

        for c in self.live:
            neighbors = self.neighborsFor(c)
            borders.update(set(neighbors))

        self.live.update(borders)

        for c in self.live:
            c.update(sum(self.neighborsFor(c)))

        deaders = set()
        for c in self.live:
            c.commit(self.generation)
            if not c.alive:
                deaders.add(c)

        return self.live.difference_update(deaders)
<commit_msg>doc strings, WorldOpt renamed, minor edits<commit_after>from . import Cell

class World(object):
    '''
    The game World is a two dimensional grid populated with Cells.

    >>> w = World()
    >>> w[0]
    Cell(location=(0,0),...)

    >>> w[x,y]
    Cell(location=(x,y),...)

    >> w.step()
    >> print(w)

    '''

    def __init__(self,CellClass=None,width=80,height=23):
        '''
        :param: CellClass - subclass of Cell
        :param: width - integer
        :param: height - integer

        Creates a world populated with cells created with
        the CellClass.  The world is a rectangular grid
        whose dimensions are specified by width and height.

        Will raise a TypeError if the supplied CellClass is
        not a subclass of Cell.

        '''
        self.generation = 0
        self.width = int(width)
        self.height = int(height)

        if CellClass is None:
            CellClass = Cell

        if not issubclass(CellClass,Cell):
            msg = 'expecting subclass of Cell, got {klass}'
            raise TypeError(msg.format(klass=CellClass))

        self.cellClass = CellClass
        self.reset()

    @property
    def cells(self):
        '''
        A list of all Cell objects managed by the world.
        '''
        try:
            return self._cells
        except AttributeError:
            pass
        self._cells = []
        return self._cells

    def __str__(self):
        '''
        '''
        s = []
        for y in range(self.height):
            r = ''
            for x in range(self.width):
                r += str(self[x,y])
            s.append(r)
        return '\n'.join(s)

    def __repr__(self):
        '''
        '''

        s = [ '{self.__class__.__name__}',
              '(CellClass={self.cellClass.__name__},',
              'width={self.width},',
              'height={self.height})']

        return ''.join(s).format(self=self)

    def _clamp(self,key):
        '''
        :param: key - tuple of x,y integer values

        Implements wrapping of x,y coordinates to form an infinite grid.

        '''

        x,y = map(int,key)

        if x < 0:
            x = self.width + x
        if x >= self.width:
            x -= self.width

        if y < 0:
            y = self.height + y
        if y >= self.height:
            y -= self.height

        return x,y

    def __getitem__(self,key):
        '''
        :key: tuple, integer or slice
        :return: Cell or list of Cells

        If tuple, it should be a two entry tuple whose first item is
        the X coordinate and the second is the Y coordinate.

        :tuple: returns the Cell at (X,Y)
        :integer: returns the i-th Cell in the list
        :slice: returns Cells or Cell satisfying the slice.

        '''
        try:
            x,y = self._clamp(key)
            return self.cells[(y * self.width)+x]
        except TypeError:
            pass

        return self.cells[key]

    @property
    def alive(self):
        '''
        Returns a list of Cells that are currently alive.
        '''
        return [c for c in self if c.alive]

    @property
    def dead(self):
        '''
        Returns a list of Cells that are currently not alive.
        '''
        return [c for c in self if not c.alive]

    def reset(self):
        '''
        Resets the simulation to base state:
        - sets generation to zero
        - deletes all cells and allocates a new set cells
        '''
        self.generation = 0
        self.cells.clear()
        for y in range(self.height):
            row = []
            for x in range(self.width):
                self.cells.append(self.cellClass(x,y))

    def neighborsFor(self,cell):
        '''
        :param: cell - Cell subclass

        Returns a list of all cells that are immediate neighbors
        of the target cell.
        '''
        return [self[key] for key in cell.neighbors]

    def step(self):
        '''
        :return: None

        This method advances the simulation one generation.

        First all cells are updated with the current count of alive
        neighbors (which drives the cell state).

        Second all cells are asked to determine their next state.

        '''
        self.generation += 1

        for c in self:
            c.update(sum(self.neighborsFor(c)))

        for c in self:
            c.commit()

    def add(self,pattern,x=0,y=0):
        '''
        :param: pattern - string
        :param: x - integer
        :param: y - integer
        :return: None

        This method uses the pattern string to affect the alive/dead
        state of cells in the world.  The x and y paramters can be used
        to place the pattern at an arbitrary position in the world.

        The first character in the string corresponds to coordinate (0,0).
        '''
        for Y,line in enumerate(pattern.split('\n')):
            for X,c in enumerate(line):
                self[x+X,y+Y].alive = not c.isspace()

class OptimizedWorld(World):
    '''
    The game World is a two dimensional grid populated with Cells.

    >>> w = World()
    >>> w[0]
    Cell(location=(0,0),...)

    >>> w[x,y]
    Cell(location=(x,y),...)

    >> w.step()
    >> print(w)

    This world has an optimized step method that only updates live
    cells and their neighbors rather than all cells, live or dead.
    '''
    def reset(self):
        '''
        Resets the simulation to base state:
        - sets generation to zero
        - deletes all cells and allocates a new set cells
        - creates an empty list of live cells
        '''
        super(OptimizedWorld,self).reset()
        self.live = set(self.alive)

    def add(self,pattern,x=0,y=0):
        '''
        :param: pattern - string
        :param: x - integer
        :param: y - integer
        :return: None

        This method uses the pattern string to affect the alive/dead
        state of cells in the world.  The x and y paramters can be used
        to place the pattern at an arbitrary position in the world.

        The first character in the string corresponds to coordinate (0,0).

        Updates the set of live cells.
        '''
        super(OptimizedWorld,self).add(pattern,x,y)
        self.live = set(self.alive)

    def step(self):
        '''
        :return: current set of live cells

        This method advances the simulation one generation.

        It is optimized to only update cells which are alive and
        their immediate neighbors which results in significant gains
        in preformance compared to the super class' step method.

        Set operations are used to ensure that alive and neighbor
        cells are only visited once during each phase; neighbor
        count and state update.
        '''
        self.generation += 1

        borders = set()

        for c in self.live:
            neighbors = self.neighborsFor(c)
            borders.update(set(neighbors))

        self.live.update(borders)

        for c in self.live:
            c.update(sum(self.neighborsFor(c)))

        deaders = set()
        for c in self.live:
            c.commit()
            if not c.alive:
                deaders.add(c)

        return self.live.difference_update(deaders)
<|endoftext|>


<commit_before>from tempfile import mkdtemp
import shutil
import os
import sys
from cStringIO import StringIO
import posixpath

from django.test import TestCase, Client
from django.conf import settings as django_settings
from django.core.management import call_command

from staticfiles import settings

class TestResolveStatic(TestCase):
    """
    Test ``resolve_static`` management command.

    TODO: test without --first, test STATICFILES_MEDIA_DIRNAMES

    """
    def _get_file(self, filepath):
        _stdout = sys.stdout
        sys.stdout = StringIO()
        try:
            call_command('resolve_static', filepath, all=False, verbosity='0')
            sys.stdout.seek(0)
            contents = open(sys.stdout.read().strip()).read()
        finally:
            sys.stdout = _stdout
        return contents

    def assertFileContains(self, filepath, text):
        self.failUnless(text in self._get_file(filepath),
                        "'%s' not in '%s'" % (text, filepath))

    def assertFileNotFound(self, filepath):
        self.assertRaises(IOError, self._get_file, filepath)

    def test_staticfiles_dirs(self):
        """
        Can find a file in a STATICFILES_DIRS directory.

        """
        self.assertFileContains('test.txt', 'Can we find')

    def test_staticfiles_dirs_subdir(self):
        """
        Can find a file in a subdirectory of a STATICFILES_DIRS
        directory.

        """
        self.assertFileContains('subdir/test.txt', 'Can we find')

    def test_staticfiles_dirs_priority(self):
        """
        File in STATICFILES_DIRS has priority over file in app.

        """
        self.assertFileContains('test/file.txt', 'STATICFILES_DIRS')

    def test_app_files(self):
        """
        Can find a file in an app media/ directory.

        """
        self.assertFileContains('test/file1.txt', 'file1 in the app dir')

    def test_prepend_label_apps(self):
        """
        Can find a file in an app media/ directory using
        STATICFILES_PREPEND_LABEL_APPS.

        """
        self.assertFileContains('no_label/file2.txt', 'file2 in no_label')

    def test_excluded_apps(self):
        """
        Can not find file in an app in STATICFILES_EXCLUDED_APPS.

        """
        self.assertFileNotFound('skip/skip_file.txt')

class TestBuildStatic(TestResolveStatic):
    """
    Test ``build_static`` management command.

    TODO: test -i, -n, -l, --exclude-dirs, --no-default-ignore
          test alternate storages

    """
    def setUp(self):
        self._old_root = settings.ROOT
        self.root = settings.ROOT = mkdtemp()
        call_command('build_static', interactive=False, verbosity='0')

    def tearDown(self):
        shutil.rmtree(self.root)
        settings.ROOT = self._old_root

    def _get_file(self, filepath):
        return open(os.path.join(self.root, filepath)).read()

class TestServeStatic(TestResolveStatic):
    """
    Test static asset serving view.

    """
    def setUp(self):
        self.client = Client()

    def _response(self, url):
        return self.client.get(posixpath.join(settings.URL, url))

    def assertFileContains(self, filepath, text):
        self.assertContains(self._response(filepath), text)

    def assertFileNotFound(self, filepath):
        self.assertEquals(self._response(filepath).status_code, 404)

class TestServeMedia(TestCase):
    """
    Test serving media from MEDIA_URL.

    """
    def test_serve_media(self):
        client = Client()
        response = client.get(posixpath.join(django_settings.MEDIA_URL,
                                             'media-file.txt'))
        self.assertContains(response, 'Media file.')
<commit_msg>refactor tests to prepare for adding missing tests<commit_after>from tempfile import mkdtemp
import shutil
import os
import sys
from cStringIO import StringIO
import posixpath

from django.test import TestCase, Client
from django.conf import settings as django_settings
from django.core.management import call_command

from staticfiles import settings

class BaseFileResolutionTests:
    """
    Tests shared by all file-resolving features (build_static,
    resolve_static, and static serve view).

    """
    def assertFileContains(self, filepath, text):
        self.failUnless(text in self._get_file(filepath),
                        "'%s' not in '%s'" % (text, filepath))

    def assertFileNotFound(self, filepath):
        self.assertRaises(IOError, self._get_file, filepath)

    def test_staticfiles_dirs(self):
        """
        Can find a file in a STATICFILES_DIRS directory.

        """
        self.assertFileContains('test.txt', 'Can we find')

    def test_staticfiles_dirs_subdir(self):
        """
        Can find a file in a subdirectory of a STATICFILES_DIRS
        directory.

        """
        self.assertFileContains('subdir/test.txt', 'Can we find')

    def test_staticfiles_dirs_priority(self):
        """
        File in STATICFILES_DIRS has priority over file in app.

        """
        self.assertFileContains('test/file.txt', 'STATICFILES_DIRS')

    def test_app_files(self):
        """
        Can find a file in an app media/ directory.

        """
        self.assertFileContains('test/file1.txt', 'file1 in the app dir')

    def test_prepend_label_apps(self):
        """
        Can find a file in an app media/ directory using
        STATICFILES_PREPEND_LABEL_APPS.

        """
        self.assertFileContains('no_label/file2.txt', 'file2 in no_label')

    def test_excluded_apps(self):
        """
        Can not find file in an app in STATICFILES_EXCLUDED_APPS.

        """
        self.assertFileNotFound('skip/skip_file.txt')

class TestResolveStatic(TestCase, BaseFileResolutionTests):
    """
    Test ``resolve_static`` management command.

    TODO: test without --first, test STATICFILES_MEDIA_DIRNAMES

    """
    def _get_file(self, filepath):
        _stdout = sys.stdout
        sys.stdout = StringIO()
        try:
            call_command('resolve_static', filepath, all=False, verbosity='0')
            sys.stdout.seek(0)
            contents = open(sys.stdout.read().strip()).read()
        finally:
            sys.stdout = _stdout
        return contents

class TestBuildStatic(TestCase, BaseFileResolutionTests):
    """
    Test ``build_static`` management command.

    TODO: test -i, -n, -l, --exclude-dirs, --no-default-ignore
          test alternate storages

    """
    def setUp(self):
        self._old_root = settings.ROOT
        self.root = settings.ROOT = mkdtemp()
        call_command('build_static', interactive=False, verbosity='0')

    def tearDown(self):
        shutil.rmtree(self.root)
        settings.ROOT = self._old_root

    def _get_file(self, filepath):
        return open(os.path.join(self.root, filepath)).read()

class TestServeStatic(TestCase, BaseFileResolutionTests):
    """
    Test static asset serving view.

    """
    def setUp(self):
        self.client = Client()

    def _response(self, url):
        return self.client.get(posixpath.join(settings.URL, url))

    def assertFileContains(self, filepath, text):
        self.assertContains(self._response(filepath), text)

    def assertFileNotFound(self, filepath):
        self.assertEquals(self._response(filepath).status_code, 404)

class TestServeMedia(TestCase):
    """
    Test serving media from MEDIA_URL.

    """
    def test_serve_media(self):
        client = Client()
        response = client.get(posixpath.join(django_settings.MEDIA_URL,
                                             'media-file.txt'))
        self.assertContains(response, 'Media file.')
<|endoftext|>


<commit_before># -*- coding: utf-8  -*-
__version__ = '$Id$'
import family

# The Anarchopedia family

class Family(family.Family):
    def __init__(self):
        family.Family.__init__(self)
        self.name = 'anarchopedia'

        self.languages_by_size = [
            'ar','sr','da','de','nl','el','en','fa','fi','fr','he','sr','hy','id','it','ja',
            'ko','lv','lit','no','sr','pl','pt','ro','ru','es','sq','sr','sv','tr','zh',
        ]
        for l in self.languages_by_size:
            self.langs[l] = '%s.anarchopedia.org' % l

        self.nocapitalize = self.langs.keys()

        self.obsolete = {
            'ara': 'ar',
            'bos': 'bs',
            'zho': 'zh',
            'dan': 'da',
            'deu': 'de',
            'dut': 'nl',
            'ell': 'el',
            'eng': 'en',
            'epo': 'eo',
            'fas': 'fa',
            'fra': 'fr',
            'fin': 'fi',
            'heb': 'he',
            'ind': 'id',
            'ita': 'it',
            'jpn': 'ja',
            'lit': 'lt',
            'lav': 'lv',
            'nor': 'no',
            'nsh': 'sh',
            'pol': 'pl',
            'por': 'pt',
            'rum': 'ro',
            'rus': 'ru',
            'spa': 'es',
            'srp': 'sr',
            'srp': 'hr',
            'swe': 'sv',
            'kor': 'ko',
            'sqi': 'sq',
            'hye': 'hy',
            'tur': 'tr',

            'ell': 'gre',
            'srp': 'hrv',
            'nno': None,
            'nob': None,
        }

    def version(self, code):
        return "1.14alpha"

    def scriptpath(self, code):
        return ''

    def path(self, code):
        return '/index.php'

    def apipath(self, code):
        return '/api.php'
<commit_msg>minor changes (blank line added/removed)<commit_after># -*- coding: utf-8  -*-
__version__ = '$Id$'

import family

# The Anarchopedia family

class Family(family.Family):
    def __init__(self):
        family.Family.__init__(self)
        self.name = 'anarchopedia'

        self.languages_by_size = [
            'ar','sr','da','de','nl','el','en','fa','fi','fr','he','sr','hy','id','it','ja',
            'ko','lv','lit','no','sr','pl','pt','ro','ru','es','sq','sr','sv','tr','zh',
        ]
        for l in self.languages_by_size:
            self.langs[l] = '%s.anarchopedia.org' % l

        self.nocapitalize = self.langs.keys()

        self.obsolete = {
            'ara': 'ar',
            'bos': 'bs',
            'zho': 'zh',
            'dan': 'da',
            'deu': 'de',
            'dut': 'nl',
            'ell': 'el',
            'eng': 'en',
            'epo': 'eo',
            'fas': 'fa',
            'fra': 'fr',
            'fin': 'fi',
            'heb': 'he',
            'ind': 'id',
            'ita': 'it',
            'jpn': 'ja',
            'lit': 'lt',
            'lav': 'lv',
            'nor': 'no',
            'nsh': 'sh',
            'pol': 'pl',
            'por': 'pt',
            'rum': 'ro',
            'rus': 'ru',
            'spa': 'es',
            'srp': 'sr',
            'srp': 'hr',
            'swe': 'sv',
            'kor': 'ko',
            'sqi': 'sq',
            'hye': 'hy',
            'tur': 'tr',

            'ell': 'gre',
            'srp': 'hrv',
            'nno': None,
            'nob': None,
        }

    def version(self, code):
        return "1.14alpha"

    def scriptpath(self, code):
        return ''

    def path(self, code):
        return '/index.php'

    def apipath(self, code):
        return '/api.php'
<|endoftext|>


<commit_before>from collections import deque
import pdb

from intermol.Atom import *
from intermol.Molecule import *
from intermol.System import System

def readStructure(filename):
    """Read in a Gromacs structure file

    Args:
        filename (str): the file to be read in
    """

    fd = open(filename, 'r')
    lines = list(fd)
    fd.close()

    i = 2
    for moleculetype in System._sys._molecules.values():
        for molecule in moleculetype.moleculeSet:
            for atom in molecule._atoms:
                if lines[i]:
                    atom.residueIndex=int(lines[i][0:5])
                    atom.residueName=lines[i][6:10].strip()
                    atom.atomName=lines[i][11:15].strip()
                    atom.atomIndex=int(lines[i][16:20])
                    position = [None, None, None]
                    position[0]=float(lines[i][20:28]) * units.nanometers
                    position[1]=float(lines[i][28:36]) * units.nanometers
                    position[2]=float(lines[i][36:44]) * units.nanometers
                    atom.setPosition(position[0], position[1], position[2])
                    velocity  = [None, None, None]
                    try:
                        velocity[0]=float(lines[i][44:52]) * units.nanometers / units.picoseconds
                        velocity[1]=float(lines[i][52:60]) * units.nanometers / units.picoseconds
                        velocity[2]=float(lines[i][60:68]) * units.nanometers / units.picoseconds
                    except:
                        velocity[0] = 0.0 * units.nanometers / units.picoseconds
                        velocity[1] = 0.0 * units.nanometers / units.picoseconds
                        velocity[2] = 0.0 * units.nanometers / units.picoseconds
                    atom.setVelocity(velocity[0], velocity[1], velocity[2])
                    i += 1

                else:
                    sys.exit()

    rawBoxVector = lines[i]
    v1x = None
    v2x = None
    v3x = None
    v1y = None
    v2y = None
    v3y = None
    v1z = None
    v2z = None
    v3z = None
    if len(rawBoxVector.split()) == 3:
        v1x = float(rawBoxVector[0:10]) * units.nanometers
        v2x = 0.0 * units.nanometers
        v3x = 0.0 * units.nanometers
        v1y = 0.0 * units.nanometers
        v2y = float(rawBoxVector[11:22]) * units.nanometers
        v3y = 0.0 * units.nanometers
        v1z = 0.0 * units.nanometers
        v2z = 0.0 * units.nanometers
        v3z = float(rawBoxVector[23:34]) * units.nanometers

    elif len(rawBoxVector.split()) == 9:
        v1x = float(rawBoxVector[0:10]) * units.nanometers
        v2x = float(rawBoxVector[11:22]) * units.nanometers
        v3x = float(rawBoxVector[23:34]) * units.nanometers
        v1y = float(rawBoxVector[35:46]) * units.nanometers
        v2y = float(rawBoxVector[47:58]) * units.nanometers
        v3y = float(rawBoxVector[59:70]) * units.nanometers
        v1z = float(rawBoxVector[71:82]) * units.nanometers
        v2z = float(rawBoxVector[83:94]) * units.nanometers
        v3z = float(rawBoxVector[95:106]) * units.nanometers
    System._sys.setBoxVector(v1x, v2x, v3x, v1y, v2y, v3y, v1z, v2z, v3z)

def writeStructure(filename):
    """Write the system out  in a Gromacs 4.5.4 format

    Args:
        filename (str): the file to write out to
    """
    lines = list()
    i=0
    for moleculetype in System._sys._molecules.values():
        for molecule in moleculetype.moleculeSet:
            for atom in molecule._atoms:
                i += 1
                lines.append('%5d%-4s%6s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f\n'
                        %(atom.residueIndex,
                        atom.residueName,
                        atom.atomName,
                        atom.atomIndex,
                        atom._position[0]._value,
                        atom._position[1]._value,
                        atom._position[2]._value,
                        atom._velocity[0]._value,
                        atom._velocity[1]._value,
                        atom._velocity[2]._value))
    lines.append('%10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f\n'
          %(System._sys._v1x._value,
            System._sys._v2y._value,
            System._sys._v3z._value,
            System._sys._v1y._value,
            System._sys._v1z._value,
            System._sys._v2x._value,
            System._sys._v2z._value,
            System._sys._v3x._value,
            System._sys._v3y._value))

    lines.insert(0, (System._sys._name+'\n'))
    lines.insert(1, str(i)+'\n')

    fout = open(filename, 'w')
    for line in lines:
        fout.write(line)
    fout.close()

<commit_msg>fixed bug in .gro reader - correctly reads full precision; GtoG for system2_GMX shows perfect conversion<commit_after>from collections import deque
import pdb

from intermol.Atom import *
from intermol.Molecule import *
from intermol.System import System

def readStructure(filename):
    """Read in a Gromacs structure file

    Args:
        filename (str): the file to be read in
    """

    fd = open(filename, 'r')
    lines = list(fd)
    fd.close()

    i = 2
    for moleculetype in System._sys._molecules.values():
        for molecule in moleculetype.moleculeSet:
            for atom in molecule._atoms:
                if lines[i]:
                    atom.residueIndex=int(lines[i][0:5])
                    atom.residueName=lines[i][6:10].strip()
                    atom.atomName=lines[i][11:15].strip()
                    atom.atomIndex=int(lines[i][16:20])
                    position = [None, None, None]
                    position[0]=float(lines[i][20:28]) * units.nanometers
                    position[1]=float(lines[i][28:36]) * units.nanometers
                    position[2]=float(lines[i][36:44]) * units.nanometers
                    atom.setPosition(position[0], position[1], position[2])
                    velocity  = [None, None, None]
                    try:
                        velocity[0]=float(lines[i][44:52]) * units.nanometers / units.picoseconds
                        velocity[1]=float(lines[i][52:60]) * units.nanometers / units.picoseconds
                        velocity[2]=float(lines[i][60:68]) * units.nanometers / units.picoseconds
                    except:
                        velocity[0] = 0.0 * units.nanometers / units.picoseconds
                        velocity[1] = 0.0 * units.nanometers / units.picoseconds
                        velocity[2] = 0.0 * units.nanometers / units.picoseconds
                    atom.setVelocity(velocity[0], velocity[1], velocity[2])
                    i += 1

                else:
                    sys.exit()

    rawBoxVector = lines[i].split()
    v1x = None
    v2x = None
    v3x = None
    v1y = None
    v2y = None
    v3y = None
    v1z = None
    v2z = None
    v3z = None
    if len(rawBoxVector) == 3:
        v1x = float(rawBoxVector[0]) * units.nanometers
        v2x = 0.0 * units.nanometers
        v3x = 0.0 * units.nanometers
        v1y = 0.0 * units.nanometers
        v2y = float(rawBoxVector[1]) * units.nanometers
        v3y = 0.0 * units.nanometers
        v1z = 0.0 * units.nanometers
        v2z = 0.0 * units.nanometers
        v3z = float(rawBoxVector[2]) * units.nanometers

    elif len(rawBoxVector) == 9:
        v1x = float(rawBoxVector[0:10]) * units.nanometers
        v2x = float(rawBoxVector[11:22]) * units.nanometers
        v3x = float(rawBoxVector[23:34]) * units.nanometers
        v1y = float(rawBoxVector[35:46]) * units.nanometers
        v2y = float(rawBoxVector[47:58]) * units.nanometers
        v3y = float(rawBoxVector[59:70]) * units.nanometers
        v1z = float(rawBoxVector[71:82]) * units.nanometers
        v2z = float(rawBoxVector[83:94]) * units.nanometers
        v3z = float(rawBoxVector[95:106]) * units.nanometers
    System._sys.setBoxVector(v1x, v2x, v3x, v1y, v2y, v3y, v1z, v2z, v3z)

def writeStructure(filename):
    """Write the system out  in a Gromacs 4.5.4 format

    Args:
        filename (str): the file to write out to
    """
    lines = list()
    i=0
    for moleculetype in System._sys._molecules.values():
        for molecule in moleculetype.moleculeSet:
            for atom in molecule._atoms:
                i += 1
                lines.append('%5d%-4s%6s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f\n'
                        %(atom.residueIndex,
                        atom.residueName,
                        atom.atomName,
                        atom.atomIndex,
                        atom._position[0]._value,
                        atom._position[1]._value,
                        atom._position[2]._value,
                        atom._velocity[0]._value,
                        atom._velocity[1]._value,
                        atom._velocity[2]._value))
    lines.append('%10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f\n'
          %(System._sys._v1x._value,
            System._sys._v2y._value,
            System._sys._v3z._value,
            System._sys._v1y._value,
            System._sys._v1z._value,
            System._sys._v2x._value,
            System._sys._v2z._value,
            System._sys._v3x._value,
            System._sys._v3y._value))

    lines.insert(0, (System._sys._name+'\n'))
    lines.insert(1, str(i)+'\n')

    fout = open(filename, 'w')
    for line in lines:
        fout.write(line)
    fout.close()

<|endoftext|>


<commit_before>import sys, os

def go():
	if 'interpret.py' in os.listdir('..') and\
		not 'interpret.py' in os.listdir('.'):
		os.chdir('..')
		sys.path.append('.')<commit_msg>fixed test path<commit_after>import sys, os

def go():
	if 'interpret.py' in os.listdir('..') and\
		not 'interpret.py' in os.listdir('.'):
		os.chdir('..')

	sys.path.append('.')
<|endoftext|>


<commit_before>import compare_mt.ngram_utils
import compare_mt.stat_utils
import compare_mt.corpus_utils
import compare_mt.sign_utils
import compare_mt.scorers
import compare_mt.bucketers
import compare_mt.reporters
import compare_mt.arg_utils
import compare_mt.print_utils

__version__ = "0.2.1"
<commit_msg>Bump up version number to update pypi<commit_after>import compare_mt.ngram_utils
import compare_mt.stat_utils
import compare_mt.corpus_utils
import compare_mt.sign_utils
import compare_mt.scorers
import compare_mt.bucketers
import compare_mt.reporters
import compare_mt.arg_utils
import compare_mt.print_utils

__version__ = "0.2.2"
<|endoftext|>


<commit_before>from bottle import HTTPResponse
import os, json

def make_hash(*args):
    value = 0x345678
    for arg in args:
        value = (1000003 * value) ^ hash(arg)
    if value == -1:
        value = -2
    return value

def error(status, message):
    return HTTPResponse({'error': message}, status)
def abort(status, message):
    raise error(status, message)

# Error checking
def get_simulation_config(name, version, config_sim):
    if '/' in name or '\\' in name:
        abort(400, 'simulation name is malformed')

    path = os.path.join(config_sim['path'], name + ".json")
    try:
        with open(path) as f:
            sim_str = f.read()
    except:
        abort(404, 'simulation "' + name + '" not found')

    try:
        sim = json.loads(sim_str)
    except:
        abort(500, {'error': 'simulation "' + name + '" is not well configured on the server; contact the server administrator.'})

    if version is None:
        version = 'latest'

    if version not in sim:
        abort(404, 'version "' + version + '" of simulation "' + name + '" not found')

    try:
        while type(sim[version]) == str:
            version = sim[version]
    except KeyError:
        abort(500, 'simulation "' + name + '" is not fully configured on the server; contact the server administrator.')

    return (sim, version)<commit_msg>Fixed string type check for unicode<commit_after>from bottle import HTTPResponse
import os, json

def make_hash(*args):
    value = 0x345678
    for arg in args:
        value = (1000003 * value) ^ hash(arg)
    if value == -1:
        value = -2
    return value

def error(status, message):
    return HTTPResponse({'error': message}, status)
def abort(status, message):
    raise error(status, message)

# Error checking
def get_simulation_config(name, version, config_sim):
    if '/' in name or '\\' in name:
        abort(400, 'simulation name is malformed')

    path = os.path.join(config_sim['path'], name + ".json")
    try:
        with open(path) as f:
            sim_str = f.read()
    except:
        abort(404, 'simulation "' + name + '" not found')

    try:
        sim = json.loads(sim_str)
    except:
        abort(500, {'error': 'simulation "' + name + '" is not well configured on the server; contact the server administrator.'})

    if version is None:
        version = 'latest'

    if version not in sim:
        abort(404, 'version "' + version + '" of simulation "' + name + '" not found')

    try:
        while type(sim[version]) != dict:
            version = sim[version]
    except KeyError:
        abort(500, 'simulation "' + name + '" is not fully configured on the server; contact the server administrator.')

    return (sim, version)<|endoftext|>


<commit_before>import sys, traceback
import tableau
import tour
import fou
import cavalier
import pion
import roi
import reine
from piece import piece

tableau = tableau.tableau()

possible = set()

def openFile(filename):
    global curPlayer
    if filename != "":
        tableau.loadFile(filename)
        curPlayer = -1
        draw()

def showEchec():
    print("Echec !")

def showEchecEtMat():
    print("Echec et mat !")

def showPromotion(curPlayer):
    print("Enter the type of piece you want (P, T, C, F, Q) :")
    piece = input("Piece : ")
    if piece == "P":
        res = tableau.setPromoted(pion.pion(curPlayer), curPlayer)
    elif piece == "T":
        res = tableau.setPromoted(tour.tour(curPlayer), curPlayer)
    elif piece == "C":
        res = tableau.setPromoted(cavalier.cavalier(curPlayer), curPlayer)
    elif piece == "F":
        res = tableau.setPromoted(fou.fou(curPlayer), curPlayer)
    elif piece == "Q":
        res = tableau.setPromoted(reine.reine(curPlayer), curPlayer)
    else:
        return
    if res == 1:
        showEchec()
    elif res == 2:
        showEchecEtMat()
    elif res == 3:
        showEchec()
        curPlayer = curPlayer * (-1)
    elif res == 4:
        curPlayer = curPlayer * (-1)
    else:
        return
    possible.clear()
    draw()

def draw():
    print ("    0   1   2   3   4   5   6   7")
    print (" ")
    for Y in range(0,8):
        for Z in range(0,3):
            strValue = ""
            for X in range(0, 8):
                if ((X+Y) % 2 == 0):
                    bkg = "*"
                else:
                    bkg = " "
                if (tableau.isPossible(X, Y, possible)):
                    bkg = "+"
                if Z == 0 or Z == 2:
                    if X == 0:
                        strValue = '  '
                    strValue = strValue + bkg + bkg + bkg + bkg
                else:
                    if X == 0:
                        strValue = str(Y) + ' '
                    pionClass = tableau.getPion(X, Y)
                    bkg_pion = bkg
                    if (pionClass == None):
                        bkg_pion = bkg
                        pionString = bkg + bkg
                    elif (pionClass.getColor() < 0):
                        pionString = pionClass.getLetter() + "B"
                    elif (pionClass.getColor() > 0):
                        pionString = pionClass.getLetter() + "N"
                    else:
                        bkg_pion = bkg
                        pionString = pionClass.getLetter()
                    strValue = strValue + bkg + pionString + bkg
            print (strValue)
curPlayer = piece._players['BLANC']
selected = False
selectedPion = 0
init_x = 0
init_y = 0

draw()
LOOP_ACTIVE = True
while LOOP_ACTIVE:
    if (curPlayer == piece._players['NOIR']) :
        print ("Joueur noir")
    else:
        print ("Joueur blanc")
    action = input("Action : ")
    try:
        if (action == "quit"):
            LOOP_ACTIVE = False
        elif (action.find("load") != -1):
            values = action.split(" ")
            print("Filename : " + values[1])
            openFile(values[1])
        else:
            values = action.split(" ")
            res = tableau.play(int(values[0]), int(values[1]), curPlayer, possible)
            if res == 1:
                showEchec()
            elif res == 2:
                showEchecEtMat()
            elif res == 3:
                showEchec()
                curPlayer = curPlayer * (-1)
            elif res == 4:
                curPlayer = curPlayer * (-1)
            elif res ==8:
                showPromotion(curPlayer)
            draw()

    except:
        print ("Commande non comprise")
        traceback.print_exc(file=sys.stdout)
<commit_msg>Update chess_simple.py<commit_after>import sys, traceback
import tableau
import tour
import fou
import cavalier
import pion
import roi
import reine
from piece import piece

tableau = tableau.tableau()

possible = set()

def openFile(filename):
    global curPlayer
    if filename != "":
        tableau.loadFile(filename)
        curPlayer = -1
        draw()

def showEchec():
    print("Echec !")

def showEchecEtMat():
    print("Echec et mat !")

def showPromotion(curPlayer):
    print("Enter the type of piece you want (P, T, C, F, Q) :")
    piece = input("Piece : ")
    if piece == "P":
        res = tableau.setPromoted(pion.pion(curPlayer), curPlayer)
    elif piece == "T":
        res = tableau.setPromoted(tour.tour(curPlayer), curPlayer)
    elif piece == "C":
        res = tableau.setPromoted(cavalier.cavalier(curPlayer), curPlayer)
    elif piece == "F":
        res = tableau.setPromoted(fou.fou(curPlayer), curPlayer)
    elif piece == "Q":
        res = tableau.setPromoted(reine.reine(curPlayer), curPlayer)
    else:
        return
    if res == 1:
        showEchec()
    elif res == 2:
        showEchecEtMat()
    elif res == 3:
        showEchec()
        curPlayer = curPlayer * (-1)
    elif res == 4:
        curPlayer = curPlayer * (-1)
    else:
        return
    possible.clear()
    draw()

def draw():
    print ("    0   1   2   3   4   5   6   7")
    print (" ")
    for Y in range(0,8):
        for Z in range(0,3):
            strValue = ""
            for X in range(0, 8):
                if ((X+Y) % 2 == 0):
                    bkg = "*"
                else:
                    bkg = " "
                if (tableau.isPossible(X, Y, possible)):
                    bkg = "+"
                if Z == 0 or Z == 2:
                    if X == 0:
                        strValue = '  '
                    strValue = strValue + bkg + bkg + bkg + bkg
                else:
                    if X == 0:
                        strValue = str(Y) + ' '
                    pionClass = tableau.getPion(X, Y)
                    bkg_pion = bkg
                    if (pionClass == None):
                        bkg_pion = bkg
                        pionString = bkg + bkg
                    elif (pionClass.getColor() < 0):
                        pionString = pionClass.getLetter() + "B"
                    elif (pionClass.getColor() > 0):
                        pionString = pionClass.getLetter() + "N"
                    else:
                        bkg_pion = bkg
                        pionString = pionClass.getLetter()
                    strValue = strValue + bkg + pionString + bkg
            print (strValue)
curPlayer = piece._players['BLANC']
selected = False
selectedPion = 0
init_x = 0
init_y = 0

draw()
LOOP_ACTIVE = True
while LOOP_ACTIVE:
    if (curPlayer == piece._players['NOIR']) :
        print ("Joueur noir")
    else:
        print ("Joueur blanc")
    action = input("Action : ")
    try:
        if (action == "quit"):
            LOOP_ACTIVE = False
        elif (action.find("load") != -1):
            values = action.split(" ")
            print("Filename : " + values[1])
            openFile(values[1])
        else:
            input_x = -1
            if (action[0] == "A" or action[0] == "a"):
                input_x = 0
            if (action[0] == "B" or action[0] == "b"):
                input_x = 1
            if (action[0] == "C" or action[0] == "c"):
                input_x = 2
            if (action[0] == "D" or action[0] == "d"):
                input_x = 3
            if (action[0] == "E" or action[0] == "e"):
                input_x = 4
            if (action[0] == "F" or action[0] == "f"):
                input_x = 5
            if (action[0] == "G" or action[0] == "g"):
                input_x = 6
            if (action[0] == "H" or action[0] == "h"):
                input_x = 7
            if input_x == -1:
                values = action.split(" ")
                input_x = int(values[0])
                input_y =int(values[1])
            else:
                input_y = 8-int(action[1])
            res = tableau.play(input_x, input_y, curPlayer, possible)
            if res == 1:
                showEchec()
            elif res == 2:
                showEchecEtMat()
            elif res == 3:
                showEchec()
                curPlayer = curPlayer * (-1)
            elif res == 4:
                curPlayer = curPlayer * (-1)
            elif res ==8:
                showPromotion(curPlayer)
            draw()

    except:
        print ("Commande non comprise")
        traceback.print_exc(file=sys.stdout)
<|endoftext|>


<commit_before>from openerp import api, models, fields, SUPERUSER_ID
from openerp.http import request
import fnmatch
import werkzeug.utils

class website_redirect(models.Model):
    _name = 'website.redirect'

    _order = 'sequence,id'

    name = fields.Char('Name')
    active = fields.Boolean('Active', default=True)
    sequence = fields.Integer('Sequence')
    domain = fields.Char('Domain Name', placeholder='odoo.com', help='keep empty to apply rules for any domain')

    rule_ids = fields.One2many('website.redirect.rule', 'redirect_id', string='Rules')

class website_redirect(models.Model):
    _name = 'website.redirect.rule'

    _order = 'sequence,id'
    sequence = fields.Integer('Sequence')
    pattern = fields.Char('From', help='Unix shell-style wildcards. Check https://docs.python.org/2/library/fnmatch.html for details')
    target = fields.Char('To')
    redirect_id = fields.Many2one('website.redirect')

class ir_http(models.AbstractModel):
    _inherit = 'ir.http'

    def _dispatch(self):
        host = request.httprequest.environ.get('HTTP_HOST', '').split(':')[0]
        www, _, h = host.partition('.')
        if www == 'www':
            host = h
        path = request.httprequest.path
        for redirect in request.env['website.redirect'].sudo().search([]):
            if redirect.domain and redirect.domain != host:
                continue

            for rule in redirect.rule_ids:
                if fnmatch.fnmatch(path, rule.pattern):
                    code = 302
                    return werkzeug.utils.redirect(rule.target, code)
        return super(ir_http, self)._dispatch()
<commit_msg>fields from and to should be required<commit_after>from openerp import api, models, fields, SUPERUSER_ID
from openerp.http import request
import fnmatch
import werkzeug.utils

class website_redirect(models.Model):
    _name = 'website.redirect'

    _order = 'sequence,id'

    name = fields.Char('Name')
    active = fields.Boolean('Active', default=True)
    sequence = fields.Integer('Sequence')
    domain = fields.Char('Domain Name', placeholder='odoo.com', help='keep empty to apply rules for any domain')

    rule_ids = fields.One2many('website.redirect.rule', 'redirect_id', string='Rules')

class website_redirect(models.Model):
    _name = 'website.redirect.rule'

    _order = 'sequence,id'
    sequence = fields.Integer('Sequence')
    pattern = fields.Char('From', help='Unix shell-style wildcards. Check https://docs.python.org/2/library/fnmatch.html for details', required=True)
    target = fields.Char('To', required=True)
    redirect_id = fields.Many2one('website.redirect')

class ir_http(models.AbstractModel):
    _inherit = 'ir.http'

    def _dispatch(self):
        host = request.httprequest.environ.get('HTTP_HOST', '').split(':')[0]
        www, _, h = host.partition('.')
        if www == 'www':
            host = h
        path = request.httprequest.path
        for redirect in request.env['website.redirect'].sudo().search([]):
            if redirect.domain and redirect.domain != host:
                continue

            for rule in redirect.rule_ids:
                if fnmatch.fnmatch(path, rule.pattern):
                    code = 302
                    return werkzeug.utils.redirect(rule.target, code)
        return super(ir_http, self)._dispatch()
<|endoftext|>


<commit_before>from rgbmatrix import RGBMatrix
from rgbmatrix import graphics
from field import Field

Matrix = RGBMatrix(32, 2, 1)
Matrix.pwmBits = 11
Matrix.brightness = 50

def colorize(foods, base, ants):
    for food in foods:
        Matrix.SetPixel(food[0], food[1], 0, 200, 0)

    for ant in ants:
        Matrix.SetPixel(ant[0], ant[1], 255, 255, 0)
	#base
    Matrix.SetPixel(base[0], base[1], 100, 255, 100)

field = Field("field.txt", (30, 40))

field.food.append((10, 10))
field.food.append((20, 20))

for i in range(1, 30):
    field.units.append(Ant(Color(0, 0, 100), 30, 40, i))
    field.add_occupied((30, 40))

offscreenCanvas = Matrix.CreateFrameCanvas()

i = 1
while True:
    i+=1
    offscreenCanvas.Clear()
    field.draw()
    colorize(field.food, field.base, field.occupied)
    field.generate_next()
    if i % 10 == 0:
        i = 1
        field.evaporate_pheromones()
    time.sleep(0.4)
    offscreenCanvas = Matrix.SwapOnVSync(offscreenCanvas)

<commit_msg>add missing imports<commit_after>from rgbmatrix import RGBMatrix
from rgbmatrix import graphics
from field import Field
from color import Color
from ant import Ant

Matrix = RGBMatrix(32, 2, 1)
Matrix.pwmBits = 11
Matrix.brightness = 50

def colorize(foods, base, ants):
    for food in foods:
        Matrix.SetPixel(food[0], food[1], 0, 200, 0)

    for ant in ants:
        Matrix.SetPixel(ant[0], ant[1], 255, 255, 0)
	#base
    Matrix.SetPixel(base[0], base[1], 100, 255, 100)

field = Field("field.txt", (30, 40))

field.food.append((10, 10))
field.food.append((20, 20))

for i in range(1, 30):
    field.units.append(Ant(Color(0, 0, 100), 30, 40, i))
    field.add_occupied((30, 40))

offscreenCanvas = Matrix.CreateFrameCanvas()

i = 1
while True:
    i+=1
    offscreenCanvas.Clear()
    field.draw()
    colorize(field.food, field.base, field.occupied)
    field.generate_next()
    if i % 10 == 0:
        i = 1
        field.evaporate_pheromones()
    time.sleep(0.4)
    offscreenCanvas = Matrix.SwapOnVSync(offscreenCanvas)

<|endoftext|>


<commit_before>"""
This file is part of Ludolph: Ansible plugin
Copyright (C) 2015 Erigones, s. r. o.

See the LICENSE file for copying permission.
"""

__version__ = '0.2'
<commit_msg>Bumped up version to 0.3.0<commit_after>"""
This file is part of Ludolph: Ansible plugin
Copyright (C) 2015 Erigones, s. r. o.

See the LICENSE file for copying permission.
"""

__version__ = '0.3'
<|endoftext|>


<commit_before>##########################################################################
#
#  Copyright (c) 2010, Image Engine Design Inc. All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#
#     * Neither the name of Image Engine Design nor the names of any
#       other contributors to this software may be used to endorse or
#       promote products derived from this software without specific prior
#       written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import maya.cmds

import IECore
import IECoreMaya

class CompoundParameterUI( IECoreMaya.ParameterUI ) :

	def __init__( self, node, parameter, **kw  ) :

		IECoreMaya.ParameterUI.__init__( self, node, parameter, **kw )

		visible = True
		try:
			visible = parameter.userData()['UI']['visible'].value
		except:
			pass

		if 'visibleOnly' in kw :

			visible = False

			for i in kw['visibleOnly'] :

				if kw['longParameterName'] == "" or i.startswith( kw['longParameterName'] + "." ) :

					visible = True

		if not visible :

			return

		if 'hierarchyDepth' in kw :
			kw['hierarchyDepth'] += 1
		else :
			kw['hierarchyDepth'] = 0

		self.__childUIsLayout = None
		self.__childUIs = {}

		self._layout = None

		fnPH = IECoreMaya.FnParameterisedHolder( node )

		withCompoundFrame = False
		if 'withCompoundFrame' in kw :
			withCompoundFrame = kw['withCompoundFrame']

		if not withCompoundFrame and parameter.isSame( fnPH.getParameterised()[0].parameters() ) :
			self._layout = maya.cmds.columnLayout()
			self.__createChildUIs( **kw )
			maya.cmds.setParent("..")
		else:
			# \todo Retrieve the "collapsed" state
			collapsed = True

			font = "boldLabelFont"
			labelIndent = 5 + ( 8 * max( 0, kw['hierarchyDepth']-1 ) )

			if kw['hierarchyDepth'] == 2 :

				font = "smallBoldLabelFont"

			elif kw['hierarchyDepth'] >= 3 :

				font = "tinyBoldLabelFont"

			self._layout = maya.cmds.frameLayout(
				label = self.label(),
				font = font,
				labelIndent = labelIndent,
				borderVisible = False,
				preExpandCommand = IECore.curry( self.__createChildUIs, **kw),
				collapseCommand = self.__collapse,
				collapsable = True,
				collapse = collapsed,
			)

			if not collapsed:
				self.__createChildUIs( **kw )

			maya.cmds.setParent("..")

	def replace( self, node, parameter ) :

		IECoreMaya.ParameterUI.replace( self, node, parameter )

		for pName in self.__childUIs.keys():
			ui = self.__childUIs[pName]
			p = self.parameter[pName]

			ui.replace( node, p )

	def __collapse(self):
		# \todo Store collapsed state of self._layout
		pass

	def __createChildUIs(self, **kw):

		# this is the most common entry point into the ui
		# creation code, and unfortunately it's called from
		# a maya ui callback. maya appears to suppress all
		# exceptions which occur in such callbacks, so we
		# have to wrap with our own exception handling to
		# make sure any errors become visible.
		try :

			if self.__childUIsLayout:
				return

			kw['labelWithNodeName'] = False

			# \todo Store collapsed state of self._layout

			maya.cmds.setUITemplate(
				"attributeEditorTemplate",
				pushTemplate = True
			)

			self.__childUIsLayout = maya.cmds.columnLayout(
				parent = self._layout,
				width = 381
			)

			draggable = False
			try:
				draggable = self.parameter.userData()['UI']['draggable'].value
			except :
				pass

			if draggable :

				maya.cmds.rowLayout(
					numberOfColumns = 2,
					columnWidth2 = ( 361, 20 )

				)

				maya.cmds.text( label = "" )

				dragIcon = maya.cmds.iconTextStaticLabel(
					image = "pick.xpm",
					height = 20
				)
				self.addDragCallback( dragIcon, **kw )

			for pName in self.parameter.keys():

				p = self.parameter[pName]

				visible = True
				try:
					visible = p.userData()['UI']['visible'].value
				except:
					pass

				if 'visibleOnly' in kw :

					fullChildName = kw['longParameterName']

					if len( fullChildName ) :
						fullChildName += "."

					fullChildName += pName

					visible = fullChildName in kw['visibleOnly']

					if not visible and p.isInstanceOf( IECore.TypeId.CompoundParameter ) :

						for i in kw['visibleOnly'] :

							if i.startswith( fullChildName + "." ) :

								visible = True

				if visible:
					maya.cmds.setParent( self.__childUIsLayout )

					ui = IECoreMaya.ParameterUI.create( self.node(), p, **kw )

					if ui:
						self.__childUIs[pName] = ui

			maya.cmds.setParent("..")

			maya.cmds.setUITemplate(
				"attributeEditorTemplate",
				popTemplate = True
			)

		except :

			IECore.msg( IECore.Msg.Level.Error, "IECoreMaya.ParameterUI", traceback.format_exc() )

IECoreMaya.ParameterUI.registerUI( IECore.TypeId.CompoundParameter, CompoundParameterUI )
<commit_msg>Documented the keyword arguments for CompoundParameterUI that I understand and which work. Added a todo to figure out a situation where the draggable keyword does something useful and document it. Removed the code that would shortcut the constructor based on visibility flags - I can't find a place where this is useful and I don't think the behaviour is desirable in the first place - it gives us an object for which the _layout member is unitialised, and it certainly won't work if we get round to deriving ParameterUI from UIElement.<commit_after>##########################################################################
#
#  Copyright (c) 2010, Image Engine Design Inc. All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#
#     * Neither the name of Image Engine Design nor the names of any
#       other contributors to this software may be used to endorse or
#       promote products derived from this software without specific prior
#       written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import maya.cmds

import IECore
import IECoreMaya

class CompoundParameterUI( IECoreMaya.ParameterUI ) :

	## Supports the following keyword arguments :
	#
	# bool "withCompoundFrame"
	# May be specified as False to suppress the creation of a
	# frameLayout when this parameter is the toplevel parameter
	# for the node.
	#
	# list "visibleOnly"
	# A list of strings specifying the full parameter paths for
	# parameters which should be displayed. Any parameters not in
	# this list will not be visible.
	def __init__( self, node, parameter, **kw  ) :

		IECoreMaya.ParameterUI.__init__( self, node, parameter, **kw )

		if 'hierarchyDepth' in kw :
			kw['hierarchyDepth'] += 1
		else :
			kw['hierarchyDepth'] = 0

		self.__childUIsLayout = None
		self.__childUIs = {}

		self._layout = None

		fnPH = IECoreMaya.FnParameterisedHolder( node )

		withCompoundFrame = kw.get( "withCompoundFrame", False )

		if not withCompoundFrame and parameter.isSame( fnPH.getParameterised()[0].parameters() ) :
			self._layout = maya.cmds.columnLayout()
			self.__createChildUIs( **kw )
			maya.cmds.setParent("..")
		else:
			# \todo Retrieve the "collapsed" state
			collapsed = True

			font = "boldLabelFont"
			labelIndent = 5 + ( 8 * max( 0, kw['hierarchyDepth']-1 ) )

			if kw['hierarchyDepth'] == 2 :

				font = "smallBoldLabelFont"

			elif kw['hierarchyDepth'] >= 3 :

				font = "tinyBoldLabelFont"

			self._layout = maya.cmds.frameLayout(
				label = self.label(),
				font = font,
				labelIndent = labelIndent,
				borderVisible = False,
				preExpandCommand = IECore.curry( self.__createChildUIs, **kw),
				collapseCommand = self.__collapse,
				collapsable = True,
				collapse = collapsed,
			)

			if not collapsed:
				self.__createChildUIs( **kw )

			maya.cmds.setParent("..")

	def replace( self, node, parameter ) :

		IECoreMaya.ParameterUI.replace( self, node, parameter )

		for pName in self.__childUIs.keys():
			ui = self.__childUIs[pName]
			p = self.parameter[pName]

			ui.replace( node, p )

	def __collapse(self):
		# \todo Store collapsed state of self._layout
		pass

	def __createChildUIs(self, **kw):

		# this is the most common entry point into the ui
		# creation code, and unfortunately it's called from
		# a maya ui callback. maya appears to suppress all
		# exceptions which occur in such callbacks, so we
		# have to wrap with our own exception handling to
		# make sure any errors become visible.
		try :

			if self.__childUIsLayout:
				return

			kw['labelWithNodeName'] = False

			# \todo Store collapsed state of self._layout

			maya.cmds.setUITemplate(
				"attributeEditorTemplate",
				pushTemplate = True
			)

			self.__childUIsLayout = maya.cmds.columnLayout(
				parent = self._layout,
				width = 381
			)

			draggable = False
			try:
				draggable = self.parameter.userData()['UI']['draggable'].value
			except :
				pass

			## \todo Figure out what this draggable stuff is all about and document it.
			# I think it's intended to allow parameters to be dragged and dropped onto
			# an IECoreMaya.ParameterPanel but I can't get that to work right now.
			if draggable :

				maya.cmds.rowLayout(
					numberOfColumns = 2,
					columnWidth2 = ( 361, 20 )

				)

				maya.cmds.text( label = "" )

				dragIcon = maya.cmds.iconTextStaticLabel(
					image = "pick.xpm",
					height = 20
				)
				self.addDragCallback( dragIcon, **kw )

			for pName in self.parameter.keys():

				p = self.parameter[pName]

				visible = True
				try:
					visible = p.userData()['UI']['visible'].value
				except:
					pass

				if 'visibleOnly' in kw :

					fullChildName = kw['longParameterName']

					if len( fullChildName ) :
						fullChildName += "."

					fullChildName += pName

					visible = fullChildName in kw['visibleOnly']

					if not visible and p.isInstanceOf( IECore.TypeId.CompoundParameter ) :

						for i in kw['visibleOnly'] :

							if i.startswith( fullChildName + "." ) :

								visible = True

				if visible:
					maya.cmds.setParent( self.__childUIsLayout )

					ui = IECoreMaya.ParameterUI.create( self.node(), p, **kw )

					if ui:
						self.__childUIs[pName] = ui

			maya.cmds.setParent("..")

			maya.cmds.setUITemplate(
				"attributeEditorTemplate",
				popTemplate = True
			)

		except :

			IECore.msg( IECore.Msg.Level.Error, "IECoreMaya.ParameterUI", traceback.format_exc() )

IECoreMaya.ParameterUI.registerUI( IECore.TypeId.CompoundParameter, CompoundParameterUI )
<|endoftext|>


<commit_before>from flask import Flask, got_request_exception
from flask_restful import Resource, Api, fields, marshal_with, reqparse
import requests
import xml.etree.ElementTree as etree
import uuid
import pysolr
import re

############################
# Application wide variables
app = Flask(__name__)
app.config['BUNDLE_ERRORS'] = True
api = Api(app)
url_parameters = ['modality', 'indication', 'areaimaged', 'technique', 'comparison', 'findings', 'conclusions']
############################

@app.route('/')
def hello_world():
    return 'JSON API RESTFUL URL available at /searchResults'

def log_exception(sender, exception, **extra):
    """ Log an exception to our logging framework """
    sender.logger.debug('Got exception during processing: %s', exception)
    for name, value in extra.items():
        sender.logger.debug('{0} = {1}'.format(name, value))

got_request_exception.connect(log_exception, app)

searchResults_fields = {
    'id' : fields.Integer(default=0),
    'resultID' : fields.Integer,
    'imageLink' : fields.String(default=''),
    'source' : fields.String(default=''),
    'resultTitle' : fields.String(default=''),
    'linkTitle' : fields.String(default=''),
    'articleLink' : fields.String(default=''),
    'figsonlyLink' : fields.String(default=''),
    'content' : fields.String(default=''),
    'modality' : fields.String(default=''),
    'date' : fields.String(default=''),
}

class searchResults(Resource):

    def xml_to_dict(self, xmlstr):
        # XML Sample result
        #
        #

        #   <ResultID>1</ResultID>
        #   <ThumbLocalLink>http://www.yottalook.com/images/thumbnails/small/cf6539a170fe8de1b15f581563580182540bdbf2.jpg</ThumbLocalLink>
        #   <Source>AJR</Source>
        #   <FullFigureLink>http://www.ajronline.org/content/198/3/W217/F5.expansion.html</FullFigureLink>
        #   <ArticleTitle>Review: Inflammatory Pseudotumor: The Great Mimicker</ArticleTitle>
        #   <ArticleLink>http://www.ajronline.org/content/198/3/W217.full</ArticleLink>
        #   <ArticleLinkPDF>http://www.ajronline.org/content/198/3/W217.reprint</ArticleLinkPDF>
        #   <FigsonlyLink>http://www.ajronline.org/content/198/3/W217.figsonly</FigsonlyLink>
        #
Fig. 4A —14-year-old girl with history of asthma. A,Axial (A)...

        #   <ImageType>CT</ImageType>
        #   <Date>2012-03-01</Date>
        #   <SubscriptionStatus>n</SubscriptionStatus>
        #

        #
        root = etree.fromstring(xmlstr)
        retval = []

        # # some exmples for parsing the xml string
        # # YottalookWS
        # print("root : ", root.findall("."))
        # # YottalookImages
        # print("root[0] : ", root[0].findall("."))
        # # results
        # print("root[0][1] : ", root[0][1].findall("."))
        # # first figure (first result)
        # print("root[0][1][0] : ", root[0][1][0].findall("."))
        # # get all figure elements
        # print("root .//Figure: ", root.findall(".//Figure"))
        #

        for idx, val in enumerate(root.findall('.//Figure')):
            document = {}

            # map XML value to dictionary object - could use XML elements directly, but plan to change output
            # format eventually, so this will be needed soon
            document['id'] = uuid.uuid5(uuid.NAMESPACE_URL, val.find('FullFigureLink').text).int
            document['resultID'] = val.find('ResultID').text
            document['imageLink'] = val.find('ThumbLocalLink').text
            document['source'] = val.find('Source').text
            document['resultTitle'] = val.find('Caption').text
            document['linkTitle'] = val.find('ArticleTitle').text
            document['articleLink'] = val.find('ArticleLink').text
            document['figsonlyLink'] = val.find('FigsonlyLink').text
            document['content'] = val.find('Caption').text
            document['modality'] = val.find('ImageType').text
            document['date'] = val.find('Date').text

            retval.append(document)

        return retval

    @marshal_with(searchResults_fields, envelope='searchResults')
    def get(self):
        # get request parameters
        get_parser = reqparse.RequestParser()
        for u in url_parameters:
            get_parser.add_argument(
                u,
                dest = u,
                help = 'Text from ' + u + ' field',
            )
        args = get_parser.parse_args()

        # build the parameterized URL for Yottalook
        yottalook_url = 'http://www.yottalook.com/api_images_2_0.php'
        query_terms = ''
        for u in url_parameters[1:]:
            if args[u] != None:
                if " " in args[u]:
                    query_terms += '"' + args[u] + '"+'
                else:
                    query_terms += args[u] + '+'
        if query_terms.endswith('+'):
            query_terms = query_terms[:-1]

        yottalook_url += '?q=' + query_terms

        # due to needing to customize query_terms, not including it as part of params dictionary
        payload = {
            'app_id' : '4b94305d853d3e7c91ed4774aa428f75',
            'mod'    : args.modality,
            'cl'     : 50,
        }

        prepared = requests.Request(url=yottalook_url).prepare()
        prepared.prepare_url(prepared.url, payload)
        #&t=yy required to be at the end of the URL
        prepared.prepare_url(prepared.url, {'t' : 'yy'})

        resp = requests.get(prepared.url)
        print("    DEBUG URL : " + resp.url)

        if resp.status_code != 200:
            # This means something went wrong.
            print('GET YOTTALOOK returned status code: ', resp.status_code)
            return {}
        else:
            r = resp.text
            r = r.split('\n', 1)[-1]

            return self.xml_to_dict(r)

api.add_resource(searchResults, '/searchResults' )

class solrSearch(Resource):

    @marshal_with(searchResults_fields, envelope='searchResults')
    def get(self):
        # get request parameters
        get_parser = reqparse.RequestParser()
        solrquery = ''
        retval = []

        for u in url_parameters:
            get_parser.add_argument(
                u,
                dest = u,
                help = 'Text from ' + u + ' field',
            )
        args = get_parser.parse_args()

        # handle the special cases
        modality = args['modality']
        if modality != None and modality != 'all':
            if modality == 'XR':
                solrquery = 'content:"modality conventional radiograph"~3 AND '
            elif modality == 'NM':
                solrquery = 'content:"modality nuc med"~7 OR content:"Nuclear Medicine" AND '
            else:
                solrquery = 'content:"modality ' + modality + '"~7 AND '

        # search for gender - can't yet enter in UI
        #results = solr.search('content:"patient: female"~7')
        #results = solr.search('content:"patient: male"~7')

        for u in url_parameters[1:]:
            print(u)
            if args[u] != None:
                solrquery += 'content:"' + args[u] + '" AND '
        if solrquery.endswith(' AND '):
            solrquery = solrquery[:-5]

        # Setup a Solr instance.
        solr = pysolr.Solr('http://localhost:8983/solr/mypacs')

        # sample SOLR result
        # {
        #     'date':'2012-04-27T15:58:26Z',
        #     'boost':0.0,
        #     'lastModified':'2012-04-27T15:58:26Z',
        #     'url':'http://www.mypacs.net/cases/220339.html',
        #     'contentLength':'6876',
        #     'digest':'85dd4d2462da0ffecabe5ca711621cb4',
        #     'title':[
        #         'ANKLE PAIN FOLLOWING TRAUMA'
        #     ],
        #     'tstamp':'2015-12-20T04:54:49.803Z',
        #     'id':'net.mypacs.www:http/cases/220339.html',
        #     'content':'ANKLE PAIN FOLLOWING TRAUMA MyPACS.net: Radiology Teaching Files > Case 220339 \xa0 ANKLE PAIN FOLLOWING TRAUMA Contributed by: Lee Hoagland, Radiologist, University of Wisconsin, Madison, Wisconsin, USA. Patient: female History: Fall. Images: [small] larger Fig. 1: Axial CT through the distal tibia. Fig. 2: Sagittal CT reconstruction of the ankle. Fig. 3: Coronal CT reconstruction of the distal tibia. Findings: Fracture of the distal tibial epiphysis extending into the physis with widening of the lateral aspect of the growth plate. The medial portion of the physis is fused. Diagnosis: Juvenile Tillaux Fracture Comments: Nice case, Lee. Welcome to the club. -- Dean Thornton , 2003-11-13 Additional Details: Case Number: 220339 Last Updated: 2011-09-24 Anatomy: Skeletal System\xa0\xa0\xa0 Pathology: Trauma Modality: CT Access Level: Readable by all users The reader is fully responsible for confirming the accuracy of this content. Text and images may be copyrighted by the case author or institution. You can help keep MyPACS tidy: if you notice a case which is not useful (e.g. a test case) or inaccurate, please contact us .',
        #     '_version_':1518338815171756034,
        #     'type':[
        #         'text/html',
        #         'text',
        #         'html'
        #     ]
        # }

        print("solrquery: ", solrquery)
        results = solr.search(solrquery)
        counter = 1
        for result in results:
            document = {}
            document['id'] = uuid.uuid5(uuid.NAMESPACE_URL, result['url']).int
            document['resultID'] = counter
            document['source'] = 'MyPACS'
            document['resultTitle'] = result['title']
            document['linkTitle'] = result['title']
            document['articleLink'] = result['url']
            document['content'] = result['content']

            modality_pattern = re.compile('Modality: (.*) Access Level:')
            modality_result = modality_pattern.search(result['content'])
            if modality_result:
                document['modality'] = modality_result.groups()[0]

            lastupdated_pattern = re.compile('Last Updated: (\d{4}-\d{2}-\d{2})')
            lastupdated_result = lastupdated_pattern.search(result['content'])
            if lastupdated_result:
                document['date'] = lastupdated_result.groups()[0]

            counter += 1
            retval.append(document)

        # total number of matches found (will only see the first 10)
        print("    Total Solr results found: ", results.hits)

        return retval

api.add_resource(solrSearch, '/solr' )

# these response headers allow for client side code to request resources
@app.after_request
def after_request(response):
  response.headers.add('Access-Control-Allow-Origin', '*')
  response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
  response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
  return response

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
<commit_msg>Added gender parameter. Now combining results from search engines. Improved home page.<commit_after>from flask import Flask, got_request_exception
from flask_restful import Resource, Api, fields, marshal_with, reqparse
import requests
import xml.etree.ElementTree as etree
import uuid
import pysolr
import re

############################
# Application wide variables
app = Flask(__name__)
app.config['BUNDLE_ERRORS'] = True
api = Api(app)
url_parameters = ['modality', 'gender', 'indication', 'areaimaged', 'technique', 'comparison', 'findings', 'conclusions']
############################

@app.route('/')
def hello_world():
    return '' \
           + '
JSON API RESTFUL URL available at /searchResults
' \
           + '
To test individual backends try:
' \
           + '
' \
           + '
/yottalook - Yottalook search engine results
' \
           + '
/solr - Solr search engine results
' \
           + '
' \
           + ''

def log_exception(sender, exception, **extra):
    """ Log an exception to our logging framework """
    sender.logger.debug('Got exception during processing: %s', exception)
    for name, value in extra.items():
        sender.logger.debug('{0} = {1}'.format(name, value))

got_request_exception.connect(log_exception, app)

searchResults_fields = {
    'id' : fields.Integer(default=0),
    'resultID' : fields.Integer,
    'imageLink' : fields.String(default=''),
    'source' : fields.String(default=''),
    'resultTitle' : fields.String(default=''),
    'linkTitle' : fields.String(default=''),
    'articleLink' : fields.String(default=''),
    'figsonlyLink' : fields.String(default=''),
    'content' : fields.String(default=''),
    'modality' : fields.String(default=''),
    'date' : fields.String(default=''),
}

class yottalookSearch(Resource):

    def xml_to_dict(xmlstr):
        # XML Sample result
        #
        #

        #   <ResultID>1</ResultID>
        #   <ThumbLocalLink>http://www.yottalook.com/images/thumbnails/small/cf6539a170fe8de1b15f581563580182540bdbf2.jpg</ThumbLocalLink>
        #   <Source>AJR</Source>
        #   <FullFigureLink>http://www.ajronline.org/content/198/3/W217/F5.expansion.html</FullFigureLink>
        #   <ArticleTitle>Review: Inflammatory Pseudotumor: The Great Mimicker</ArticleTitle>
        #   <ArticleLink>http://www.ajronline.org/content/198/3/W217.full</ArticleLink>
        #   <ArticleLinkPDF>http://www.ajronline.org/content/198/3/W217.reprint</ArticleLinkPDF>
        #   <FigsonlyLink>http://www.ajronline.org/content/198/3/W217.figsonly</FigsonlyLink>
        #
Fig. 4A —14-year-old girl with history of asthma. A,Axial (A)...

        #   <ImageType>CT</ImageType>
        #   <Date>2012-03-01</Date>
        #   <SubscriptionStatus>n</SubscriptionStatus>
        #

        #
        root = etree.fromstring(xmlstr)
        retval = []

        # # some exmples for parsing the xml string
        # # YottalookWS
        # print("root : ", root.findall("."))
        # # YottalookImages
        # print("root[0] : ", root[0].findall("."))
        # # results
        # print("root[0][1] : ", root[0][1].findall("."))
        # # first figure (first result)
        # print("root[0][1][0] : ", root[0][1][0].findall("."))
        # # get all figure elements
        # print("root .//Figure: ", root.findall(".//Figure"))
        #

        for idx, val in enumerate(root.findall('.//Figure')):
            document = {}

            # map XML value to dictionary object - could use XML elements directly, but plan to change output
            # format eventually, so this will be needed soon
            document['id'] = uuid.uuid5(uuid.NAMESPACE_URL, val.find('FullFigureLink').text).int
            document['resultID'] = val.find('ResultID').text
            document['imageLink'] = val.find('ThumbLocalLink').text
            document['source'] = val.find('Source').text
            document['resultTitle'] = val.find('Caption').text
            document['linkTitle'] = val.find('ArticleTitle').text
            document['articleLink'] = val.find('ArticleLink').text
            document['figsonlyLink'] = val.find('FigsonlyLink').text
            document['content'] = val.find('Caption').text
            document['modality'] = val.find('ImageType').text
            document['date'] = val.find('Date').text

            retval.append(document)

        return retval

    def search():
        # get request parameters
        get_parser = reqparse.RequestParser()
        for u in url_parameters:
            get_parser.add_argument(
                u,
                dest = u,
                help = 'Text from ' + u + ' field',
            )
        args = get_parser.parse_args()

        # build the parameterized URL for Yottalook
        yottalook_url = 'http://www.yottalook.com/api_images_2_0.php'
        query_terms = ''
        # modality is a special case, so skip it and handle later
        for u in url_parameters[1:]:
            if args[u] != None:
                if " " in args[u]:
                    query_terms += '"' + args[u] + '"+'
                else:
                    query_terms += args[u] + '+'
        if query_terms.endswith('+'):
            query_terms = query_terms[:-1]

        yottalook_url += '?q=' + query_terms

        # due to needing to customize query_terms, not including it as part of params dictionary
        payload = {
            'app_id' : '4b94305d853d3e7c91ed4774aa428f75',
            'mod'    : args.modality,
            'cl'     : 50,
        }

        prepared = requests.Request(url=yottalook_url).prepare()
        prepared.prepare_url(prepared.url, payload)
        #&t=yy required to be at the end of the URL
        prepared.prepare_url(prepared.url, {'t' : 'yy'})

        resp = requests.get(prepared.url)
        print("    DEBUG URL : " + resp.url)

        if resp.status_code != 200:
            # This means something went wrong.
            print('GET YOTTALOOK returned status code: ', resp.status_code)
            return {}
        else:
            r = resp.text
            r = r.split('\n', 1)[-1]

            return yottalookSearch.xml_to_dict(r)

    @marshal_with(searchResults_fields, envelope='searchResults')
    def get(self):
        return yottalookSearch.search()

api.add_resource(yottalookSearch, '/yottalook' )

class solrSearch(Resource):

    def search():
        # get request parameters
        get_parser = reqparse.RequestParser()
        solrquery = ''
        retval = []

        for u in url_parameters:
            get_parser.add_argument(
                u,
                dest = u,
                help = 'Text from ' + u + ' field',
            )
        args = get_parser.parse_args()

        # handle the special cases
        modality = args['modality']
        if modality != None and modality != 'all':
            if modality == 'XR':
                solrquery = 'content:"modality conventional radiograph"~3 AND '
            elif modality == 'NM':
                solrquery = 'content:"modality nuc med"~7 OR content:"Nuclear Medicine" AND '
            else:
                solrquery = 'content:"modality ' + modality + '"~7 AND '

        gender = args['gender']
        if gender != None:
            if gender == 'female':
                solrquery = 'content:"patient: female"~7 AND '
            elif gender == 'male':
                solrquery = 'content:"patient: male"~7 AND '

        # handle remaining cases
        for u in url_parameters[2:]:
            if args[u] != None:
                solrquery += 'content:"' + args[u] + '" AND '
        if solrquery.endswith(' AND '):
            solrquery = solrquery[:-5]

        # Setup a Solr instance.
        solr = pysolr.Solr('http://localhost:8983/solr/mypacs')

        # sample SOLR result
        # {
        #     'date':'2012-04-27T15:58:26Z',
        #     'boost':0.0,
        #     'lastModified':'2012-04-27T15:58:26Z',
        #     'url':'http://www.mypacs.net/cases/220339.html',
        #     'contentLength':'6876',
        #     'digest':'85dd4d2462da0ffecabe5ca711621cb4',
        #     'title':[
        #         'ANKLE PAIN FOLLOWING TRAUMA'
        #     ],
        #     'tstamp':'2015-12-20T04:54:49.803Z',
        #     'id':'net.mypacs.www:http/cases/220339.html',
        #     'content':'ANKLE PAIN FOLLOWING TRAUMA MyPACS.net: Radiology Teaching Files > Case 220339 \xa0 ANKLE PAIN FOLLOWING TRAUMA Contributed by: Lee Hoagland, Radiologist, University of Wisconsin, Madison, Wisconsin, USA. Patient: female History: Fall. Images: [small] larger Fig. 1: Axial CT through the distal tibia. Fig. 2: Sagittal CT reconstruction of the ankle. Fig. 3: Coronal CT reconstruction of the distal tibia. Findings: Fracture of the distal tibial epiphysis extending into the physis with widening of the lateral aspect of the growth plate. The medial portion of the physis is fused. Diagnosis: Juvenile Tillaux Fracture Comments: Nice case, Lee. Welcome to the club. -- Dean Thornton , 2003-11-13 Additional Details: Case Number: 220339 Last Updated: 2011-09-24 Anatomy: Skeletal System\xa0\xa0\xa0 Pathology: Trauma Modality: CT Access Level: Readable by all users The reader is fully responsible for confirming the accuracy of this content. Text and images may be copyrighted by the case author or institution. You can help keep MyPACS tidy: if you notice a case which is not useful (e.g. a test case) or inaccurate, please contact us .',
        #     '_version_':1518338815171756034,
        #     'type':[
        #         'text/html',
        #         'text',
        #         'html'
        #     ]
        # }

        print("solrquery: ", solrquery)
        results = solr.search(solrquery)
        counter = 1
        for result in results:
            document = {}
            document['id'] = uuid.uuid5(uuid.NAMESPACE_URL, result['url']).int
            document['resultID'] = counter
            document['source'] = 'MyPACS'
            document['resultTitle'] = result['title'][0]
            document['linkTitle'] = result['title'][0]
            document['articleLink'] = result['url']
            document['content'] = result['content']

            modality_pattern = re.compile('Modality: (.*) Access Level:')
            modality_result = modality_pattern.search(result['content'])
            if modality_result:
                document['modality'] = modality_result.groups()[0]
            else:
                document['modality'] = "See Article"

            lastupdated_pattern = re.compile('Last Updated: (\d{4}-\d{2}-\d{2})')
            lastupdated_result = lastupdated_pattern.search(result['content'])
            if lastupdated_result:
                document['date'] = lastupdated_result.groups()[0]

            counter += 1
            retval.append(document)

        # total number of matches found (will only see the first 10)
        print("    Total Solr results found: ", results.hits)

        if retval:
            return retval
        else:
            return {}

    @marshal_with(searchResults_fields, envelope='searchResults')
    def get(self):
        return solrSearch.search()

api.add_resource(solrSearch, '/solr' )

class searchResults(Resource):

    @marshal_with(searchResults_fields, envelope='searchResults')
    def get(self):
        # call yottalookSearch
        yr = yottalookSearch.search()

        # call solrSearch
        sr = solrSearch.search()

        if yr:
            print("Yottalook returned results")
        if sr:
            print("Solr returned restults")

        # combine results and return
        return yr + sr

api.add_resource(searchResults, '/searchResults' )

# these response headers allow for client side code to request resources
@app.after_request
def after_request(response):
  response.headers.add('Access-Control-Allow-Origin', '*')
  response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
  response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
  return response

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
<|endoftext|>