comparison tools/myTools/bin/sfa/base.py @ 1:7e5c71b2e71f draft default tip

Uploaded
author laurenmarazzi
date Wed, 22 Dec 2021 16:00:34 +0000
parents
children
comparison
equal deleted inserted replaced
0:f24d4892aaed 1:7e5c71b2e71f
1 import os
2 import sys
3 if sys.version_info <= (2, 8):
4 from builtins import super
5
6 # from abc import ABC, abstractmethod
7 import abc
8 import copy
9
10 import pandas as pd
11 import six
12 import sfa.utils
13
14 __all__ = ['Algorithm', 'Data', 'Result']
15
16
17 @six.add_metaclass(abc.ABCMeta)
18 class ContainerItem():
19 """
20 The base class that defines the item object of
21 ``sfa.containers.Container``.
22
23 """
24 def __init__(self, abbr=None, name=None):
25 self._abbr = abbr
26 self._name = name
27
28 def __str__(self):
29 return self._abbr
30
31 def __repr__(self):
32 class_name = self.__class__.__name__
33 return "%s object" % (class_name)
34
35 @property
36 def abbr(self):
37 """Abbreviation or symbol representing this item.
38 """
39 return self._abbr
40
41 @abbr.setter
42 def abbr(self, val):
43 self._abbr =val
44
45 @property
46 def name(self):
47 """Full name or description of this item.
48 """
49 return self._name
50
51 @name.setter
52 def name(self, val):
53 self._name = val
54
55
56 class ParameterSet(sfa.utils.FrozenClass):
57 """The base class of ParameterSet objects.
58 """
59
60 def __init__(self, abbr):
61 """
62 """
63 super().__init__(abbr)
64
65
66 class Algorithm(ContainerItem):
67 """The base class of Algorithm classes.
68
69 Attributes
70 ----------
71 abbr : str
72 name : str
73 data : sfa.base.Data
74 params : sfa.base.ParameterSet
75 result : sfa.base.Result
76
77 Examples
78 --------
79 >>> class AnAlgorithm(sfa.base.Algorithm):
80 # Definition of algorithm ...
81 ...
82
83 >>> alg = AnAlgorithm()
84 >>> alg.params = params_obj # Parameters of the algorithm
85 >>> alg.data = data_obj # Data to be analyzed by the algorithm
86 >>> alg.initialize()
87 >>> res = alg.compute()
88
89 """
90 def __init__(self, abbr):
91 super().__init__(abbr)
92 self._data = None
93 self._params = None
94 self._result = None
95
96 def copy(self, is_deep=False):
97 """
98
99 """
100 if is_deep:
101 copy.deepcopy(self)
102 else:
103 return copy.copy(self)
104
105 # Read-only properties
106 @property
107 def result(self):
108 """The object of ``sfa.base.Result``.
109 The result of computing the batch.
110 """
111 return self._result
112
113 # Read & write properties
114 @property
115 def params(self):
116 """The object of ``sfa.base.ParameterSet``.
117 Parameters of the algorithm can accessed
118 through this member.
119 """
120 return self._params
121
122 @params.setter
123 def params(self, obj):
124 self._params = obj
125
126 @property
127 def data(self):
128 """The object of ``sfa.base.Data``.
129 Data to be processed based on the algorithm
130 can accessed through this member.
131 """
132 return self._data
133
134 @data.setter
135 def data(self, obj):
136 self._data = obj
137
138 def initialize(self, network=True, ba=True):
139 """
140 """
141 if network:
142 self.initialize_network()
143
144 if ba:
145 self.initialize_basal_activity()
146
147 def initialize_network(self):
148 """Initialize the data structures related to network.
149 """
150 pass
151
152 def initialize_basal_activity(self):
153 """Initialize the basal activity, :math:`b`.
154 """
155 pass
156
157 @abc.abstractmethod
158 def compute(self, b,pi):
159 r"""Process the assigned data
160 with the given basal activity, :math:`b`.
161
162 Parameters
163 ----------
164 b : numpy.ndarray
165 1D array of basal activity.
166
167 pi: list
168 list of fixed node perturbations
169 Returns
170 -------
171 x : numpy.ndarray
172 1D-array object of activity at steady-state.
173 """
174 raise NotImplementedError("compute() should be implemented")
175
176 @abc.abstractmethod
177 def compute_batch(self):
178 """Process the assigned data that contains a batch data.
179 The result is stored in ``result`` member.
180 """
181 raise NotImplementedError("compute_batch() should be implemented")
182
183 # end of class Algorithm
184
185
186 class Data(ContainerItem):
187 def __init__(self):
188 super().__init__()
189 self._A = None
190 self._n2i = None
191 self._i2n = None
192 self._dg = None
193 self._inputs= None
194 self._df_conds = None
195 self._df_exp = None
196 self._df_ptb = None
197 self._names_ptb = None
198 self._iadj_to_idf = None
199 self._has_link_perturb = None
200
201 def initialize(self,
202 fpath,
203 fname_network="network.sif",
204 fname_ptb="ptb.tsv",
205 fname_conds="conds.tsv",
206 fname_exp="exp.tsv",
207 inputs={}):
208
209 dpath = os.path.dirname(fpath)
210 fpath_network = os.path.join(dpath, fname_network)
211 fpath_ptb = os.path.join(dpath, fname_ptb)
212
213 A, n2i, dg = sfa.read_sif(fpath_network, as_nx=True)
214 self._A = A
215 self._n2i = n2i
216 self._dg = dg
217 self._df_conds = pd.read_table(os.path.join(dpath, fname_conds),
218 header=0, index_col=0)
219 self._df_exp = pd.read_table(os.path.join(dpath, fname_exp),
220 header=0, index_col=0)
221
222 self._inputs = inputs
223 self._df_ptb = pd.read_table(fpath_ptb, index_col=0)
224 if any(self._df_ptb.Type == 'link'):
225 self._has_link_perturb = True
226 else:
227 self._has_link_perturb = False
228
229 self._names_ptb = []
230 for i, row in enumerate(self._df_conds.iterrows()):
231 row = row[1]
232 list_name = [] # Target names
233 for target in self._df_conds.columns[row.nonzero()]:
234 list_name.append(target)
235 # end of for
236 self._names_ptb.append(list_name)
237 # end of for
238
239 # For mapping from the indices of adj. matrix to those of DataFrame
240 # (arrange the indices of adj. matrix according to df_exp.columns)
241 self._iadj_to_idf = [n2i[x] for x in self._df_exp.columns]
242
243 self._i2n = {idx: name for name, idx in n2i.items()}
244
245 # end of def
246
247 # Read-only members
248 @property
249 def A(self): # Adjacency matrix (numpy.ndarray)
250 return self._A
251
252 @property
253 def n2i(self): # Name to index mapping (hashable)
254 return self._n2i
255
256 @property
257 def i2n(self): # Index to name mapping (hashable)
258 return self._i2n
259
260 @property
261 def dg(self): # Directed graph object of NetworkX
262 return self._dg
263
264 @property # List of perturbation targets
265 def names_ptb(self):
266 return self._names_ptb
267
268 @property # List of values for perturbation
269 def vals_ptb(self):
270 return self._vals_ptb
271
272 # @property # List of perturbation types
273 # def types_ptb(self):
274 # return self._types_ptb
275
276 @property
277 def iadj_to_idf(self):
278 return self._iadj_to_idf
279
280 @iadj_to_idf.setter
281 def iadj_to_idf(self, arr):
282 self._iadj_to_idf = arr
283
284 # Replaceable (assignable) members
285 @property
286 def inputs(self): # Input conditions
287 return self._inputs
288
289 @inputs.setter
290 def inputs(self, obj_dict):
291 self._inputs = obj_dict
292
293 @property # DataFrame of experimental conditions
294 def df_conds(self):
295 return self._df_conds
296
297 @df_conds.setter
298 def df_conds(self, df):
299 self._df_conds = df
300
301 @property # DataFrame of experimental results
302 def df_exp(self):
303 return self._df_exp
304
305 @df_exp.setter
306 def df_exp(self, df):
307 self._df_exp = df
308
309 @property # DataFrame of perturbation information
310 def df_ptb(self):
311 return self._df_ptb
312
313 @df_ptb.setter
314 def df_ptb(self, df):
315 self._df_ptb = df
316
317 @property
318 def has_link_perturb(self):
319 return self._has_link_perturb
320
321 @has_link_perturb.setter
322 def has_link_perturb(self, val):
323 if not isinstance(val, bool):
324 raise TypeError("has_link_perturb should be boolean.")
325 self._has_link_perturb = val
326
327 # end of class Data
328
329
330 class Result(sfa.utils.FrozenClass):
331
332 def __init__(self):
333 self._df_sim = None
334 self._freeze()
335
336 @property
337 def df_sim(self):
338 return self._df_sim
339
340 @df_sim.setter
341 def df_sim(self, val):
342 self._df_sim = val
343
344 # end of def class Result