예제 #1
0
def load_hypothesis_xvol(filename, name=''):
    '''
    Load excluded volumes from a hypothesis.xvol file.
    '''
    from epymol import m2io
    from chempy import Atom, models

    if not name:
        name = _name_from_filename(filename, '.xvol')

    reader = m2io.M2IOReader(filename)

    try:
        table = reader.find_block('f_m_table').m_row
        col_radius = table.keys.index('r_m_phase_radius')
        cols_xyz = [
            table.keys.index(n)
            for n in ['r_m_phase_x', 'r_m_phase_y', 'r_m_phase_z']
        ]
    except (AttributeError, IndexError):
        print(' Error: could not find table')
        return

    model = models.Indexed()

    for row in table:
        atom = Atom()
        atom.coord = [row[i] for i in cols_xyz]
        atom.vdw = row[col_radius]
        atom.trgb = 0x00FFFF00
        atom.visible = 0x2  # spheres
        model.add_atom(atom)

    pymol.cmd.load_model(model, name)
예제 #2
0
def load_rigimol_inp(filename, oname, _self=cmd):
    '''
DESCRIPTION

    Load the structures from a RigiMOL "inp" file.
    '''
    import shlex
    from chempy import Atom, Bond, models

    parsestate = ''
    model = None
    state = 0

    for line in open(filename):
        lex = shlex.shlex(line, posix=True)
        lex.whitespace_split = True
        lex.quotes = '"'
        a = list(lex)

        if not a:
            continue

        if a[0] == '+':
            if a[1] == 'NAME':
                assert a[2:] == [
                    'RESI', 'RESN', 'CHAIN', 'SEGI', 'X', 'Y', 'Z', 'B'
                ]
                parsestate = 'ATOMS'
                model = models.Indexed()
            elif a[1] == 'FROM':
                assert a[2:] == ['TO']
                parsestate = 'BONDS'
            else:
                parsestate = ''
        elif a[0] == '|':
            if parsestate == 'ATOMS':
                atom = Atom()
                atom.coord = [float(x) for x in a[6:9]]
                atom.name = a[1]
                atom.resi = a[2]
                atom.resn = a[3]
                atom.chain = a[4]
                atom.segi = a[5]
                atom.b = a[9]
                atom.symbol = ''
                model.add_atom(atom)
            elif parsestate == 'BONDS':
                bnd = Bond()
                bnd.index = [int(a[1]), int(a[2])]
                model.add_bond(bnd)
        elif a[0] == 'end':
            if parsestate in ('ATOMS', 'BONDS'):
                state += 1
                _self.load_model(model, oname, state=state)
            parsestate = ''
예제 #3
0
def _create_molecule(n, mydata, resolution, created):
    model = models.Indexed()
    name = _get_molecule_name(n.get_name(), resolution)
    if name in created:
        name = name + "-2"
    print n, name, resolution
    th = RMF.TraverseHelper(n, name, resolution)
    created[name] = (th, model)
    print "creating molecule", name
    cgol = []
    _create_atoms(th, mydata, model, cgol, created)
    frame = n.get_file().get_current_frame().get_index() + 1

    if len(cgol) > 0:
        print cgol
        cmd.load_cgo(cgol, name + "-graphics", frame)
예제 #4
0
    def load_xvol(oname):
        lines = get_blob('s_phasehypo_ExcludedVolumes').splitlines()
        if len(lines) < 2:
            return

        model = models.Indexed()

        for line in lines[1:]:
            row = [float(c) for c in line.split()]
            atom = Atom()
            atom.coord = row[:3]
            atom.vdw = row[3]
            atom.trgb = 0x0033E5F2
            atom.visible = 0x2  # spheres
            model.add_atom(atom)

        pymol.cmd.load_model(model, oname, zoom=zoom)
예제 #5
0
    def test(self):
        from chempy import Atom, Bond, models

        m = models.Indexed()

        for i in range(2):
            a = Atom()
            a.coord = [float(i), 0., 0.]
            m.add_atom(a)

        b = Bond()
        b.index = [0, 1]
        b.order = 0
        m.add_bond(b)

        cmd.load_model(m, 'foo')

        cmd.set('valence')
        cmd.show('sticks')
