Esempio n. 1
0
 def selections_group(self):
     """Group all selections"""
     cmd.group('Structures', '%s %s %sCartoon' % (self.protname, self.ligname, self.protname))
     cmd.group('Interactions', 'Hydrophobic HBonds HalogenBonds WaterBridges PiCation PiStackingP PiStackingT '
                               'Saltbridges MetalComplexes')
     cmd.group('Atoms', '')
     cmd.group('Atoms.Protein', 'Hydrophobic-P HBondAccept-P HBondDonor-P HalogenAccept Centroids-P PiCatRing-P '
                                'StackRings-P PosCharge-P NegCharge-P AllBSRes Chargecenter-P  Metal-P')
     cmd.group('Atoms.Ligand', 'Hydrophobic-L HBondAccept-L HBondDonor-L HalogenDonor Centroids-L NegCharge-L '
                               'PosCharge-L NegCharge-L ChargeCenter-L StackRings-L PiCatRing-L Metal-L Metal-M '
                               'Unpaired-HBA Unpaired-HBD Unpaired-HAL Unpaired-RINGS')
     cmd.group('Atoms.Other', 'Water Metal-W')
     cmd.order('*', 'y')
Esempio n. 2
0
    def test(self):
        names_ungrouped = ['a0', 'a1', 'b0', 'b1', 'c0', 'c1', 'g1']
        names_grouped   = ['a0', 'a1', 'c0', 'c1', 'b0', 'g1', 'b1']

        for name in names_ungrouped[:-1]:
            cmd.pseudoatom(name)
        cmd.group(names_ungrouped[-1])

        self.assertEqual(cmd.get_names(), names_ungrouped)

        cmd.group('g1', 'b*')
        cmd.order('b0 g1', location="upper")

        self.assertEqual(cmd.get_names(), names_grouped)
Esempio n. 3
0
    def testOrder(self):
        # proper group ordering only in incentive, see jira/PYMOL-1382.py

        for i in range(3):
            cmd.pseudoatom('m%i' % i)
        self.assertEqual(cmd.get_names(), ['m0', 'm1', 'm2'])

        cmd.order('m2 m1')
        self.assertEqual(cmd.get_names(), ['m0', 'm2', 'm1'])

        cmd.order('m2 m1', location="top")
        self.assertEqual(cmd.get_names(), ['m2', 'm1', 'm0'])

        cmd.order('m2', location="bottom")
        self.assertEqual(cmd.get_names(), ['m1', 'm0', 'm2'])

        cmd.order('m2 m0', location="upper")
        self.assertEqual(cmd.get_names(), ['m1', 'm2', 'm0'])

        cmd.order('*', 'yes')
        self.assertEqual(cmd.get_names(), ['m0', 'm1', 'm2'])
Esempio n. 4
0
    def testOrder(self):
        # proper group ordering only in incentive, see jira/PYMOL-1382.py

        for i in range(3):
            cmd.pseudoatom('m%i' % i)
        self.assertEqual(cmd.get_names(), ['m0', 'm1', 'm2'])

        cmd.order('m2 m1')
        self.assertEqual(cmd.get_names(), ['m0', 'm2', 'm1'])

        cmd.order('m2 m1', location="top")
        self.assertEqual(cmd.get_names(), ['m2', 'm1', 'm0'])

        cmd.order('m2', location="bottom")
        self.assertEqual(cmd.get_names(), ['m1', 'm0', 'm2'])

        cmd.order('m2 m0', location="upper")
        self.assertEqual(cmd.get_names(), ['m1', 'm2', 'm0'])

        cmd.order('*', 'yes')
        self.assertEqual(cmd.get_names(), ['m0', 'm1', 'm2'])
Esempio n. 5
0
def ramp_levels(name, levels, quiet=1):
    '''
DESCRIPTION

    Changes the slot levels of a ramp.

SEE ALSO

    ramp_new, isolevel
    '''
    quiet = int(quiet)
    if cmd.is_string(levels):
        levels = cmd.safe_list_eval(levels)

    try:
        position = cmd.get_names('all').index(name)

        odata = cmd.get_session(name, 1, 1, 0, 0)['names'][0]
        if odata[4] != 8:
            raise TypeError('not a ramp')
        data = odata[5]
    except:
        print(' Error: Get session data for ramp "%s" failed' % (name))
        raise CmdException

    if len(levels) != len(data[3]):
        print(' Error: number of levels must agree with existing object')
        raise CmdException

    map_name = data[6]
    colors = [data[4][i:i+3] for i in range(0, len(data[4]), 3)]
    cmd.ramp_new(name, map_name, levels, colors, quiet=quiet)

    # restore original position
    if position == 0:
        cmd.order(name, location='top')
    else:
        cmd.order(cmd.get_names('all')[position-1] + ' ' + name)
Esempio n. 6
0
def ramp_levels(name, levels, quiet=1):
    '''
DESCRIPTION

    Changes the slot levels of a ramp.

SEE ALSO

    ramp_new, isolevel
    '''
    quiet = int(quiet)
    if cmd.is_string(levels):
        levels = cmd.safe_list_eval(levels)

    try:
        position = cmd.get_names('all').index(name)

        odata = cmd.get_session(name, 1, 1, 0, 0)['names'][0]
        if odata[4] != 8:
            raise TypeError('not a ramp')
        data = odata[5]
    except:
        print(' Error: Get session data for ramp "%s" failed' % (name))
        raise CmdException

    if len(levels) != len(data[3]):
        print(' Error: number of levels must agree with existing object')
        raise CmdException

    map_name = data[6]
    colors = [data[4][i:i + 3] for i in range(0, len(data[4]), 3)]
    cmd.ramp_new(name, map_name, levels, colors, quiet=quiet)

    # restore original position
    if position == 0:
        cmd.order(name, location='top')
    else:
        cmd.order(cmd.get_names('all')[position - 1] + ' ' + name)
