Method: createChainFragments
Creates ChainFragments for all Residues that do not already have them, while making no modification to existing ChainFragments or their contents. Is called automatically on Chain creation. Any program that modifies the automatically created ChainFragments should call this function at the end, to ensure that every Residue belongs to a ChainFragment.
The function divides the residues in four molTypes: protein, carbohydrate, DNA/RNA ,and other. Within each molType, stretches of linear polymer of two or more residues are identified without regard to the seqId value of the residues. These are put in separate ChainFragments, with the residues ordered by sequence rather than seqID. Subsequently, residues not part of a linear polymer are grouped in the largest directly connected fragments of uniform molType. Finally, for fragments of type DNA/RNA the molType is set to DNA or RNA if this is the only molType that happens to be present, to DNA/RNA otherwise.
guid:
|
www.ccpn.ac.uk_Fogh_2006-08-16-18:23:32_00020
|
OpType:
|
other
|
OpSubType:
|
None
|
isQuery:
|
False
|
isAbstract:
|
False
|
Scope:
|
instance_level
|
Code:
|
# global set up
dnarna = 'DNA/RNA'
topdict = {'protein':{}, 'carbohydrate':{}, 'other':{}, dnarna:{}}
linearTags = ('prev', 'next')
#partition residues by molType
for molres in self.molecule.molResidues:
res = self.findFirstResidue(seqId=molres.serial)
if res is not None and not res.chainFragment:
molType = molres.molType
dd = topdict.get(molType)
if dd is None:
dd = topdict['other']
dd[molres] = res
# analyse link graph and make ChainFragments
for (molType, dd) in topdict.items():
if molType == 'carbohydrate':
dd2 = dd
else:
# make linear polymer fragments
dd2 = {}
while dd:
# start at molres with largest serial, to get cyclic polymers to start at serial one
refserial = -1
for mr in dd:
serial = mr.serial
if serial > refserial:
refserial = serial
molres = mr
res0 = dd.pop(molres)
#(molres, res0) = dd.popitem()
# set up
res = res0
mr = molres
residues = [res]
(tag1, tag2) = linearTags
firstTime = True
while True:
# find linear polymer linked molResidue, and add residue to residues list
linkEnd = mr.findFirstMolResLinkEnd(linkCode=tag1)
if linkEnd:
ml = linkEnd.molResLink
if ml:
(le, le2) = ml.molResLinkEnds
if le is linkEnd:
le = le2
if le.linkCode == tag2:
mr = le.molResidue
res = dd.get(mr)
if res is not None:
del dd[mr]
residues.append(res)
continue
# If we get here, we have reached the end of the polymer chain
if firstTime:
# now start again at molres, going in opposite direction
firstTime = False
(tag1, tag2) = (tag2, tag1)
residues.reverse()
mr = molres
else:
# both ends done, finalise
if len(residues) < 2:
# no linear polymer found - put molres in new dictionary
dd2[molres] = res0
else:
if molType == dnarna:
mt = residues[0].molType
for rr in residues[1:]:
if rr.molType != mt:
mt = 'DNA/RNA'
break
else:
mt = molType
ChainFragment(
self, molType=mt, isLinearPolymer=True, residues=residues
)
#
break
# make fragments that are not linear polyumers
while dd2:
# set up
(molres, res) = dd2.popitem()
mrs = [molres]
residues = [res]
for molres in mrs:
for linkEnd in molres.molResLinkEnds:
ml = linkEnd.molResLink
if ml:
(le, le2) = ml.molResLinkEnds
if le is linkEnd:
le = le2
mr = le.molResidue
res = dd2.get(mr)
if res is not None:
del dd2[mr]
mrs.append(mr)
residues.append(res)
if molType == dnarna:
mt = residues[0].molType
for rr in residues[1:]:
if rr.molType != mt:
mt = 'DNA/RNA'
break
else:
mt = molType
ChainFragment(
self,molType=mt, isLinearPolymer=False, residues=residues
)
|
|