Ejemplo n.º 1
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
Ejemplo n.º 2
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())
Ejemplo n.º 3
0
    def _load_reaction_list(self) -> None:
        sheet = self._xlrd_book.sheet_by_name(SHEET_REACTION_LIST)
        reaction_rows = [row for row in sheet.get_rows()][DATA_ROW:]

        for row in reaction_rows:
            if not row[self._column_reaction_full_name].value:
                logger.debug('{}: Empty row'.format(current_function_name()))
                continue

            logger.debug('{}: {}'.format(current_function_name(), row[self._column_reaction_full_name].value))

            # When a verb such as 'ppi' is encountered, the function 'preprocessed_reaction_strs'
            # will split it into 'ppi+' and 'ppi-'.
            reaction_strs = split_bidirectional_reaction_str(row[self._column_reaction_full_name].value)
            self._reactions += [reaction_from_str(x) for x in reaction_strs]
Ejemplo n.º 4
0
def with_connectivity_constraints(cont_set: VennSet[State]) -> VennSet:
    complexes = calc_connected_complexes(cont_set.values)
    complex_constraints = []

    for complex in complexes:  # pylint: disable=redefined-builtin
        state_paths = calc_state_paths(complex)
        constraint = UniversalSet()  # type:  VennSet[State]

        for state in complex:
            assert not state.is_global, 'Global state {} appearing in connectivity constraints.'.format(state)

            if any(path == [] for path in state_paths[state]):
                continue

            state_constraints = [Complement(ValueSet(state))]  # type: List[VennSet[State]]
            for path in state_paths[state]:
                state_constraints.append(Intersection(*(ValueSet(x) for x in path)))

            constraint = Intersection(constraint, Union(*state_constraints))  # pylint: disable=redefined-variable-type

        complex_constraints.append(constraint.to_simplified_set())

    if complex_constraints:
        LOGGER.debug('{} : Complex constraints {}'.format(current_function_name(), ' XOR '.join(str(x) for x in complex_constraints)))
        return Intersection(cont_set, DisjunctiveUnion(*complex_constraints))
    else:
        return cont_set
Ejemplo n.º 5
0
    def build(self, only_reactants: bool=True) -> List[Complex]:
        complexes = []

        LOGGER.debug('{} : Building complex with molecules {}'.format(current_function_name(),
                                                                      ' & '.join(str(spec) for spec in self._mol_builders.keys())))
        LOGGER.debug('{} : Grouped specs are {}'.format(current_function_name(), ', '.join(str(x) for x in self._grouped_specs())))
        for group in self._grouped_specs():
            possible_complex = Complex([self._mol_builders[spec].build() for spec in group])

            if not only_reactants or (only_reactants and possible_complex.is_reactant):
                complexes.append(possible_complex)
                LOGGER.debug('{} : Adding complex {}'.format(current_function_name(), possible_complex))
            else:
                LOGGER.info('{} : DISCONNECTED CONTINGENCY Reaction {} / Not adding complex {}'
                            .format(current_function_name(), self.reaction, possible_complex))

        return complexes
