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
Beispiel #2
0
 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
Beispiel #5
0
    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)