pyaging 0.0.1__tar.gz → 0.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyaging might be problematic. Click here for more details.
- {pyaging-0.0.1 → pyaging-0.0.4}/PKG-INFO +8 -19
- {pyaging-0.0.1 → pyaging-0.0.4}/README.md +2 -13
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/data/_data.py +5 -1
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/logger/_logger.py +4 -3
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/predict/__init__.py +1 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/predict/_postprocessing.py +12 -0
- pyaging-0.0.4/pyaging/predict/_pred.py +137 -0
- pyaging-0.0.1/pyaging/predict/_pred.py → pyaging-0.0.4/pyaging/predict/_pred_utils.py +191 -208
- pyaging-0.0.4/pyaging/predict/_preprocessing.py +57 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/preprocess/__init__.py +1 -0
- pyaging-0.0.4/pyaging/preprocess/_preprocess.py +196 -0
- pyaging-0.0.1/pyaging/preprocess/_preprocess.py → pyaging-0.0.4/pyaging/preprocess/_preprocess_utils.py +60 -237
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/utils/_utils.py +10 -10
- {pyaging-0.0.1 → pyaging-0.0.4}/pyproject.toml +6 -6
- pyaging-0.0.1/pyaging/predict/_preprocessing.py +0 -47
- {pyaging-0.0.1 → pyaging-0.0.4}/LICENSE +0 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/__init__.py +0 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/data/__init__.py +0 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/logger/__init__.py +0 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/models/__init__.py +0 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/models/_models.py +0 -0
- {pyaging-0.0.1 → pyaging-0.0.4}/pyaging/utils/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyaging
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: A Python-based compendium of GPU-optimized aging clocks.
|
|
5
5
|
License: BSD
|
|
6
6
|
Author: Lucas Paulo de Lima Camillo
|
|
@@ -13,12 +13,12 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Provides-Extra: docs
|
|
16
|
-
Requires-Dist: anndata (>=0.10.
|
|
17
|
-
Requires-Dist: numpy (>=1.26.
|
|
18
|
-
Requires-Dist: pandas (>=2.
|
|
16
|
+
Requires-Dist: anndata (>=0.10.3,<0.11.0)
|
|
17
|
+
Requires-Dist: numpy (>=1.26.2,<2.0.0)
|
|
18
|
+
Requires-Dist: pandas (>=2.1.3,<3.0.0)
|
|
19
19
|
Requires-Dist: pyBigWig (>=0.3.22,<0.4.0)
|
|
20
|
-
Requires-Dist: scikit-learn (>=1.3.
|
|
21
|
-
Requires-Dist: torch (>=2.
|
|
20
|
+
Requires-Dist: scikit-learn (>=1.3.2,<2.0.0)
|
|
21
|
+
Requires-Dist: torch (>=2.1.1,<3.0.0)
|
|
22
22
|
Project-URL: homepage, https://github.com/rsinghlab/pyaging
|
|
23
23
|
Project-URL: repository, https://github.com/rsinghlab/pyaging
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
@@ -43,29 +43,18 @@ Description-Content-Type: text/markdown
|
|
|
43
43
|
|
|
44
44
|
`pyaging` is a cutting-edge Python package designed for the longevity research community, offering a comprehensive suite of GPU-optimized biological aging clocks.
|
|
45
45
|
|
|
46
|
-
[Installation](https://pyaging.readthedocs.io/en/latest/installation.html) - [Search, cite, and get metadata](https://pyaging.readthedocs.io/en/latest/tutorial_utils.html) - [Bulk DNA methylation](https://pyaging.readthedocs.io/en/latest/tutorial_dnam.html) - [Bulk histone mark ChIP-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_histonemarkchipseq.html) - [Bulk ATAC-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_atacseq.html) - [Bulk RNA-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_rnaseq.html) - [API Reference](https://pyaging.readthedocs.io/en/latest/pyaging.html)
|
|
46
|
+
[Installation](https://pyaging.readthedocs.io/en/latest/installation.html) - [Search, cite, and get metadata](https://pyaging.readthedocs.io/en/latest/tutorial_utils.html) - [Bulk DNA methylation](https://pyaging.readthedocs.io/en/latest/tutorial_dnam.html) - [Bulk histone mark ChIP-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_histonemarkchipseq.html) - [Bulk ATAC-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_atacseq.html) - [Bulk RNA-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_rnaseq.html) - [Blood chemistry](https://pyaging.readthedocs.io/en/latest/tutorial_bloodchemistry.html) - [API Reference](https://pyaging.readthedocs.io/en/latest/pyaging.html)
|
|
47
47
|
|
|
48
48
|
With a growing number of aging clocks, comparing and analyzing them can be challenging. `pyaging` simplifies this process, allowing researchers to input various molecular layers (DNA methylation, histone ChIP-Seq, ATAC-seq, transcriptomics, etc.) and quickly analyze them using multiple aging clocks, thanks to its GPU-backed infrastructure. This makes it an ideal tool for large datasets and multi-layered analysis.
|
|
49
49
|
|
|
50
50
|
## 📝 To-Do List
|
|
51
51
|
|
|
52
|
-
- [X] Integrate `black` for PEP8 compliant code formatting
|
|
53
|
-
- [X] Improve and expand `readthedocs` documentation
|
|
54
|
-
- [X] Add option to specify download directory for datasets
|
|
55
|
-
- [X] Rename datasets to reflect source publications
|
|
56
|
-
- [X] Include mammalian array example datasets
|
|
57
|
-
- [X] Add feature to control logging verbosity
|
|
58
|
-
- [ ] Publish to PyPi
|
|
59
|
-
- [ ] Add percentage of missing features in anndata after age prediction for each clock
|
|
60
|
-
- [ ] Add table in readthedocs with all clock metadata
|
|
61
|
-
- [ ] Add and populate "Notes" tab in metadata
|
|
62
52
|
- [ ] Integrate scAge and scRNAseq clocks (and datasets)
|
|
63
53
|
- [ ] Incorporate murine DNA methylation and proteomic clocks (and datasets)
|
|
64
|
-
- [ ] Add PhenoAge based on blood chemistry analysis (and datasets)
|
|
65
54
|
|
|
66
55
|
## ❓ Can't find an aging clock?
|
|
67
56
|
|
|
68
|
-
If you have recently developed an aging clock and would like it to be integrated into `pyaging`, please [email us](lucas_camillo@alumni.brown.edu). We aim to incorporate it within two weeks!
|
|
57
|
+
If you have recently developed an aging clock and would like it to be integrated into `pyaging`, please [email us](lucas_camillo@alumni.brown.edu). We aim to incorporate it within two weeks! We are also happy to adapt to any licensing terms for commercial entities.
|
|
69
58
|
|
|
70
59
|
## 💬 Community Discussion
|
|
71
60
|
For coding-related queries, feedback, and discussions, please visit our [GitHub Issues](https://github.com/rsinghlab/pyaging/issues) page.
|
|
@@ -18,29 +18,18 @@
|
|
|
18
18
|
|
|
19
19
|
`pyaging` is a cutting-edge Python package designed for the longevity research community, offering a comprehensive suite of GPU-optimized biological aging clocks.
|
|
20
20
|
|
|
21
|
-
[Installation](https://pyaging.readthedocs.io/en/latest/installation.html) - [Search, cite, and get metadata](https://pyaging.readthedocs.io/en/latest/tutorial_utils.html) - [Bulk DNA methylation](https://pyaging.readthedocs.io/en/latest/tutorial_dnam.html) - [Bulk histone mark ChIP-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_histonemarkchipseq.html) - [Bulk ATAC-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_atacseq.html) - [Bulk RNA-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_rnaseq.html) - [API Reference](https://pyaging.readthedocs.io/en/latest/pyaging.html)
|
|
21
|
+
[Installation](https://pyaging.readthedocs.io/en/latest/installation.html) - [Search, cite, and get metadata](https://pyaging.readthedocs.io/en/latest/tutorial_utils.html) - [Bulk DNA methylation](https://pyaging.readthedocs.io/en/latest/tutorial_dnam.html) - [Bulk histone mark ChIP-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_histonemarkchipseq.html) - [Bulk ATAC-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_atacseq.html) - [Bulk RNA-Seq](https://pyaging.readthedocs.io/en/latest/tutorial_rnaseq.html) - [Blood chemistry](https://pyaging.readthedocs.io/en/latest/tutorial_bloodchemistry.html) - [API Reference](https://pyaging.readthedocs.io/en/latest/pyaging.html)
|
|
22
22
|
|
|
23
23
|
With a growing number of aging clocks, comparing and analyzing them can be challenging. `pyaging` simplifies this process, allowing researchers to input various molecular layers (DNA methylation, histone ChIP-Seq, ATAC-seq, transcriptomics, etc.) and quickly analyze them using multiple aging clocks, thanks to its GPU-backed infrastructure. This makes it an ideal tool for large datasets and multi-layered analysis.
|
|
24
24
|
|
|
25
25
|
## 📝 To-Do List
|
|
26
26
|
|
|
27
|
-
- [X] Integrate `black` for PEP8 compliant code formatting
|
|
28
|
-
- [X] Improve and expand `readthedocs` documentation
|
|
29
|
-
- [X] Add option to specify download directory for datasets
|
|
30
|
-
- [X] Rename datasets to reflect source publications
|
|
31
|
-
- [X] Include mammalian array example datasets
|
|
32
|
-
- [X] Add feature to control logging verbosity
|
|
33
|
-
- [ ] Publish to PyPi
|
|
34
|
-
- [ ] Add percentage of missing features in anndata after age prediction for each clock
|
|
35
|
-
- [ ] Add table in readthedocs with all clock metadata
|
|
36
|
-
- [ ] Add and populate "Notes" tab in metadata
|
|
37
27
|
- [ ] Integrate scAge and scRNAseq clocks (and datasets)
|
|
38
28
|
- [ ] Incorporate murine DNA methylation and proteomic clocks (and datasets)
|
|
39
|
-
- [ ] Add PhenoAge based on blood chemistry analysis (and datasets)
|
|
40
29
|
|
|
41
30
|
## ❓ Can't find an aging clock?
|
|
42
31
|
|
|
43
|
-
If you have recently developed an aging clock and would like it to be integrated into `pyaging`, please [email us](lucas_camillo@alumni.brown.edu). We aim to incorporate it within two weeks!
|
|
32
|
+
If you have recently developed an aging clock and would like it to be integrated into `pyaging`, please [email us](lucas_camillo@alumni.brown.edu). We aim to incorporate it within two weeks! We are also happy to adapt to any licensing terms for commercial entities.
|
|
44
33
|
|
|
45
34
|
## 💬 Community Discussion
|
|
46
35
|
For coding-related queries, feedback, and discussions, please visit our [GitHub Issues](https://github.com/rsinghlab/pyaging/issues) page.
|
|
@@ -4,6 +4,7 @@ import ntpath
|
|
|
4
4
|
import os
|
|
5
5
|
from urllib.request import urlretrieve
|
|
6
6
|
from functools import wraps
|
|
7
|
+
|
|
7
8
|
from ..utils import progress, download
|
|
8
9
|
from ..logger import LoggerManager, main_tqdm, silence_logger
|
|
9
10
|
|
|
@@ -21,7 +22,9 @@ def download_example_data(
|
|
|
21
22
|
Parameters
|
|
22
23
|
----------
|
|
23
24
|
data_type : str
|
|
24
|
-
The type of data to download. Valid options are '
|
|
25
|
+
The type of data to download. Valid options are 'GSE139307' (human methylation),
|
|
26
|
+
'GSE223748' (mammalian methylation), 'ENCFF386QWG' (histone mark),
|
|
27
|
+
'GSE65765' (C. elegans RNA-seq), 'atac_example' (ATAC-Seq), 'blood_chemistry_example' (blood chemistry).
|
|
25
28
|
|
|
26
29
|
dir : str
|
|
27
30
|
The directory to deposit the downloaded file. Defaults to "pyaging_data".
|
|
@@ -61,6 +64,7 @@ def download_example_data(
|
|
|
61
64
|
"ENCFF386QWG": "https://pyaging.s3.amazonaws.com/example_data/ENCFF386QWG.bigWig",
|
|
62
65
|
"GSE65765": "https://pyaging.s3.amazonaws.com/example_data/GSE65765_CPM.pkl",
|
|
63
66
|
"atac_example": "https://pyaging.s3.amazonaws.com/example_data/atac_example.pkl",
|
|
67
|
+
"blood_chemistry_example": "https://pyaging.s3.amazonaws.com/example_data/blood_chemistry_example.pkl",
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
if data_type not in list(data_type_to_url.keys()):
|
|
@@ -273,7 +273,8 @@ class Logger:
|
|
|
273
273
|
self.logger_stream_handler.terminator = saved_terminator
|
|
274
274
|
|
|
275
275
|
def start_progress(self, message, indent_level=1, *args, **kwargs):
|
|
276
|
-
|
|
276
|
+
now = time.time()
|
|
277
|
+
self.previous_timestamp = now
|
|
277
278
|
message = format_logging_message(
|
|
278
279
|
"⚙️ " + message, logging.INFO, indent_level=indent_level
|
|
279
280
|
)
|
|
@@ -281,8 +282,8 @@ class Logger:
|
|
|
281
282
|
self.logger_stream_handler.flush()
|
|
282
283
|
|
|
283
284
|
def finish_progress(self, progress_name="", time_unit="s", indent_level=1):
|
|
284
|
-
|
|
285
|
-
|
|
285
|
+
now = time.time()
|
|
286
|
+
self.time_passed = now - self.previous_timestamp
|
|
286
287
|
|
|
287
288
|
saved_terminator = self.logger_stream_handler.terminator
|
|
288
289
|
self.logger_stream_handler.terminator = ""
|
|
@@ -35,3 +35,15 @@ def anti_log_log(x):
|
|
|
35
35
|
"""
|
|
36
36
|
# Double transformation: logarithmic followed by anti-logarithmic
|
|
37
37
|
return math.exp(-math.exp(-x))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def mortality_to_phenoage(x):
|
|
41
|
+
"""
|
|
42
|
+
Applies a convertion from a CDF of the mortality score from a Gompertz
|
|
43
|
+
distribution to phenotypic age.
|
|
44
|
+
"""
|
|
45
|
+
# lambda
|
|
46
|
+
l = 0.0192
|
|
47
|
+
mortality_score = 1 - math.exp(-math.exp(x) * (math.exp(120 * l) - 1) / l)
|
|
48
|
+
age = 141.50225 + math.log(-0.00553 * math.log(1 - mortality_score)) / 0.090165
|
|
49
|
+
return age
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import anndata
|
|
2
|
+
|
|
3
|
+
from ._pred_utils import *
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def predict_age(
|
|
7
|
+
adata: anndata.AnnData,
|
|
8
|
+
clock_names: str = "horvath2013",
|
|
9
|
+
dir: str = "pyaging_data",
|
|
10
|
+
verbose: bool = True,
|
|
11
|
+
) -> anndata.AnnData:
|
|
12
|
+
"""
|
|
13
|
+
Predicts biological age using specified aging clocks.
|
|
14
|
+
|
|
15
|
+
This function takes an AnnData object and applies one or more specified aging
|
|
16
|
+
clock models to predict the biological age of the samples. It handles the entire pipeline from data
|
|
17
|
+
preprocessing, model loading, prediction, to postprocessing. It also enriches the input AnnData
|
|
18
|
+
object with the predicted ages and relevant clock metadata.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
adata: AnnData
|
|
23
|
+
An AnnData object. The object should have .X attribute for the
|
|
24
|
+
data matrix and .var_names for feature names.
|
|
25
|
+
|
|
26
|
+
clock_names: str or list of str, optional
|
|
27
|
+
Names of the aging clocks to be applied. It can be a single clock name as a string or a list
|
|
28
|
+
of clock names, by default "horvath2013".
|
|
29
|
+
|
|
30
|
+
dir: str
|
|
31
|
+
The directory to deposit the downloaded file. Defaults to "pyaging_data".
|
|
32
|
+
|
|
33
|
+
verbose: bool
|
|
34
|
+
Whether to log the output to console with the logger. Defaults to True.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
AnnData
|
|
39
|
+
The input AnnData object enriched with the predicted ages and clock metadata in the .obs and
|
|
40
|
+
.uns attributes, respectively.
|
|
41
|
+
|
|
42
|
+
Notes
|
|
43
|
+
-----
|
|
44
|
+
The function is designed to be flexible and can handle both single and multiple clock predictions.
|
|
45
|
+
The predicted ages are appended to the .obs attribute of the AnnData object with the clock name as
|
|
46
|
+
the key. The metadata of each clock used in the prediction is stored in the .uns attribute.
|
|
47
|
+
|
|
48
|
+
It is important that the input AnnData object's .X attribute contains data suitable for age
|
|
49
|
+
prediction.
|
|
50
|
+
|
|
51
|
+
The function automatically handles the transfer of data and models to the appropriate compute
|
|
52
|
+
device (CPU or GPU) based on system configuration.
|
|
53
|
+
|
|
54
|
+
Examples
|
|
55
|
+
--------
|
|
56
|
+
>>> adata = anndata.read_h5ad("sample_data.h5ad")
|
|
57
|
+
>>> adata = predict_age(adata, clock_names=["horvath2013", "hannum"])
|
|
58
|
+
>>> adata.obs["horvath2013"] # Access predicted ages by clock name
|
|
59
|
+
|
|
60
|
+
"""
|
|
61
|
+
logger = LoggerManager.gen_logger("predict_age")
|
|
62
|
+
if not verbose:
|
|
63
|
+
silence_logger("predict_age")
|
|
64
|
+
logger.first_info("Starting predict_age function")
|
|
65
|
+
|
|
66
|
+
# Ensure clock_names is a list
|
|
67
|
+
if isinstance(clock_names, str):
|
|
68
|
+
clock_names = [clock_names]
|
|
69
|
+
|
|
70
|
+
# Set device for PyTorch operations
|
|
71
|
+
device = set_torch_device(logger)
|
|
72
|
+
|
|
73
|
+
for clock_name in clock_names:
|
|
74
|
+
logger.info(f"🕒 Processing clock: {clock_name}", indent_level=1)
|
|
75
|
+
|
|
76
|
+
# Load and prepare the clock
|
|
77
|
+
clock_name = clock_name.lower()
|
|
78
|
+
features, weight_dict, preprocessing, postprocessing, preprocessing_helper, postprocessing_helper = load_clock(
|
|
79
|
+
clock_name, dir, logger, indent_level=2
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Check and update adata for missing features
|
|
83
|
+
adata = check_features_in_adata(
|
|
84
|
+
adata, clock_name, features, logger, indent_level=2
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Apply preprocessing
|
|
88
|
+
if preprocessing:
|
|
89
|
+
adata = preprocess_data(
|
|
90
|
+
adata, preprocessing, preprocessing_helper, features, logger, indent_level=2
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Filter features and then extract data matrix
|
|
94
|
+
x_numpy = filter_features_and_extract_data(
|
|
95
|
+
adata, preprocessing, features, logger, indent_level=2
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# Convert numpy array to tensor
|
|
99
|
+
x_tensor = convert_numpy_array_to_tensor(
|
|
100
|
+
x_numpy, device, logger, indent_level=2
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Initialize and configure the model
|
|
104
|
+
clock_model = initialize_model(
|
|
105
|
+
clock_name, features, weight_dict, device, logger, indent_level=2
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Perform age prediction using the model
|
|
109
|
+
predicted_ages_tensor = predict_ages_with_model(
|
|
110
|
+
clock_model, x_tensor, logger, indent_level=2
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Convert adata tensor to numpy array
|
|
114
|
+
predicted_ages = convert_tensor_to_numpy_array(
|
|
115
|
+
predicted_ages_tensor, logger, indent_level=2
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Apply postprocessing if specified
|
|
119
|
+
if postprocessing:
|
|
120
|
+
predicted_ages = postprocess_data(
|
|
121
|
+
predicted_ages, postprocessing, postprocessing_helper, logger, indent_level=2
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Add predicted ages to adata
|
|
125
|
+
add_pred_ages_adata(adata, predicted_ages, clock_name, logger, indent_level=2)
|
|
126
|
+
|
|
127
|
+
# Load all clocks metadata
|
|
128
|
+
all_clock_metadata = load_clock_metadata(dir, logger, indent_level=2)
|
|
129
|
+
|
|
130
|
+
# Add clock metadata to adata object
|
|
131
|
+
add_clock_metadata_adata(
|
|
132
|
+
adata, clock_name, all_clock_metadata, logger, indent_level=2
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
logger.done()
|
|
137
|
+
return adata
|