1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# Copyright 2007-2008 Nanorex, Inc. See LICENSE file for details.
"""
DnaStrandOrSegment.py - abstract superclass for DnaStrand and DnaSegment
@author: Bruce
@version: $Id$
@copyright: 2007-2008 Nanorex, Inc. See LICENSE file for details.
"""
from foundation.LeafLikeGroup import LeafLikeGroup
_superclass = LeafLikeGroup
class DnaStrandOrSegment(LeafLikeGroup):
"""
Abstract superclass for DnaStrand and DnaSegment,
which represent a Dna Strand or Dna Segment inside a Dna Group.
Internally, this is just a specialized Group containing various
subobjects:
- as Group members (not visible in MT, but for convenience of
reusing preexisting copy/undo/mmp code):
- one or more DnaMarkers, one of which determines this
strand's or segment's base indexing, and whether/how it survives if its
chains of PAM atoms are broken or merged with other strands or segments
- this DnaStrands's DnaStrandChunks, or this DnaSegment's
DnaAxisChunks (see docstrings of DnaStrand/DnaSegment for details)
- As other attributes:
- (probably) a WholeChain, which has a chain of DnaAtomChainOrRings (sp?)
which together comprise all the PAM atoms in this strand, or all
the PAM atoms in the axis of this segment. From these,
related objects like DnaLadders and connected DnaSegments/DnaStrands
can be found. This is used to help the dna updater reconstruct
the PAM atom chunks after a change by old code which didn't do that itself.
- whatever other properties the user needs to assign, which are not
covered by the member nodes or superclass attributes. However,
some of these might be stored on the controlling DnaMarker,
so that if we are merged with another strand or segment, and later separated
again, that marker can again control the properties of a new strand
or segment (as it will in any case control its base indexing).
"""
def permit_as_member(self, node, pre_updaters = True, **opts): # in DnaStrandOrSegment
"""
[friend method for enforce_permitted_members_in_groups and subroutines]
Does self permit node as a direct member,
when called from enforce_permitted_members_in_groups with
the same options as we are passed?
@rtype: boolean
[extends superclass method]
"""
#bruce 080319
if not LeafLikeGroup.permit_as_member(self, node, pre_updaters, **opts):
# reject if superclass would reject [bruce 081217]
return False
del opts
assy = self.assy
res = isinstance( node, assy.DnaMarker) or \
isinstance( node, assy.DnaLadderRailChunk) or \
pre_updaters and isinstance( node, assy.Chunk)
return res
def getDnaGroup(self):
"""
Return the DnaGroup we are contained in, or None if we're not
inside one.
@note: Returning None should never happen
if we have survived a run of the dna updater.
"""
return self.parent_node_of_class( self.assy.DnaGroup)
def move_into_your_members(self, node):
"""
Move node into self's members, and if node was not
already there but left some other existing Group,
return that Group.
@param node: a node of a suitable type for being our direct child
@type node: a DnaLadderRailChunk or DnaMarker (see: permit_as_member)
@return: Node's oldgroup (if we moved it out of a Group other than self)
or None
@rtype: Group or None
"""
# note: this is not yet needed in our superclass LeafLikeGroup,
# but if it someday is, nothing in it is dna-specific except
# the docstring.
oldgroup = node.dad # might be None
self.addchild(node)
newgroup = node.dad
assert newgroup is self
if oldgroup and oldgroup is not newgroup:
if oldgroup.part is newgroup.part: #k guess
return oldgroup
return None
pass # end of class DnaStrandOrSegment
# end
|