pyaging 0.0.1__py3-none-any.whl
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/__init__.py +10 -0
- pyaging/data/__init__.py +3 -0
- pyaging/data/_data.py +75 -0
- pyaging/logger/__init__.py +3 -0
- pyaging/logger/_logger.py +477 -0
- pyaging/models/__init__.py +3 -0
- pyaging/models/_models.py +154 -0
- pyaging/predict/__init__.py +5 -0
- pyaging/predict/_postprocessing.py +37 -0
- pyaging/predict/_pred.py +909 -0
- pyaging/predict/_preprocessing.py +47 -0
- pyaging/preprocess/__init__.py +3 -0
- pyaging/preprocess/_preprocess.py +578 -0
- pyaging/utils/__init__.py +3 -0
- pyaging/utils/_utils.py +438 -0
- pyaging-0.0.1.dist-info/LICENSE +28 -0
- pyaging-0.0.1.dist-info/METADATA +72 -0
- pyaging-0.0.1.dist-info/RECORD +20 -0
- pyaging-0.0.1.dist-info/WHEEL +4 -0
- pyaging-0.0.1.dist-info/entry_points.txt +3 -0
pyaging/__init__.py
ADDED
pyaging/data/__init__.py
ADDED
pyaging/data/_data.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import torch
|
|
3
|
+
import ntpath
|
|
4
|
+
import os
|
|
5
|
+
from urllib.request import urlretrieve
|
|
6
|
+
from functools import wraps
|
|
7
|
+
from ..utils import progress, download
|
|
8
|
+
from ..logger import LoggerManager, main_tqdm, silence_logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def download_example_data(
|
|
12
|
+
data_type: str, dir: str = "pyaging_data", verbose: bool = True
|
|
13
|
+
) -> None:
|
|
14
|
+
"""
|
|
15
|
+
Downloads example datasets for various types of biological data used in aging studies.
|
|
16
|
+
|
|
17
|
+
This function facilitates the download of example datasets for different types of biological data,
|
|
18
|
+
including methylation, histone mark, RNA-seq, and ATAC-seq data. It is designed to provide quick
|
|
19
|
+
access to standard datasets for users to test and explore the functionalities of the pyaging package.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
data_type : str
|
|
24
|
+
The type of data to download. Valid options are 'methylation', 'histone_mark', 'rnaseq', and 'atac'.
|
|
25
|
+
|
|
26
|
+
dir : str
|
|
27
|
+
The directory to deposit the downloaded file. Defaults to "pyaging_data".
|
|
28
|
+
|
|
29
|
+
verbose: bool
|
|
30
|
+
Whether to log the output to console with the logger. Defaults to True.
|
|
31
|
+
|
|
32
|
+
Raises
|
|
33
|
+
------
|
|
34
|
+
ValueError
|
|
35
|
+
If the specified data_type is not implemented, a ValueError is raised with a message suggesting
|
|
36
|
+
the user to request its implementation.
|
|
37
|
+
|
|
38
|
+
Notes
|
|
39
|
+
-----
|
|
40
|
+
The function maps the specified data_type to its corresponding URL and then calls the `download`
|
|
41
|
+
function to retrieve the dataset. The datasets are sourced from AWS S3
|
|
42
|
+
and are chosen to represent typical data formats and structures used in aging research.
|
|
43
|
+
|
|
44
|
+
The downloaded data can be used for various analyses, including testing the pyaging package's
|
|
45
|
+
functionalities, learning data processing techniques, or as a benchmark for custom analyses.
|
|
46
|
+
|
|
47
|
+
Examples
|
|
48
|
+
--------
|
|
49
|
+
>>> download_example_data("methylation")
|
|
50
|
+
# This will download the example methylation dataset to the local system.
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
logger = LoggerManager.gen_logger("download_example_data")
|
|
54
|
+
if not verbose:
|
|
55
|
+
silence_logger("download_example_data")
|
|
56
|
+
logger.first_info("Starting download_example_data function")
|
|
57
|
+
|
|
58
|
+
data_type_to_url = {
|
|
59
|
+
"GSE139307": "https://pyaging.s3.amazonaws.com/example_data/GSE139307.pkl",
|
|
60
|
+
"GSE223748": "https://pyaging.s3.amazonaws.com/example_data/GSE223748_subset.pkl",
|
|
61
|
+
"ENCFF386QWG": "https://pyaging.s3.amazonaws.com/example_data/ENCFF386QWG.bigWig",
|
|
62
|
+
"GSE65765": "https://pyaging.s3.amazonaws.com/example_data/GSE65765_CPM.pkl",
|
|
63
|
+
"atac_example": "https://pyaging.s3.amazonaws.com/example_data/atac_example.pkl",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if data_type not in list(data_type_to_url.keys()):
|
|
67
|
+
logger.error(
|
|
68
|
+
f"Example data {data_type} has not yet been implemented in pyaging.",
|
|
69
|
+
indent_level=2,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
url = data_type_to_url[data_type]
|
|
73
|
+
download(url, dir, logger, indent_level=1)
|
|
74
|
+
|
|
75
|
+
logger.done()
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# The code in this file is mostly taken from the dynamo-release package
|
|
2
|
+
|
|
3
|
+
import functools
|
|
4
|
+
import logging
|
|
5
|
+
import sys
|
|
6
|
+
import time
|
|
7
|
+
from contextlib import contextmanager
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def silence_logger(name):
|
|
11
|
+
"""Given a logger name, silence it completely.
|
|
12
|
+
|
|
13
|
+
:param name: name of the logger
|
|
14
|
+
:type name: str
|
|
15
|
+
"""
|
|
16
|
+
package_logger = logging.getLogger(name)
|
|
17
|
+
package_logger.setLevel(logging.CRITICAL + 100)
|
|
18
|
+
package_logger.propagate = False
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def set_logger_level(name, level):
|
|
22
|
+
"""Given a logger name, silence it completely.
|
|
23
|
+
|
|
24
|
+
:param name: name of the logger
|
|
25
|
+
:type name: str
|
|
26
|
+
"""
|
|
27
|
+
package_logger = logging.getLogger(name)
|
|
28
|
+
package_logger.setLevel(level)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def format_logging_message(msg, logging_level, indent_level=1, indent_space_num=6):
|
|
32
|
+
indent_str = "-" * indent_space_num
|
|
33
|
+
prefix = indent_str * indent_level
|
|
34
|
+
prefix = "|" + prefix[1:]
|
|
35
|
+
if logging_level == logging.INFO:
|
|
36
|
+
prefix += ">"
|
|
37
|
+
elif logging_level == logging.WARNING:
|
|
38
|
+
prefix += "?"
|
|
39
|
+
elif logging_level == logging.CRITICAL:
|
|
40
|
+
prefix += "!!"
|
|
41
|
+
elif logging_level == logging.DEBUG:
|
|
42
|
+
prefix += ">>>"
|
|
43
|
+
new_msg = prefix + " " + str(msg)
|
|
44
|
+
return new_msg
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class Logger:
|
|
48
|
+
"""Dynamo-specific logger that sets up logging for the package."""
|
|
49
|
+
|
|
50
|
+
FORMAT = "%(message)s"
|
|
51
|
+
|
|
52
|
+
def __init__(self, namespace="main", level=None):
|
|
53
|
+
self.namespace = namespace
|
|
54
|
+
self.logger = logging.getLogger(namespace)
|
|
55
|
+
self.previous_timestamp = time.time() # in seconds
|
|
56
|
+
self.time_passed = 0
|
|
57
|
+
self.warning_logged = False
|
|
58
|
+
self.report_hook_percent_state = None
|
|
59
|
+
self.indent_level = 1
|
|
60
|
+
# TODO add file handler in future
|
|
61
|
+
# e.g. logging.StreamHandler(None) if log_file_path is None else logging.FileHandler(name)
|
|
62
|
+
|
|
63
|
+
# ensure only one stream handler exists in one logger instance
|
|
64
|
+
if len(self.logger.handlers) == 0:
|
|
65
|
+
self.logger_stream_handler = logging.StreamHandler(sys.stdout)
|
|
66
|
+
self.logger_stream_handler.setFormatter(logging.Formatter(self.FORMAT))
|
|
67
|
+
self.logger.addHandler(self.logger_stream_handler)
|
|
68
|
+
else:
|
|
69
|
+
self.logger_stream_handler = self.logger.handlers[0]
|
|
70
|
+
|
|
71
|
+
self.logger.propagate = False
|
|
72
|
+
self.log_time()
|
|
73
|
+
|
|
74
|
+
# Other global initialization
|
|
75
|
+
silence_logger("anndata")
|
|
76
|
+
silence_logger("h5py")
|
|
77
|
+
silence_logger("numba")
|
|
78
|
+
silence_logger("pysam")
|
|
79
|
+
silence_logger("pystan")
|
|
80
|
+
|
|
81
|
+
if not (level is None):
|
|
82
|
+
self.logger.setLevel(level)
|
|
83
|
+
else:
|
|
84
|
+
self.logger.setLevel(logging.INFO)
|
|
85
|
+
|
|
86
|
+
def namespaced(self, namespace):
|
|
87
|
+
"""Function decorator to set the logging namespace for the duration of
|
|
88
|
+
the function.
|
|
89
|
+
|
|
90
|
+
:param namespace: the namespace
|
|
91
|
+
:type namespace: str
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
def wrapper(func):
|
|
95
|
+
@functools.wraps(func)
|
|
96
|
+
def inner(*args, **kwargs):
|
|
97
|
+
previous = self.namespace
|
|
98
|
+
try:
|
|
99
|
+
self.namespace = namespace
|
|
100
|
+
return func(*args, **kwargs)
|
|
101
|
+
finally:
|
|
102
|
+
self.namespace = previous
|
|
103
|
+
|
|
104
|
+
return inner
|
|
105
|
+
|
|
106
|
+
return wrapper
|
|
107
|
+
|
|
108
|
+
@contextmanager
|
|
109
|
+
def namespaced_context(self, namespace):
|
|
110
|
+
"""Context manager to set the logging namespace.
|
|
111
|
+
|
|
112
|
+
:param namespace: the namespace
|
|
113
|
+
:type namespace: str
|
|
114
|
+
"""
|
|
115
|
+
previous = self.namespace
|
|
116
|
+
self.namespace = namespace
|
|
117
|
+
yield
|
|
118
|
+
self.namespace = previous
|
|
119
|
+
|
|
120
|
+
def namespace_message(self, message):
|
|
121
|
+
"""Add namespace information at the beginning of the logging message.
|
|
122
|
+
|
|
123
|
+
:param message: the logging message
|
|
124
|
+
:type message: str
|
|
125
|
+
|
|
126
|
+
:return: namespaced message
|
|
127
|
+
:rtype: string
|
|
128
|
+
"""
|
|
129
|
+
return f"[{self.namespace}] {message}"
|
|
130
|
+
|
|
131
|
+
def setLevel(self, *args, **kwargs):
|
|
132
|
+
return self.logger.setLevel(*args, **kwargs)
|
|
133
|
+
|
|
134
|
+
def debug(self, message, indent_level=1, *args, **kwargs):
|
|
135
|
+
message = format_logging_message(
|
|
136
|
+
message, logging.DEBUG, indent_level=indent_level
|
|
137
|
+
)
|
|
138
|
+
return self.logger.debug(message, *args, **kwargs)
|
|
139
|
+
|
|
140
|
+
def info(self, message, indent_level=1, *args, **kwargs):
|
|
141
|
+
message = format_logging_message(
|
|
142
|
+
message, logging.INFO, indent_level=indent_level
|
|
143
|
+
)
|
|
144
|
+
return self.logger.info(message, *args, **kwargs)
|
|
145
|
+
|
|
146
|
+
def first_info(self, message, indent_level=1, *args, **kwargs):
|
|
147
|
+
self.start_time = time.time() # Store the start time
|
|
148
|
+
message = format_logging_message(
|
|
149
|
+
"🏗️ " + message, logging.INFO, indent_level=indent_level
|
|
150
|
+
)
|
|
151
|
+
return self.logger.info(message, *args, **kwargs)
|
|
152
|
+
|
|
153
|
+
def done(self, indent_level=1, *args, **kwargs):
|
|
154
|
+
if hasattr(self, "start_time"):
|
|
155
|
+
elapsed_time = time.time() - self.start_time
|
|
156
|
+
message = format_logging_message(
|
|
157
|
+
f"🎉 Done! [%.4fs]" % (elapsed_time),
|
|
158
|
+
logging.INFO,
|
|
159
|
+
indent_level=indent_level,
|
|
160
|
+
)
|
|
161
|
+
else:
|
|
162
|
+
message = format_logging_message(
|
|
163
|
+
"🎉 Done!", logging.INFO, indent_level=indent_level
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return self.logger.info(message, *args, **kwargs)
|
|
167
|
+
|
|
168
|
+
def warning(self, message, indent_level=1, *args, **kwargs):
|
|
169
|
+
self.warning_logged = True
|
|
170
|
+
message = format_logging_message(
|
|
171
|
+
message, logging.WARNING, indent_level=indent_level
|
|
172
|
+
)
|
|
173
|
+
return self.logger.warning(message, *args, **kwargs)
|
|
174
|
+
|
|
175
|
+
def exception(self, message, indent_level=1, *args, **kwargs):
|
|
176
|
+
message = format_logging_message(
|
|
177
|
+
message, logging.ERROR, indent_level=indent_level
|
|
178
|
+
)
|
|
179
|
+
return self.logger.exception(message, *args, **kwargs)
|
|
180
|
+
|
|
181
|
+
def critical(self, message, indent_level=1, *args, **kwargs):
|
|
182
|
+
message = format_logging_message(
|
|
183
|
+
message, logging.CRITICAL, indent_level=indent_level
|
|
184
|
+
)
|
|
185
|
+
return self.logger.critical(message, *args, **kwargs)
|
|
186
|
+
|
|
187
|
+
def error(self, message, indent_level=1, *args, **kwargs):
|
|
188
|
+
message = format_logging_message(
|
|
189
|
+
"🛑 " + message, logging.ERROR, indent_level=indent_level
|
|
190
|
+
)
|
|
191
|
+
return self.logger.error(message, *args, **kwargs)
|
|
192
|
+
|
|
193
|
+
def info_insert_adata(
|
|
194
|
+
self,
|
|
195
|
+
key,
|
|
196
|
+
adata_attr="obsm",
|
|
197
|
+
log_level=logging.NOTSET,
|
|
198
|
+
indent_level=1,
|
|
199
|
+
*args,
|
|
200
|
+
**kwargs,
|
|
201
|
+
):
|
|
202
|
+
message = "<insert> %s to %s in AnnData Object." % (key, adata_attr)
|
|
203
|
+
if log_level == logging.NOTSET or log_level == logging.DEBUG:
|
|
204
|
+
self.debug(message, indent_level=indent_level, *args, **kwargs)
|
|
205
|
+
elif log_level == logging.INFO:
|
|
206
|
+
self.info(message, indent_level=indent_level, *args, **kwargs)
|
|
207
|
+
elif log_level == logging.WARN:
|
|
208
|
+
self.warning(message, indent_level=indent_level, *args, **kwargs)
|
|
209
|
+
elif log_level == logging.ERROR:
|
|
210
|
+
self.error(message, indent_level=indent_level, *args, **kwargs)
|
|
211
|
+
elif log_level == logging.CRITICAL:
|
|
212
|
+
self.critical(message, indent_level=indent_level, *args, **kwargs)
|
|
213
|
+
else:
|
|
214
|
+
raise NotImplementedError
|
|
215
|
+
|
|
216
|
+
def info_insert_adata_var(self, key, log_level, indent_level, *args, **kwargs):
|
|
217
|
+
return self.info_insert_adata(
|
|
218
|
+
self,
|
|
219
|
+
key,
|
|
220
|
+
adata_attr="var",
|
|
221
|
+
log_level=log_level,
|
|
222
|
+
indent_level=indent_level,
|
|
223
|
+
*args,
|
|
224
|
+
**kwargs,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
def info_insert_adata_obsm(self, key, log_level, indent_level, *args, **kwargs):
|
|
228
|
+
return self.info_insert_adata(
|
|
229
|
+
self,
|
|
230
|
+
key,
|
|
231
|
+
adata_attr="obsm",
|
|
232
|
+
log_level=log_level,
|
|
233
|
+
indent_level=indent_level,
|
|
234
|
+
*args,
|
|
235
|
+
**kwargs,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
def info_insert_adata_uns(self, key, log_level, indent_level, *args, **kwargs):
|
|
239
|
+
return self.info_insert_adata(
|
|
240
|
+
self,
|
|
241
|
+
key,
|
|
242
|
+
adata_attr="uns",
|
|
243
|
+
log_level=log_level,
|
|
244
|
+
indent_level=indent_level,
|
|
245
|
+
*args,
|
|
246
|
+
**kwargs,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
def log_time(self):
|
|
250
|
+
now = time.time()
|
|
251
|
+
self.time_passed = now - self.previous_timestamp
|
|
252
|
+
self.previous_timestamp = now
|
|
253
|
+
return self.time_passed
|
|
254
|
+
|
|
255
|
+
def report_progress(
|
|
256
|
+
self, percent=None, count=None, total=None, progress_name="", indent_level=1
|
|
257
|
+
):
|
|
258
|
+
if percent is None:
|
|
259
|
+
assert (not count is None) and (not total is None)
|
|
260
|
+
percent = count / total * 100
|
|
261
|
+
saved_terminator = self.logger_stream_handler.terminator
|
|
262
|
+
if percent != 100:
|
|
263
|
+
self.logger_stream_handler.terminator = ""
|
|
264
|
+
if progress_name != "":
|
|
265
|
+
progress_name = "[" + str(progress_name) + "] "
|
|
266
|
+
message = "\r" + format_logging_message(
|
|
267
|
+
"%sin progress: %.4f%%" % (progress_name, percent),
|
|
268
|
+
logging_level=logging.INFO,
|
|
269
|
+
indent_level=indent_level,
|
|
270
|
+
)
|
|
271
|
+
self.logger.info(message)
|
|
272
|
+
self.logger_stream_handler.flush()
|
|
273
|
+
self.logger_stream_handler.terminator = saved_terminator
|
|
274
|
+
|
|
275
|
+
def start_progress(self, message, indent_level=1, *args, **kwargs):
|
|
276
|
+
self.log_time()
|
|
277
|
+
message = format_logging_message(
|
|
278
|
+
"⚙️ " + message, logging.INFO, indent_level=indent_level
|
|
279
|
+
)
|
|
280
|
+
self.logger.info(message, *args, **kwargs)
|
|
281
|
+
self.logger_stream_handler.flush()
|
|
282
|
+
|
|
283
|
+
def finish_progress(self, progress_name="", time_unit="s", indent_level=1):
|
|
284
|
+
# self.log_time()
|
|
285
|
+
# self.report_progress(percent=100, progress_name=progress_name)#
|
|
286
|
+
|
|
287
|
+
saved_terminator = self.logger_stream_handler.terminator
|
|
288
|
+
self.logger_stream_handler.terminator = ""
|
|
289
|
+
self.logger_stream_handler.flush()
|
|
290
|
+
self.logger_stream_handler.terminator = saved_terminator #
|
|
291
|
+
|
|
292
|
+
if self.warning_logged:
|
|
293
|
+
token = "⚠️"
|
|
294
|
+
else:
|
|
295
|
+
token = "✅" #
|
|
296
|
+
|
|
297
|
+
if time_unit == "s":
|
|
298
|
+
self.info(
|
|
299
|
+
token + " %s [%.4fs]" % (progress_name, self.time_passed),
|
|
300
|
+
indent_level=indent_level,
|
|
301
|
+
)
|
|
302
|
+
elif time_unit == "ms":
|
|
303
|
+
self.info(
|
|
304
|
+
token + " %s [%.4fms]" % (progress_name, self.time_passed * 1e3),
|
|
305
|
+
indent_level=indent_level,
|
|
306
|
+
)
|
|
307
|
+
else:
|
|
308
|
+
raise NotImplementedError
|
|
309
|
+
# self.logger.info("|")
|
|
310
|
+
self.logger_stream_handler.flush()
|
|
311
|
+
self.warning_logged = False #
|
|
312
|
+
|
|
313
|
+
def request_report_hook(self, bn: int, rs: int, ts: int) -> None:
|
|
314
|
+
"""A callback required by the request lib:
|
|
315
|
+
The reporthook argument should be a callable that accepts a block number, a read size, and the
|
|
316
|
+
total file size of the URL target. The data argument should be valid URL encoded data.
|
|
317
|
+
|
|
318
|
+
Parameters
|
|
319
|
+
----------
|
|
320
|
+
bs :
|
|
321
|
+
block number
|
|
322
|
+
rs :
|
|
323
|
+
read size
|
|
324
|
+
ts :
|
|
325
|
+
total size
|
|
326
|
+
"""
|
|
327
|
+
if self.report_hook_percent_state is None:
|
|
328
|
+
self.report_hook_percent_state = 0
|
|
329
|
+
|
|
330
|
+
if ts == -1:
|
|
331
|
+
return
|
|
332
|
+
|
|
333
|
+
cur_percent = rs * bn / ts
|
|
334
|
+
|
|
335
|
+
if cur_percent - self.report_hook_percent_state > 0.01:
|
|
336
|
+
self.report_progress(
|
|
337
|
+
count=rs * bn, total=ts, indent_level=self.indent_level
|
|
338
|
+
)
|
|
339
|
+
self.report_hook_percent_state = cur_percent
|
|
340
|
+
if rs * bn >= ts:
|
|
341
|
+
self.report_hook_percent_state = None
|
|
342
|
+
self.report_progress(
|
|
343
|
+
count=100, total=100, indent_level=self.indent_level
|
|
344
|
+
) # 100%
|
|
345
|
+
# self.finish_progress(progress_name="download")
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class LoggerManager:
|
|
349
|
+
DEBUG = logging.DEBUG
|
|
350
|
+
INFO = logging.INFO
|
|
351
|
+
CRITICAL = logging.CRITICAL
|
|
352
|
+
EXCEPTION = logging.ERROR
|
|
353
|
+
|
|
354
|
+
main_logger = Logger("dynamo")
|
|
355
|
+
temp_timer_logger = Logger("dynamo-temp-timer-logger")
|
|
356
|
+
|
|
357
|
+
@staticmethod
|
|
358
|
+
def get_main_logger():
|
|
359
|
+
return LoggerManager.main_logger
|
|
360
|
+
|
|
361
|
+
@staticmethod
|
|
362
|
+
def gen_logger(namespace: str):
|
|
363
|
+
return Logger(namespace)
|
|
364
|
+
|
|
365
|
+
@staticmethod
|
|
366
|
+
def get_temp_timer_logger():
|
|
367
|
+
return LoggerManager.temp_timer_logger
|
|
368
|
+
|
|
369
|
+
@staticmethod
|
|
370
|
+
def progress_logger(generator, logger=None, progress_name="", indent_level=1):
|
|
371
|
+
if logger is None:
|
|
372
|
+
logger = LoggerManager.get_temp_timer_logger()
|
|
373
|
+
iterator = iter(generator)
|
|
374
|
+
logger.log_time()
|
|
375
|
+
i = 0
|
|
376
|
+
prev_progress_percent = 0
|
|
377
|
+
while i < len(generator):
|
|
378
|
+
i += 1
|
|
379
|
+
new_progress_percent = i / len(generator) * 100
|
|
380
|
+
# report every `interval` percent
|
|
381
|
+
if (
|
|
382
|
+
new_progress_percent - prev_progress_percent > 1
|
|
383
|
+
or new_progress_percent >= 100
|
|
384
|
+
):
|
|
385
|
+
logger.report_progress(
|
|
386
|
+
count=i,
|
|
387
|
+
total=len(generator),
|
|
388
|
+
progress_name=progress_name,
|
|
389
|
+
indent_level=indent_level,
|
|
390
|
+
)
|
|
391
|
+
prev_progress_percent = new_progress_percent
|
|
392
|
+
yield next(iterator)
|
|
393
|
+
# logger.finish_progress(progress_name=progress_name, indent_level=indent_level)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def main_info(message, indent_level=1):
|
|
397
|
+
LoggerManager.main_logger.info(message, indent_level)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def main_debug(message, indent_level=1):
|
|
401
|
+
LoggerManager.main_logger.debug(message, indent_level)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
def main_warning(message, indent_level=1):
|
|
405
|
+
LoggerManager.main_logger.warning(message, indent_level)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def main_exception(message, indent_level=1):
|
|
409
|
+
LoggerManager.main_logger.exception(message, indent_level)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def main_critical(message, indent_level=1):
|
|
413
|
+
LoggerManager.main_logger.critical(message, indent_level)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def main_tqdm(generator, desc="", indent_level=1, logger=LoggerManager().main_logger):
|
|
417
|
+
"""a TQDM style wrapper for logging something like a loop.
|
|
418
|
+
e.g.
|
|
419
|
+
for item in main_tqdm(alist, desc=""):
|
|
420
|
+
do something
|
|
421
|
+
|
|
422
|
+
Parameters
|
|
423
|
+
----------
|
|
424
|
+
generator : [type]
|
|
425
|
+
same as what you put in tqdm
|
|
426
|
+
desc : str, optional
|
|
427
|
+
description of your progress
|
|
428
|
+
"""
|
|
429
|
+
return LoggerManager.progress_logger(
|
|
430
|
+
generator, logger=logger, progress_name=desc, indent_level=indent_level
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def main_log_time():
|
|
435
|
+
LoggerManager.main_logger.log_time()
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def main_silence():
|
|
439
|
+
LoggerManager.main_logger.setLevel(logging.CRITICAL + 100)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def main_finish_progress(progress_name=""):
|
|
443
|
+
LoggerManager.main_logger.finish_progress(progress_name=progress_name)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def main_info_insert_adata(key, adata_attr="obsm", indent_level=1, *args, **kwargs):
|
|
447
|
+
LoggerManager.main_logger.info_insert_adata(
|
|
448
|
+
key, adata_attr=adata_attr, indent_level=indent_level, *args, **kwargs
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def main_info_insert_adata_var(key, indent_level=1, *args, **kwargs):
|
|
453
|
+
main_info_insert_adata(key, "var", indent_level, *args, **kwargs)
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
def main_info_insert_adata_uns(key, indent_level=1, *args, **kwargs):
|
|
457
|
+
main_info_insert_adata(key, "uns", indent_level, *args, **kwargs)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def main_info_insert_adata_obsm(key, indent_level=1, *args, **kwargs):
|
|
461
|
+
main_info_insert_adata(key, "obsm", indent_level, *args, **kwargs)
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def main_info_insert_adata_obs(key, indent_level=1, *args, **kwargs):
|
|
465
|
+
main_info_insert_adata(key, "obs", indent_level, *args, **kwargs)
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
def main_info_insert_adata_layer(key, indent_level=1, *args, **kwargs):
|
|
469
|
+
main_info_insert_adata(key, "layers", indent_level, *args, **kwargs)
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
def main_info_verbose_timeit(msg):
|
|
473
|
+
LoggerManager.main_logger.info(msg)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def main_set_level(level):
|
|
477
|
+
set_logger_level("dynamo", level)
|