Ejemplo n.º 6
0
def _dereference_boolean_contingency_effectors(
        self: Effector, effector_table: Dict[str, Effector],
        equivalence_table: Dict[str, List[Tuple[QualSpec, QualSpec]]]) -> None:
    if isinstance(self, _BooleanContingencyEffector):
        LOGGER.debug('{} : {}'.format(current_function_name(), self.expr))
        LOGGER.debug('{} : {}'.format(current_function_name(), effector_table))
        LOGGER.debug('{} : {}'.format(current_function_name(), self.equivs))
        name = self.expr.name
        equivs = self.equivs
        self.__class__ = effector_table[self.expr.name].__class__
        self.__dict__ = effector_table[self.expr.name].__dict__
        self.name = name
        try:
            self.equivs.merge_with(equivs, [])
            LOGGER.debug('{} : Merged structure information.'.format(
                current_function_name()))
        except AttributeError:
            self.equivs = equivs
            LOGGER.debug('{} : Initialized structure information.'.format(
                current_function_name()))
    elif isinstance(self, StateEffector):
        pass
    elif isinstance(self, NotEffector):
        _dereference_boolean_contingency_effectors(self.expr, effector_table,
                                                   equivalence_table)
    elif isinstance(self, OrEffector) or isinstance(self, AndEffector):
        try:
            assert self.name is not None
            equivs_list = equivalence_table[self.name]

            for equiv in equivs_list:
                self.equivs.add_equivalence(*equiv)

        except KeyError:
            pass

        for expr in self.exprs:
            _dereference_boolean_contingency_effectors(expr, effector_table,
                                                       equivalence_table)
    else:
        raise AssertionError
Ejemplo n.º 7
0
def split_bidirectional_reaction_str(rxn_str: str) -> List[str]:
    for verb in BIDIRECTIONAL_REACTIONS:
        if '_{}_'.format(verb).lower() in rxn_str.lower():
            verb = re.findall('(?i)_{}_'.format(verb), rxn_str)[0][1:-1]

            logger.info('{}: {}'.format(current_function_name(), rxn_str))

            return [
                rxn_str.replace('_{}_'.format(verb), '_{}+_'.format(verb)),
                rxn_str.replace('_{}_'.format(verb), '_{}-_'.format(verb)),
            ]

    return [rxn_str]
Ejemplo n.º 8
0
    def to_merged_struct_effector(self,
                                  glob_equivs: StructEquivalences = None,
                                  counter: StructCounter = None,
                                  cur_namespace: List[str] = None) -> Effector:
        glob_equivs, counter, cur_namespace = self._init_to_struct_effector_args(
            glob_equivs, counter, cur_namespace)
        state = deepcopy(self.expr)
        updates = {}

        assert not (
            state.is_homodimer and not state.is_structured
        ), 'Please provide structure annotation for homodimer {}'.format(state)

        LOGGER.debug('{} : Merging {}'.format(current_function_name(),
                                              str(self)))
        LOGGER.debug('{} : Equivs {}'.format(current_function_name(),
                                             glob_equivs))

        for spec in state.specs:
            existing_spec = glob_equivs.find_unqualified_spec(
                QualSpec(cur_namespace, spec))

            if existing_spec:
                updates[spec] = existing_spec
            else:
                new_spec = deepcopy(spec)
                new_spec.struct_index = self._generate_index(
                    glob_equivs, counter)

                updates[spec] = new_spec
                glob_equivs.add_equivalence(QualSpec([], new_spec),
                                            QualSpec(cur_namespace, spec))

        state.update_specs(updates)
        LOGGER.debug('{} : Result {}'.format(current_function_name(),
                                             str(state)))

        return StateEffector(state)
Ejemplo n.º 9
0
    def _load_contingency_list_entries(self) -> None:
        sheet = self._xlrd_book.sheet_by_name(SHEET_CONTINGENCY_LIST)
        contingency_rows = [row for row in sheet.get_rows()][DATA_ROW:]

        for row in contingency_rows:
            if not row[self._column_contingency_target].value:
                continue

            # When a reaction with a verb such as 'ppi' is encountered, we only apply the contingency to the
            # positive reaction.
            target = row[self._column_contingency_target].value
            if split_bidirectional_reaction_str(target) != [target]:
                target = split_bidirectional_reaction_str(target)[0]
                logger.info('{0}: applying contingency {1} to forward target {2}'
                            .format(current_function_name(), row[self._column_contingency_modifier].value, target))

            entry = contingency_list_entry_from_strs(
                target, row[self._column_contingency_type].value,
                row[self._column_contingency_modifier].value
            )
            self._cont_list_entries.append(entry)
