summaryrefslogtreecommitdiff
path: root/cad/src/dna/model/outtakes/PositionInWholeChain-outtakes.py
blob: 09258d342fa9839b34f1f59a5c1268a096a646e7 (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
from Numeric import sign

class PositionInWholeChain(object):
    """
    """
    def __init__(self, wholechain, rail, index, direction):
        self.wholechain = wholechain
        self.rail = rail
        self.index = index # base index in current rail
        self.direction = direction # in current rail only
            # note: our direction in each rail can differ.
        self.off_end = False # might not be true, but if so we'll find out
        # review: should we now move_by 0 to normalize index if out of range?
        return
    
    def move_by(self, relindex):
        # don't i recall code similar to this somewhere? yes, BaseIterator.py - stub, not yet used
        self.index += self.direction * relindex
        self.off_end = False # be optimistic, we might be back on if we were off
        assert 0 # LOGIC BUG: if rail dirs alternate as we move, then the following conds alternate too --
                # we're not always in the same loop below!! (better find out if i need to write it this way
                # or only as the scanner which yields the atoms -- might be easier that way) ### DECIDE
        while self.index < 0 and not self.off_end:
            self._move_to_prior_rail(sign(relindex))
        while self.index >= len(self.rail) and not self.off_end:
            self._move_to_next_rail(sign(relindex))
        return

    def _move_to_prior_rail(self, motion_direction):
        assert self.index < 0 and not self.off_end
        self._move_to_neighbor_rail(END0, motion_direction)# IMPORT, which variant of END0? 

    def _move_to_next_rail(self, motion_direction):
        assert self.index >= len(self.rail) and not self.off_end
        self._move_to_neighbor_rail(END1, motion_direction)
        
    def _move_to_neighbor_rail(self, end, motion_direction):
        neighbor_rail, index, direction = self.find_neighbor_rail(end) # IMPLEM
        # index is on end we get onto first, direction is pointing into that rail,
        # but does this correspond to our dir of motion or its inverse? depends on sign of relindex that got us here!
        if not neighbor_rail:
            self.off_end = True # self.index is negative but remains valid for self.rail
            return
        self.rail = neighbor_rail # now set index, direction to match
        
    def yield_atom_posns(self, counter = 0, countby = 1, pos = None):
        # maybe 1: might be a method on WholeChain which is passed rail, index, direction, then dispense with this object,
        # OR, maybe 2: might yield a stream of objects of this type, instead
        grab the vars
        if pos is None: # if pos passed, self is useless -- so use WholeChain method which is always passed pos; in here, no pos arg
            pos = self.pos
        
        while 1: # or, while not hitting end condition, like hitting start posn again
            if direction > 0:
                while index < len(rail):
                    yield rail, index, direction # and counter?
                    index += 1
                now jump into next rail, no data needed except jump off END1 of this rail
            else:
                while index >= 0:
                    yield rail, index, direction # and counter?
                    index -= 1
                now jump off END0 of this rail, and continue




this might be correct:

class PositionInWholeChain(object):
    """
    """
    def __init__(self, wholechain, rail, index, direction):
        self.wholechain = wholechain
        self.rail = rail
        self.index = index # base index in current rail
        self.direction = direction # in current rail only
            # note: our direction in each rail can differ.
        
        self.pos = (rail, index, direction) ##k or use property for one or the other?
        return
        
    def yield_rail_index_direction_counter(self, **options):
        return self.wholechain.yield_rail_index_direction_counter( self.pos, **options )
    
    def _that_method_in_WholeChain(self, pos, counter = 0, countby = 1):
        """
        @note: the first position we yield is always pos, with the initial value of counter.
        """
        rail, index, direction = pos
        # assert one of our rails, valid index in it
        assert direction in (-1, 1)
        while 1:
            # yield, move, adjust, check, continue
            yield rail, index, direction, counter
            # move
            counter += countby
            index += direction
            # adjust
            def jump_off(end):
                neighbor_atom = rail.neighbor_baseatoms[end]
                # neighbor_atom might be None, atom, or -1 if not yet set
                assert neighbor_atom != -1
                if neighbor_atom is None:
                    rail = None # outer code will return due to this
                    index, direction = None, None # illegal values (to detect bugs in outer code)
                else:
                    rail, index, direction = self._find_end_atom_chain_and_index(neighbor_atom)
                    assert rail
                return rail, index, direction
            if index < 0:
                # jump off END0 of this rail
                rail, index, direction = jump_off(LADDER_END0)
            elif index >= len(rail):
                # jump off END1 of this rail
                rail, index, direction = jump_off(LADDER_END1)
            else:
                pass
            # check
            if not rail:
                return
            assert 0 <= index < len(rail)
            assert direction in (-1, 1)
            } # TODO: or if reached starting pos or passed ending pos, return
            continue
        assert 0 # not reached
        pass