Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7e5a973
New code for setting a dataset key
stewarthe6 Aug 27, 2026
6985115
These are the auto fixes for ruff version 0.16 using --fix and --unsa…
stewarthe6 Aug 27, 2026
aedf552
Ruff fixes done by Nemotron-3-ultra
stewarthe6 Aug 27, 2026
d05231a
Nemotron-3-ultra fix for target_data_curation. Also ignore N999, whic…
stewarthe6 Aug 27, 2026
5c79998
Nemotron-3-ultra fixed ruff errors
stewarthe6 Aug 27, 2026
a4da064
Ignore N999, camel case module names
stewarthe6 Aug 27, 2026
cf67549
Nemotron-3-ultra fix for ruff errors
stewarthe6 Aug 27, 2026
014163b
Nemotron-3-ultra fix for ruff errors
stewarthe6 Aug 27, 2026
59ea657
Nemotron-3-ultra ruff fixes
stewarthe6 Aug 27, 2026
d335074
Nemotron-3-ultra ruff fixes
stewarthe6 Aug 27, 2026
a9d8518
Nemotron-3-ultra ruff fixes
stewarthe6 Aug 27, 2026
6b6700f
Nemotron-3-ultra ruff fixes
stewarthe6 Aug 27, 2026
b662916
Nemotron-3-ultra ruff fixes
stewarthe6 Aug 27, 2026
b930568
Nemotron-3-ultra ruff fixes
stewarthe6 Aug 27, 2026
963306d
Address EXE001 errors to make sure Shebang was only present in files …
stewarthe6 Aug 31, 2026
5046e59
Merge branch 'ruff_fixes' of github.com:ATOMScience-org/AMPL into ruf…
stewarthe6 Aug 31, 2026
43bbe2e
We also encounter TypeErrors when dataset_key is None
stewarthe6 Aug 31, 2026
cfbb78a
This throws a NotImplementedError
stewarthe6 Aug 31, 2026
a31352f
This is an unused variable
stewarthe6 Aug 31, 2026
7a48a02
Merge in ruff_fixes from 1.8.1
stewarthe6 Sep 1, 2026
8bd4417
Rebase to 1.8.1
stewarthe6 Sep 1, 2026
f897d3e
Fixed some ruff errors
stewarthe6 Sep 1, 2026
bb34804
Include better error messages for checking model versions
stewarthe6 Oct 6, 2026
14d8981
Cleaned up mix use of tabs and spaces
stewarthe6 Oct 7, 2026
7016440
Committing first draft of query by committee code
stewarthe6 Oct 7, 2026
04d9c67
Added a test for query_by_committee
stewarthe6 Oct 7, 2026
0a29b4c
Fixed some bugs and sped up the tests
stewarthe6 Oct 7, 2026
3d1f15e
Only recalculate features if the feature file is not found
stewarthe6 Oct 7, 2026
ac74c42
Updated MRP3 datasets to include pIC50 column
stewarthe6 Oct 7, 2026
a10ca78
Fixed bugs in query by committee tests
stewarthe6 Oct 7, 2026
de1741f
Fixed ruff errors in query_by_committee* and thresholded_spearmanr
stewarthe6 Oct 7, 2026
7422579
Reverting to the old exception handling. Recalculating features solve…
stewarthe6 Oct 7, 2026
ec9c2a1
Updated and corrected tests for thresholded spearman r
stewarthe6 Oct 8, 2026
ede960b
This now builds a new dataframe by combining the features from scaled…
stewarthe6 Oct 8, 2026
a2d04a6
Removing unecessary pass
stewarthe6 Oct 8, 2026
7ddf336
Don't even bother checking for a scaled file if we're using dynamic f…
stewarthe6 Oct 8, 2026
2cc44bc
Updated version
stewarthe6 Oct 13, 2026
ada7ea4
Updated version in conf.py
stewarthe6 Oct 13, 2026
528d502
Updated docs for new query by committee and thresholded_spearmanr
stewarthe6 Oct 13, 2026
ed0a1c1
Updating documentation to include the new modules
stewarthe6 Oct 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The ATOM Modeling PipeLine (AMPL) extends the functionality of DeepChem and supp

Check out our new tutorial series that walks through AMPL's end-to-end modeling pipeline to build a machine learning model! View them in our [docs](https://ampl.readthedocs.io/en/latest/) or as Jupyter notebooks in our [repo](https://github.com/ATOMScience-org/AMPL/tree/master/atomsci/ddm/examples/tutorials).