Esempio n. 7
0
def plot_noe(filename, line_color=None, line_width='1.0', advanced_coloring=0, single=0, quiet=1, aria=0, per_atom=0,
             per_residue=1):
    """
DESCRIPTION

    A function for plotting XPLOR NOE restraints on a structure

ARGUMENTS

    filename = string: The filename of the NOE retraint file in XPLOR NIH format.

    line_color = string: The color for the NOE lines. {default: yellow}

    line_width = float: The thickness of the NOE lines. {default: 1.0}

    advanced_coloring = color restraints by distance.

    single = string: create a single object for all restraints.

    aria = integer: Name NOEs after Aria IDs.

    per_atom: Group NOEs on atom basis

    per_residue: Group NOEs on residue basis (default)

NOE Restraint Format Example

    assign (residue 5 and name HB#) (residue 21 and name HA) 3.0 0.7 0.7

EXAMPLE

    PyMOL> plot_noe noe_short.tbl
    """

    single, quiet, aria, per_residue, per_atom, advanced_coloring = \
        int(single), int(quiet), int(aria), int(per_residue), int(per_atom), int(advanced_coloring)

    count = 0

    if advanced_coloring == 1:
        cmd.set("group_auto_mode", 2)

    rgx_assi = re.compile("\s*[asignASIGN]+\s+.*")
    rgx_or = re.compile("\s*[orOR]+\s+.*")
    rgx_bracket = re.compile("(\(|\))")
    rgx_tick = re.compile("(\w)\'")

    restraint_line = None
    restraint_block = []
    restraints_blocks = []

    for line in open(filename):
        if rgx_assi.match(line):
            if restraint_line:
                restraint_block.append(rgx_tick.sub("\g<1>^", rgx_bracket.sub(" ", restraint_line)))
                restraints_blocks.append(restraint_block)
            restraint_block = []
            restraint_line = line
        elif rgx_or.match(line):
            restraint_block.append(rgx_tick.sub("\g<1>^", rgx_bracket.sub(" ", restraint_line)))
            restraint_line = line
        else:
            restraint_line += line

    restraint_block.append(rgx_tick.sub("\g<1>^", rgx_bracket.sub(" ", restraint_line)))
    restraints_blocks.append(restraint_block)

    for restraint_block in restraints_blocks:
        restraints = {"connections": []}

        try:
            shlex_split = shlex.split(restraint_block[0])
        except ValueError:
            print('Cannot process "%s"' % restraint_block[0])
        try:
            restraints["distance"] = float(shlex_split[11].strip())
        except IndexError:
            print('Cannot process "%s"' % "".join(restraint_block))
            continue
        except ValueError:
            try:
                restraints["distance"] = float(shlex_split[17].strip())
            except ValueError:
                print("Failed to extract distance, setting to 1A")
                restraints["distance"] = 1

        if len(shlex_split) > 20:
            restraints["ID"] = shlex_split[26][3:-1].strip()
        else:
            restraints["ID"] = str(count + 1)

        for restraint_line in restraint_block:
            distance = {}
            try:
                shlex_split = shlex.split(restraint_line)

                if len(shlex_split) > 6:
                    if shlex_split[1].strip().lower() == shlex_split[9].strip().lower() == "segid":
                        distance["src_segid"] = shlex_split[2].strip()
                        distance["src_resid"] = shlex_split[5].strip()
                        distance["src_atom"] = shlex_split[8].strip().replace("^", "'")
                        distance["dst_segid"] = shlex_split[10].strip()
                        distance["dst_resid"] = shlex_split[13].strip()
                        distance["dst_atom"] = shlex_split[16].strip().replace("^", "'")
                    else:
                        distance["src_segid"] = "A"
                        distance["src_resid"] = shlex_split[2].strip()
                        distance["src_atom"] = shlex_split[5].strip().replace("^", "'")
                        distance["dst_segid"] = "A"
                        distance["dst_resid"] = shlex_split[10].strip()
                        distance["dst_atom"] = shlex_split[13].strip().replace("^", "'")

                else:
                    print('Cannot process "%s"' % restraint_line)
                    continue
            except IndexError:
                print('Cannot process "%s"' % restraint_line)
                continue
            except ValueError:
                print('Cannot process "%s"' % restraint_line)
                continue

            restraints["connections"].append(distance)

        count += _draw_restraint(
            restraints,
            line_color,
            line_width,
            single,
            quiet,
            per_residue,
            per_atom,
            advanced_coloring
        )

    if not quiet:
        print(' Info: Created distance objects for %d restraints' % count)

    cmd.order("NOE*", "yes")
def plot_noe(filename, selection='', line_color='gray20', line_width='1.0', single=0, quiet=1, aria=0, per_atom=0, per_residue=1):
    """
DESCRIPTION

    A function for plotting XPLOR NOE restraints on a structure

ARGUMENTS

    filename = string: The filename of the NOE retraint file in XPLOR NIH format.

    selection = string: atom selection {default: all}

    line_color = string: The color for the NOE lines. {default: black}

    line_width = float: The thickness of the NOE lines. {default: 1.0}

    aria = integer: Name NOEs after Aria IDs.

    per_atom: Group NOEs on atom basis

    per_residue: Group NOEs on residue basis (default)

NOE Restraint Format Example

    assign (residue 5 and name HB#) (residue 21 and name HA) 3.0 0.7 0.7

EXAMPLE

    PyMOL> plot_noe noe_short.tbl
    """
    from pymol.parsing import split

    single, quiet, aria, per_residue, per_atom = int(single), int(quiet), int(aria), int(per_residue), int(per_atom)

    count = 0
    parent_id = None

    rgx_restraint = re.compile(
                        r"""
                            \s*(?P<parent>\w*)\s+\(
                            (segid\s+\"\s*(?P<src_segid>[\w\d]+)\"\s+and\s+)?
                            resid\s+(?P<src_resid>\d+)\s+and\s+
                            name\s+(?P<src_atom>[\w\d]+)
                            \)\s+\(
                            (segid\s+\"\s+(?P<dst_segid>[\w\d]+)\"\s+and\s+)?
                            resid\s*(?P<dst_resid>\d+)\s+and\s+
                            name\s*(?P<dst_atom>[\w\d]+)
                            \)
                            (\s+(?P<dist>[\d\.]+))?
                            (.*id=(?P<ID>\d+))?
                            .*
                        """, re.X)


    for line in open(filename):
        restraint = rgx_restraint.match(line)
        count += 1

        if restraint:
            restraint = restraint.groupdict()

            if restraint["src_segid"] == None:
                restraint["src_segid"] = "A"

            if restraint["dst_segid"] == None:
                restraint["dst_segid"] = "A"

            if restraint["parent"][:4].upper() == "ASSI":
                parent = restraint

            sele1 = 'segid %s and resi %s and name %s' % (restraint["src_segid"], restraint["src_resid"], restraint["src_atom"])
            sele2 = 'segid %s and resi %s and name %s' % (restraint["dst_segid"], restraint["dst_resid"], restraint["dst_atom"])

            if single:
                label = "NOE"

            elif aria and restraint["ID"]:
                label = "NOE_" + restraint["ID"]
            elif aria and parent and parent["ID"]:
                label = "NOE_" + parent["ID"]

            elif per_atom:
                label = "NOE_%s_%s_%s" % (restraint["dst_segid"], restraint["dst_resid"], restraint["dst_atom"])
            elif per_residue:
                label = "NOE_%s_%s" % (restraint["dst_segid"], restraint["dst_resid"])

            elif restraint["parent"][:4].upper() == "ASSI":
                label = parent_id
            else:
                parent_id = "NOE_%d" % count
                label = parent_id

            try:
                cmd.distance(label, sele1, sele2, quiet=quiet,
                        width=line_width, gap=0, label=0)
            except CmdException:
                print 'FAILED: %s - %s' % (sele1, sele2)
                continue

            cmd.set("dash_color", line_color, label)
        else:
            print line

    cmd.order("NOE*", "yes")

    if not quiet:
        print ' Info: Created distance objects for %d restraints' % (count)
