コード例 #1
0
    def mol_defs_from_rxncon(rxncon_sys: RxnConSystem) -> List[MolDef]:
        mol_defs = {}
        for spec in rxncon_sys.components():
            LOGGER.debug('{} : Creating MolDefBuilder for {}'.format(current_function_name(), str(spec)))
            builder = MolDefBuilder(spec)
            for state in rxncon_sys.states_for_component(spec):
                LOGGER.debug('{} : Applying State {} of type {}'.format(current_function_name(), str(state), type(state)))
                for func in STATE_TO_MOL_DEF_BUILDER_FN[type(state)]:
                    func(state, builder)

            mol_defs[spec] = builder.build()

        return list(mol_defs.values())
コード例 #2
0
def components_microstate(
        cont_set: VennSet[State],
        rxncon_system: RxnConSystem) -> Dict[Spec, VennSet[State]]:
    """Returns, for each component, the VennSet expression for the modification states."""
    bond_filter = make_bond_filter(cont_set)
    comp_to_states = group_states(cont_set, lambda s: not bond_filter(s))

    constraints = dict()  # type: Dict[Spec, VennSet[State]]

    for comp, states in comp_to_states.items():

        def state_to_locus(state: State) -> Locus:
            return state.specs[0].locus

        complement_states = set()
        for state in states:
            complement_states |= set(
                rxncon_system.complement_states_for_component(comp, state))

        states = set(states) | complement_states

        comp_constraint = Intersection()  # type: VennSet[State]

        for _, locus_states in groupby(sorted(states, key=state_to_locus),
                                       state_to_locus):
            comp_constraint = Intersection(
                comp_constraint,
                DisjunctiveUnion(*(ValueSet(s) for s in locus_states)))

        constraints[comp] = comp_constraint

    return constraints
コード例 #3
0
    def calc_observables(rxncon_sys: RxnConSystem) -> List[Observable]:
        def observable_complex(states: List[State]) -> Complex:
            builder = ComplexExprBuilder()

            assert all(x.is_structured for x in states)

            for state in states:
                for func in STATE_TO_COMPLEX_BUILDER_FN[type(state)]:
                    func(state, builder)

            complexes = builder.build(only_reactants=False)

            assert len(complexes) == 1
            return complexes[0]

        observables = []
        output_rxns = [rxn for rxn in rxncon_sys.reactions if isinstance(rxn, OutputReaction)]
        for rxn in output_rxns:
            LOGGER.debug('{} : calculating observable {}'.format(current_function_name(), str(rxn)))
            solns = Intersection(*(x.to_venn_set() for x
                                   in rxncon_sys.contingencies_for_reaction(rxn))).calc_solutions()
            positive_solns = []  # type: List[List[State]]
            for soln in solns:
                positive_solns += calc_positive_solutions(rxncon_sys, soln)

            for index, positive_soln in enumerate(positive_solns):
                LOGGER.debug('{} : solution {} : {}'.format(current_function_name(), index, positive_soln))
                observables.append(Observable('{}{}'.format(rxn.name, index), observable_complex(positive_soln)))

        return observables
コード例 #4
0
 def _construct_rxncon_system(self) -> None:
     self._rxncon_system = RxnConSystem(self._reactions,
                                        self._contingencies)