예제 #6
0
def gen_model(mol):
    from chempy import models
    from chempy import Atom
    from chempy import Bond
    # print('generating model')
    model = models.Indexed()
    i = 1
    for at in mol['atoms']:
        atom = Atom()
        atom.name = at['name']
        atom.resi = at['residue']
        atom.resi_number = int(at['residue'])
        atom.segi = at['segment']
        atom.symbol = at['element']
        atom.coord = [float(at["x"]), float(at["y"]), float(at["z"])]
        model.add_atom(atom)
        # model.update_index()

    # model.update_index()
    for b in mol['bonds']:
        bond = Bond()
        bond.index = [int(b['atom1']) - 1, int(b['atom2']) - 1]
        model.add_bond(bond)
    return model
예제 #7
0
def load_cml(filename, object='', discrete=0, multiplex=1, zoom=-1,
        quiet=1, _self=cmd):
    '''
DESCRIPTION

    Load a CML formatted structure file
    '''
    from chempy import Atom, Bond, models

    multiplex, discrete = int(multiplex), int(discrete)

    try:
        root = etree.fromstring(_self.file_read(filename))
    except etree.XMLSyntaxError:
        raise CmdException("File doesn't look like XML")

    if root.tag != 'cml':
        raise CmdException('not a CML file')

    molecule_list = root.findall('./molecule')

    if len(molecule_list) < 2:
        multiplex = 0
    elif not multiplex:
        discrete = 1

    for model_num, molecule_node in enumerate(molecule_list, 1):
        model = models.Indexed()

        atom_idx = {}

        for atom_node in molecule_node.findall('./atomArray/atom'):
            atom = Atom()
            atom.name = atom_node.get('id', '')

            if 'x3' in atom_node.attrib:
                atom.coord = [float(atom_node.get(a))
                        for a in ['x3', 'y3', 'z3']]
            elif 'x2' in atom_node.attrib:
                atom.coord = [float(atom_node.get(a))
                        for a in ['x2', 'y2']] + [0.0]
            else:
                print(' Warning: no coordinates for atom', atom.name)
                continue

            atom.symbol = atom_node.get('elementType', '')
            atom.formal_charge = int(atom_node.get('formalCharge', 0))
            atom_idx[atom.name] = len(model.atom)
            model.add_atom(atom)

        for bond_node in molecule_node.findall('./bondArray/bond'):
            refs = bond_node.get('atomsRefs2', '').split()
            if len(refs) == 2:
                bnd = Bond()
                bnd.index = [int(atom_idx[ref]) for ref in refs]
                bnd.order = int(bond_node.get('order', 1))
                model.add_bond(bnd)

        # object name
        if not object:
            object = os.path.basename(filename).split('.', 1)[0]

        # load models as objects or states
        if multiplex:
            oname = molecule_node.get('id') or _self.get_unused_name('unnamed')
            model_num = 1
        else:
            oname = object

        _self.load_model(model, oname,
                state=model_num, zoom=zoom, discrete=discrete)
예제 #8
0
def sidechaincenters(object='scc', selection='all', method='bahar1996', name='PS1', *, _self=cmd):
    '''
DESCRIPTION

    Creates an object with sidechain representing pseudoatoms for each residue
    in selection.

    Two methods are available:
    (1) Sidechain interaction centers as defined by Bahar and Jernigan 1996
        http://www.ncbi.nlm.nih.gov/pubmed/9080182
    (2) Sidechain centroids, the pseudoatom is the centroid of all atoms except
        hydrogens and backbone atoms (N, C and O).

NOTE

    With method "bahar1996", if a residue has all relevant sidechain center
    atoms missing (for example a MET without SD), it will be missing in the
    created pseudoatom object.

    With method "centroid", if you want to exclude C-alpha atoms from
    sidechains, modify the selection like in this example:

    sidechaincenters newobject, all and (not name CA or resn GLY), method=2

USAGE

    sidechaincenters object [, selection [, method ]]

ARGUMENTS

    object = string: name of object to create

    selection = string: atoms to consider {default: (all)}

    method = string: bahar1996 or centroid {default: bahar1996}

    name = string: atom name of pseudoatoms {default: PS1}

SEE ALSO

    pseudoatom
    '''
    from chempy import Atom, cpv, models

    atmap = dict()
    if method in ['bahar1996', '1', 1]:
        modelAll = _self.get_model('(%s) and resn %s' % (selection, '+'.join(sidechaincenteratoms)))
        for at in modelAll.atom:
            if at.name in sidechaincenteratoms[at.resn]:
                atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at)
    elif method in ['centroid', '2', 2]:
        modelAll = _self.get_model('(%s) and polymer and not (hydro or name C+N+O)' % selection)
        for at in modelAll.atom:
            atmap.setdefault((at.segi, at.chain, at.resn, at.resi), []).append(at)
    else:
        raise CmdException('unknown method: {}'.format(method))

    model = models.Indexed()
    for centeratoms in atmap.values():
        center = cpv.get_null()
        for at in centeratoms:
            center = cpv.add(center, at.coord)
        center = cpv.scale(center, 1./len(centeratoms))
        atom = Atom()
        atom.coord = center
        atom.index = model.nAtom + 1
        atom.name = name
        for key in [
                'segi',
                'chain',
                'resi_number',
                'resi',
                'resn',
                'hetatm',
                'ss',
                'b',
        ]:
            setattr(atom, key, getattr(at, key))
        model.add_atom(atom)
    model.update_index()
    if object in _self.get_object_list():
        _self.delete(object)
    _self.load_model(model, object)
    return model