Esempio n. 9
0
def read_moestr(contents,
                object,
                state=0,
                finish=1,
                discrete=1,
                quiet=1,
                zoom=-1,
                _self=cmd):
    moestr = contents
    name = object

    import sys
    if sys.version_info[0] > 2 and isinstance(moestr, bytes):
        moestr = moestr.decode()

    cmd = _self
    mr = MOEReader()
    mr.appendFromStr(moestr)
    split_chains = cmd.get_setting_int("moe_separate_chains")
    cmd.group(name)
    if hasattr(mr, 'system'):
        have_valences = 0
        chain_count = 0
        cmd.set_color("_aseg0", [1.0, 1.0, 1.0])
        aseg_color = cmd.get_color_index("_aseg0")
        aseg_flag = 0
        aseg_rep = {}
        model = Indexed()
        molecule = mr.system['molecule']
        if 'atoms' in molecule:
            n_atom = molecule['atoms']
            model.atom = [Atom() for x in range(n_atom)]
        residues = {}
        chains = {}
        for columns, data in molecule['attr']:
            for row in data:
                cur_atom = None
                for key, value in zip(columns, row):
                    key = key[0]
                    if key == 'ID':
                        ID = value
                    else:
                        aProp = _atom_prop_map.get(key, None)
                        if aProp != None:
                            setattr(model.atom[ID - 1], aProp, value)
                        else:
                            xyz = _atom_coord_map.get(key, None)
                            if xyz != None:
                                coord = list(model.atom[ID - 1].coord)
                                coord[xyz] = value
                                model.atom[ID - 1].coord = coord
                            elif key in _atom_vis_map:
                                atom = model.atom[ID - 1]
                                if hasattr(atom, 'visible'):
                                    visible = atom.visible
                                else:
                                    visible = _default_visible
                                if key == 'aBondLook':
                                    if value == 'cylinder':
                                        atom.visible = 0x00000001 | visible
                                    elif value == 'line':
                                        atom.visible = 0x00000080 | visible
                                    elif value == 'none':
                                        atom.visible = -129 & Visible  # 0xFFFFFF7F
                                elif key == 'aNucleusLook':
                                    if value == 'sphere':
                                        atom.visible = 0x00000002 | visible
                                    elif value == 'small-sphere':  # need to set sphere_scale=0.2 for these atoms
                                        atom.visible = 0x00000002 | visible
                                        atom.sphere_scale = 0.2
                                    elif value == 'point':  # nonbonded
                                        atom.visible = 0x00000800 | visible
                                    elif value == 'none':
                                        atom.visible = -2067 & visible  # 0xFFFFF7ED
                                elif key == 'aHidden':
                                    atom.visible = 0
                                    atom.hidden = 1
                                if hasattr(
                                        atom, 'hidden'
                                ):  # be sure that hidden atoms aren't shown
                                    atom.visible = 0
                            elif key in _atom_color_map:
                                if key == 'aRGB':
                                    model.atom[ID - 1].trgb = value
                                elif key == 'aColorBy':
                                    model.atom[ID - 1].aColorBy = value
                            elif key in _atom_label_map:
                                atom = model.atom[ID - 1]
                                if hasattr(atom, 'label_dict'):
                                    atom.label_dict[key] = None
                                else:
                                    atom.label_dict = {key: None}
                            elif key in _residue_prop_map:
                                resi_dict = residues.get(ID, {})
                                resi_dict[key] = value
                                residues[ID] = resi_dict
                            elif key in _chain_prop_map:
                                chain_dict = chains.get(ID, {})
                                if ID not in chains:
                                    chain_count = chain_count + 1
                                    chain_dict['count'] = chain_count
                                chain_dict[key] = value
                                chains[ID] = chain_dict
        chn_keys = list(chains.keys())
        chn_keys.sort()
        res_keys = list(residues.keys())
        res_keys.sort()
        # map chain properties onto residues
        chn_resi = 0
        ch_colors = copy.deepcopy(_ch_colors)
        unique_chain_names = {}
        for chn_idx in chn_keys:
            chain_dict = chains[chn_idx]
            cName = make_valid_name(chain_dict.get('cName', ''))
            segi = cName[0:4]
            chain = cName[-1:]
            if not len(cName):
                if 'count' in chain_dict:
                    cName = "chain_" + str(chain_dict['count'])
                else:
                    cName = str(chn_idx)
            if cName not in unique_chain_names:
                unique_chain_names[cName] = cName
            else:
                cnt = 2
                while (cName + "_" + str(cnt)) in unique_chain_names:
                    cnt = cnt + 1
                newCName = cName + "_" + str(cnt)
                unique_chain_names[newCName] = cName
                cName = newCName
            chain_dict['chain_color'] = ch_colors[0]
            ch_colors = ch_colors[1:] + [ch_colors[0]]
            cResCount = chain_dict.get('cResidueCount', 0)
            for res_idx in range(chn_resi, chn_resi + cResCount):
                resi_dict = residues[res_keys[res_idx]]
                resi_dict['chain'] = chain
                resi_dict['segi'] = segi
                resi_dict['cName'] = cName
                resi_dict['chain_dict'] = chain_dict
            chn_resi = chn_resi + cResCount
        # map residue properties onto atoms
        res_atom = 0
        for res_idx in res_keys:
            resi_dict = residues[res_idx]
            rRibbonMode = resi_dict.get('rRibbonMode', 'none')
            rAtomCount = resi_dict['rAtomCount']
            rType = resi_dict.get('rType', '')
            if rAtomCount > 0:
                for at_idx in range(res_atom, res_atom + rAtomCount):
                    atom = model.atom[at_idx]
                    setattr(
                        atom, 'resi',
                        string.strip(
                            str(resi_dict.get('rUID', '')) +
                            resi_dict.get('rINS', '')))
                    setattr(atom, 'resn', resi_dict.get('rName', ''))
                    setattr(atom, 'chain', resi_dict.get('chain', ''))
                    setattr(atom, 'segi', resi_dict.get('segi', ''))
                    setattr(atom, 'custom', resi_dict.get('cName', ''))
                    # add labels
                    if hasattr(atom, 'label_dict'):
                        label = ''
                        label_dict = atom.label_dict
                        if 'aLabelElement' in label_dict:
                            label = atom.symbol
                        if 'aLabelRes' in label_dict:
                            if len(label):
                                label = label + ","
                            label = label + atom.resn + "_" + atom.resi
                        if 'aLabelName' in label_dict:
                            if len(label):
                                label = label + "."
                            label = label + atom.name
                        atom.label = label
                    if rType not in ['none', 'heme']:
                        atom.hetatm = 0  # all normal atoms
                    else:
                        atom.flags = 0x02000000  # hetatom or ligand -- ignore when surfacing

                    if rRibbonMode != 'none':
                        if hasattr(atom, 'visible'):
                            visible = atom.visible
                        else:
                            visible = _default_visible

                        rRibbonColorBy = resi_dict['rRibbonColorBy']
                        repeat = 1
                        while repeat:
                            repeat = 0
                            if rRibbonColorBy in ['rgb', 'r:rgb'
                                                  ]:  # handled automatically
                                pass
                            elif rRibbonColorBy == 'chain':
                                chain_dict = resi_dict['chain_dict']
                                cColorBy = chain_dict['cColorBy']
                                if cColorBy == 'rgb':
                                    cColorBy = 'c:rgb'
                                rRibbonColorBy = cColorBy
                                repeat = 1

                        rRibbon_color = 0
                        rRibbon_trgb = 0xFFFFFF  # default -- white

                        # now color ribbon
                        if rRibbonColorBy == 'r:rgb':
                            rRibbon_trgb = resi_dict.get('rRGB', 0xFFFFFF)
                        elif rRibbonColorBy == 'rgb':
                            rRibbon_trgb = resi_dict.get(
                                'rRibbonRGB', 0xFFFFFF)
                        elif rRibbonColorBy == 'c:rgb':
                            chain_dict = resi_dict['chain_dict']
                            rRibbon_trgb = chain_dict.get('cRGB', 0xFFFFFF)
                        elif rRibbonColorBy == 'r:aseg':
                            rRibbon_trgb = None
                            rRibbon_color = aseg_color
                            aseg_flag = 1
                        elif rRibbonColorBy == 'tempfactor':
                            pass  # TO DO
                        elif rRibbonColorBy == 'c:number':  # per chain colors
                            rRibbon_trgb = chain_dict['chain_color']
                        if rRibbonMode in ['line', 'trace']:
                            atom.visible = 0x00000040 | visible  # PyMOL ribbon
                            if rRibbon_trgb != None:
                                atom.ribbon_trgb = rRibbon_trgb
                            else:
                                atom.ribbon_color = rRibbon_color
                            aseg_rep['ribbon'] = 1
                        else:
                            atom.visible = 0x00000020 | visible  # PyMOL cartoon
                            if rRibbon_trgb != None:
                                atom.cartoon_trgb = rRibbon_trgb
                            else:
                                atom.cartoon_color = rRibbon_color
                            aseg_rep['cartoon'] = 1

                    if hasattr(atom, 'label'):
                        if hasattr(atom, 'visible'):
                            visible = atom.visible
                        else:
                            visible = _default_visible
                        atom.visible = 0x00000028 | visible  # labels
                    if not hasattr(atom, 'aColorBy'):
                        atom.aColorBy = 'element'
                    if hasattr(atom, 'aColorBy'):
                        aColorBy = atom.aColorBy
                        repeat = 1
                        while repeat:
                            repeat = 0
                            if aColorBy == 'ribbon':
                                aColorBy = resi_dict.get('rRibbonColorBy')
                                if aColorBy == 'rgb':
                                    aColorBy = 'rib:rgb'
                                else:
                                    repeat = 1
                                # TO DO still need to handle "cartoon_color", "ribbon_color"
                            elif aColorBy == 'element':
                                if hasattr(atom, 'trgb'):
                                    del atom.trgb
                            elif aColorBy in ['rgb', 'a:rgb'
                                              ]:  # handled automatically
                                pass
                            elif aColorBy == 'residue':
                                rColorBy = resi_dict.get('rColorBy')
                                if rColorBy == 'rgb':
                                    rColorBy = 'r:rgb'
                                aColorBy = rColorBy
                                repeat = 1
                            elif aColorBy == 'chain':
                                chain_dict = resi_dict['chain_dict']
                                cColorBy = chain_dict['cColorBy']
                                if cColorBy == 'rgb':
                                    cColorBy = 'c:rgb'
                                aColorBy = cColorBy
                                repeat = 1

                        # now color atom...
                        if aColorBy == 'r:rgb':
                            atom.trgb = resi_dict.get('rRGB', 0xFFFFFF)
                        elif aColorBy == 'rib:rgb':
                            atom.trgb = resi_dict.get('rRibbonRGB', 0xFFFFFF)
                        elif aColorBy == 'c:rgb':
                            chain_dict = resi_dict['chain_dict']
                            atom.trgb = chain_dict.get('cRGB', 0xFFFFFF)
                        elif aColorBy == 'r:aseg':
                            pass  # TO DO
                        elif aColorBy == 'tempfactor':
                            pass  # TO DO
                        elif aColorBy == 'c:number':  # per chain colors
                            atom.trgb = chain_dict['chain_color']

                res_atom = res_atom + rAtomCount
        bond_list = molecule.get('bond', [])
        for bond in bond_list:
            new_bond = Bond()
            new_bond.index = [bond[0] - 1, bond[1] - 1]
            if len(bond) > 2:
                new_bond.order = bond[2]
                if bond[2] == 2:  # work around .MOE bug with triple bonds
                    if model.atom[new_bond.index[0]].hybridization == 'sp':
                        if model.atom[new_bond.index[1]].hybridization == 'sp':
                            new_bond.order = 3
                have_valences = 1
            model.bond.append(new_bond)
        if 'ViewOrientationY' in mr.system:
            vy = mr.system['ViewOrientationY']
            vz = mr.system['ViewOrientationZ']
            pos = mr.system['ViewLookAt']
            scale = mr.system['ViewScale']
            vx = cpv.cross_product(vy, vz)
            m = [cpv.normalize(vx), cpv.normalize(vy), cpv.normalize(vz)]
            m = cpv.transpose(m)
            asp_rat = 0.8  # MOE default (versus 0.75 for PyMOL)
            cmd.set("field_of_view", 25.0)
            fov = float(cmd.get("field_of_view"))
            window_height = scale * asp_rat
            dist = (0.5 * window_height) / math.atan(3.1415 *
                                                     (0.5 * fov) / 180.0)
            new_view = tuple(m[0] + m[1] + m[2] + [0.0, 0.0, -dist] + pos +
                             [dist * 0.5, dist * 1.5, 0.0])
            cmd.set_view(new_view)
            zoom = 0
        cmd.set("auto_color", 0)
        cmd.set_color("carbon", [0.5, 0.5, 0.5])  # default MOE grey

        obj_name = name + ".system"
        if split_chains < 0:  # by default, don't split chains if over 50 objects would be created
            if len(unique_chain_names) > 50:
                split_chains = 0
        if not split_chains:
            cmd.load_model(model,
                           obj_name,
                           state=state,
                           finish=finish,
                           discrete=discrete,
                           quiet=quiet,
                           zoom=zoom)
            obj_name_list = [obj_name]
        else:
            cmd.load_model(model,
                           obj_name,
                           state=state,
                           finish=finish,
                           discrete=discrete,
                           quiet=1,
                           zoom=zoom)
            obj_name_list = []
            system_name = obj_name
            for chain in unique_chain_names.keys():
                obj_name = name + "." + chain
                obj_name_list.append(obj_name)
                cmd.select("_moe_ext_tmp",
                           "custom %s" % chain,
                           domain=system_name)
                cmd.extract(obj_name, "_moe_ext_tmp", quiet=quiet, zoom=0)
                # cmd.extract(obj_name,system_name+" and text_type %s"%chain,quiet=quiet)
                cmd.delete("_moe_ext_tmp")
            if not cmd.count_atoms(system_name):
                cmd.delete(system_name)
            else:
                obj_name_list.append(system_name)
            cmd.order(name + ".*", sort=1)
        for obj_name in obj_name_list:
            cmd.set("stick_radius", 0.1, obj_name)
            cmd.set("line_width", 2.0, obj_name)
            cmd.set("label_color", "white", obj_name)
            cmd.set("nonbonded_size", 0.05,
                    obj_name)  # temporary workaround...
            if have_valences:  # if this MOE file has valences, then show em!
                cmd.set("valence", 1, obj_name)
                cmd.set("stick_valence_scale", 1.25, obj_name)
            if aseg_flag:
                cmd.dss(obj_name)
                if 'cartoon' in aseg_rep:
                    cmd.set("cartoon_color", "red",
                            obj_name + " and cartoon_color _aseg0 and ss h")
                    cmd.set("cartoon_color", "yellow",
                            obj_name + " and cartoon_color _aseg0 and ss s")
                    cmd.set(
                        "cartoon_color", "cyan",
                        obj_name + " and cartoon_color _aseg0 and not ss h+s")
                if 'ribbon' in aseg_rep:
                    cmd.set("ribbon_color", "red",
                            obj_name + " and ribbon_color _aseg0 and ss h"
                            )  # need selection op ribbon_color
                    cmd.set("ribbon_color", "yellow",
                            obj_name + " and ribbon_color _aseg0 and ss s")
                    cmd.set(
                        "ribbon_color", "cyan",
                        obj_name + " and ribbon_color _aseg0 and not ss h+s")
        if 'ViewZFront' in mr.system:
            moe_front = mr.system['ViewZFront']
            moe_width = mr.system['ViewZWidth']
            extent = cmd.get_extent(
                name)  # will this work with groups? TO DO: check!
            dx = (extent[0][0] - extent[1][0])
            dy = (extent[0][1] - extent[1][1])
            dz = (extent[0][2] - extent[1][2])
            half_width = 0.5 * math.sqrt(dx * dx + dy * dy + dz * dz)
            cmd.clip("atoms", 0.0, name)
            cur_view = cmd.get_view()
            center = (cur_view[-3] +
                      cur_view[-2]) * 0.5  # center of clipping slab
            front = center - half_width
            back = center + half_width
            width = half_width * 2
            new_view = tuple(
                list(cur_view[0:15]) + [
                    front + width * moe_front, front + width *
                    (moe_front + moe_width), 0.0
                ])
            cmd.set_view(new_view)
        if 'graphics' in mr.system:
            cgo_cnt = 1
            lab_cnt = 1
            unique_cgo_names = {}
            for graphics in mr.system['graphics']:
                cgo = []
                for gvertex in graphics.get('gvertex', []):
                    vrt = gvertex[0]
                    seg_list = gvertex[1]['seg']
                    idx = gvertex[1]['idx']
                    len_idx = len(idx)
                    if not cmd.is_list(seg_list):
                        seg_list = [seg_list] * (len_idx / seg_list)
                    last_seg = None
                    ix_start = 0
                    for seg in seg_list:
                        if seg != last_seg:
                            if last_seg != None:
                                cgo.append(END)
                            if seg == 3:
                                cgo.extend([BEGIN, TRIANGLES])
                            elif seg == 2:
                                cgo.extend([BEGIN, LINES])
                            elif seg == 1:
                                cgo.extend([BEGIN, POINTS])
                        ix_stop = seg + ix_start
                        if seg == 3:
                            for s in idx[ix_start:ix_stop]:
                                v = vrt[s - 1]
                                cgo.extend([
                                    COLOR, (0xFF & (v[0] >> 16)) / 255.0,
                                    (0xFF & (v[0] >> 8)) / 255.0,
                                    (0xFF & (v[0])) / 255.0
                                ])
                                if len(v) > 4:
                                    cgo.extend([NORMAL, v[4], v[5], v[6]])
                                cgo.extend([VERTEX, v[1], v[2], v[3]])
                        elif seg == 2:
                            for s in idx[ix_start:ix_stop]:
                                v = vrt[s - 1]
                                cgo.extend([
                                    COLOR, (0xFF & (v[0] >> 16)) / 255.0,
                                    (0xFF & (v[0] >> 8)) / 255.0,
                                    (0xFF & (v[0])) / 255.0
                                ])
                                if len(v) > 4:
                                    cgo.extend([NORMAL, v[4], v[5], v[6]])
                                cgo.extend([VERTEX, v[1], v[2], v[3]])
                        elif seg == 1:
                            for s in idx[ix_start:ix_stop]:
                                v = vrt[s - 1]
                                cgo.extend([
                                    COLOR, (0xFF & (v[0] >> 16)) / 255.0,
                                    (0xFF & (v[0] >> 8)) / 255.0,
                                    (0xFF & (v[0])) / 255.0
                                ])
                                if len(v) > 4:
                                    cgo.extend([NORMAL, v[4], v[5], v[6]])
                                cgo.extend([VERTEX, v[1], v[2], v[3]])
                        ix_start = ix_stop
                        last_seg = seg
                    if last_seg != None:
                        cgo.append(END)
                for gtext in graphics.get('gtext', []):
                    lab_name = name + ".label_%02d" % lab_cnt
                    exists = 0
                    for entry in gtext:
                        exists = 1
                        cmd.pseudoatom(lab_name,
                                       pos=[
                                           float(entry[1]),
                                           float(entry[2]),
                                           float(entry[3])
                                       ],
                                       color="0x%06x" % entry[0],
                                       label=entry[4])
                    if exists:
                        cmd.set('label_color', -1, lab_name)
                        lab_cnt = lab_cnt + 1
                    # TO DO -- via CGO's?

                if len(cgo):
                    cgo_name = name + "." + make_valid_name(
                        graphics.get('GTitle', 'graphics'))
                    if cgo_name not in unique_cgo_names:
                        unique_cgo_names[cgo_name] = cgo_name
                    else:
                        cnt = 2
                        while cgo_name + "_" + str(cnt) in unique_cgo_names:
                            cnt = cnt + 1
                        new_name = cgo_name + "_" + str(cnt)
                        unique_cgo_names[new_name] = new_name
                        cgo_name = new_name
                    cmd.load_cgo(cgo,
                                 cgo_name,
                                 state=state,
                                 quiet=quiet,
                                 zoom=0)
                    cgo_cnt = cgo_cnt + 1
                    cmd.set("two_sided_lighting", 1)  # global setting...
                    cmd.set("cgo_line_width", 2, cgo_name)
                    if 'GTransparency' in graphics:
                        g_trans = graphics['GTransparency']
                        if len(g_trans) >= 2:
                            if g_trans[0] != 0:
                                cmd.set('cgo_transparency',
                                        '%1.6f' % (g_trans[0] / 255.0),
                                        cgo_name)
                                cmd.set('transparency_global_sort')
        if 'meter' in mr.system:
            meter_name = name + ".meter"
            exists = 0
            for meter_block in mr.system['meter']:
                if meter_block[0][0:2] == ['type', 'atoms']:
                    for meter in meter_block[1]:
                        (type, atoms) = meter[0:2]
                        arg = tuple([meter_name] + list(
                            map(lambda x, o=name: o + " and id " + str(x - 1),
                                atoms)))
                        getattr(cmd, type)(*arg)
                        exists = 1
            if exists:
                cmd.color("green", meter_name)