コード例 #5
0
def rule_based_model_from_rxncon(rxncon_sys: RxnConSystem) -> RuleBasedModel:  # pylint: disable=too-many-locals
    """Returns a RBM given a rxncon system."""
    def mol_defs_from_rxncon(rxncon_sys: RxnConSystem) -> List[MolDef]:
        mol_defs = {}
        for spec in rxncon_sys.components():
            LOGGER.debug(
                'mol_defs_from_rxncon : Creating MolDefBuilder for {}'.format(
                    str(spec)))
            builder = MolDefBuilder(spec)
            for state in rxncon_sys.states_for_component(spec):
                LOGGER.debug(
                    'mol_defs_from_rxncon : Applying State {} of type {}'.
                    format(str(state), type(state)))
                for func in STATE_TO_MOL_DEF_BUILDER_FN[type(
                        state)]:  # type: ignore
                    func(state, builder)

            mol_defs[spec] = builder.build()

        return list(mol_defs.values())

    def remove_global_states(
            solutions: List[Dict[State, bool]]) -> List[Dict[State, bool]]:
        filtered_solutions = []  # type: List[Dict[State, bool]]
        for soln in solutions:
            cleaned_solution = {}
            for state, val in soln.items():
                if state.is_global:
                    LOGGER.warning(
                        'remove_global_states : REMOVING INPUT STATE {} from contingencies.'
                        .format(state))
                else:
                    cleaned_solution[state] = val

            if cleaned_solution not in filtered_solutions:
                filtered_solutions.append(cleaned_solution)

        return filtered_solutions

    def is_satisfiable(states: Iterable[State]) -> bool:
        for pair in combinations(states, 2):
            if pair[0].is_mutually_exclusive_with(pair[1]):
                return False

        return True

    def calc_positive_solutions(
            rxncon_sys: RxnConSystem,
            solution: Dict[State, bool]) -> List[List[State]]:
        def complementary_state_combos(state: State) -> List[List[State]]:
            combos = product(*(rxncon_sys.complement_states_for_component(
                spec.to_component_spec(), state) for spec in state.specs))
            return [list(combo) for combo in combos if is_satisfiable(combo)]

        def structure_states(states: List[State]) -> List[State]:
            cur_index = max(spec.struct_index for state in states
                            for spec in state.specs if spec.is_structured)
            assert cur_index is not None

            spec_to_index = {}  # type: Dict[Spec, int]
            struct_states = []  # type: List[State]

            for state in states:
                if state.is_structured:
                    struct_states.append(state)
                    continue

                for spec in state.specs:
                    if spec.is_structured:
                        continue

                    try:
                        state = state.to_structured_from_spec(
                            spec.with_struct_index(
                                spec_to_index[spec.to_component_spec()]))
                    except KeyError:
                        cur_index += 1
                        state = state.to_structured_from_spec(
                            spec.with_struct_index(cur_index))
                        spec_to_index[spec.to_component_spec()] = cur_index

                struct_states.append(state)

            return struct_states

        ordered_solution = OrderedDict(
            sorted(solution.items(), key=lambda x: x[0]))

        trues = [state for state, val in ordered_solution.items() if val]
        falses = [
            state for state, val in ordered_solution.items()
            if not val and not any(
                state.is_mutually_exclusive_with(x) for x in trues)
        ]

        if not falses:
            return [trues] if is_satisfiable(trues) else []

        positivized_falses = [
            list(chain(*x))
            for x in product(*(complementary_state_combos(state)
                               for state in falses))
        ]

        solutions = []

        for positivized_false in positivized_falses:
            possible_solution = []  # type: List[State]
            for soln_state in structure_states(trues + positivized_false):
                if soln_state not in possible_solution:
                    possible_solution.append(soln_state)

            if is_satisfiable(possible_solution):
                solutions.append(possible_solution)

        return solutions

    def calc_rule(reaction: Reaction, cont_soln: List[State],
                  quant_cont: VennSet[State]) -> Rule:
        def calc_complexes(terms: List[ReactionTerm],
                           states: List[State]) -> List[Complex]:
            if not all(x.is_structured for x in states):
                unstructs = [x for x in states if not x.is_structured]
                raise AssertionError(
                    'Error in building rule for Reaction {}, States {} appear unstructured'
                    .format(str(reaction),
                            ', '.join(str(x) for x in unstructs)))

            if not is_satisfiable(cont_soln):
                raise AssertionError(
                    'Cannot satisfy contingencies {} simultaneously'.format(
                        ' & '.join(str(s) for s in cont_soln)))

            states = copy(states)
            builder = ComplexExprBuilder(reaction=reaction)
            struct_index = 0
            for term in terms:
                struct_states = deepcopy(term.states)
                for spec in term.specs:
                    struct_spec = copy(spec)
                    struct_spec.struct_index = struct_index
                    builder.add_mol(struct_spec, is_reactant=True)
                    struct_states = [
                        state.to_structured_from_spec(struct_spec)
                        for state in struct_states
                    ]
                    struct_index += 1

                states += struct_states

            assert all(x.is_structured for x in states)

            for state in states:
                for func in STATE_TO_COMPLEX_BUILDER_FN[type(
                        state)]:  # type: ignore
                    func(state, builder)

            return builder.build()

        lhs = calc_complexes(reaction.terms_lhs, cont_soln)
        rhs = calc_complexes(reaction.terms_rhs, cont_soln)

        rate = Parameter('k_{}{}'.format(
            rxncon_sys.reaction_number(reaction) + 1,
            quant_cont.rate_constant_desc),
                         '1.0',
                         description=str(reaction))

        return Rule(lhs,
                    rhs,
                    rate,
                    parent_reaction=reaction,
                    quant_cont=quant_cont)

    def calc_initial_conditions(
            mol_defs: List[MolDef]) -> List[InitialCondition]:
        return \
            [InitialCondition(mol_def.create_neutral_complex(),
                              Parameter('Num{}'.format(mol_def.name), str(INITIAL_MOLECULE_COUNT))) for mol_def in
             mol_defs]

    def calc_observables(rxncon_sys: RxnConSystem) -> List[Observable]:
        def observable_complex(states: List[State]) -> Complex:
            builder = ComplexExprBuilder()

            assert all(x.is_structured for x in states), 'Unstructured states appearing in observable ' \
                                                         '{}'.format(states)

            for state in states:
                for func in STATE_TO_COMPLEX_BUILDER_FN[type(
                        state)]:  # type: ignore
                    func(state, builder)

            complexes = builder.build(only_reactants=False)

            assert len(
                complexes
            ) == 1, 'Multiple complexes appearing in observable {}'.format(
                states)
            return complexes[0]

        observables = []
        output_rxns = [
            rxn for rxn in rxncon_sys.reactions
            if isinstance(rxn, OutputReaction)
        ]
        for rxn in output_rxns:
            LOGGER.debug('calc_observables : calculating observable {}'.format(
                str(rxn)))
            solns = Intersection(
                *(x.to_venn_set()
                  for x in rxncon_sys.contingencies_for_reaction(rxn)
                  )).calc_solutions()
            positive_solns = []  # type: List[List[State]]
            for soln in solns:
                positive_solns += calc_positive_solutions(rxncon_sys, soln)

            for index, positive_soln in enumerate(positive_solns):
                LOGGER.debug('calc_observables : solution {} : {}'.format(
                    index, positive_soln))
                observables.append(
                    Observable('{}{}'.format(rxn.name, index),
                               observable_complex(positive_soln)))

        return observables

    mol_defs = mol_defs_from_rxncon(rxncon_sys)
    LOGGER.debug('rule_based_model_from_rxncon : Generated MolDefs: {}'.format(
        ', '.join(str(mol_def) for mol_def in mol_defs)))

    rules = []  # type: List[Rule]

    for reaction in (x for x in rxncon_sys.reactions
                     if not isinstance(x, OutputReaction)):
        LOGGER.debug(
            'rule_based_model_from_rxncon : Generating rules for reaction {}'.
            format(str(reaction)))
        strict_cont_set = Intersection(
            *(x.to_venn_set()
              for x in rxncon_sys.s_contingencies_for_reaction(reaction)
              ))  # type: VennSet[State]
        quant_contingencies = QuantContingencyConfigs(
            rxncon_sys.q_contingencies_for_reaction(reaction))
        LOGGER.debug(
            'rule_based_model_from_rxncon : Strict contingencies {}'.format(
                str(strict_cont_set)))

        found_solution = False

        for quant_contingency_set in quant_contingencies:
            LOGGER.debug(
                'rule_based_model_from_rxncon : quantitative contingency config: {}'
                .format(str(quant_contingency_set)))

            cont_set = Intersection(
                strict_cont_set, quant_contingency_set)  # type: VennSet[State]
            LOGGER.debug(
                'rule_based_model_from_rxncon : adding constraints...')
            cont_set = with_connectivity_constraints(cont_set, rxncon_sys)
            LOGGER.debug(
                'rule_based_model_from_rxncon {} : calculating solutions...'.
                format(datetime.now()))
            solutions = cont_set.calc_solutions()
            LOGGER.debug(
                'rule_based_model_from_rxncon {} : found {} non-positivized solutions...'
                .format(datetime.now(), len(solutions)))
            solutions = remove_global_states(solutions)

            LOGGER.debug(
                'rule_based_model_from_rxncon : contingency solutions {}'.
                format(str(solutions)))
            positive_solutions = []  # type: List[List[State]]
            for solution in solutions:
                positive_solutions += calc_positive_solutions(
                    rxncon_sys, solution)

            for positive_solution in positive_solutions:
                found_solution = True
                LOGGER.debug(
                    'rule_based_model_from_rxncon : positivized contingency solution {}'
                    .format(' & '.join(str(x) for x in positive_solution)))
                rule = calc_rule(reaction, positive_solution,
                                 quant_contingency_set)
                if not any(
                        rule.is_equivalent_to(existing) for existing in rules):
                    rules.append(rule)

        if not found_solution:
            LOGGER.error(
                'rule_based_model_from_rxncon : could not find positive solutions for rxn {}'
                .format(str(reaction)))

    return RuleBasedModel(mol_defs, calc_initial_conditions(mol_defs), [],
                          calc_observables(rxncon_sys), rules)
コード例 #6
0
 def complementary_state_targets(self, rxnconsys: RxnConSystem,
                                 component: Spec) -> List['StateTarget']:
     others = rxnconsys.complement_states_for_component(
         component, self.state_parent)
     return [StateTarget(x) for x in others]