def test_pickle(coreactant_dict, smiles_dict, default_rule): """Test pickling of pickaxe objects.""" pickle_path = Path("test_pickle.pk") pk = pickaxe.Pickaxe(errors=False, explicit_h=True) pk._load_coreactant(coreactant_dict["ATP"]) pk._load_coreactant(coreactant_dict["ADP"]) pk._add_compound( smiles_dict["FADH"], smiles_dict["FADH"], cpd_type="Starting Compound" ) pk.operators["2.7.1.a"] = default_rule pk.transform_all(generations=2) pk.pickle_pickaxe(pickle_path) del pk pk = pickaxe.Pickaxe(errors=False) pk.load_pickled_pickaxe(pickle_path) assert len(pk.compounds) == 31 assert len(pk.reactions) == 49 comp_gens = set([x["Generation"] for x in pk.compounds.values()]) assert comp_gens == {0, 1, 2} pickle_path.unlink()
def test_database_already_exists(default_rule, smiles_dict, coreactant_dict): """Test database collision. GIVEN an existing MINE WHEN a new pickaxe object is defined THEN make sure program exits with database collision """ delete_database("MINE_test") pk = pickaxe.Pickaxe(database="MINE_test") pk.operators["2.7.1.a"] = default_rule pk._load_coreactant(coreactant_dict["ATP"]) pk._load_coreactant(coreactant_dict["ADP"]) pk._add_compound("FADH", smiles_dict["FADH"], cpd_type="Starting Compound") pk.transform_all(generations=2) pk.save_to_mine(processes=1) try: with pytest.raises(SystemExit) as pytest_wrapped_e: pk = pickaxe.Pickaxe(database="MINE_test") assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == ( "Exiting due to database name collision." ) finally: delete_database("MINE_test")
def test_pruning(default_rule, smiles_dict, coreactant_dict): """ GIVEN a Pickaxe expansion WHEN that expansion is pruned via Pickaxe.prune_network() THEN make sure that the pruned compounds no longer exist in the network """ pk = pickaxe.Pickaxe(database=None, image_dir=None) pk.operators['2.7.1.a'] = default_rule pk = multiprocess(pk, smiles_dict, coreactant_dict) ids = [ 'C89d19c432cbe8729c117cfe50ff6ae4704a4e6c1', 'C750e93db23dd3f796ffdf9bdefabe32b10710053', 'C41' ] pk.prune_network(ids) pk.assign_ids() pk.write_compound_output_file(DATA_DIR + '/pruned_comps') pk.write_reaction_output_file(DATA_DIR + '/pruned_rxns') assert os.path.exists(DATA_DIR + '/pruned_comps_new') assert os.path.exists(DATA_DIR + '/pruned_rxns_new') try: assert cmp(DATA_DIR + '/pruned_comps', DATA_DIR + '/pruned_comps_new') assert cmp(DATA_DIR + '/pruned_rxns', DATA_DIR + '/pruned_rxns_new') finally: os.remove(DATA_DIR + '/pruned_comps_new') os.remove(DATA_DIR + '/pruned_rxns_new')
def test_save_target_mine(default_rule, smiles_dict, coreactant_dict): """Test saving the target run to a MINE.""" delete_database("MINE_test") pk = pickaxe.Pickaxe(database="MINE_test", explicit_h=True) pk.operators["2.7.1.a"] = default_rule pk._load_coreactant(coreactant_dict["ATP"]) pk._load_coreactant(coreactant_dict["ADP"]) pk._add_compound("FADH", smiles_dict["FADH"], cpd_type="Starting Compound") pk.load_targets(file_dir / "../data/test_targets.csv") pk.transform_all(generations=2) pk.prune_network_to_targets() pk.save_to_mine() mine_db = MINE("MINE_test") try: assert mine_db.compounds.estimated_document_count() == 6 assert mine_db.reactions.estimated_document_count() == 4 assert mine_db.operators.estimated_document_count() == 1 assert mine_db.operators.find_one()["Reactions_predicted"] == 4 start_comp = mine_db.target_compounds.find_one() assert start_comp["InChI_key"] == "RYNUDNWPSBJQQY-UHFFFAOYSA-N" assert all([i in start_comp.keys() for i in ["_id", "SMILES", "InChI_key"]]) finally: delete_database("MINE_test")
def test_pruning(default_rule, smiles_dict, coreactant_dict): """Test pruning network to targets. GIVEN a Pickaxe expansion WHEN that expansion is pruned via Pickaxe.prune_network() THEN make sure that the pruned compounds no longer exist in the network """ pk = pickaxe.Pickaxe(explicit_h=True) pk.operators["2.7.1.a"] = default_rule pk._load_coreactant(coreactant_dict["ATP"]) pk._load_coreactant(coreactant_dict["ADP"]) pk._add_compound("FADH", smiles_dict["FADH"], cpd_type="Starting Compound") pk.transform_all(generations=2) ids = [ "C89d19c432cbe8729c117cfe50ff6ae4704a4e6c1", "C750e93db23dd3f796ffdf9bdefabe32b10710053", "C41", ] pk.prune_network(ids) pk.assign_ids() DATA_DIR = (file_dir / "../data").resolve() pk.write_compound_output_file(DATA_DIR / "pruned_comps.tsv") pk.write_reaction_output_file(DATA_DIR / "pruned_rxns.tsv") assert os.path.exists(DATA_DIR / "pruned_comps_new.tsv") assert os.path.exists(DATA_DIR / "pruned_rxns_new.tsv") try: assert cmp(DATA_DIR / "pruned_comps.tsv", DATA_DIR / "pruned_comps_new.tsv") assert cmp(DATA_DIR / "pruned_rxns.tsv", DATA_DIR / "pruned_rxns_new.tsv") finally: os.remove((DATA_DIR / "pruned_comps_new.tsv").resolve()) os.remove((DATA_DIR / "pruned_rxns_new.tsv").resolve())
def test_save_as_mine_multiprocess(default_rule, smiles_dict, coreactant_dict): """ GIVEN a Pickaxe expansion WHEN that expansion is saved as a MINE DB in the MongoDB THEN make sure that all features are saved in the MongoDB as expected """ delete_database('MINE_test') pk = pickaxe.Pickaxe(database='MINE_test', image_dir=DATA_DIR) pk.operators['2.7.1.a'] = default_rule pk = multiprocess(pk, smiles_dict, coreactant_dict) pk.save_to_mine(num_workers=2) mine_db = MINE('MINE_test') try: assert mine_db.compounds.estimated_document_count() == 31 assert mine_db.reactions.estimated_document_count() == 49 assert mine_db.operators.estimated_document_count() == 1 assert os.path.exists(DATA_DIR + '/X9c29f84930a190d9086a46c344020283c85fb917.svg') start_comp = mine_db.compounds.find_one({'Type': 'Starting Compound'}) assert len(start_comp['Reactant_in']) > 0 # Don't track sources of coreactants coreactant = mine_db.compounds.find_one({'Type': 'Coreactant'}) assert 'Product_of' not in coreactant assert 'Reactant_in' not in coreactant product = mine_db.compounds.find_one({'Generation': 2}) assert len(product['Product_of']) > 0 assert product['Type'] == 'Predicted' finally: delete_database('MINE_test') purge(DATA_DIR, r".*\.svg$")
def test_metacyc_intermediate_specify_number(): rule_list, correactant_list, rule_name = metacyc_intermediate(n_rules=20) pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_intermediate_20_rules" assert len(pk.operators) == 20 assert len(pk.coreactants) == 45
def test_metacyc_include(): rule_list, correactant_list, rule_name = metacyc_generalized( fraction_coverage=0.9, include_containing=["aromatic", "halogen"]) pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_generalized_0,9_fraction_coverage_with_inclusion" assert len(pk.operators) == 377 assert len(pk.coreactants) == 45
def test_metacyc_intermediate_include(): rule_list, correactant_list, rule_name = metacyc_intermediate( fraction_coverage=0.9, include_containing=["halogen"]) pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_intermediate_0,9_fraction_coverage_with_inclusion" assert len(pk.operators) == 67 assert len(pk.coreactants) == 45
def test_metacyc_intermediate_specify_fraction(): rule_list, correactant_list, rule_name = metacyc_intermediate( fraction_coverage=0.2) pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_intermediate_0,2_fraction_coverage" assert len(pk.operators) == 75 assert len(pk.coreactants) == 45
def test_metacyc_intermediate(): rule_list, correactant_list, rule_name = metacyc_intermediate() pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_intermediate" assert len(pk.operators) == 7154 assert len(pk.coreactants) == 45 assert (pk.operators["rule0001_0167"][1]["SMARTS"] == rule_assert_dict["Metacyc_intermediate_rule0001_0167"])
def test_metacyc_generalized_specify_number(): rule_list, correactant_list, rule_name = metacyc_generalized(n_rules=10) pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_generalized_10_rules" assert len(pk.operators) == 10 assert len(pk.coreactants) == 45 assert (pk.operators["rule0001"][1]["SMARTS"] == rule_assert_dict["Metacyc_generalized_rule0001"])
def test_BNICE(): rule_list, correactant_list, rule_name = BNICE() pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "BNICE" assert len(pk.operators) == 250 assert len(pk.coreactants) == 33 assert pk.operators["1.1.1_01"][1]["SMARTS"] == rule_assert_dict[ "BNICE_1.1.1_01"]
def test_database_already_exists(default_rule, smiles_dict, coreactant_dict): """ GIVEN an existing MINE WHEN a new pickaxe object is defined THEN make sure program exits with database collision """ delete_database('MINE_test') pk = pickaxe.Pickaxe(database='MINE_test') pk.operators['2.7.1.a'] = default_rule pk = multiprocess(pk, smiles_dict, coreactant_dict) pk.save_to_mine(num_workers=1) try: with pytest.raises(SystemExit) as pytest_wrapped_e: pk = pickaxe.Pickaxe(database='MINE_test') assert pytest_wrapped_e.type == SystemExit assert pytest_wrapped_e.value.code == 'Exiting due to database name collision.' finally: delete_database('MINE_test')
def test_metacyc_generalized_full(): rule_list, correactant_list, rule_name = metacyc_generalized() pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_generalized" assert len(pk.operators) == 1216 assert len(pk.coreactants) == 45 assert (pk.operators["rule0001"][1]["SMARTS"] == rule_assert_dict["Metacyc_generalized_rule0001"])
def test_metacyc_generalized_specify_fraction(): rule_list, correactant_list, rule_name = metacyc_generalized( fraction_coverage=0.9) pk = pickaxe.Pickaxe(rule_list=rule_list, coreactant_list=correactant_list) assert rule_name == "Metacyc_generalized_0,9_fraction_coverage" assert len(pk.operators) == 413 assert len(pk.coreactants) == 45 assert (pk.operators["rule0001"][1]["SMARTS"] == rule_assert_dict["Metacyc_generalized_rule0001"])
def pk_transformed(default_rule, smiles_dict, coreactant_dict): """Create Pickaxe object with a few predicted reactions.""" pk_transformed = pickaxe.Pickaxe() pk_transformed._add_compound("Start", smi=smiles_dict['FADH'], cpd_type='Starting Compound') pk_transformed._load_coreactant(coreactant_dict['ATP']) pk_transformed._load_coreactant(coreactant_dict['ADP']) pk_transformed.operators['2.7.1.a'] = default_rule pk_transformed.transform_all() pk_transformed.assign_ids() return pk_transformed
def test_target_generation(default_rule, smiles_dict, coreactant_dict): """Test generating a target from starting compounds.""" pk = pickaxe.Pickaxe(explicit_h=True) pk.operators["2.7.1.a"] = default_rule pk._load_coreactant(coreactant_dict["ATP"]) pk._load_coreactant(coreactant_dict["ADP"]) pk._add_compound("FADH", smiles_dict["FADH"], cpd_type="Starting Compound") pk.load_targets(file_dir / "../data/test_targets.csv") pk.transform_all(generations=2) pk.prune_network_to_targets() assert "C11088915f64b93293e70af9c3b7822a4f131225d" in pk.compounds assert len(pk.reactions) == 4 assert len(pk.compounds) == 6
def test_save_no_rxn_mine(): """ GIVEN a Pickaxe object with no expansion WHEN that Pickaxe object is saved into a MINE DB in the MongoDB THEN check that starting compounds are present and that no reactions exist """ delete_database('MINE_test') pk = pickaxe.Pickaxe(database='MINE_test') pk.load_compound_set(compound_file=DATA_DIR + '/test_compounds.tsv') pk.save_to_mine(num_workers=1) mine_db = MINE('MINE_test') try: assert mine_db.compounds.estimated_document_count() == 14 assert mine_db.reactions.estimated_document_count() == 0 finally: delete_database('MINE_test')
def test_transform_all(default_rule, smiles_dict, coreactant_dict): """ GIVEN a set of rules and starting compounds WHEN we run pickaxe to predict potential transformations THEN make sure all expected transformations are predicted """ pk = pickaxe.Pickaxe(errors=False) pk._load_coreactant(coreactant_dict['ATP']) pk._load_coreactant(coreactant_dict['ADP']) pk._add_compound(smiles_dict['FADH'], smiles_dict['FADH'], cpd_type='Starting Compound') pk.operators['2.7.1.a'] = default_rule pk.transform_all(max_generations=2) assert len(pk.compounds) == 31 assert len(pk.reactions) == 49 comp_gens = set([x['Generation'] for x in pk.compounds.values()]) assert comp_gens == {0, 1, 2}
def test_transform_all(default_rule, smiles_dict, coreactant_dict): """Test transform function. GIVEN a set of rules and starting compounds WHEN we run pickaxe to predict potential transformations THEN make sure all expected transformations are predicted """ pk = pickaxe.Pickaxe(errors=False, explicit_h=True) pk._load_coreactant(coreactant_dict["ATP"]) pk._load_coreactant(coreactant_dict["ADP"]) pk._add_compound( smiles_dict["FADH"], smiles_dict["FADH"], cpd_type="Starting Compound" ) pk.operators["2.7.1.a"] = default_rule pk.transform_all(generations=2) assert len(pk.compounds) == 31 assert len(pk.reactions) == 49 comp_gens = set([x["Generation"] for x in pk.compounds.values()]) assert comp_gens == {0, 1, 2}
def test_save_as_mine(default_rule, smiles_dict, coreactant_dict): """Test saving compounds to database. GIVEN a Pickaxe expansion WHEN that expansion is saved as a MINE DB in the MongoDB THEN make sure that all features are saved in the MongoDB as expected """ DATA_DIR = (file_dir / "../data").resolve() delete_database("MINE_test") pk = pickaxe.Pickaxe(database="MINE_test", image_dir=DATA_DIR, explicit_h=True) pk.operators["2.7.1.a"] = default_rule pk._load_coreactant(coreactant_dict["ATP"]) pk._load_coreactant(coreactant_dict["ADP"]) pk._add_compound("FADH", smiles_dict["FADH"], cpd_type="Starting Compound") pk.transform_all(generations=2) pk.save_to_mine(processes=1) mine_db = MINE("MINE_test") try: assert mine_db.compounds.estimated_document_count() == 31 assert mine_db.reactions.estimated_document_count() == 49 assert mine_db.operators.estimated_document_count() == 1 assert mine_db.operators.find_one()["Reactions_predicted"] == 49 assert os.path.exists( DATA_DIR / "X9c29f84930a190d9086a46c344020283c85fb917.svg" ) start_comp = mine_db.compounds.find_one({"Type": "Starting Compound"}) assert len(start_comp["Reactant_in"]) > 0 # Don't track sources of coreactants coreactant = mine_db.compounds.find_one({"Type": "Coreactant"}) assert "Product_of" not in coreactant assert "Reactant_in" not in coreactant product = mine_db.compounds.find_one({"Generation": 2}) assert len(product["Product_of"]) > 0 assert product["Type"] == "Predicted" finally: delete_database("MINE_test") purge(DATA_DIR, r".*\.svg$")
def pk(): """Create default Pickaxe object.""" return pickaxe.Pickaxe(coreactant_list=DATA_DIR + '/test_coreactants.tsv', rule_list=DATA_DIR + '/test_reaction_rules.tsv')