#            print mr.system['meter']
    elif hasattr(mr, 'feature'):
        model = Indexed()
        cols = mr.feature[0]
        rows = mr.feature[1]
        col = {}
        cnt = 0
        for a in cols:
            col[a] = cnt
            cnt = cnt + 1
        for row in rows:
            atom = Atom()
            atom.coord = [row[col['x']], row[col['y']], row[col['z']]]
            atom.vdw = row[col['r']]
            atom.custom = row[col['expr']]
            model.atom.append(atom)
        obj_name = name + ".feature"
        cmd.load_model(model,
                       obj_name,
                       state=state,
                       finish=finish,
                       discrete=discrete,
                       quiet=quiet,
                       zoom=zoom)
        rank = 1
        for row in rows:
            cmd.color("0x%06x" % row[col['color']],
                      obj_name + " & id %d" % (rank - 1))
            rank = rank + 1
        cmd.show("mesh", obj_name)
        cmd.set("min_mesh_spacing", 0.55, obj_name)
        cmd.label(obj_name, "' '+custom")
        cmd.set("label_color", "yellow", obj_name)
    else:
        print(dir(mr))
Esempio n. 10
0
def scanDamage(nucleosome, uvddb, cutoff=2, clashKeep=1, writeModels=False):
    """
USAGE

  scanDamage nucleosome object (DNA in chains I and J),
             UVDDB probe object (containing appropriately positioned 2 bp ssDNA in chain Z as residues 1-2 for superpositioning),
             distance in Ångstrom closer than which atoms are considered clashing,
             keep models with fewer than the specified number of clashes,
             write all models (for scoring externally for instance) 

  """

    chains = ['I', 'J']
    results = []
    if writeModels:
        dirName = None
        dirName = ("%s_%s_models" % (nucleosome, uvddb))
        if not os.path.exists(dirName):
            os.mkdir("%s" % (dirName))

    for chain in chains:

        chainLength = (len(
            cmd.get_model("polymer and %s and chain %s" %
                          (nucleosome, chain)).get_residues()))

        for i in range(0, chainLength + 1):
            #        for i in range(130, 146):
            j = (i + 1)

            if chain == 'I':
                comnplementaryChain = 'J'
            elif chain == 'J':
                matchedChain = 'I'

            # Handle lack of 5' phosphate on first nucleotide
            if i == 0:
                cmd.select(
                    "moving",
                    "%s and chain Z and resi 2 and backbone and not (n. P or n. OP1 or n. OP2)"
                    % (uvddb))
                cmd.select(
                    "target",
                    "%s and chain %s and resi %d and backbone and not (n. P or n. OP1 or n. OP2)"
                    % (nucleosome, chain, j))
            elif i == 1:
                cmd.select(
                    "moving",
                    "%s and chain Z and resi 1-2 and backbone and not (n. P or n. OP1 or n. OP2)"
                    % (uvddb))
                cmd.select(
                    "target",
                    "%s and chain %s and resi %d-%d and backbone and not (n. P or n. OP1 or n. OP2)"
                    % (nucleosome, chain, i, j))
            # Handle final base
            elif i == chainLength:
                cmd.select("moving",
                           "%s and chain Z and resi 1 and backbone" % (uvddb))
                cmd.select(
                    "target", "%s and chain %s and resi %d and backbone" %
                    (nucleosome, chain, i))
            else:
                cmd.select(
                    "moving",
                    "%s and chain Z and resi 1-2 and backbone" % (uvddb))
                cmd.select(
                    "target", "%s and chain %s and resi %d-%d and backbone" %
                    (nucleosome, chain, i, j))

            #numAtomMoving=(cmd.count_atoms("moving"))
            #print ("\nNumber of moving atoms: %d" % (numAtomMoving) )
            #numAtomTarget=(cmd.count_atoms("target"))
            #print ("Number of target atoms: %d" % (numAtomTarget) )

            alignResult = []

            alignResult = cmd.pair_fit("moving", "target")
            # alignResult = cmd.super("moving", "target")

            # print ("RMSD after refinement %.4f with %d atoms in alignhment after %d refinement cycles" % (alignResult[0],alignResult[1],alignResult[2]) )
            # print(" ".join('%s' % x for x in alignResult))

            clashes = ("clashes")
            # Calculate clashes excluding DNA portion (chain Z resi 1-2) of UV-DDB probe
            cmd.select(
                "%s" % (clashes), "(%s and not chain Z) within %d of %s" %
                (uvddb, float(cutoff), nucleosome))
            scoreAtoms = (cmd.count_atoms("%s" % (clashes)))
            cmd.select("%s" % (clashes), "clashes byres clashes")
            scoreRes = (cmd.count_atoms("%s" % (clashes) + " and name CA"))

            # Write out models (nucleosome + current superimposed UV-DDB probe) for Rosetta scoring
            if writeModels:
                modelName = None
                modelName = ("%s_uvddb_%s_%d-%d" % (nucleosome, chain, i, j))

                editing.copy_to("%s" % (modelName),
                                "(%s or %s)" % (nucleosome, uvddb))
                cmd.save("%s/%s.pdb" % (dirName, modelName),
                         "(%s)" % (modelName))
                cmd.delete("%s" % (modelName))

            # Retain models with no. residue clashes less than or equal to 'clashKeep'
            if scoreRes < (int(clashKeep) + 1):
                editing.copy_to("uvddb_%s_%d-%d" % (chain, i, j),
                                "%s" % (uvddb))
                cmd.group("ClashKeep %s)" % (clashKeep),
                          "nonclashing + uvddb_%s_%d-%d" % (chain, i, j))
                cmd.order("uvddb_*", "yes")

            print(
                "DNA chain %s bases %d - %d :  UV-DDB clashes atoms %d residues %d "
                % (chain, i, j, scoreAtoms, scoreRes))
            clashes = ("%s,%d,%d,%d,%d" % (chain, i, j, scoreAtoms, scoreRes))
            results.append((clashes))

    with open('%s_scanDamage.csv' % (nucleosome), 'w') as output:
        output.write("DNAchain,start,end,atomClashes,residueClashes\n")
        for i in results:
            output.write("%s\n" % i)
    print("\nOutput saved to %s_scanDamage.csv\n" % (nucleosome))
