0
|
1 #!/usr/bin/env python
|
|
2
|
|
3 from OrderedDict import OrderedDict
|
|
4
|
|
5 class Individual(object):
|
|
6 __slots__ = ['_column', '_name', '_alias']
|
|
7
|
|
8 def __init__(self, column, name, alias=None):
|
|
9 self._column = column
|
|
10 self._name = name
|
|
11 self._alias = alias
|
|
12
|
|
13 @property
|
|
14 def column(self):
|
|
15 return self._column
|
|
16
|
|
17 @property
|
|
18 def name(self):
|
|
19 return self._name if self._alias is None else self._alias
|
|
20
|
|
21 @property
|
|
22 def alias(self):
|
|
23 return self._alias
|
|
24
|
|
25 @alias.setter
|
|
26 def alias(self, alias):
|
|
27 self._alias = alias
|
|
28
|
|
29 @property
|
|
30 def real_name(self):
|
|
31 return self._name
|
|
32
|
|
33 def __eq__(self, other):
|
|
34 return self._column == other._column and self._name == other._name
|
|
35
|
|
36 def __ne__(self, other):
|
|
37 return not self.__eq__(other)
|
|
38
|
|
39 def __repr__(self):
|
|
40 return 'Individual: column={0} name={1} alias={2}'.format(self._column, self._name, self._alias)
|
|
41
|
|
42
|
|
43 class Population(object):
|
|
44 def __init__(self, name=None):
|
|
45 self._columns = OrderedDict()
|
|
46 self._name = name
|
|
47
|
|
48 @property
|
|
49 def name(self):
|
|
50 return self._name
|
|
51
|
|
52 @name.setter
|
|
53 def name(self, name):
|
|
54 self._name = name
|
|
55
|
|
56 def add_individual(self, individual, alias=None):
|
|
57 if individual.column not in self._columns:
|
|
58 self._columns[individual.column] = individual
|
|
59 elif self._columns[individual.column] == individual:
|
|
60 # should should this be an error?
|
|
61 # should we replace the alias using this entry?
|
|
62 pass
|
|
63 else:
|
|
64 raise 'Duplicate column: {0}'.format(individual)
|
|
65
|
|
66 def is_superset(self, other):
|
|
67 for column, other_individual in other._columns.items():
|
|
68 our_individual = self._columns.get(column)
|
|
69 if our_individual is None or our_individual != other_individual:
|
|
70 return False
|
|
71 return True
|
|
72
|
|
73 def is_disjoint(self, other):
|
|
74 for column, our_individual in self._columns.items():
|
|
75 other_individual = other._columns.get(column)
|
|
76 if other_individual is not None and other_individual == our_individual:
|
|
77 return False
|
|
78 return True
|
|
79
|
|
80 def column_list(self):
|
|
81 return self._columns.keys()
|
|
82
|
|
83 def individual_with_column(self, column):
|
|
84 if column in self._columns:
|
|
85 return self._columns[column]
|
|
86 return None
|
|
87
|
|
88 def tag_list(self, delimiter=':'):
|
|
89 entries = []
|
|
90 for column, individual in self._columns.items():
|
|
91 entry = '{0}{1}{2}'.format(column, delimiter, individual.name)
|
|
92 entries.append(entry)
|
|
93 return entries
|
|
94
|
|
95 def to_string(self, delimiter=':', separator=' ', replace_names_with=None):
|
|
96 entries = []
|
|
97 for column, individual in self._columns.items():
|
|
98 value = individual.name
|
|
99 if replace_names_with is not None:
|
|
100 value = replace_names_with
|
|
101 entry = '{0}{1}{2}'.format(column, delimiter, value)
|
|
102 entries.append(entry)
|
|
103 return separator.join(entries)
|
|
104
|
|
105 def __str__(self):
|
|
106 return self.to_string()
|
|
107
|
|
108 def from_population_file(self, filename):
|
|
109 with open(filename) as fh:
|
|
110 for line in fh:
|
|
111 line = line.rstrip('\r\n')
|
|
112 column, name, alias = line.split('\t')
|
|
113 alias = alias.strip()
|
|
114 individual = Individual(column, name)
|
|
115 if alias:
|
|
116 individual.alias = alias
|
|
117 self.add_individual(individual)
|
|
118
|
|
119 def from_tag_list(self, tag_list):
|
|
120 for tag in tag_list:
|
|
121 column, name = tag.split(':')
|
|
122 individual = Individual(column, name)
|
|
123 self.add_individual(individual)
|
|
124
|
|
125 def individual_names(self):
|
|
126 for column, individual in self._columns.items():
|
|
127 yield individual.name
|
|
128
|