Ejemplo n.º 10
0
        def expanded_effector(effector: Effector) -> Effector:
            if isinstance(effector, StateEffector):
                if effector.expr.is_elemental:
                    return effector
                else:
                    elemental_states = [
                        state.to_structured_from_state(effector.expr)
                        for state in self.states
                        if state.is_subset_of(effector.expr)
                    ]
                    assert elemental_states, 'Could not find elemental states which are subset of the non-elemental ' \
                                             'state {}'.format(effector.expr)
                    assert all(state.is_elemental
                               for state in elemental_states)

                    LOGGER.info('{}: {} -> {}'.format(
                        current_function_name(), str(effector.expr),
                        ' | '.join(str(x) for x in elemental_states)))

                    if len(elemental_states) == 1:
                        return StateEffector(elemental_states[0])
                    else:
                        return OrEffector(*(StateEffector(x)
                                            for x in elemental_states),
                                          name=str(effector.expr))
            elif isinstance(effector, AndEffector):
                return AndEffector(*(expanded_effector(x)
                                     for x in effector.exprs),
                                   name=effector.name,
                                   equivs=effector.equivs)
            elif isinstance(effector, OrEffector):
                return OrEffector(*(expanded_effector(x)
                                    for x in effector.exprs),
                                  name=effector.name,
                                  equivs=effector.equivs)
            elif isinstance(effector, NotEffector):
                return NotEffector(expanded_effector(effector.expr),
                                   name=effector.name)
            else:
                raise AssertionError
Ejemplo n.º 11
0
    def to_structured(self) -> 'Contingency':
        LOGGER.debug('{}: {}'.format(current_function_name(), str(self)))

        if isinstance(self.effector,
                      StateEffector) and self.effector.is_structured:
            # A fully structured StateEffector is fine.
            return self
        elif isinstance(self.effector,
                        StateEffector) and not self.effector.is_structured:
            # For a non-structured StateEffector, assume the Specs appearing in the Effector
            # match those appearing in the Reaction.
            equivs = StructEquivalences()
            struct_components = {
                spec.to_non_struct_spec(): spec
                for spec in self.reaction.components_lhs_structured
            }
            for spec in self.effector.expr.specs:
                try:
                    equivs.add_equivalence(
                        QualSpec([],
                                 struct_components[spec.to_component_spec()]),
                        QualSpec([str(self.reaction)],
                                 spec.to_component_spec()))
                except KeyError:
                    pass

            return self.with_merged_struct_effector(equivs, None,
                                                    [str(self.reaction)])
        elif self.effector.is_structured:
            # A fully structured Boolean Effector needs to have its structure indices merged.
            return self.with_merged_struct_effector()
        else:
            # For a non-structured Boolean Effector, assume all Specs that could match, actually do match.
            struct_components = {
                spec.to_non_struct_spec(): spec
                for spec in self.reaction.components_lhs_structured
            }
            equivs = TrivialStructEquivalences(struct_components)  # pylint: disable=redefined-variable-type
            return self.with_merged_struct_effector(equivs)