Esempio n. 11
0
def plot_noe(filename, line_color=None, advanced_coloring=0, line_width='1.0', single=0, quiet=1, aria=0, per_atom=0,
             per_residue=1):
    """
DESCRIPTION

    A function for plotting XPLOR NOE restraints on a structure

ARGUMENTS

    filename = string: The filename of the NOE retraint file in XPLOR NIH format.

    single = string: create a single object for all restraints.

    selection = string: atom selection {default: all}

    line_color = string: The color for the NOE lines. {default: black}

    line_width = float: The thickness of the NOE lines. {default: 1.0}

    aria = integer: Name NOEs after Aria IDs.

    per_atom: Group NOEs on atom basis

    per_residue: Group NOEs on residue basis (default)

NOE Restraint Format Example

    assign (residue 5 and name HB#) (residue 21 and name HA) 3.0 0.7 0.7

EXAMPLE

    PyMOL> plot_noe noe_short.tbl
    """

    single, quiet, aria, per_residue, per_atom, advanced_coloring = \
        int(single), int(quiet), int(aria), int(per_residue), int(per_atom), int(advanced_coloring)

    count = 0

    if advanced_coloring == 1:
        cmd.set("group_auto_mode", 2)

    rgx_assi = re.compile("\s*[asignASIGN]+\s+.*")
    rgx_or = re.compile("\s*[orOR]+\s+.*")
    rgx_bracket = re.compile("(\(|\))")
    rgx_tick = re.compile("(\w)\'")

    restraint_line = None
    restraint_block = []
    restraints_blocks = []

    for line in open(filename):
        if rgx_assi.match(line):
            if restraint_line:
                restraint_block.append(rgx_tick.sub("\g<1>^", rgx_bracket.sub(" ", restraint_line)))
                restraints_blocks.append(restraint_block)
            restraint_block = []
            restraint_line = line
        elif rgx_or.match(line):
            restraint_block.append(rgx_tick.sub("\g<1>^", rgx_bracket.sub(" ", restraint_line)))
            restraint_line = line
        else:
            restraint_line += line

    restraint_block.append(rgx_tick.sub("\g<1>^", rgx_bracket.sub(" ", restraint_line)))
    restraints_blocks.append(restraint_block)

    for restraint_block in restraints_blocks:
        restraints = {"connections": []}

        try:
            shlex_split = shlex.split(restraint_block[0])
        except ValueError:
            print 'Cannot process "%s"' % restraint_block[0]
        try:
            restraints["distance"] = float(shlex_split[11].strip())
        except IndexError:
            print 'Cannot process "%s"' % "".join(restraint_block)
            continue
        except ValueError:
            try:
                restraints["distance"] = float(shlex_split[17].strip())
            except ValueError:
                print "Failed to extract distance, setting to 1A"
                restraints["distance"] = 1

        if len(shlex_split) > 20:
            restraints["ID"] = shlex_split[26][3:-1].strip()
        else:
            restraints["ID"] = str(count + 1)

        for restraint_line in restraint_block:
            distance = {}
            try:
                shlex_split = shlex.split(restraint_line)

                if len(shlex_split) > 6:
                    if shlex_split[1].strip().lower() == shlex_split[9].strip().lower() == "segid":
                        distance["src_segid"] = shlex_split[2].strip()
                        distance["src_resid"] = shlex_split[5].strip()
                        distance["src_atom"] = shlex_split[8].strip().replace("^", "'")
                        distance["dst_segid"] = shlex_split[10].strip()
                        distance["dst_resid"] = shlex_split[13].strip()
                        distance["dst_atom"] = shlex_split[16].strip().replace("^", "'")
                    else:
                        distance["src_segid"] = "A"
                        distance["src_resid"] = shlex_split[2].strip()
                        distance["src_atom"] = shlex_split[5].strip().replace("^", "'")
                        distance["dst_segid"] = "A"
                        distance["dst_resid"] = shlex_split[10].strip()
                        distance["dst_atom"] = shlex_split[13].strip().replace("^", "'")

                else:
                    print 'Cannot process "%s"' % restraint_line
                    continue
            except IndexError:
                print 'Cannot process "%s"' % restraint_line
                continue
            except ValueError:
                print 'Cannot process "%s"' % restraint_line
                continue

            restraints["connections"].append(distance)

        count += _draw_restraint(
            restraints,
            line_color,
            line_width,
            single,
            quiet,
            per_residue,
            per_atom,
            advanced_coloring
        )

    if not quiet:
        print ' Info: Created distance objects for %d restraints' % count

    cmd.order("NOE*", "yes")