예제 #9
0
def load_3d(filename, object=''):
    '''
DESCRIPTION

    Load a survex 3d cave survey as "molecule"

    http://survex.com
    http://trac.survex.com/browser/trunk/doc/3dformat.htm
    '''
    from chempy import Atom, Bond, models
    from struct import unpack

    if object == '':
        object = os.path.splitext(os.path.basename(filename))[0]

    f = open(filename, 'rb')

    line = f.readline()  # File ID
    if not line.startswith('Survex 3D Image File'):
        print(" Error: not a Survex 3D File")
        raise CmdException

    line = f.readline()  # File format version
    assert line[0] == 'v'
    ff_version = int(line[1:])

    line = f.readline().decode('latin1')  # Survex title
    line = f.readline()  # Timestamp

    class Station:
        def __init__(self):
            self.labels = []
            self.adjacent = []
            self.lrud = None
            self.flag = 0

        def connect(self, other):
            self.adjacent.append(other)

        def is_surface(self):
            return self.flag & 0x01

        def is_underground(self):
            return self.flag & 0x02

        def is_entrance(self):
            return self.flag & 0x04

        def is_exported(self):
            return self.flag & 0x08

        def is_fixed(self):
            return self.flag & 0x10

    class Survey(dict):
        def __init__(self):
            self.prev = None
            self.curr_label = ''
            self.labelmap = {}

        def get(self, xyz):
            return dict.setdefault(self, tuple(xyz), Station())

        def line(self, xyz):
            s = self.get(xyz)
            self.prev.connect(s)
            self.prev = s

        def move(self, xyz):
            s = self.get(xyz)
            self.prev = s

        def label(self, xyz, flag=0):
            s = self.get(xyz)
            s.labels.append(self.curr_label)
            self.labelmap[s.labels[-1]] = s
            if flag > 0:
                s.flag = flag

        def lrud(self, lrud):
            s = self.labelmap[self.curr_label]
            s.lrud = lrud

    survey = Survey()

    def read_xyz():
        return unpack('<iii', f.read(12))

    def read_len():
        len = read_byte()
        if len == 0xfe:
            len += unpack('<H', f.read(2))[0]
        elif len == 0xff:
            len += unpack('<I', f.read(4))[0]
        return len

    def read_label():
        len = read_len()
        if len > 0:
            survey.curr_label += skip_bytes(len)

    def skip_bytes(n):
        return f.read(n)

    def read_byte():
        byte = f.read(1)
        if len(byte) != 1:
            return -1
        return ord(byte)

    while 1:
        byte = read_byte()
        if byte == -1:
            break

        if byte == 0x00:
            # STOP
            survey.curr_label = ''
        elif byte <= 0x0e:
            # TRIM
            # FIXME: according to doc, trim 16 bytes, but img.c does 17!
            (i, n) = (-17, 0)
            while n < byte:
                i -= 1
                if survey.curr_label[i] == '.': n += 1
            survey.curr_label = survey.curr_label[:i + 1]
        elif byte <= 0x0f:
            # MOVE
            xyz = read_xyz()
            survey.move(xyz)
        elif byte <= 0x1f:
            # TRIM
            survey.curr_label = survey.curr_label[:15 - byte]
        elif byte <= 0x20:
            # DATE
            if ff_version < 7:
                skip_bytes(4)
            else:
                skip_bytes(2)
        elif byte <= 0x21:
            # DATE
            if ff_version < 7:
                skip_bytes(8)
            else:
                skip_bytes(3)
        elif byte <= 0x22:
            # Error info
            skip_bytes(5 * 4)
        elif byte <= 0x23:
            # DATE
            skip_bytes(4)
        elif byte <= 0x24:
            # DATE
            continue
        elif byte <= 0x2f:
            # Reserved
            continue
        elif byte <= 0x31:
            # XSECT
            read_label()
            lrud = unpack('<hhhh', f.read(8))
            survey.lrud(lrud)
        elif byte <= 0x33:
            # XSECT
            read_label()
            lrud = unpack('<iiii', f.read(16))
            survey.lrud(lrud)
        elif byte <= 0x3f:
            # Reserved
            continue
        elif byte <= 0x7f:
            # LABEL
            read_label()
            xyz = read_xyz()
            survey.label(xyz, byte & 0x3f)
        elif byte <= 0xbf:
            # LINE
            read_label()
            xyz = read_xyz()
            survey.line(xyz)
        elif byte <= 0xff:
            # Reserved
            continue

    model = models.Indexed()
    for (xyz, s) in survey.items():
        l0, _, l1 = s.labels[0].rpartition('.')
        resi, name = l1[:5], l1[5:]
        segi, chain, resn = l0[-8:-4], l0[-4:-3], l0[-3:]
        atom = Atom()
        atom.coord = [i / 100.0 for i in xyz]
        atom.segi = segi
        atom.chain = chain
        atom.resn = resn
        atom.name = name
        atom.resi = resi
        atom.b = atom.coord[2]
        atom.label = s.labels[0]
        if s.lrud is not None:
            atom.vdw = sum(s.lrud) / 400.0
        model.add_atom(atom)

    s2i = dict((s, i) for (i, s) in enumerate(survey.values()))
    for (s, i) in s2i.items():
        for o in s.adjacent:
            bnd = Bond()
            bnd.index = [i, s2i[o]]
            model.add_bond(bnd)

    cmd.load_model(model, object, 1)
    cmd.show_as('lines', object)
    cmd.spectrum('b', 'rainbow', object)