Ejemplo n.º 12
0
def contingency_list_entry_from_strs(subject_str: str, verb_str: str,
                                     object_str: str) -> ContingencyListEntry:
    subject_str, verb_str, object_str = subject_str.strip(), verb_str.lower(
    ).strip(), object_str.strip()

    LOGGER.debug('{}: {} / {} / {}'.format(current_function_name(),
                                           subject_str, verb_str, object_str))

    subject = None  # type: Optional[Union[Reaction, BooleanContingencyName]]
    verb = None  # type: Optional[Union[BooleanOperator, ContingencyType]]
    object = None  # type: Optional[Union[State, BooleanContingencyName, Tuple[QualSpec, QualSpec]]]

    if re.match(BOOLEAN_CONTINGENCY_REGEX, subject_str):
        # subject: Boolean contingency,
        # verb   : Boolean operator,
        # object : State / Boolean contingency / Qual Spec pair.
        subject = BooleanContingencyName(subject_str)
        verb = BooleanOperator(verb_str)
    else:
        # subject: Reaction,
        # verb   : Contingency type,
        # object : State / Boolean contingency.
        subject = reaction_from_str(subject_str)
        verb = ContingencyType(verb_str)

    if re.match(BOOLEAN_CONTINGENCY_REGEX,
                object_str) and not isinstance(subject, Reaction):
        # subject: Boolean contingency,
        # verb   : Contingency type / Boolean operator,
        # object : Boolean contingency.
        object = BooleanContingencyName(object_str)
    elif re.match(BOOLEAN_CONTINGENCY_REGEX,
                  object_str.split('#')[0]) and isinstance(subject, Reaction):
        # subject: Reaction,
        # verb   : Contingency type,
        # object : Boolean contingency + '#' + reactant equivs.
        name = object_str.split('#')[0]
        equivs_strs = [s.split(',') for s in object_str.split('#')[1:]]
        equivs_dict = {
            int(i):
            qual_spec_from_str(qual_spec_str).with_prepended_namespace([name])
            for i, qual_spec_str in equivs_strs
        }
        equivs = StructEquivalences()
        for index, spec in enumerate(subject.components_lhs):
            try:
                equivs.add_equivalence(
                    QualSpec([], spec.with_struct_index(index)),
                    equivs_dict[index])
            except KeyError:
                pass

        object = BooleanContingencyNameWithEquivs(name, equivs)
        LOGGER.debug('{} : Created {}'.format(current_function_name(),
                                              str(object)))
    elif verb == BooleanOperator.op_eqv:
        strs = [x.strip() for x in object_str.split(',')]
        object = (qual_spec_from_str(strs[0]).with_prepended_namespace(
            [subject.name]), qual_spec_from_str(
                strs[1]).with_prepended_namespace([subject.name]))
    else:
        object = state_from_str(object_str)

    assert subject is not None
    assert verb is not None
    assert object is not None

    return ContingencyListEntry(subject, verb, object)
Ejemplo n.º 13
0
    ],
    InteractionState: [
        lambda state, builder: builder.add_mol(state.first),
        lambda state, builder: builder.add_mol(state.second),
        lambda state, builder: builder.set_bond(state.first, state.second)
    ],
    SelfInteractionState: [
        lambda state, builder: builder.add_mol(state.first),
        lambda state, builder: builder.set_bond(state.first, state.second)
    ],
    EmptyBindingState: [
        lambda state, builder: builder.add_mol(state.spec),
        lambda state, builder: builder.set_half_bond(state.spec, None)
    ],
    GlobalState: [
        lambda state, builder: LOGGER.warning('{} : IGNORING INPUT STATE {}'.format(current_function_name(), str(state)))
    ]
}  # type: ignore