Esempio n. 12
0
def scanFactor( nucleosome, probe, cutoff=2, clashKeep=1, writeModels=False ):
  """
USAGE

  scanFactor nucleosome object,
             probe object,
             probe DNA chain ID,
             distance in Ångstrom below which atoms are considered clashing,
             keep models with fewer than the specified number of residue clashes

  """

  results=[]
  if writeModels:
    dirName =  None
    dirName = ("%s_%s_models" % (nucleosome, probe) )
    if not os.path.exists(dirName):
      os.mkdir("%s" % (dirName) )


  if not cmd.select("polymer.nucleic and %s" % (nucleosome) ) :
    print("\nThe nucleosome object \'%s\' must contain contain DNA – are you sure this is a nucleosome model?\n" % (nucleosome) )
    return

  if not cmd.select("polymer.nucleic and %s" % (probe) ) :
    print("\nThe probe object \'%s\' must contain at least two DNA bases for superposition, the first two of which should correspond\nto the position of the central two bases of the factor's recognition sequence when bound to DNA\n" % (probe) )
    return
      

  # Determine probe DNA chain ID
  cmd.select("probeDNA","polymer.nucleic and %s" % (probe) )
  probeDNAChain = cmd.get_model("probeDNA").atom[0].chain

  # Renumber probe DNA chain to start from 1
  firstBase = []
  firstBase = int(cmd.get_model("%s and chain %s" % (probe, probeDNAChain)).atom[0].resi)
  secondBase = firstBase+1
  offset = firstBase-1

  print ("Renumbering %s chain %s to start at residue 1\n" % (probe, probeDNAChain) )
  cmd.alter("%s and chain %s" % (probe, probeDNAChain), "resi=str(int(resi)-%d)" % (offset) )

  # Remove hydrogens
  print ("\nRemoving hydrogens\n")
  cmd.remove("hydrogens")
  
  # Determine nucleosomal DNA chain IDs
  chains = []
  chains = cmd.get_chains("polymer.nucleic and %s" % (nucleosome) )

  # Loop over nuclesomal DNA
  for chain in chains:

     firstBase = int(cmd.get_model("%s and chain %s" % (nucleosome, chain)).atom[0].resi)
     chainLength = (len(cmd.get_model("polymer and %s and chain %s" % (nucleosome, chain)).get_residues()))
     
     for i in range(firstBase, (firstBase + chainLength) ):

        j=(i+1)
        
        # Handle lack of 5' phosphates (such as on the first base)
        if not cmd.select("%s and chain %s and resi %d and name P" % (nucleosome, chain, i) ) :
           cmd.select("moving", "%s and chain %s and resi 2 and backbone and not (n. P or n. OP1 or n. OP2)" % (probe, probeDNAChain) )
           cmd.select("target", "%s and chain %s and resi %d and backbone and not (n. P or n. OP1 or n. OP2)" % (nucleosome, chain, j) )
        # Handle overhanging superposition for final base
        elif i == (firstBase + chainLength - 1):
           cmd.select("moving", "%s and chain %s and resi 1 and backbone" % (probe, probeDNAChain) )
           cmd.select("target", "%s and chain %s and resi %d and backbone" % (nucleosome, chain, i) )
        else:
           cmd.select("moving", "%s and chain %s and resi 1-2 and backbone" % (probe, probeDNAChain) )
           cmd.select("target", "%s and chain %s and resi %d-%d and backbone" % (nucleosome, chain, i, j) )

        #numAtomMoving=(cmd.count_atoms("moving"))
        #print ("Number of moving atoms: %d" % (numAtomMoving) )
        #numAtomTarget=(cmd.count_atoms("target"))
        #print ("Number of target atoms: %d" % (numAtomTarget) ) 

        alignResult=[]
        alignResult = cmd.pair_fit("moving", "target")
        
        if alignResult:
        
          # alignResult = cmd.super("moving", "target")
          # print ("RMSD after refinement %.4f with %d atoms in alignhment after %d refinement cycles" % (alignResult[0],alignResult[1],alignResult[2]) )
          # print(" ".join('%s' % x for x in alignResult))

          clashes=("clashes")
          # Calculate clashes excluding DNA portion of probe
          cmd.select("%s" % (clashes), "(%s and not chain %s) within %f of %s" % (probe, probeDNAChain, float(cutoff), nucleosome) )
          scoreAtoms = (cmd.count_atoms("%s" % (clashes) ))
          cmd.select("%s" % (clashes), "clashes byres clashes")
          scoreRes = (cmd.count_atoms("%s" % (clashes) + " and name CA"))

          # Write out models (nuclesome + current superimposed probe) for Rosetta scoring
          if  writeModels :
            modelName = None
            modelName = ("%s_probe_%s_%d-%d" % (nucleosome, chain, i, j) )

            editing.copy_to("%s" % (modelName), "(%s or %s)" % (nucleosome, probe) )
            cmd.save("%s/%s.pdb" % (dirName,modelName), "(%s)" % (modelName) )
            cmd.delete("%s" % (modelName) )

         # Retain models with no. residue clashes less than or equal to 'clashKeep'
          if scoreRes < (int(clashKeep)+1):
             editing.copy_to("probe_%s_%d-%d" % (chain, i, j), "%s" % (probe) )
             cmd.group("ClashKeep %s)" % (clashKeep),"nonclashing + probe_%s_%d-%d" % (chain, i, j) )
             cmd.order("probe_*", "yes")

          print ("DNA chain %s bases %d - %d : %s clashes with %d non-hydrogen atoms in %d residues" % (chain, i, j, probe, scoreAtoms, scoreRes) )
          clashes=("%s,%d,%d,%d,%d" % (chain, i, j, scoreAtoms, scoreRes) )
          results.append((clashes))
        # Catch superpostion failures
        else:
            
          print ("DNA chain %s bases %d - %d : %s superpositon failed and clashes were not calculated – check for missing atoms, alternate conformations, or unsual bases at these positions" % (chain, i, j, probe) )
          clashes=("%s,%d,%d,-,-" % (chain, i, j) )
          results.append((clashes))


  with open('%s_scanFactor.csv' % (nucleosome), 'w') as output:
    output.write("DNAchain,start,end,atomClashes,residueClashes\n")
    for i in results:
      output.write("%s\n" % i)
  print ("\nOutput saved to %s_scanFactor.csv\n" % (nucleosome) )