DRAW_BEADS = DrawingMethod('Beads', ('size', 'resolution'), {'size': 1., 'resolution': 12}) DRAW_BONDS = DrawingMethod('Bonds', ('size', 'resolution'), {'size': 0.3, 'resolution': 10}) DRAW_CARTOON = DrawingMethod('Cartoon', ('helix_size', 'resolution', 'sheet_size'),
                             {'helix_size': 2.1, 'resolution': 12, 'sheet_size': 5.}) DRAW_CPK = DrawingMethod('CPK', ('size', 'bond_radius', 'resolution', 'bond_resolution'),
                         {'size': 1., 'bond_radius': 0.3, 'resolution': 12, 'bond_resolution': 10}) DRAW_DOTTED = DrawingMethod('Dotted', ('size', 'resolution'), {'size': 1., 'resolution': 12}) DRAW_DYNAMIC_BONDS = DrawingMethod('DynamicBonds', ('cutoff', 'size', 'resolution'),
                                   {'cutoff': 3., 'size': 0.3, 'resolution': 10}) DRAW_FIELD_LINES = DrawingMethod('FieldLines', ('volume_id', 'gradient', 'min_length', 'max_length', 'size'),
                                 {'volume_id': 0, 'gradient': 1.8, 'min_length': 10, 'max_length': 50, 'size': 1}) DRAW_HBONDS = DrawingMethod('HBonds', ('cutoff', 'angle_cutoff', 'size'),
                            {'cutoff': 3., 'angle_cutoff': 20., 'size': 1.}) DRAW_ISOSURFACE = DrawingMethod('Isosurface', ('isovalue', 'volume_id', 'display', 'method', 'step', 'size'),
                                {'isovalue': 0.5, 'volume_id': 0, 'display': 2, 'method': 2, 'step': 1, 'size': 1}) DRAW_LICORICE = DrawingMethod('Licorice', ('size', 'resolution', 'bond_resolution'),
                              {'size': 0.3, 'resolution': 10, 'bond_resolution': 10}) DRAW_LINES = DrawingMethod('Lines', ('size', ), {'size': 1.}) DRAW_MSMS = DrawingMethod('MSMS', ('probe_radius', 'density', 'atoms', 'method'),
                          {'probe_radius': 1.5, 'density': 1.5, 'atoms': 0, 'method': 0}) DRAW_NEW_CARTOON = DrawingMethod('NewCartoon', ('thickness', 'resolution', 'width', 'spline'),
                                 {'thickness': 0.3, 'resolution': 10, 'width': 4.5, 'spline': 0}) DRAW_NEW_RIBBONS = DrawingMethod('NewRibbons', ('thickness', 'resolution', 'width', 'spline'),
                                 {'thickness': 0.3, 'resolution': 10, 'width': 3., 'spline': 0}) DRAW_ORBITAL = DrawingMethod(
    'Orbital',
    ('isovalue', 'orbital_id', 'display', 'method', 'grid_spacing', 'size', 'wavefunction', 'spin', 'excitation',
     'step'),
    {'isovalue': 0.05, 'orbital_id': 0, 'display': 0, 'method': 0, 'grid_spacing': 0.075, 'size': 1, 'wavefunction': 0,
     'spin': 0, 'excitation': 0, 'step': 1}
) DRAW_PAPER_CHAIN = DrawingMethod('PaperChain', ('height', 'max_ring_size'), {'height': 1., 'max_ring_size': 10}) DRAW_POINTS = DrawingMethod('Points', ('size', ), {'size': 1.}) DRAW_POLYHEDRA = DrawingMethod('Polyhedra', ('cutoff', ), {'cutoff': 3.}) DRAW_QUICKSURF = DrawingMethod('QuickSurf', ('sphere_scale', 'density_isovalue', 'grid_spacing', 'resolution'),
                               {'sphere_scale': 1., 'density_isovalue': 0.5, 'grid_spacing': 1., 'resolution': 0}) DRAW_RIBBONS = DrawingMethod('Ribbons', ('margin_size', 'resolution', 'size'),
                             {'margin_size': 0.3, 'resolution': 10, 'size': 2.}) DRAW_SOLVENT = DrawingMethod('Solvent', ('probe_radius', 'detail', 'method'),
                             {'probe_radius': 0, 'detail': 7, 'method': 1}) DRAW_SURF = DrawingMethod('Surf', ('probe_radius', 'method'), {'probe_radius': 1.4, 'method': 0}) DRAW_TRACE = DrawingMethod('Trace', ('size', 'resolution'), {'size': 0.3, 'resolution': 10}) DRAW_TUBE = DrawingMethod('Tube', ('size', 'resolution'), {'size': 0.3, 'resolution': 10}) DRAW_TWISTER = DrawingMethod(
    'Twister',
    ('start', 'hide_shared_links', 'steps', 'width', 'height', 'max_ring_size', 'linking_distance'),
    {'start': 1, 'hide_shared_links': 0, 'steps': 10, 'width': 0.3, 'height': 0.05, 'max_ring_size': 10,
     'linking_distance': 5},
) DRAW_VDW = DrawingMethod('VDW', ('size', 'resolution'), {'size': 1., 'resolution': 12}) DRAW_VOLUME_SLICE = DrawingMethod('VolumeSlice', ('slice', 'volume_id', 'axis', 'quality'),
                                  {'slice': 0.5, 'volume_id': 0, 'axis': 0, 'quality': 2}) class Representation(object):
    """
    Representation of molecule graphical representation.

    This class is a proxy for molecule represenation in VMD.
    """
    def __init__(self, name, molecule=None):
        """
        Creates a molecule representation.

        @param name: Representation identifier.
        @type name: String
        @param molecule: Molecule to select from. Top if not provided.
        @type molecule: Molecule or None
        """
        if molecule is None:
            molecule = MOLECULES.top
        else:
            assert isinstance(molecule, Molecule)
        self._molecule = molecule

        self._name = name
        # If the representation does not exists, complain immediately
        self.repindex

    def __repr__(self):
        return "<%s: '%s' of '%r'>" % (type(self).__name__, self._name, self._molecule)

    def __eq__(self, other):
        return type(self) == type(other) and self._molecule == other.molecule and self._name == other.name

    def __ne__(self, other):
        return not self.__eq__(other)

    @property
    def name(self):
        """Index"""
        return self._name

    @property
    def molecule(self):
        """Molecule"""
        return self._molecule

    @property
    def repindex(self):
        """Utility property to facilitate the VMD calls."""
        repindex = _molrep.repindex(self._molecule.molid, self._name)
        if repindex < 0:
            raise ValueError("Molecule %s does not have a representation '%s'." % (self._molecule, self._name))
        return repindex

    @classmethod
    def create(cls, molecule=None):
        """
        Creates new molecule representation.

        @param molecule: Molecule to select from. Top if not provided.
        @type molecule: Molecule or None
        """
        if molecule is None:
            molecule = MOLECULES.top
        else:
            assert isinstance(molecule, Molecule)
        _molrep.addrep(molecule.molid)
        # XXX: `addrep` has no return value, get the index of the newly created representation from their number.
        index = _molrep.num(molecule.molid) - 1
        name = _molrep.get_repname(molecule.molid, index)

        return cls(name, molecule)

    def delete(self):
        """
        Deletes the molecule representation.
        """
        _molrep.delrep(self._molecule.molid, self.repindex)

    ############################################################################
    # Representation properties
    def _get_selection(self):
        return Selection(_molrep.get_selection(self._molecule.molid, self.repindex), self._molecule)

    def _set_selection(self, selection):
        assert isinstance(selection, Selection)
        assert self._molecule == selection.molecule
        _modrep(self, sel=selection.selection)

    selection = property(_get_selection, _set_selection, doc="Selection")

    def _get_visible(self):
        return _molrep.get_visible(self._molecule.molid, self.repindex)

    def _set_visible(self, value):
        """
        Sets visibility

        @type value: Boolean
        """
        _molrep.set_visible(self._molecule.molid, self.repindex, value)

    visible = property(_get_visible, _set_visible, doc="Visibility")

    def _get_update_selection(self):
        return _molrep.get_autoupdate(self._molecule.molid, self.repindex)

    def _set_update_selection(self, value):
        """
        Sets selection update

        @type value: Boolean
        """
        _molrep.set_autoupdate(self._molecule.molid, self.repindex, value)

    update_selection = property(_get_update_selection, _set_update_selection, doc="Update selection every frame")

    def _get_update_color(self):
        return _molrep.get_colorupdate(self._molecule.molid, self.repindex)

    def _set_update_color(self, value):
        """
        Sets color update

        @type value: Boolean
        """
        _molrep.set_colorupdate(self._molecule.molid, self.repindex, value)

    update_color = property(_get_update_color, _set_update_color, doc="Update color every frame")

    @property
    def style(self):
        """Graphical style"""
        return Style(self)

    @property
    def color(self):
        """Color"""
        return Color(self) def data(filename):
    """
    Return full filename of the test datafile.
    """
    return os.path.join(os.path.dirname(__file__), 'data', filename) class PyvmdTestCase(unittest.TestCase):
    """
    Enhanced test case for pyvmd tests.
    """
    def tearDown(self):
        # Delete all molecule when we're finished
        for molid in VMD.molecule.listall():
            VMD.molecule.delete(molid)
        # Restore Collector's auto_name_counter
        Collector.auto_name_counter = 0

    def assertAlmostEqualSeqs(self, seq1, seq2, places=None, msg=None, delta=None):
        """
        An assertion for ordered sequences. Compares items one by one with
        their differences rounded to the given number of decimal places (default 7).

        Note that decimal places (from zero) are usually not the same
        as significant digits (measured from the most signficant digit).

        If the two objects compare equal then they will automatically
        compare almost equal.
        """
        # This method is copied from unittest's assertSequenceEqual method.
        seq_type_name = "sequence"
        differing = None
        try:
            len1 = len(seq1)
        except (TypeError, NotImplementedError):
            differing = 'First %s has no length.    Non-sequence?' % (
                        seq_type_name)

        if differing is None:
            try:
                len2 = len(seq2)
            except (TypeError, NotImplementedError):
                differing = 'Second %s has no length.    Non-sequence?' % (
                            seq_type_name)

        if differing is None:
            if seq1 == seq2:
                return

            seq1_repr = safe_repr(seq1)
            seq2_repr = safe_repr(seq2)
            if len(seq1_repr) > 30:
                seq1_repr = seq1_repr[:30] + '...'
            if len(seq2_repr) > 30:
                seq2_repr = seq2_repr[:30] + '...'
            elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
            differing = '%ss differ: %s != %s\n' % elements

            for i in xrange(min(len1, len2)):
                try:
                    item1 = seq1[i]
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('\nUnable to index element %d of first %s\n' %
                                  (i, seq_type_name))
                    break

                try:
                    item2 = seq2[i]
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('\nUnable to index element %d of second %s\n' %
                                  (i, seq_type_name))
                    break

                try:
                    self.assertAlmostEqual(item1, item2, places=places, delta=delta)
                except self.failureException, error:
                    differing += ('\nFirst differing element %d:\n%s\n' %
                                  (i, error))
                    break
            else:
                if len1 == len2:
                    # The sequences are the same.
                    return

            if len1 > len2:
                differing += ('\nFirst %s contains %d additional '
                              'elements.\n' % (seq_type_name, len1 - len2))
                try:
                    differing += ('First extra element %d:\n%s\n' %
                                  (len2, seq1[len2]))
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('Unable to index element %d '
                                  'of first %s\n' % (len2, seq_type_name))
            elif len1 < len2:
                differing += ('\nSecond %s contains %d additional '
                              'elements.\n' % (seq_type_name, len2 - len1))
                try:
                    differing += ('First extra element %d:\n%s\n' %
                                  (len1, seq2[len1]))
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('Unable to index element %d '
                                  'of second %s\n' % (len1, seq_type_name))
        standardMsg = differing
        diffMsg = '\n' + '\n'.join(
            difflib.ndiff(pprint.pformat(seq1).splitlines(),
                          pprint.pformat(seq2).splitlines()))
        standardMsg = self._truncateMessage(standardMsg, diffMsg)
        msg = self._formatMessage(msg, standardMsg)
        self.fail(msg)