예제 #10
0
def peptide_rebuild(name, selection='all', cycles=1000, state=1, quiet=1, *, _self=cmd):
    '''
DESCRIPTION

    Rebuild the peptide from selection. All atoms which are present in
    selection will be kept fixed, while atoms missing in selection are
    placed by sculpting.

USAGE

    peptide_rebuild name [, selection [, cycles [, state ]]]

SEE ALSO

    stub2ala, add_missing_atoms, peptide_rebuild_modeller
    '''
    from chempy import fragments, feedback, models

    cycles, state, quiet = int(cycles), int(state), int(quiet)

    # suppress feedback for model merging
    feedback['actions'] = False

    # work with named selection
    namedsele = _self.get_unused_name('_')
    _self.select(namedsele, '{} & present'.format(selection), 0)

    identifiers = []
    _self.iterate(namedsele + ' and polymer and guide and alt +A',
            'identifiers.append([segi,chain,resi,resv,resn])', space=locals())

    model = models.Indexed()
    for (segi,chain,resi,resv,resn) in identifiers:
        try:
            fname = resn.lower() if resn != 'MSE' else 'met'
            frag = fragments.get(fname)
        except IOError:
            print(' Warning: unknown residue: ' + resn)
            continue

        for a in frag.atom:
            a.segi = segi
            a.chain = chain
            a.resi = resi
            a.resi_number = resv
            a.resn = resn

        model.merge(frag)

    if not quiet:
        print(' Loading model...')

    _self.load_model(model, name, 1, zoom=0)
    if _self.get_setting_boolean('auto_remove_hydrogens'):
        _self.remove(name + ' and hydro')

    _self.protect(name + ' in ' + namedsele)
    _self.sculpt_activate(name)
    _self.update(name, namedsele, 1, state)
    _self.delete(namedsele)

    if not quiet:
        print(' Sculpting...')

    _self.set('sculpt_field_mask', 0x003, name) # bonds and angles only
    _self.sculpt_iterate(name, 1, int(cycles / 4))

    _self.set('sculpt_field_mask', 0x09F, name) # local + torsions
    _self.sculpt_iterate(name, 1, int(cycles / 4))

    _self.set('sculpt_field_mask', 0x0FF, name) # ... + vdw
    _self.sculpt_iterate(name, 1, int(cycles / 2))

    _self.sculpt_deactivate(name)
    _self.deprotect(name)
    _self.unset('sculpt_field_mask', name)

    if not quiet:
        print(' Connecting peptide...')

    pairs = _self.find_pairs(name + ' and name C', name + ' and name N', 1, 1, 2.0)
    for pair in pairs:
        _self.bond(*pair)
    _self.h_fix(name)

    if not quiet:
        print(' peptide_rebuild: done')