STATE_TO_MOL_DEF_BUILDER_FN = {
    ModificationState: [
        lambda state, builder: builder.add_site(state.spec),
        lambda state, builder: builder.add_mod(state.spec, state.modifier)
    ],
    InteractionState: [
        lambda state, builder: builder.add_site(state.first) if builder.spec == state.first.to_component_spec()
        else builder.add_site(state.second),
    ],
    SelfInteractionState: [
        lambda state, builder: builder.add_site(state.first),
Ejemplo n.º 14
0
def test_current_function_name() -> None:
    assert current_function_name(colored=False) == 'test_current_function_name'
Ejemplo n.º 15
0
def rxngraph_from_rxncon_system(rxncon_system: RxnConSystem) -> ReactionGraph:
    """
    Creating the reaction graph from the rxncon system.

    Args:
        rxncon_system: The reconstructed rxncon system.

    Returns:
        The reaction graph (ReactionGraph)

    """
    def get_reaction_type(rxn: Reaction) -> EdgeType:
        """
        Getting the type of a reaction.

        Args:
            rxn: Elemental rxncon reaction.

        Returns:
            The type of the reaction (EdgeType)

        """
        if len(rxn.components_lhs) > len(rxn.components_rhs):
            return EdgeType.degradation
        elif len(rxn.components_lhs) < len(rxn.components_rhs):
            return EdgeType.synthesis
        elif len(rxn.produced_states) == 1:
            return STATES[type(rxn.produced_states[0])]
        elif len(rxn.produced_states) == 2:
            if all(STATES[type(produced_state)] == EdgeType.modification for produced_state in rxn.produced_states):
                return EdgeType.bimodification
            elif all(STATES[type(produced_state)] == EdgeType.interaction for produced_state in rxn.produced_states):
                return EdgeType.interaction
            else:
                return EdgeType.unknown
        else:
            return EdgeType.unknown

    def add_reaction_to_graph(rxn: Reaction) -> None:
        """
        Adding a reaction to the reaction graph.

        Args:
            rxn: Elemental rxncon reaction.

        Returns:
            None

        """
        edge_type = get_reaction_type(rxn)
        if edge_type is EdgeType.synthesis:
            for syn_comp in rxn.synthesised_components:
                logger.info('Adding synthesis of {0} -> {1}'.format(rxn['$x'], syn_comp))
                builder.add_spec_information(rxn['$x'])
                builder.add_spec_information(syn_comp)
                builder.add_external_edge(rxn['$x'], syn_comp, edge_type)
        else:
            logger.info('Adding {2} of {0} -> {1}'.format(rxn['$x'], rxn['$y'], get_reaction_type(rxn)))
            builder.add_spec_information(rxn['$x'])
            builder.add_spec_information(rxn['$y'])
            builder.add_external_edge(rxn['$x'], rxn['$y'], get_reaction_type(rxn))

    builder = GraphBuilder()

    for reaction in rxncon_system.reactions:
        if not isinstance(reaction, OutputReaction):
            logger.debug('{}: {}'.format(current_function_name(), str(reaction)))
            add_reaction_to_graph(reaction)

    return ReactionGraph(builder.get_graph())
Ejemplo n.º 16
0
def rule_based_model_from_rxncon(rxncon_sys: RxnConSystem) -> RuleBasedModel:  # pylint: disable=too-many-locals
    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())

    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('{} : REMOVING INPUT STATE {} from contingencies.'.format(current_function_name(), 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]) -> 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)]:
                    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', '1.0')

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

    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)

            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

    LOGGER.debug('{} : Entered function'.format(current_function_name()))

    mol_defs = mol_defs_from_rxncon(rxncon_sys)
    LOGGER.debug('{} : Generated MolDefs: {}'.format(current_function_name(), ', '.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('{} : Generating rules for reaction {}'.format(current_function_name(), 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('{} : Strict contingencies {}'.format(current_function_name(), str(strict_cont_set)))

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

            cont_set = Intersection(strict_cont_set, quant_contingency_set)  # type: VennSet[State]
            cont_set = with_connectivity_constraints(cont_set)
            solutions = cont_set.calc_solutions()
            solutions = remove_global_states(solutions)

            LOGGER.debug('{} : contingency solutions {}'.format(current_function_name(), 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:
                LOGGER.debug('{} : positivized contingency solution {}'
                             .format(current_function_name(), ' & '.join(str(x) for x in positive_solution)))
                rule = calc_rule(reaction, positive_solution)
                if not any(rule.is_equivalent_to(existing) for existing in rules):
                    rules.append(rule)

    return RuleBasedModel(mol_defs, calc_initial_conditions(mol_defs), [], calc_observables(rxncon_sys), rules)
Ejemplo n.º 17
0
    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('{} : REMOVING INPUT STATE {} from contingencies.'.format(current_function_name(), state))
                else:
                    cleaned_solution[state] = val

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

        return filtered_solutions