from VMD import molecule as _molecule, molrep as _molrep
from pyvmd.representations import (DRAW_BEADS, DRAW_BONDS, DRAW_CARTOON, DRAW_CPK, DRAW_DOTTED, DRAW_DYNAMIC_BONDS,
                                   DRAW_FIELD_LINES, DRAW_HBONDS, DRAW_ISOSURFACE, DRAW_LICORICE, DRAW_LINES, DRAW_MSMS,
                                   DRAW_NEW_CARTOON, DRAW_NEW_RIBBONS, DRAW_ORBITAL, DRAW_PAPER_CHAIN, DRAW_POINTS,
                                   DRAW_POLYHEDRA, DRAW_QUICKSURF, DRAW_RIBBONS, DRAW_SOLVENT, DRAW_SURF, DRAW_TRACE,
                                   DRAW_TUBE, DRAW_TWISTER, DRAW_VDW, DRAW_VOLUME_SLICE, Representation)
from .utils import data, PyvmdTestCase

    def test_new_ribbons(self):
        self.style.method = DRAW_NEW_RIBBONS
        self.assertEqual(self.style.method, DRAW_NEW_RIBBONS)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 10, 'width': 3, 'spline': 0})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewRibbons')

        self.style.set_parameters(width=5.)
        self.assertEqual(self.style.method, DRAW_NEW_RIBBONS)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 10, 'width': 5, 'spline': 0})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewRibbons 0.3 10 5.0 0')

        self.style.set_parameters(resolution=20.)
        self.assertEqual(self.style.method, DRAW_NEW_RIBBONS)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 20, 'width': 5, 'spline': 0})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewRibbons 0.3 20.0 5.0 0.0')

        self.style.set_parameters(spline=1)
        self.assertEqual(self.style.method, DRAW_NEW_RIBBONS)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 20, 'width': 5, 'spline': 1})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewRibbons 0.3 20.0 5.0 1')

        self.style.set_parameters(thickness=0.7)
        self.assertEqual(self.style.method, DRAW_NEW_RIBBONS)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.7, 'resolution': 20, 'width': 5, 'spline': 1})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewRibbons 0.7 20.0 5.0 1.0')

    def test_cartoon(self):
        self.style.method = DRAW_CARTOON
        self.assertEqual(self.style.method, DRAW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'helix_size': 2.1, 'resolution': 12, 'sheet_size': 5})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Cartoon')

        self.style.set_parameters(helix_size=3.)
        self.assertEqual(self.style.method, DRAW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'helix_size': 3, 'resolution': 12, 'sheet_size': 5})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Cartoon 3.0 12 5.0')

        self.style.set_parameters(resolution=20.)
        self.assertEqual(self.style.method, DRAW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'helix_size': 3, 'resolution': 20, 'sheet_size': 5})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Cartoon 3.0 20.0 5.0')

        self.style.set_parameters(sheet_size=0.7)
        self.assertEqual(self.style.method, DRAW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'helix_size': 3, 'resolution': 20, 'sheet_size': 0.7})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Cartoon 3.0 20.0 0.7')

    def test_new_cartoon(self):
        self.style.method = DRAW_NEW_CARTOON
        self.assertEqual(self.style.method, DRAW_NEW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 10, 'width': 4.5, 'spline': 0})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewCartoon')

        self.style.set_parameters(width=5.)
        self.assertEqual(self.style.method, DRAW_NEW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 10, 'width': 5, 'spline': 0})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewCartoon 0.3 10 5.0 0')

        self.style.set_parameters(resolution=20.)
        self.assertEqual(self.style.method, DRAW_NEW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 20, 'width': 5, 'spline': 0})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewCartoon 0.3 20.0 5.0 0.0')

        self.style.set_parameters(spline=1)
        self.assertEqual(self.style.method, DRAW_NEW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.3, 'resolution': 20, 'width': 5, 'spline': 1})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewCartoon 0.3 20.0 5.0 1')

        self.style.set_parameters(thickness=0.7)
        self.assertEqual(self.style.method, DRAW_NEW_CARTOON)
        self.assertEqual(self.style.get_parameters(), {'thickness': 0.7, 'resolution': 20, 'width': 5, 'spline': 1})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'NewCartoon 0.7 20.0 5.0 1.0')

    def test_paper_chain(self):
        self.style.method = DRAW_PAPER_CHAIN
        self.assertEqual(self.style.method, DRAW_PAPER_CHAIN)
        self.assertEqual(self.style.get_parameters(), {'height': 1, 'max_ring_size': 10})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'PaperChain')

        self.style.set_parameters(height=3.)
        self.assertEqual(self.style.method, DRAW_PAPER_CHAIN)
        self.assertEqual(self.style.get_parameters(), {'height': 3, 'max_ring_size': 10})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'PaperChain 3.0 10')

        self.style.set_parameters(max_ring_size=12.)
        self.assertEqual(self.style.method, DRAW_PAPER_CHAIN)
        self.assertEqual(self.style.get_parameters(), {'height': 3, 'max_ring_size': 12})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'PaperChain 3.0 12.0')

    def test_twister(self):
        self.style.method = DRAW_TWISTER
        self.assertEqual(self.style.method, DRAW_TWISTER)
        self.assertEqual(self.style.get_parameters(),
                         {'start': 1, 'hide_shared_links': 0, 'steps': 10, 'width': 0.3, 'height': 0.05,
                          'max_ring_size': 10, 'linking_distance': 5})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Twister')

        self.style.set_parameters(width=0.5)
        self.assertEqual(self.style.method, DRAW_TWISTER)
        self.assertEqual(self.style.get_parameters(),
                         {'start': 1, 'hide_shared_links': 0, 'steps': 10, 'width': 0.5, 'height': 0.05,
                          'max_ring_size': 10, 'linking_distance': 5})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Twister 1 0 10 0.5 0.05 10 5')

        self.style.set_parameters(height=0.1)
        self.assertEqual(self.style.method, DRAW_TWISTER)
        self.assertEqual(self.style.get_parameters(),
                         {'start': 1, 'hide_shared_links': 0, 'steps': 10, 'width': 0.5, 'height': 0.1,
                          'max_ring_size': 10, 'linking_distance': 5})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Twister 1.0 0.0 10.0 0.5 0.1 10.0 5.0')

        self.style.set_parameters(start=0.)
        self.assertEqual(self.style.method, DRAW_TWISTER)
        self.assertEqual(self.style.get_parameters(),
                         {'start': 0, 'hide_shared_links': 0, 'steps': 10, 'width': 0.5, 'height': 0.1,
                          'max_ring_size': 10, 'linking_distance': 5})
        self.assertEqual(_molrep.get_style(self.molid, 0), 'Twister 0.0 0.0 10.0 0.5 0.1 10.0 5.0')

        self.style.set_parameters(hide_shared_links=1.)

        self.assertEqual(self.style.method, DRAW_TWISTER)