-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathis_classes.py
executable file
·327 lines (271 loc) · 14.3 KB
/
is_classes.py
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
class Callable:
def __init__(self, anycallable):
self.__call__ = anycallable
class Tree:
"""The class description of a tree.
The class contains only one attribute: the __init__ function.
But whenever an instance of Tree is created (i.e., during
instantiation), __init__ is called, with its "self" parameter pointing
to the instance object. The __init__ function, because of the
assignments in it, cause the following data attributes to spring into
existence in the instance object (but not in the class object).
(all the attributes will get their proper value after appropriate
functions are called during parsing.)
all_leaves a list of all leaves in the tree.
partial_order a list of all nodes in the tree such that a parent node
appears onnly after its children have appeared.
height is the length of the longest path (measured in terms of
the number of branches) from the root of the tree to a
leaf.
num_leaves the total number of leaves in the tree.
name the name of the tree (like tree_13, tree_14 in
onetree.nex) as in the nexus file that contains the
tree in parenthesis notation.
levels A level is a portion of the tree between two
branching events (or the portion from the leaves to
the most recent branching event).
levels[] is a list that contains all the levels in the
tree. A level should be implemented as an instance of
the class Level (see below).
"""
def __init__(self):
self.all_leaves = []
self.partial_order = []
self.height = 0
self.num_leaves = 0
self.root = None
self.name = None
self.levels = []
def Copy(self):
import cjumpchain;
G_prime=cjumpchain.PrepareTree();
return G_prime;
Copy = Callable(Copy)
class Level:
"""
A level in the genealogical history of a sample is that portion
two successive branching events (or between the tips and the first
branching event, as the case may be).
The class contains only one attribute: the __init__ function.
But whenever an instance of Level is created (i.e., during
instantiation), __init__ is called, with its "self" parameter pointing
to the instance object. The __init__ function, because of the
assignments in it, cause the following data attributes to spring into
existence in the instance object (but not in the class object).
(all the attributes will get their proper value after appropriate
functions are called during level demarcation.)
begin_time As mentioned earlier, a level is a portion of the
sample history between two successive branching events,
or between the tips and the most recent branching event
in the history of the sample. begin_time either 0.0
(for the most recent level) or is the age (date) of the
more recent of the two branching events that demarcate
it. Time is measured backwards, with the tips having
the age 0.0.
begin_node the parent node of the more recent branching event that
demarcates the level (a branching event involves one
parent node and two daughter nodes).
For the very first (i.e., most recent) level, the begin_node is one of the
leaves.
end_time The age of the less recent of the two branching events
that demarcate the level.
end_node the parent node of the less recent branching event that
demarcates the level
lineages A list of lineages in a level.
* Lineages and nodes are used interchangeably *, with a
lineage being identified with the more recent of its
two end points. For example, the following tree has
three nodes x, y and z; and three lineages 1, 2 & 3.
We consider 1 = a, 2 = b and 3 = b.
|
3 |
|z
1 / \ 2
/ \
x y
event_history The (backwards) proposal algorithm will propose
migration events for each level.
The character state assignment at the beginning (i.e.,
at its most recent) and the subsequent migration events
are recorded in event_history.
Suppose level = 4, and that there are 4 lineaages 1, 2, 3, & 4.
And let the character state assignments be {1:0, 2:1, 3:1,
4:1}. And let following events happen before the chain goes to
level 3:
a. lineage 2 goes from character state 1 to character state 0
b. lineage 3 goes from character state 1 to character state 0
c. lineages 2 & 3 coalesce to form a parent lineage 5; and this
ends level 4.
The event history for level 4 will be a list: [{1:0, 2:1, 3:1,
4:1}, 2, 3]. The first element is the character state at the
beginning. The other elements are the lineages that undergo
migration. Given that lineages only migrate between 2 states,
it is sufficient to list the lineages that migrated (their
states can be inferred).
For the next level, (i.e., level 3) the initial character state
assignment will be: {1:0, 4:1, 5:1} (since 2 & 3 were in state
1, their parent 5 also will be in state 1).
"""
def __init__(self):
self.begin_time = 0.0
self.end_time = 0.0
self.lineages = []
self.begin_node = None
self.end_node = None
self.event_history = []
#Specify what the print function would print
def __str__(self):
return lineages
class Node:
"""The class description of a node in a tree
The class contains only one attribute: the __init__ function.
But whenever an instance of Node is created (i.e., during
instantiation), __init__ is called, with its "self" parameter pointing
to the instance object. The __init__ function, because of the
assignments in it, cause the following data attributes to spring into
existence in the instance object (but not in the class object).
(all the attributes will get their proper value after appropriate
functions are called during parsing.)
children a list containing the two children of a node. For leaves,
this list should be empty.
all_leaves a list containing all the leaves whose most recent
common ancestor is the node.
the list contains the *node itself* for nodes that are leaves.
partial_order each node is a root of a subtree.
partial_order is a list of nodes of this subtree
such that a parent node appears in the list only after its
children have appeared.
num_leaves the number of leaves for which the node is the most
recent common ancestor.
parent the parent of the node in the tree.
if the node is teh root of the whole tree, this
should be None.
label The label of a node is the subtree under the node
(i.e., one for which the node is the root)
described in parenthesis notation.
This field is useful to see if parsing is being
done correctly, but otherwise is not used much.
taxon_name for leaves, this is the name of the taxon as in the
nexus file.
state this field is *deprecated* - which means it is not
really used anywhere, and in the future also it
shouldn't be used.
brlen the length of the branch (or equivalently, lineage) identified
with the node. Recall:
* Lineages and nodes are used interchangeably *, with a
lineage being identified with the more recent of its
two end points. For example, the following tree has
three nodes x, y and z; and three lineages 1, 2 & 3.
We consider 1 = a, 2 = b and 3 = b.
|
3 |
|z
1 / \ 2
/ \
x y
bifurcation_age The is really the age of the node. In the above
picture, z.bifurcation_age would have been 0.2 if
the branches (x, z) and (y, z) have the same
length, 0.2.
For leaves, this age is 0.0
parent_age The age of the the parent of the node; equals
bifurcation_age + brlen
"""
def __init__(self):
self.children = []
self.all_leaves = []
self.partial_order = []
self.num_leaves = 0
self.parent = None
self.label = 'None'
self.taxon_name = 'None'
self.state = 'NOWHERE'
self.brlen = 0.0
self.bifurcation_age = 0.0
self.parent_age = 0.0
self.index = 0 #a numerical representation of node. so node1 is represented as "1", for instance
def __repr__(self):
return self.label
# Tally & Perry: Ignore the following class definition.
# class definition begins.
#class CondJumpChain:
# """ The conditional jump chain class definition.
#
# The class CondJumpChain itself is an object, and this object has only
# function attributes, namely:
#
# fn. attrib. short desc.
# ---------- ----------
#
# MakeTreeByLevels makes a level-by-level representation
# of the input tree G.
#
# MakeStateSpacesByLevels constructs the state space of the
## jump chain level by level.
#
# MakeTransitionMatricesbyLevels constructs the transition
# matrix level-by-level.
#
# SampleFromIS Runs the chain once and returns
# the resulting event history
# along with its density.
#
# __init__ This is called on
# instantiation.
#
# Except __init__, the other functions are actually defined outside
# under a slightly different name. A function FunctionName is
# will actually be a a local variable of the class; a function by the
# slightly different name __FunctionName is defined outside and
# assigned to the local variable FunctionName.
#
# Detailed descriptions of the functions are provided with their
# definitions.
#
# Data attributes of the instance objects:
# ----------------------------------------
#
# While the class CondJumpChain itself has only function attributes,
# the instances of this class also have data attributes that spring
# into existence upon instantiation.
#
# For example, the following statement creates an instance
# cond_jump_chain_instance of the class CondJumpChain.
#
# cond_jump_chain_instance = CondJumpChain(G, delta, sigma)
#
# At instantiation, the __init__ function of the class is automatically
# called. Calling __init__ causes the following variables
# to spring into existence as data attributes of the
# instance object cond_jump_chain_instance.
#
# data attribute brief desc.
# -------------- ----------
#
# tree_by_levels return value of call to MakeTreeByLevels
# state_spaces_by_levels return value of call to MakeStateSpacesByLevels
# initial_state return value of call to GetInitialStateofCondJumpChain
# transition_matrices return value of call to MakeTransitionMatricesbyLevels
# """
#
# # The following are functions defined outside the class.
# MakeTreeByLevels = __MakeTreeByLevels
# MakeStateSpacesByLevels = __MakeStateSpacesByLevels
# GetInitialStateofCondJumpChain = __GetInitialStateofCondJumpChain
# MakeTransitionMatricesbyLevels = __MakeTransitionMatricesbyLevels
# SampleFromIS = __SampleFromIS
#
# def __init__(G, delta, sigma):
#
# # When an instance object is initialized by, say, the statement
# # cond_jump_chain_instance = CondJumpChain(G, delta, sigma), tree_by_levels, state_spaces_by_levels,
# # initial_state and transition_matrices, will spring into existence as the data
# # attributes of the *instance* object cond_jump_chain_instance.
# # For each function attribute of the class object CondJumpChain,
# # there will be a corresponding method attribute in the instance
# # object.
# self.tree_by_levels = self.MakeTreeByLevels(G)
# self.state_spaces_by_levels = self.MakeStateSpacesByLevels(G, delta)
# self.initial_state = self.GetInitialStateofCondJumpChain(G, delta)
# self.transition_matrices = self.MakeTransitionMatricesbyLevels(sigma)
###### class definition ends.