def load_3d(filename, object=''):
	'''
DESCRIPTION

    Load a survex 3d cave survey as "molecule"

    http://survex.com
	'''
	from chempy import Atom, Bond, models

	if object == '':
		import os
		object = os.path.splitext(os.path.basename(filename))[0]

	f = open(filename, 'rb')

	line = f.readline() # File ID
	if not line.startswith('Survex 3D Image File'):
		print " Error: not a Survex 3D File"
		raise CmdException

	line = f.readline() # File format version
	assert line[0] == 'v'
	ff_version = int(line[1:])

	line = unicode(f.readline(), 'latin1') # Survex title
	line = f.readline() # Timestamp

	class Station(tuple):
		def __new__(cls, xyz):
			return tuple.__new__(cls, xyz)
		def __init__(self, xyz):
			self.labels = []
			self.adjacent = []
		def connect(self, other):
			self.adjacent.append(other)

	class Survey(dict):
		def __init__(self):
			self.prev = None
			self.curr_label = ''
		def get(self, xyz):
			s = Station(xyz)
			return dict.setdefault(self, s, s)
		def line(self, xyz):
			s = self.get(xyz)
			self.prev.connect(s)
			self.prev = s
		def move(self, xyz):
			s = self.get(xyz)
			self.prev = s
		def label(self, xyz):
			s = survey.get(xyz)
			s.labels.append(self.curr_label)
		def __repr__(self):
			return 'Survey(' + repr(self.keys())[1:-1] + ')'

	survey = Survey()

	def read_xyz():
		x = read_int(4, 1)
		y = read_int(4, 1)
		z = read_int(4, 1)
		return [ x, y, z ]

	def read_int(len, sign):
		int = 0
		for i in range(len):
			int |= read_byte() << (8 * i)
		if sign and (int >> (8 * len - 1)):
			int -= (1 << 8 * len)
		return int

	def read_len():
		len = read_byte()
		if len == 0xfe:
			len += read_int(2, 0)
		elif len == 0xff:
			len = read_int(4, 0)
		return len

	def read_label():
		len = read_len()
		if len > 0:
			survey.curr_label += skip_bytes(len)

	def skip_bytes(n):
		return f.read(n)

	def read_byte():
		byte = f.read(1)
		if len(byte) != 1:
			return -1
		return ord(byte)

	while 1:
		byte = read_byte()
		if byte == -1:
			break
		
		if byte == 0x00:
			# STOP
			survey.curr_label = ''
		elif byte <= 0x0e:
			# TRIM
			(i,n) = (-16,0)
			while n < byte:
				i -= 1
				if survey.curr_label[i] == '.': n += 1
			survey.curr_label = survey.curr_label[:i + 1]
		elif byte <= 0x0f:
			# MOVE
			xyz = read_xyz()
			survey.move(xyz)
		elif byte <= 0x1f:
			# TRIM
			survey.curr_label = survey.curr_label[:15 - byte]
		elif byte <= 0x20:
			# DATE
			if ff_version < 7:
				skip_bytes(4)
			else:
				skip_bytes(2)
		elif byte <= 0x21:
			# DATE
			if ff_version < 7:
				skip_bytes(8)
			else:
				skip_bytes(3)
		elif byte <= 0x22:
			# Error info
			skip_bytes(5 * 4)
		elif byte <= 0x23:
			# DATE
			skip_bytes(4)
		elif byte <= 0x24:
			# DATE
			continue
		elif byte <= 0x2f:
			# Reserved
			continue
		elif byte <= 0x31:
			# XSECT
			read_label()
			skip_bytes(4 * 2)
		elif byte <= 0x33:
			# XSECT
			read_label()
			skip_bytes(4 * 4)
		elif byte <= 0x3f:
			# Reserved
			continue
		elif byte <= 0x7f:
			# LABEL
			read_label()
			xyz = read_xyz()
			survey.label(xyz)
		elif byte <= 0xbf:
			# LINE
			read_label()
			xyz = read_xyz()
			survey.line(xyz)
		elif byte <= 0xff:
			# Reserved
			continue

	model = models.Indexed()
	for s in survey:
		l0, _, l1 = s.labels[0].rpartition('.')
		resi, name = l1[:5], l1[5:]
