def test_property_set_construction() -> None: assert ValueSet('a') assert ValueSet(1) assert ValueSet(1.45) with pytest.raises(TypeError): ValueSet([1, 2, 3])
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
def synthesis_factor(state_target: StateTarget) -> VennSet[Target]: fac = EmptySet() # type: VennSet[Target] for rxn in (x for x in reaction_targets if x.synthesises(state_target)): fac = Union(fac, ValueSet(rxn)) for prod_rxn in (x for x in reaction_targets if x.produces(state_target)): sources = [] for source in prod_rxn.consumed_targets: sources.append( [source] + [x for x in reaction_targets if x.synthesises(source)]) for source_combi in product(*sources): # At least one source should be synthesised. if all(isinstance(x, StateTarget) for x in source_combi): continue assert any( isinstance(x, ReactionTarget) and x.synthesised_targets for x in source_combi) fac = Union( fac, Intersection(ValueSet(prod_rxn), *(ValueSet(x) for x in source_combi))) return fac
def calc_component_presence_factors( ) -> Tuple[Dict[Spec, VennSet[StateTarget]], List[ComponentStateTarget]]: """The form of the component presence factor is: (state_a1 | ... | state_an) & (state_b1 | ... | state_bm) & ... Mutually exclusive states are combined by boolean OR (state_a1 ... state_an , state_b1 ... state_bm). These ORs are then combines with ANDs. If a component does not carry states, this will be a ComponentStateTarget. """ component_state_targets = [] # type: List[ComponentStateTarget] component_to_factor = {} # type: Dict[Spec, VennSet[StateTarget]] for component in rxncon_sys.components(): grouped_states = rxncon_sys.states_for_component_grouped(component) # component is not part of any state if not grouped_states.values(): component_state_targets.append(ComponentStateTarget(component)) component_to_factor[component] = ValueSet( ComponentStateTarget(component)) # component is part of at least one state else: # mutually exclusive states are combined by OR component_to_factor[component] = \ Intersection( *(Union(*(ValueSet(StateTarget(x)) for x in group)) for group in grouped_states.values())) return component_to_factor, component_state_targets
def test_with_connectivity_constraints() -> None: first_states = [ ValueSet(state_from_str(x)) for x in ('A@0_[ac]--C@2_[ca]', 'C@2_[ce]--E@4_[ec]') ] second_states = [ ValueSet(state_from_str(x)) for x in ('B@1_[bd]--D@3_[db]', 'D@3_[df]--F@5_[fd]') ] contingency = Union(Intersection(*first_states), Intersection(*second_states)) connected = with_connectivity_constraints(contingency) print(connected) print('Not connected:') for soln in contingency.calc_solutions(): print(soln) print() print('Connected:') for soln in connected.calc_solutions(): print(soln)
def test_is_equivalent_to() -> None: assert UniversalSet().is_equivalent_to(UniversalSet()) assert EmptySet().is_equivalent_to(EmptySet()) assert not UniversalSet().is_equivalent_to(ValueSet(1)) assert not ValueSet(1).is_equivalent_to(UniversalSet()) assert UniversalSet().is_equivalent_to(Union(ValueSet(1), Complement(ValueSet(1))))
def test_property_set_dictionary_keys() -> None: x = ValueSet(1) y = ValueSet(2) dictionary = {x: 'bla', y: 'diebla'} assert dictionary[ValueSet(1)] == 'bla' assert dictionary[x] == 'bla' assert dictionary[ValueSet(2)] == 'diebla' assert dictionary[y] == 'diebla'
def test_parser() -> None: assert venn_from_str('1 & 2', int).is_equivalent_to( Intersection(ValueSet(1), ValueSet(2))) assert venn_from_str('1 & 2', str).is_equivalent_to( Intersection(ValueSet('1'), ValueSet('2'))) assert venn_from_str('( 1 | 2 ) & 3', int).is_equivalent_to( Intersection(ValueSet(3), Union(ValueSet(1), ValueSet(2)))) assert venn_from_str('~ 1', int).is_equivalent_to(Complement(ValueSet(1))) assert venn_from_str('~( 1 | 2 )', int).is_equivalent_to( Intersection(Complement(ValueSet(1)), Complement(ValueSet(2))))
def test_superset_subset_for_nested_unions() -> None: x = ValueSet(1) y = ValueSet(2) z = ValueSet(3) xy = Union(x, y) yz = Union(y, z) xz = Union(x, z) xyz = Union(x, Union(y, z)) for a in [x, y, z, xy, yz, xz, xyz]: for b in [x, y, z, xy, yz, xz, xyz]: if a != b: assert not a.is_equivalent_to(b) assert xyz.is_superset_of(x) assert xyz.is_superset_of(y) assert xyz.is_superset_of(z) assert xyz.is_superset_of(xy) assert xyz.is_superset_of(yz) assert xyz.is_superset_of(xz) assert x.is_subset_of(xyz) assert y.is_subset_of(xyz) assert z.is_subset_of(xyz) assert xy.is_subset_of(xyz) assert yz.is_subset_of(xyz) assert xz.is_subset_of(xyz)
def kappa(state_target: StateTarget, level: int) -> VennSet[Target]: res = EmptySet() # type: VennSet[Target] for r in (x for x in reaction_targets if x.consumes(state_target)): rxn_term = ValueSet(r) # type: VennSet[Target] for s in (x for x in state_targets if r.consumes(x)): rxn_term = Intersection(rxn_term, ValueSet(s), degradation_factor(s)) res = Union(res, rxn_term) return res
def test_list_form() -> None: assert venn_from_str('1', int).to_dnf_list() == [venn_from_str('1', int)] assert venn_from_str('1 & 2', int).to_dnf_list() == [venn_from_str('1 & 2', int)] assert set(venn_from_str('1 | 2', int).to_dnf_list()) == {ValueSet(1), ValueSet(2)} x = venn_from_str('1 & ( 2 | 3 )', int) assert any(elem.is_equivalent_to(venn_from_str('1 & 2', int)) for elem in x.to_dnf_list()) assert any(elem.is_equivalent_to(venn_from_str('1 & 3', int)) for elem in x.to_dnf_list()) assert UniversalSet().to_dnf_list() == [UniversalSet()] assert EmptySet().to_dnf_list() == [EmptySet()]
def parse_effector(eff: Effector) -> VennSet: if isinstance(eff, StateEffector): if structured: return ValueSet(state_wrapper(eff.expr)) else: return ValueSet(state_wrapper(eff.expr.to_non_structured())) elif isinstance(eff, NotEffector): return Complement(parse_effector(eff.expr)) elif isinstance(eff, OrEffector): return Union(*(parse_effector(x) for x in eff.exprs)) elif isinstance(eff, AndEffector): return Intersection(*(parse_effector(x) for x in eff.exprs)) else: raise AssertionError('Unknown Effector {}'.format(str(eff)))
def reaction_with_sources( reaction_target: ReactionTarget) -> VennSet[Target]: """ Calculates the source states of the respective reaction target Args: reaction_target: Reaction of the boolean model producing, consuming, degrading or synthesising state targets. Returns: VennSet of the reaction target and its source states """ sources = Intersection( *(ValueSet(x) for x in reaction_target.consumed_targets)) return Intersection(ValueSet(reaction_target), sources)
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
def pi(state_target: StateTarget, level: int) -> VennSet[Target]: res = EmptySet() # type: VennSet[Target] for r in (x for x in reaction_targets if x.produces(state_target)): rxn_term = ValueSet(r) # type: VennSet[Target] for s in (x for x in state_targets if r.consumes(x)): if r.degraded_targets: state_term = ValueSet(s) # type: VennSet[Target] else: state_term = Intersection(ValueSet(s), degradation_factor(s)) for l in range(level): state_term = Union(state_term, sigma(s, level - 1)) rxn_term = Intersection(rxn_term, state_term) res = Union(res, rxn_term) return res
def indirect_synth_path( state_target: StateTarget) -> VennSet[ReactionTarget]: my_brothers = [ x for x in state_targets if state_target.shares_component_with(x) and x != state_target ] return Union(*(ValueSet(rxn) for state in my_brothers for rxn in reaction_targets if rxn.synthesises(state)))
def sigma(state_target: StateTarget, level: int) -> VennSet[Target]: prod_cons_factor = Union( pi(state_target, level), Intersection(ValueSet(state_target), Complement(kappa(state_target, level)))) return Union( synthesis_factor(state_target), Intersection(degradation_factor(state_target), component_factor(state_target), prod_cons_factor))
def test_nested_list_form() -> None: assert venn_from_str('1', int).to_dnf_nested_list() == [[venn_from_str('1', int)]] x = venn_from_str('1 & ( 2 | 3 )', int) assert [ValueSet(1), ValueSet(2)] in x.to_dnf_nested_list() assert [ValueSet(1), ValueSet(3)] in x.to_dnf_nested_list() assert venn_from_str('1 & 2', int).to_dnf_nested_list() == [[ValueSet(1), ValueSet(2)]] assert venn_from_str('1 | 2', int).to_dnf_nested_list() == [[ValueSet(1)], [ValueSet(2)]] assert UniversalSet().to_dnf_nested_list() == [[UniversalSet()]] assert EmptySet().to_dnf_nested_list() == [[EmptySet()]]
def venn_from_effector(effector: Effector) -> VennSet[State]: if isinstance(effector, StateEffector): return ValueSet(effector.expr) elif isinstance(effector, AndEffector): return Intersection(*(venn_from_effector(x) for x in effector.exprs)) elif isinstance(effector, OrEffector): return Union(*(venn_from_effector(x) for x in effector.exprs)) elif isinstance(effector, NotEffector): return Complement(venn_from_effector(effector.expr)) else: raise AssertionError
def _effector_to_vennset(eff: Effector, con_type: Optional[ContingencyType]=None) -> VennSet: """ Preprocessing effector. Save information in leafs. Note: We need the contingency information later on in the process. Since, this information is lost during the calculation of the disjunctive normal form we have to add it beforehand. For this we say an inhibiting contingency is the complement of everything afterwards. The contingency type is only needed at the beginning of the recursion step. Args: eff: rxncon Effector. cont_type: Contingency type. Returns: Return VennSet Raises: AssertionError if the eff is not an effector. """ if isinstance(eff, StateEffector): if con_type is ContingencyType.inhibition: return Complement(ValueSet(eff.expr.to_non_structured())) return ValueSet(eff.expr.to_non_structured()) elif isinstance(eff, NotEffector): if con_type is ContingencyType.inhibition: return _effector_to_vennset(eff.expr) return Complement(_effector_to_vennset(eff.expr)) elif isinstance(eff, OrEffector): if con_type is ContingencyType.inhibition: return Complement(VennUnion(*[_effector_to_vennset(expr) for expr in eff.exprs])) return VennUnion(*[_effector_to_vennset(expr) for expr in eff.exprs]) elif isinstance(eff, AndEffector): if con_type is ContingencyType.inhibition: return Complement(Intersection(*[_effector_to_vennset(expr) for expr in eff.exprs])) return Intersection(*[_effector_to_vennset(expr) for expr in eff.exprs]) else: raise AssertionError
def calc_component_presence_factors( ) -> Tuple[Dict[Spec, VennSet[StateTarget]], List[ComponentStateTarget]]: """ Calculates the factors for components. Note: The form is: (state_a1 | ... | state_an) & (state_b1 | ... | state_bm) & ... Non-mutually exclusive states are combined by boolean AND (state_a and state_b). Mutually exclusive states are combined by boolean OR (state_a1 to state_an as well as state_b1 to state_bm). If a component is not part of any state of the system, the component will hold itself as ValueSet of a ComponentStateTarget. Mutates: component_to_factor: Mapping of components and VennSets, containing all the states the component is involved in. Returns: None """ component_state_targets = [] # type: List[ComponentStateTarget] component_to_factor = {} # type: Dict[Spec, VennSet[StateTarget]] for component in rxncon_sys.components(): grouped_states = rxncon_sys.states_for_component_grouped(component) # component is not part of any state if not grouped_states.values(): component_state_targets.append(ComponentStateTarget(component)) component_to_factor[component] = ValueSet( ComponentStateTarget(component)) # component is part of at least one state else: # mutually exclusive states are combined by OR component_to_factor[component] = \ Intersection(*(Union(*(ValueSet(StateTarget(x)) for x in group)) for group in grouped_states.values())) return component_to_factor, component_state_targets
def update_state_rules_with_knockouts( knockout_strategy: KnockoutStrategy) -> None: if knockout_strategy == KnockoutStrategy.no_knockout: return elif knockout_strategy in (KnockoutStrategy.knockout_all_states, KnockoutStrategy.knockout_neutral_states): for state_rule in state_rules: assert isinstance(state_rule.target, StateTarget) if knockout_strategy == KnockoutStrategy.knockout_neutral_states and not state_rule.target.is_neutral: continue knockout_factor = Complement( Union(*(ValueSet(KnockoutTarget(component)) for component in state_rule.target.components))) state_rule.factor = Intersection(knockout_factor, state_rule.factor)
def update_state_rules_with_overexpressions( overexpression_strategy: OverexpressionStrategy) -> None: if overexpression_strategy == OverexpressionStrategy.no_overexpression: return elif overexpression_strategy in ( OverexpressionStrategy.overexpress_all_states, OverexpressionStrategy.overexpress_neutral_states): for state_rule in state_rules: assert isinstance(state_rule.target, StateTarget) if overexpression_strategy == OverexpressionStrategy.overexpress_neutral_states and not state_rule.target.is_neutral: continue overexpression_factor = Intersection( *(ValueSet(OverexpressionTarget(component)) for component in state_rule.target.components)) state_rule.factor = Union(overexpression_factor, state_rule.factor)
def test_bond_complexes_poly_calculation() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('R@1_[Y]--Y@2_[R]', 'Y@2_[Y]--Y@3_[Y]', 'Y@3_[R]--R@4_[Y]', 'R@4_[Ras]--Ras@5_[R]'))) assert len(bond_complexes(states)) == 5
def test_bond_complexes_ring_calculation() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('A@0_[B]--B@2_[A]', 'B@2_[C]--C@3_[B]', 'C@3_[D]--D@4_[C]', 'D@4_[A]--A@0_[D]'))) assert len(bond_complexes(states)) == 11
def to_venn_set(self) -> VennSet[State]: return Intersection( *(ValueSet(s) for s in self.true_states()), *(Complement(ValueSet(s)) for s in self.false_states()))
def sets() -> List[Set]: return [ EmptySet(), ValueSet(1), UniversalSet(), Union(ValueSet(1), ValueSet(2)), Intersection(ValueSet(1), ValueSet(2)), Intersection(ValueSet(1), Complement(ValueSet(2))), Union(Intersection(ValueSet(1), ValueSet(2)), ValueSet(3)), Union(Intersection(ValueSet(1), ValueSet(2)), Intersection(ValueSet(3), ValueSet(4))), Union(Complement(Union(ValueSet(1), Complement(ValueSet(2)))), Intersection(ValueSet(3), ValueSet(4))) ]
def test_bond_complexes_calculation_unordered() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('A@0_[C]--C@5_[A]', 'C@5_[B]--B@3_[C]', 'B@3_[D]--D@2_[B]'))) assert len(bond_complexes(states)) == 4
def test_bond_complexes_calculation() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('A@0_[C]--C@2_[A]', 'C@2_[(r)]-{p}', 'A@0_[C]--0', 'C@2_[A]--0', 'C@2_[(r)]-{0}'))) assert len(bond_complexes(states)) == 3
def test_simplifies() -> None: x1 = Intersection(ValueSet(1), ValueSet(2)) x2 = Intersection(ValueSet(1), Complement(ValueSet(2))) assert Union(x1, x2).is_equivalent_to(ValueSet(1))