![Static Badge](https://img.shields.io/badge/Announcement-1.8.0-blue)
![Static Badge](https://img.shields.io/badge/Announcement-1.8.1-blue)

In addition to our written tutorials, we now provide a series of video tutorials on our YouTube channel, [ATOMScience-org](https://www.youtube.com/channel/UCOF6zZ7ltGwopYCoOGIFM-w). These videos are created to assist users in exploring and leveraging AMPL's robust capabilities. We provided a playlist for easy streamlined Learning:

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8.0
1.8.1
4 changes: 2 additions & 2 deletions atomsci/ddm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
#except TypeError:
# pass
try:
from importlib.metadata import version, PackageNotFoundError
from importlib.metadata import PackageNotFoundError, version
except ImportError:
try:
from importlib_metadata import version, PackageNotFoundError
from importlib_metadata import PackageNotFoundError, version
except ImportError:
version = None
PackageNotFoundError = Exception
Expand Down
2 changes: 1 addition & 1 deletion atomsci/ddm/docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# import atomsci.ddm
#version = atomsci.ddm.__version__
# The short X.Y version
version = '1.8.0'
version = '1.8.1'
copyright = f'{datetime.datetime.now().year}, {author}'

# The full version, including alpha/beta/rc tags
Expand Down
35 changes: 35 additions & 0 deletions atomsci/ddm/docs/source/ddm.utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ ddm.utils.model\_version\_utils module
:undoc-members:
:show-inheritance:

ddm.utils.patch\_model\_dataset\_key module
-------------------------------------------

.. automodule:: ddm.utils.patch_model_dataset_key
:members:
:undoc-members:
:show-inheritance:

ddm.utils.pubchem\_utils module
-------------------------------

Expand Down Expand Up @@ -109,6 +117,33 @@ ddm.utils.struct\_utils module
:undoc-members:
:show-inheritance:


ddm.utils.thresholded\_spearmanr module
---------------------------------------

.. automodule:: ddm.utils.thresholded_spearmanr
:members:
:undoc-members:
:show-inheritance:


ddm.utils.query\_by\_committee module
------------------------------------

.. automodule:: ddm.utils.query_by_committee
:members:
:undoc-members:
:show-inheritance:


ddm.utils.query\_by\_committee\_utils module
--------------------------------------------

.. automodule:: ddm.utils.query_by_committee_utils
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

Expand Down
34 changes: 34 additions & 0 deletions atomsci/ddm/docs/source/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ utils.model\_version\_utils module
:undoc-members:
:show-inheritance:

utils.patch\_model\_dataset\_key module
---------------------------------------

.. automodule:: utils.patch_model_dataset_key
:members:
:undoc-members:
:show-inheritance:

utils.pubchem\_utils module
---------------------------

Expand Down Expand Up @@ -117,6 +125,32 @@ utils.struct\_utils module
:undoc-members:
:show-inheritance:

utils.thresholded\_spearmanr module
-----------------------------------

.. automodule:: utils.thresholded_spearmanr
:members:
:undoc-members:
:show-inheritance:


utils.query\_by\_committee module
---------------------------------

.. automodule:: utils.query_by_committee
:members:
:undoc-members:
:show-inheritance:


utils.query\_by\_committee\_utils module
----------------------------------------

.. automodule:: utils.query_by_committee_utils
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

Expand Down
42 changes: 22 additions & 20 deletions atomsci/ddm/examples/BSEP/predict_bsep_inhibition.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
#!/usr/bin/env python
# coding: utf-8

# Script for running example BSEP inhibition classification models against user-provided data.

import sys
import argparse
import os
import sys

import pandas as pd
from sklearn import metrics
import argparse

from atomsci.ddm.pipeline import predict_from_model as pfm

# from atomsci.ddm.pipeline import model_pipeline as mp
# from atomsci.ddm.pipeline import parameter_parser as parse
from atomsci.ddm.pipeline.perf_data import negative_predictive_value

# from atomsci.ddm.utils.struct_utils import base_smiles_from_smiles

# =====================================================================================================
Expand All @@ -21,13 +23,13 @@ def predict_activity(args):
input_df = pd.read_csv(args.input_file, index_col=False)
colnames = set(input_df.columns.values)
if args.id_col not in colnames:
input_df['compound_id'] = ['compound_%.6d' % i for i in range(input_df.shape[0])]
input_df['compound_id'] = [f'compound_{i:06d}' for i in range(input_df.shape[0])]
args.id_col = 'compound_id'
if args.smiles_col not in colnames:
raise ValueError('smiles_col parameter not specified or column not in input file.')
model_files = dict(random = 'bsep_classif_random_split.tar.gz', scaffold = 'bsep_classif_scaffold_split.tar.gz')
model_files = {'random': 'bsep_classif_random_split.tar.gz', 'scaffold': 'bsep_classif_scaffold_split.tar.gz'}
if args.model_type not in model_files:
raise ValueError("model_type %s is not a recognizied value." % args.model_type)
raise ValueError(f"model_type {args.model_type} is not a recognizied value.")
if args.external_training_data is not None:
data_file = os.path.join(os.getcwd(), args.external_training_data)
else:
Expand All @@ -48,13 +50,13 @@ def predict_activity(args):

# Write predictions to output file
pred_df.to_csv(args.output_file, index=False)
print("Wrote predictions to file %s" % args.output_file)
print(f"Wrote predictions to file {args.output_file}")

# If measured activity values are provided, print some performance metrics
if args.response_col is not None:
actual_vals = pred_df['%s_actual' % args.response_col].values
pred_classes = pred_df['%s_pred' % args.response_col].values
pred_probs = pred_df['%s_prob' % args.response_col].values
actual_vals = pred_df[f'{args.response_col}_actual'].values
pred_classes = pred_df[f'{args.response_col}_pred'].values
pred_probs = pred_df[f'{args.response_col}_prob'].values
conf_matrix = metrics.confusion_matrix(actual_vals, pred_classes)
roc_auc = metrics.roc_auc_score(actual_vals, pred_probs)
prc_auc = metrics.average_precision_score(actual_vals, pred_probs)
Expand All @@ -65,19 +67,19 @@ def predict_activity(args):
mcc = metrics.matthews_corrcoef(actual_vals, pred_classes)
ncorrect = sum(actual_vals == pred_classes)
print("Performance metrics:\n")
print("%d out of %d predictions correct." % (ncorrect, pred_df.shape[0]))
print("Accuracy: %.3f" % accuracy)
print("Precision: %.3f" % precision)
print("Recall: %.3f" % recall)
print("NPV: %.3f" % npv)
print("ROC AUC: %.3f" % roc_auc)
print("PRC AUC: %.3f" % prc_auc)
print("Matthews correlation coefficient: %.3f" % mcc)
print(f"{ncorrect} out of {pred_df.shape[0]} predictions correct.")
print(f"Accuracy: {accuracy:.3f}")
print(f"Precision: {precision:.3f}")
print(f"Recall: {recall:.3f}")
print(f"NPV: {npv:.3f}")
print(f"ROC AUC: {roc_auc:.3f}")
print(f"PRC AUC: {prc_auc:.3f}")
print(f"Matthews correlation coefficient: {mcc:.3f}")
print("Confusion matrix:")
print("\t\tpredicted activity")
print("actual\nactivity\t0\t1\n")
print(" 0\t\t%d\t%d" % (conf_matrix[0][0], conf_matrix[0][1]))
print(" 1\t\t%d\t%d" % (conf_matrix[1][0], conf_matrix[1][1]))
print(f" 0\t\t{conf_matrix[0][0]}\t{conf_matrix[0][1]}")
print(f" 1\t\t{conf_matrix[1][0]}\t{conf_matrix[1][1]}")



Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import matplotlib

matplotlib.use('Agg')
import pandas as pd
import json
import os
from os import path

import json
import numpy as np
import pandas as pd
from target_data_curation import AMPLDataset

#import custom_config as cc
import atomsci.ddm.utils.pubchem_utils as pu
from os import path
from target_data_curation import AMPLDataset
from atomsci.ddm.utils import data_curation_functions as dcf
import numpy as np


# Using data_curation_functions
# Initial dataset downloaded org/record/173258#.XcXWHZJKhhE
Expand Down Expand Up @@ -185,7 +185,7 @@ def add_base_smiles_col(self):
if not path.exists(self.smiles_file) :
print("download from PubChem ")
## smiles are stored in 'smiles' column in returned dataframe
save_smiles_df,fail_lst,discard_lst=pu.download_smiles(myList)
save_smiles_df,_fail_lst,_discard_lst=pu.download_smiles(myList)
save_smiles_df.to_csv(ofile, index=False)
else :
print("retrieve SMILES from predownloaded file",self.smiles_file)
Expand Down Expand Up @@ -243,42 +243,44 @@ def __init__(self, parser=None, sec = None, raw_target_lst = None, dataset = Non

"""
if dataset is not None and df is not None :
self.set_columns(dataset.data_source_name)
self.df = df
self.set_columns(dataset.data_source_name)
self.df = df
else :
self.set_columns(sec)
mapgn=parser.check_get(sec,'target_mapping')
self.target_dict = json.load(open(mapgn))
end_point_lst=parser.check_get(sec,"end_points").split(',')
end_point_lst = [ x.lower() for x in end_point_lst ]

filename=parser.check_get(sec,'activity_csv')
dc=json.load(open(filename))
target_lst=[]

for val in raw_target_lst :
target_lst.append( self.target_dict[val] )

df_lst=[]
for kv in raw_target_lst :
tmp_df_lst=[]
for cid in dc[kv].keys() :
lst=dc[kv][cid]['pAct']
for it in range(len(lst)) :
row={ self.id_col : cid, self.value_col : dc[kv][cid]['pAct'][it], self.relation_col : dc[kv][cid]['relation'][it],
self.smiles_col : dc[kv][cid]['smiles'], self.standard_col : dc[kv][cid]['type'][it], self.units : dc[kv][cid]['units'][it], self.assay_id : dc[kv][cid]['assay_id'][it] }
tmp_df_lst.append(row)
df=pd.DataFrame(tmp_df_lst)
df[self.target_id_col] = self.target_dict[kv]
df = df.dropna(subset=[self.value_col,self.standard_col,self.id_col])
df_lst.append(df)

self.df = pd.concat(df_lst)

## do we need to do any other filter/checks here, like units?
self.df=self.df[(self.df.units.str.lower() == 'nm')]
self.df.standard_type = self.df.standard_type.str.lower()
self.df=self.df[self.df.standard_type.isin( end_point_lst ) ]
self.set_columns(sec)
mapgn = parser.check_get(sec, 'target_mapping')
with open(mapgn) as f:
self.target_dict = json.load(f)
end_point_lst = parser.check_get(sec, "end_points").split(',')
end_point_lst = [x.lower() for x in end_point_lst]

filename = parser.check_get(sec, 'activity_csv')
with open(filename) as f:
dc = json.load(f)
target_lst = []

for val in raw_target_lst :
target_lst.append( self.target_dict[val] )

df_lst=[]
for kv in raw_target_lst :
tmp_df_lst=[]
for cid in dc[kv] :
lst=dc[kv][cid]['pAct']
for it in range(len(lst)) :
row={ self.id_col : cid, self.value_col : dc[kv][cid]['pAct'][it], self.relation_col : dc[kv][cid]['relation'][it],
self.smiles_col : dc[kv][cid]['smiles'], self.standard_col : dc[kv][cid]['type'][it], self.units : dc[kv][cid]['units'][it], self.assay_id : dc[kv][cid]['assay_id'][it] }
tmp_df_lst.append(row)
df=pd.DataFrame(tmp_df_lst)
df[self.target_id_col] = self.target_dict[kv]
df = df.dropna(subset=[self.value_col,self.standard_col,self.id_col])
df_lst.append(df)

self.df = pd.concat(df_lst)

## do we need to do any other filter/checks here, like units?
self.df=self.df[(self.df.units.str.lower() == 'nm')]
self.df.standard_type = self.df.standard_type.str.lower()
self.df=self.df[self.df.standard_type.isin( end_point_lst ) ]

def filter_task(self, target_id):
"""when the gene target label isn't standardized, need to return the gene target mapping"""
Expand All @@ -289,7 +291,7 @@ def convert_dtype(x):
return 0.0
try:
return float(x)
except Exception:
except (ValueError, TypeError):
return 0.0

class GPCRChEMBLActivityDump(AMPLDataset):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import matplotlib

matplotlib.use('Agg')
import argparse
import configparser

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib.backends.backend_pdf import PdfPages
from rdkit import Chem
from rdkit.Chem import Descriptors

import atomsci.ddm.pipeline.chem_diversity as cd
import atomsci.ddm.pipeline.diversity_plots as dp
from atomsci.ddm.utils import curate_data

#import custom_config
from atomsci.ddm.utils import struct_utils as su
from atomsci.ddm.utils import curate_data
import atomsci.ddm.pipeline.diversity_plots as dp
import atomsci.ddm.pipeline.chem_diversity as cd
from rdkit.Chem import Descriptors
from rdkit import Chem
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import numpy as np
import argparse

import configparser

class CustomConfigParser(configparser.ConfigParser) :
def __init__(self):
Expand All @@ -31,7 +33,7 @@ def check_get(self,section,keyval) :
except configparser.NoOptionError :
try :
rval = super().get(self.def_sec,keyval)
except Exception:
except (configparser.NoOptionError, configparser.NoSectionError):
rval = None
return rval

Expand Down Expand Up @@ -109,7 +111,7 @@ def make_filename_by_index(self, index):
"""
r = self.df.iloc[index]

return '%s_%s.csv'%(r[self.target_name_col], r[self.standard_col])
return f'{r[self.target_name_col]}_{r[self.standard_col]}.csv'

def iterrows(self):
"""Accessor function for self.sum_df.iterrows()
Expand Down
Loading
Loading