#		segi, chain, resn = l0[:4],l0[-4:-3], l0[-3:]
		segi, chain, resn = l0[-8:-4], l0[-4:-3], l0[-3:]
		atom = Atom()
		atom.coord = [i/100.0 for i in s]
		atom.segi = segi
		atom.chain = chain
		atom.resn = resn
		atom.name = name
		atom.resi = resi
		atom.b = atom.coord[2]
		model.add_atom(atom)

	s2i = dict((s,i) for (i,s) in enumerate(survey))
	for s in survey:
		for o in s.adjacent:
			bnd = Bond()
			bnd.index = [s2i[s], s2i[o]]
			model.add_bond(bnd)

	cmd.load_model(model, object, 1)
	cmd.show_as('lines', object)
	cmd.spectrum('b', 'rainbow', object)
예제 #12
0
def _to_chempy(data, use_auth=True):
    '''
    Construct a "chempy" model (molecule) from decoded MMTF data.
    '''
    from itertools import islice
    from chempy import models, Atom, Bond

    def add_bond(i1, i2, order, offset=0):
        bond = Bond()
        bond.order = order
        bond.index = [i1 + offset, i2 + offset]
        model.add_bond(bond)

    coord_iter = data.get_table_iter([
        'xCoordList',
        'yCoordList',
        'zCoordList',
    ])

    atom_iter = data.get_table_iter([
        'bFactorList',
        'occupancyList',
        'altLocList',
        'atomIdList',
    ], [0.0, 1.0, '', -1])

    group_iter = data.get_table_iter([
        'groupTypeList',
        'sequenceIndexList',
        'groupIdList',
        'insCodeList',
        'secStructList',
    ])

    chain_list_iter = enumerate(
        data.get_table_iter([
            'chainIdList',
            'chainNameList',
            'groupsPerChain',
        ]))

    groupList = data.get('groupList')

    symmetry = (
        data.get('unitCell', None),
        as_str(data.get('spaceGroup', '')),
    )

    model_output = []

    for n_chains in data.get_iter('chainsPerModel'):
        model = models.Indexed()
        model_output.append(model)

        if symmetry[0] is not None:
            model.cell, model.spacegroup = symmetry

        for (chain_idx, (segi, chain,
                         n_groups)) in islice(chain_list_iter, n_chains):
            for (groupType, label_seq_id, auth_seq_id, ins_code, ss_info) in \
                    islice(group_iter, n_groups):

                group = groupList[groupType]
                resn = as_str(group[b'groupName'])

                group_bond_iter = izip(
                    group[b'bondAtomList'][0::2],
                    group[b'bondAtomList'][1::2],
                    group[b'bondOrderList'],
                )

                offset = len(model.atom)
                for (i1, i2, order) in group_bond_iter:
                    add_bond(i1, i2, order, offset)

                group_atom_iter = izip(
                    group[b'atomNameList'],
                    group[b'elementList'],
                    group[b'formalChargeList'],
                )

                for (name, elem, formal_charge) in group_atom_iter:
                    atom = Atom()

                    (atom.b, atom.q, atom.alt, atom.id) = next(atom_iter)

                    atom.coord = next(coord_iter)
                    atom.symbol = as_str(elem)
                    atom.name = as_str(name)
                    atom.resn = resn
                    atom.hetatm = label_seq_id == -1
                    atom.formal_charge = formal_charge
                    atom.segi = segi
                    atom.chain = chain
                    atom.ss = ss_map.get(ss_info, '')

                    if use_auth or label_seq_id is None:
                        atom.resi = auth_seq_id
                        atom.ins_code = ins_code or ''
                    else:
                        atom.resi = label_seq_id + 1

                    model.add_atom(atom)

    model_atom_max = 0
    model_atom_min = 0
    model_iter = iter(model_output)
    bondAtomList_iter = data.get_iter('bondAtomList')

    for order in data.get_iter('bondOrderList'):
        i1 = next(bondAtomList_iter)
        i2 = next(bondAtomList_iter)
        if i1 >= model_atom_max or i2 >= model_atom_max:
            model = next(model_iter)
            model_atom_min = model_atom_max
            model_atom_max += len(model.atom)
        add_bond(i1, i2, order, -model_atom_min)

    return model_output