def lump_coupled_reactions(N, V, coupled_r_id_groups, r_id2i): coupled_r_ids = reduce(lambda s1, s2: s1 | set(s2), coupled_r_id_groups, set()) ordered_r_ids = [r_id for r_id in sorted(r_id2i.keys(), key=lambda r_id: r_id2i[r_id]) if r_id not in coupled_r_ids] new_r_id2i = dict(zip(ordered_r_ids, range(0, len(ordered_r_ids)))) indices = tuple((r_id2i[r_id] for r_id in ordered_r_ids)) N_new = N[:, indices] V_new = V[indices, :] r_id2lr_id = {} lr_id2r_id2c = {} lr_i = 0 for i, r_ids in enumerate(coupled_r_id_groups, start=len(ordered_r_ids)): lumped_r_id, lr_i = get_unique_id(new_r_id2i, 'r_group', lr_i) r_id2lr_id.update({r_id: lumped_r_id for r_id in r_ids}) new_r_id2i[lumped_r_id] = i sample_r_index = r_id2i[r_ids[0]] sample_efm_index = np.nonzero(V[sample_r_index, :])[0][0] sample_efm = V[:, sample_efm_index] c = abs(sample_efm[sample_r_index]) * 1.0 sign = coefficient_to_binary(sample_efm[sample_r_index]) lr_id2r_id2c[lumped_r_id] = {r_id: sample_efm[r_id2i[r_id]] / c for r_id in r_ids} lambdas = np.array([[lr_id2r_id2c[lumped_r_id][r_id]] for r_id in r_ids]) r_new = np.dot(N[:, tuple((r_id2i[r_id] for r_id in r_ids))], lambdas) replace_zeros(r_new) N_new = np.concatenate((N_new, r_new), axis=1) V_new = np.concatenate((V_new, [V[sample_r_index, :] * sign]), axis=0) return N_new, V_new, new_r_id2i, r_id2lr_id, lr_id2r_id2c
def get_r_id2coeff(self, efm_id, binary=False, r_ids=None): if not r_ids: r_ids = self.r_id2i.keys() if binary: return {r_id: coefficient_to_binary(self.V[self.r_id2i[r_id], self.efm_id2i[efm_id]]) for r_id in r_ids if self.V[self.r_id2i[r_id], self.efm_id2i[efm_id]]} return {r_id: self.V[self.r_id2i[r_id], self.efm_id2i[efm_id]] for r_id in r_ids if self.V[self.r_id2i[r_id], self.efm_id2i[efm_id]]}
def get_efm_intersection(sign_V, i2r_id): result, sample_v = None, None for v in sign_V.T: if result is None: sample_v = v result = np.array(v) else: result[result != v] = 0 return {i2r_id[i]: coefficient_to_binary(sample_v[i]) for i in np.where(result)[0] if sample_v[i]}
def filter_efms(in_path, r_id2i, rev_r_id2i, out_path, r_id2rev=None, threshold=ZERO_THRESHOLD): i2r_id = {i: (r_id, False) for (r_id, i) in r_id2i.items()} i2r_id.update({i: (r_id, True) for (r_id, i) in rev_r_id2i.items()}) efms = [] rejected_bad, rejected_different = 0, 0 get_key = lambda r_id2coeff: \ tuple(sorted(((r_id, coefficient_to_binary(coeff)) for (r_id, coeff) in r_id2coeff.items()))) processed = set() with open(out_path, 'w+') as out_f: with open(in_path, 'r') as in_f: for line in in_f: values = line.replace("\n", "").strip().split(" ") r_id2coefficient = {} bad_em = False for i, v in enumerate(values, start=1): v = round_value(v) if not v or abs(v) <= threshold: continue r_id, rev = i2r_id[i] if rev: v *= -1 # The same reaction participates in different directions # => don't want such an EFM if r_id in r_id2coefficient: bad_em = True break r_id2coefficient[r_id] = v if bad_em: rejected_bad += 1 continue if r_id2rev: for (r_id, rev) in r_id2rev.items(): if r_id not in r_id2coefficient or (rev is not None and rev != (r_id2coefficient[r_id] < 0)): rejected_different += 1 bad_em = True break if bad_em: continue key = get_key(r_id2coefficient) if key in processed: continue processed.add(key) out_f.write(line) efms.append(r_id2coefficient) if rejected_different: logging.info('Rejected %d EFMs as not all of the reactions of interest were present in them.' % rejected_different) if rejected_bad: logging.info('Rejected %d EFMs as they contained reversible reactions in both directions' % rejected_bad) return efms
def lump_coupled_reactions(self): coupled_r_id_groups = get_coupled_reactions(self.V, self.r_id2i) lr_i = 0 for r_ids in coupled_r_id_groups: lumped_r_id, lr_i = get_unique_id(self.r_id2i, 'coupled_r', lr_i) self.coupled_rs.add(lumped_r_id) self.r_id2gr_id.update({r_id: lumped_r_id for r_id in r_ids}) self.r_id2i[lumped_r_id] = self.V.shape[0] sample_r_index = self.r_id2i[r_ids[0]] sample_efm_index = np.nonzero(self.V[sample_r_index, :])[0][0] sample_efm = self.V[:, sample_efm_index] c = abs(sample_efm[sample_r_index]) * 1.0 sign = coefficient_to_binary(sample_efm[sample_r_index]) self.gr_id2r_id2c[lumped_r_id] = {r_id: sample_efm[self.r_id2i[r_id]] / c for r_id in r_ids} lambdas = np.array([[self.gr_id2r_id2c[lumped_r_id][r_id]] for r_id in r_ids]) r_new = np.dot(self.N[:, tuple((self.r_id2i[r_id] for r_id in r_ids))], lambdas) replace_zeros(r_new) self.N = np.concatenate((self.N, r_new), axis=1) self.V = np.concatenate((self.V, [self.V[sample_r_index, :] * sign]), axis=0) self.r_ids -= set(r_ids) self.r_ids.add(lumped_r_id)