bscampp 1.0.6__py3-none-any.whl → 1.0.8__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.
- bscampp/__init__.py +1 -1
- bscampp/configs.py +24 -3
- bscampp/functions.py +43 -12
- bscampp/init_configs.py +0 -5
- bscampp/pipeline.py +0 -2
- {bscampp-1.0.6.dist-info → bscampp-1.0.8.dist-info}/METADATA +10 -6
- {bscampp-1.0.6.dist-info → bscampp-1.0.8.dist-info}/RECORD +11 -11
- {bscampp-1.0.6.dist-info → bscampp-1.0.8.dist-info}/WHEEL +1 -1
- {bscampp-1.0.6.dist-info → bscampp-1.0.8.dist-info}/entry_points.txt +0 -0
- {bscampp-1.0.6.dist-info → bscampp-1.0.8.dist-info/licenses}/LICENSE +0 -0
- {bscampp-1.0.6.dist-info → bscampp-1.0.8.dist-info}/top_level.txt +0 -0
bscampp/__init__.py
CHANGED
bscampp/configs.py
CHANGED
@@ -4,6 +4,8 @@ try:
|
|
4
4
|
except ImportError:
|
5
5
|
from ConfigParser import configparser
|
6
6
|
from argparse import ArgumentParser, Namespace
|
7
|
+
import subprocess
|
8
|
+
|
7
9
|
from bscampp.init_configs import init_config_file
|
8
10
|
from bscampp import get_logger, log_exception
|
9
11
|
#from bscampp.utils import inferDataType
|
@@ -22,7 +24,6 @@ _LOG = get_logger(__name__)
|
|
22
24
|
Configuration defined by users and by default values
|
23
25
|
'''
|
24
26
|
class Configs:
|
25
|
-
global _root_dir
|
26
27
|
|
27
28
|
# basic input paths
|
28
29
|
info_path = None # info file for pplacer or EPA-ng
|
@@ -117,6 +118,24 @@ def _read_config_file(filename, cparser, opts,
|
|
117
118
|
setattr(opts, section, section_name_space)
|
118
119
|
return config_defaults
|
119
120
|
|
121
|
+
# validate a given binary file is executable
|
122
|
+
def validate_binary_executable(name, path):
|
123
|
+
# 1. make sure path exists
|
124
|
+
if not os.path.exists(path):
|
125
|
+
raise FileNotFoundError(f"{path} is not found!")
|
126
|
+
|
127
|
+
# 2. make sure path is executable with no IO error
|
128
|
+
try:
|
129
|
+
p = subprocess.Popen([path], text=True, stdout=subprocess.PIPE,
|
130
|
+
stderr=subprocess.PIPE)
|
131
|
+
_, __ = p.communicate()
|
132
|
+
except OSError:
|
133
|
+
raise AssertionError(' '.join([
|
134
|
+
f"{path} is not executable! Please do the followings:",
|
135
|
+
f"\n\n\t1. obtain a working executable for the software: {name}",
|
136
|
+
f"\n\t2. modify {main_config_path} to replace the old executable path\n",
|
137
|
+
]))
|
138
|
+
|
120
139
|
'''
|
121
140
|
Build Config class
|
122
141
|
'''
|
@@ -170,6 +189,8 @@ def buildConfigs(parser, cmdline_args, child_process=False, rerun=False):
|
|
170
189
|
|
171
190
|
# sanity check for existence of base placement binary path
|
172
191
|
if Configs.placement_method == 'epa-ng':
|
173
|
-
|
192
|
+
validate_binary_executable(Configs.placement_method, Configs.epang_path)
|
193
|
+
#assert os.path.exists(Configs.epang_path), 'epa-ng not detected!'
|
174
194
|
elif Configs.placement_method == 'pplacer':
|
175
|
-
|
195
|
+
validate_binary_executable(Configs.placement_method, Configs.pplacer_path)
|
196
|
+
#assert os.path.exists(Configs.pplacer_path), 'pplacer not detected!'
|
bscampp/functions.py
CHANGED
@@ -11,6 +11,10 @@ import bscampp.utils as utils
|
|
11
11
|
|
12
12
|
import concurrent.futures
|
13
13
|
|
14
|
+
# suppress userwarning when doing subtree suppress_unifurcations
|
15
|
+
import warnings
|
16
|
+
warnings.filterwarnings("ignore", category=UserWarning)
|
17
|
+
|
14
18
|
_LOG = get_logger(__name__)
|
15
19
|
|
16
20
|
############################# helper functions ################################
|
@@ -29,6 +33,8 @@ def recompileBinariesFromDir(dir):
|
|
29
33
|
|
30
34
|
if cmake_p.returncode != 0:
|
31
35
|
_LOG.error("cmake failed!")
|
36
|
+
print("STDOUT:", cmake_stdout)
|
37
|
+
print("STDERR:", cmake_stderr)
|
32
38
|
exit(cmake_p.returncode)
|
33
39
|
else:
|
34
40
|
_LOG.warning("cmake succeeded!")
|
@@ -59,14 +65,26 @@ def ensureBinaryExecutable(binpath):
|
|
59
65
|
_LOG.warning(f"{binpath} does not exist!")
|
60
66
|
b_recompile = True
|
61
67
|
else:
|
62
|
-
|
63
|
-
|
64
|
-
|
68
|
+
"""
|
69
|
+
added @ 6.13.2025 by Chengze Shen
|
70
|
+
- try-catch OSError to indicate that the binary files
|
71
|
+
- are not executable on the current sytem and need to be
|
72
|
+
- recompiled
|
73
|
+
"""
|
74
|
+
try:
|
75
|
+
p = subprocess.Popen([binpath], stdout=subprocess.PIPE,
|
76
|
+
stderr=subprocess.PIPE)
|
77
|
+
stdout, stderr = p.communicate()
|
78
|
+
returncode = p.returncode
|
79
|
+
except OSError as e:
|
80
|
+
# indicating we need to recompile: anything other than 255 or -1
|
81
|
+
returncode = 7
|
82
|
+
|
65
83
|
# 255 or -1 indicates that the binaries work
|
66
|
-
if
|
84
|
+
if returncode == 255 or returncode == -1:
|
67
85
|
pass
|
68
86
|
else:
|
69
|
-
_LOG.warning(f"{binpath} return code is {
|
87
|
+
_LOG.warning(f"{binpath} return code is {returncode}!")
|
70
88
|
b_recompile = True
|
71
89
|
|
72
90
|
if b_recompile:
|
@@ -405,7 +423,8 @@ def placeQueriesToSubtrees(tree, leaf_dict, new_subtree_dict, placed_query_list,
|
|
405
423
|
aln, qaln, cmdline_args, workdir, qname_map, qname_map_rev,
|
406
424
|
pool, lock, dry_run=False):
|
407
425
|
t0 = time.perf_counter()
|
408
|
-
_LOG.info(
|
426
|
+
_LOG.info("Performing placement on each subtree with {}...".format(
|
427
|
+
Configs.placement_method))
|
409
428
|
|
410
429
|
if dry_run:
|
411
430
|
return dict()
|
@@ -461,7 +480,7 @@ def placeQueriesToSubtrees(tree, leaf_dict, new_subtree_dict, placed_query_list,
|
|
461
480
|
job = EPAngJob(path=Configs.epang_path,
|
462
481
|
info_path=Configs.info_path, tree_path=tmp_tree,
|
463
482
|
aln_path=tmp_aln, qaln_path=tmp_qaln,
|
464
|
-
outdir=subtree_dir, num_cpus=Configs.
|
483
|
+
outdir=subtree_dir, num_cpus=Configs.cpus_per_job)
|
465
484
|
jobs.append(job)
|
466
485
|
## for EPA-ng, ensure that outpath name is changed to the one we want
|
467
486
|
#_outpath = job.run(logging=f'subtree_{final_subtree_count}')
|
@@ -481,7 +500,7 @@ def placeQueriesToSubtrees(tree, leaf_dict, new_subtree_dict, placed_query_list,
|
|
481
500
|
job = PplacerTaxtasticJob(path=Configs.pplacer_path,
|
482
501
|
refpkg_dir=refpkg_dir,
|
483
502
|
#molecule=Configs.molecule, model=Configs.model,
|
484
|
-
outpath=tmp_output, num_cpus=Configs.
|
503
|
+
outpath=tmp_output, num_cpus=Configs.cpus_per_job,
|
485
504
|
qaln_path=tmp_qaln)
|
486
505
|
#tmp_output = job.run(logging=f'subtree_{final_subtree_count}')
|
487
506
|
jobs.append(job)
|
@@ -520,10 +539,22 @@ def placeQueriesToSubtrees(tree, leaf_dict, new_subtree_dict, placed_query_list,
|
|
520
539
|
field_to_idx = {field: i for i, field in enumerate(fields)}
|
521
540
|
|
522
541
|
for tmp_place in place_json["placements"]:
|
523
|
-
#
|
524
|
-
|
525
|
-
|
526
|
-
|
542
|
+
# Fixed @ 7.7.2025 - Chengze Shen
|
543
|
+
# - pplacer actually can report multiple items
|
544
|
+
# - in the ["nm"] field.
|
545
|
+
for _idx in range(len(tmp_place[tgt])):
|
546
|
+
# convert qname back using qname_map_rev
|
547
|
+
tmp_name = tmp_place[tgt][_idx]
|
548
|
+
|
549
|
+
# >EPA-ng: tgt=="n" --> qname is string
|
550
|
+
if isinstance(tmp_name, str):
|
551
|
+
qname = qname_map_rev[tmp_name]
|
552
|
+
tmp_place[tgt][_idx] = qname
|
553
|
+
# >pplacer: tgt=="nm" --> qname is a list of two fields
|
554
|
+
elif isinstance(tmp_name, list):
|
555
|
+
qname = qname_map_rev[tmp_name[0]]
|
556
|
+
tmp_place[tgt][_idx][0] = qname
|
557
|
+
placed_query_list.append(qname)
|
527
558
|
|
528
559
|
#placed_query_list.append(tmp_place[tgt][0])
|
529
560
|
for i in range(len(tmp_place["p"])):
|
bscampp/init_configs.py
CHANGED
@@ -71,11 +71,6 @@ def init_config_file(homepath, rerun=False, prioritize_user_software=True):
|
|
71
71
|
cparser.set('basic', 'hamming_distance_dir',
|
72
72
|
os.path.join(tools_dir, 'hamming_distance'))
|
73
73
|
|
74
|
-
# macOS TODO: need to recompile the binaries
|
75
|
-
if 'macos' in platform_name.lower():
|
76
|
-
cparser.set('basic', 'hamming_distance_dir',
|
77
|
-
os.path.join(tools_dir, 'macOS', 'hamming_distance'))
|
78
|
-
|
79
74
|
# prioritize user's software
|
80
75
|
if prioritize_user_software:
|
81
76
|
print('Detecting existing software from user\'s environment...')
|
bscampp/pipeline.py
CHANGED
@@ -180,8 +180,6 @@ def clean_temp_files():
|
|
180
180
|
_LOG.info(f'- Removed {temp}')
|
181
181
|
|
182
182
|
def parseArguments(dry_run=False, method="BSCAMPP"):
|
183
|
-
global _root_dir, main_config_path
|
184
|
-
|
185
183
|
default_outdir = f"{method.lower()}_output"
|
186
184
|
default_outname = f"{method.lower()}_result"
|
187
185
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: bscampp
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.8
|
4
4
|
Summary: BSCAMPP and SCAMPP - Scalable Phylogenetic Placement Tools
|
5
5
|
Author-email: Eleanor Wedell <ewedell2@illinois.edu>, Chengze Shen <chengze5@illinois.edu>
|
6
6
|
License: MIT License
|
@@ -49,12 +49,13 @@ Requires-Dist: ConfigParser>=5.0.0
|
|
49
49
|
Requires-Dist: numpy>=1.21.6
|
50
50
|
Requires-Dist: treeswift>=1.1.45
|
51
51
|
Requires-Dist: taxtastic>=0.9.3
|
52
|
+
Dynamic: license-file
|
52
53
|
|
53
54
|
# BSCAMPP and SCAMPP - Two Scalable Phylogenetic Placement Methods and Frameworks
|
55
|
+
[](https://pypi.org/project/bscampp/#history)
|
54
56
|
[](https://pypi.org/project/bscampp/)
|
55
|
-
[](https://pypi.org/project/bscampp/#history)
|
56
57
|
[](https://github.com/ewedell/BSCAMPP/)
|
57
|
-
[](https://github.com/ewedell/BSCAMPP/blob/main/LICENSE)
|
58
59
|
[](https://github.com/ewedell/BSCAMPP/blob/main/CHANGELOG.md)
|
59
60
|
|
60
61
|
**Table of Contents**
|
@@ -105,8 +106,11 @@ please contact Eleanor Wedell (ewedell2@illinois.edu).
|
|
105
106
|
EPA-ng and/or pplacer are requirements since BSCAMPP and SCAMPP will use them as the base phylogenetic placement methods.
|
106
107
|
By default, the software will search for binary executables of `pplacer` and `epa-ng` in the user's environment when running for the first time.
|
107
108
|
We also included a compiled version of `pplacer` for the Linux system under `bscampp/tools`.
|
108
|
-
* **
|
109
|
-
|
109
|
+
* **(macOS) EPA-ng and pplacer**:
|
110
|
+
For macOS systems, you need to have `EPA-ng` and/or `pplacer` installed in your environment.
|
111
|
+
* **cmake and C++ OpenMP**:
|
112
|
+
We also use C++ with OpenMP to speed up the similarity comparison between sequences, which is required to run the pre-compiled binaries.
|
113
|
+
In the case of macOS systems, the software will automatically recompile the binaries using `cmake`, which is required to be installed.
|
110
114
|
|
111
115
|
### (1) Install with `pip`
|
112
116
|
The easiest way to install BSCAMPP and SCAMPP is to use `pip install`. This will also install all required Python packages.
|
@@ -1,10 +1,10 @@
|
|
1
|
-
bscampp/__init__.py,sha256=
|
2
|
-
bscampp/configs.py,sha256=
|
1
|
+
bscampp/__init__.py,sha256=IB6IZQO2RRGF0EOTQ5wL5zzwFXACvuINO9gD3KV4klA,2289
|
2
|
+
bscampp/configs.py,sha256=z40mkOwYTeqNjpcEDtyA4G3LskN86sZWc4Vdk46OywA,7014
|
3
3
|
bscampp/default.config,sha256=CEfsUHBy--vwJhEcUuJ0btfuGQWb_lKMVWUIP9f5YGw,112
|
4
|
-
bscampp/functions.py,sha256=
|
5
|
-
bscampp/init_configs.py,sha256=
|
4
|
+
bscampp/functions.py,sha256=f5YY9LaIW3LieFvlWvcUlWysEuqVuwJXTmOq5laFxJE,23782
|
5
|
+
bscampp/init_configs.py,sha256=hDCH2oatgli2wSmi-uDM96TSiBvLKTAhobBSSKfjl2g,3381
|
6
6
|
bscampp/jobs.py,sha256=v7buZJs1AnNoXiILwu-W8fo3QjxAh3i9Mp7xfmlJvAY,7569
|
7
|
-
bscampp/pipeline.py,sha256=
|
7
|
+
bscampp/pipeline.py,sha256=J-RQH54R27m6fhzIpGX0MJuE3ZFk5rcnsROpwC_n5CE,13960
|
8
8
|
bscampp/utils.py,sha256=-wns6FaWMKD2wVqjxdBQvjTdagTjywBIaGfqb2mupe4,30039
|
9
9
|
bscampp/tools/epa-ng,sha256=f3EVoZAAOXLN6l521qp-TrWDl5J2nqL3tGgjPaQE9WQ,3772096
|
10
10
|
bscampp/tools/pplacer,sha256=p0H4eo9uuiYoWS_kJbPfauOV99i7BXJdZSiwXIuLxTw,7834576
|
@@ -17,9 +17,9 @@ bscampp/tools/hamming_distance/src/fragment_tree_hamming.cpp,sha256=xCmyAT-OZJOD
|
|
17
17
|
bscampp/tools/hamming_distance/src/fragment_tree_hamming_new.cpp,sha256=eKxgODRlpf0hU84QjNhigvRhWCT9tiJZjA5oQFQ1bUk,7404
|
18
18
|
bscampp/tools/hamming_distance/src/homology.cpp,sha256=ZE0uXZWQ-cN4U1Wk5kUr_KKHgzsgA6Sno-IViRa4tmI,6053
|
19
19
|
bscampp/tools/hamming_distance/src/new_hamming.cpp,sha256=fBRm99RquBZgZjaLOn9xDI3cH9NchhrxKbL-11j8fmk,5342
|
20
|
-
bscampp-1.0.
|
21
|
-
bscampp-1.0.
|
22
|
-
bscampp-1.0.
|
23
|
-
bscampp-1.0.
|
24
|
-
bscampp-1.0.
|
25
|
-
bscampp-1.0.
|
20
|
+
bscampp-1.0.8.dist-info/licenses/LICENSE,sha256=HEa4YQdOR0e2Gz-NiOwr9X6aJcZtY0AGmlJQDmfN0Iw,1064
|
21
|
+
bscampp-1.0.8.dist-info/METADATA,sha256=2w_otUXBGIuvf6nXV-7hY958cxllhTZd6T18rB5nR8Q,12877
|
22
|
+
bscampp-1.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
23
|
+
bscampp-1.0.8.dist-info/entry_points.txt,sha256=4Ft83qHc39tNNpMLgSgFXDHM-vuAB99JtmczCQj5pq8,204
|
24
|
+
bscampp-1.0.8.dist-info/top_level.txt,sha256=1loGRUAft6Tcdq0f3lHbVwWN7W_SW1srfhAVSpg9DWE,8
|
25
|
+
bscampp-1.0.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|