Skip to content

Commit a322092

Browse files
committed
add feature module functionality
1 parent c3f3f7b commit a322092

File tree

11 files changed

+3991
-676
lines changed

11 files changed

+3991
-676
lines changed

ncpi/Features.py

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,7 +2009,15 @@ def hctsa(self, samples, hctsa_folder, workers=None, return_meta=False):
20092009
pass
20102010

20112011

2012-
def compute_features(self, samples, n_jobs=None, chunksize=None, start_method="spawn"):
2012+
def compute_features(
2013+
self,
2014+
samples,
2015+
n_jobs=None,
2016+
chunksize=None,
2017+
start_method="spawn",
2018+
progress_callback=None,
2019+
log_callback=None,
2020+
):
20132021
"""
20142022
Compute features from a collection of 1D samples in parallel.
20152023
@@ -2023,6 +2031,12 @@ def compute_features(self, samples, n_jobs=None, chunksize=None, start_method="s
20232031
Chunk size for multiprocessing scheduling.
20242032
start_method : {"spawn","fork","forkserver"}
20252033
Process start method. "spawn" is most robust across platforms.
2034+
progress_callback : callable | None
2035+
Optional callback receiving progress updates as
2036+
``progress_callback(completed, total, percent)``.
2037+
If the callback only accepts one argument, ``percent`` is passed.
2038+
log_callback : callable | None
2039+
Optional callback receiving textual progress messages.
20262040
20272041
Returns
20282042
-------
@@ -2040,6 +2054,20 @@ def compute_features(self, samples, n_jobs=None, chunksize=None, start_method="s
20402054
if n == 0:
20412055
return []
20422056

2057+
if log_callback:
2058+
try:
2059+
log_callback(f"Starting feature computation ({self.method}) on {n} sample(s).")
2060+
except Exception:
2061+
pass
2062+
2063+
if progress_callback:
2064+
try:
2065+
progress_callback(0, n, 0)
2066+
except TypeError:
2067+
progress_callback(0)
2068+
except Exception:
2069+
pass
2070+
20432071
if self.method == "hctsa":
20442072
hctsa_folder = self.params.get("hctsa_folder", None)
20452073
if hctsa_folder is None:
@@ -2048,7 +2076,25 @@ def compute_features(self, samples, n_jobs=None, chunksize=None, start_method="s
20482076
"Make sure hctsa is installed and its setup instructions have been followed."
20492077
)
20502078
workers = n_jobs if n_jobs is not None else (os.cpu_count() or 1)
2051-
return self.hctsa(samples_list, hctsa_folder=hctsa_folder, workers=workers)
2079+
if log_callback:
2080+
try:
2081+
log_callback(f"Running hctsa with {workers} worker(s).")
2082+
except Exception:
2083+
pass
2084+
result = self.hctsa(samples_list, hctsa_folder=hctsa_folder, workers=workers)
2085+
if progress_callback:
2086+
try:
2087+
progress_callback(n, n, 100)
2088+
except TypeError:
2089+
progress_callback(100)
2090+
except Exception:
2091+
pass
2092+
if log_callback:
2093+
try:
2094+
log_callback("Feature computation finished.")
2095+
except Exception:
2096+
pass
2097+
return result
20522098

20532099
# Determine number of processes
20542100
if n_jobs is None:
@@ -2072,5 +2118,32 @@ def compute_features(self, samples, n_jobs=None, chunksize=None, start_method="s
20722118

20732119
if self.tqdm_inst:
20742120
it = self.tqdm(it, total=n, desc=f"Computing {self.method} features")
2075-
2076-
return list(it)
2121+
results = []
2122+
last_percent = -1
2123+
next_log_percent = 5
2124+
for completed, feature_out in enumerate(it, start=1):
2125+
results.append(feature_out)
2126+
percent = int((completed * 100) / n)
2127+
if percent != last_percent and progress_callback:
2128+
try:
2129+
progress_callback(completed, n, percent)
2130+
except TypeError:
2131+
progress_callback(percent)
2132+
except Exception:
2133+
pass
2134+
last_percent = percent
2135+
2136+
if log_callback and (percent >= next_log_percent or completed == n):
2137+
try:
2138+
log_callback(f"Feature progress: {completed}/{n} ({percent}%).")
2139+
except Exception:
2140+
pass
2141+
while next_log_percent <= percent:
2142+
next_log_percent += 5
2143+
2144+
if log_callback:
2145+
try:
2146+
log_callback("Feature computation finished.")
2147+
except Exception:
2148+
pass
2149+
return results

0 commit comments

Comments
 (0)