apscale-gui 3.2.4__tar.gz → 3.3.0__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.
- {apscale_gui-3.2.4/apscale_gui.egg-info → apscale_gui-3.3.0}/PKG-INFO +1 -1
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui/apscale_gui.py +161 -34
- {apscale_gui-3.2.4 → apscale_gui-3.3.0/apscale_gui.egg-info}/PKG-INFO +1 -1
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/setup.py +1 -1
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/LICENSE +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/MANIFEST.in +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/README.md +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui/__init__.py +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui/__main__.py +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui/_user_data/.DS_Store +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui/_user_data/user_data.txt +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui.egg-info/SOURCES.txt +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui.egg-info/dependency_links.txt +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui.egg-info/entry_points.txt +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui.egg-info/requires.txt +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/apscale_gui.egg-info/top_level.txt +0 -0
- {apscale_gui-3.2.4 → apscale_gui-3.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apscale_gui
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Summary: Advanced Pipeline for Simple yet Comprehensive AnaLysEs of DNA metabarcoding data - Graphical User Interface
|
|
5
5
|
Home-page: https://github.com/TillMacher/apscale_gui
|
|
6
6
|
Author: Till-Hendrik Macher
|
|
@@ -25,6 +25,9 @@ import importlib.metadata
|
|
|
25
25
|
import subprocess
|
|
26
26
|
import asyncio
|
|
27
27
|
import sys
|
|
28
|
+
import datetime, sys, getpass, requests_html, duckdb
|
|
29
|
+
from tqdm import tqdm
|
|
30
|
+
from stqdm import stqdm
|
|
28
31
|
|
|
29
32
|
# demultiplexer2
|
|
30
33
|
from demultiplexer2.create_primerset import create_primerset
|
|
@@ -51,9 +54,10 @@ from apscale_blast.__main__ import organism_filter as organism_filter
|
|
|
51
54
|
|
|
52
55
|
# BOLDigger3
|
|
53
56
|
from boldigger3 import id_engine
|
|
54
|
-
from boldigger3 import metadata_download
|
|
55
57
|
from boldigger3 import add_metadata
|
|
56
58
|
from boldigger3 import select_top_hit
|
|
59
|
+
from boldigger3 import download_database
|
|
60
|
+
import requests
|
|
57
61
|
|
|
58
62
|
# help texts
|
|
59
63
|
n_cores_help = """
|
|
@@ -555,7 +559,117 @@ def download_seafile_zip(public_url, output_dir="downloads"):
|
|
|
555
559
|
|
|
556
560
|
st.success(f"Finished the extraction of {len(list(output_dir.glob('*')))} databases!")
|
|
557
561
|
|
|
558
|
-
|
|
562
|
+
class DownloadProgressBar(tqdm):
|
|
563
|
+
def update_to(self, b=1, bsize=1, tsize=None):
|
|
564
|
+
if tsize is not None:
|
|
565
|
+
self.total = tsize
|
|
566
|
+
self.update(b * bsize - self.n)
|
|
567
|
+
|
|
568
|
+
def run_boldigger3_db_download(output_dir, user_name, password):
|
|
569
|
+
|
|
570
|
+
"""Download the latest BOLD public database and save it as a DuckDB file.
|
|
571
|
+
|
|
572
|
+
Logs into BOLD Systems, checks whether the local database is already up to
|
|
573
|
+
date, and if not, downloads the latest Parquet release and converts it to
|
|
574
|
+
DuckDB format.
|
|
575
|
+
|
|
576
|
+
Args:
|
|
577
|
+
output_file: Full path (including filename) for the output .ddb file.
|
|
578
|
+
user_name: BOLD Systems username.
|
|
579
|
+
password: BOLD Systems password.
|
|
580
|
+
"""
|
|
581
|
+
|
|
582
|
+
# --- Login ---
|
|
583
|
+
data = {
|
|
584
|
+
"name": user_name,
|
|
585
|
+
"password": password,
|
|
586
|
+
"destination": "MAS_Management_UserConsole",
|
|
587
|
+
"loginType": "",
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
session = requests_html.HTMLSession()
|
|
591
|
+
session.post("https://bench.boldsystems.org/index.php/Login", data=data)
|
|
592
|
+
|
|
593
|
+
r = session.get("https://bench.boldsystems.org/index.php/datapackages/Latest")
|
|
594
|
+
log_out_text = r.html.find(".site-navigation > li:nth-child(4) > a:nth-child(1)")[0].text
|
|
595
|
+
|
|
596
|
+
if log_out_text != "Log out":
|
|
597
|
+
print(f"{datetime.datetime.now():%H:%M:%S}: Login failed, please check credentials.")
|
|
598
|
+
return
|
|
599
|
+
|
|
600
|
+
st.write(f"{datetime.datetime.now():%H:%M:%S}: Login successful, checking database status.")
|
|
601
|
+
|
|
602
|
+
# --- Check DB status ---
|
|
603
|
+
r = session.get("https://bench.boldsystems.org/index.php/datapackages/Latest")
|
|
604
|
+
button = r.html.find(
|
|
605
|
+
"div.row:nth-child(5) > div:nth-child(1) > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(4) > td:nth-child(2) > button:nth-child(1)"
|
|
606
|
+
)
|
|
607
|
+
package_id = button[0].attrs["data-package-id"]
|
|
608
|
+
data_url = button[0].attrs["data-url"]
|
|
609
|
+
|
|
610
|
+
parquet_path = output_dir / f"{package_id}.parquet"
|
|
611
|
+
database_path = output_dir / f"{package_id}.duckdb"
|
|
612
|
+
|
|
613
|
+
if database_path.is_file():
|
|
614
|
+
st.info(f"{datetime.datetime.now():%H:%M:%S}: Database is up to date.")
|
|
615
|
+
return
|
|
616
|
+
|
|
617
|
+
st.write(f"{datetime.datetime.now():%H:%M:%S}: Database does not exist or is outdated.")
|
|
618
|
+
|
|
619
|
+
# --- Download and convert ---
|
|
620
|
+
uid = session.get(f"https://bench.boldsystems.org{data_url}")
|
|
621
|
+
uid = uid.text.replace('"', "")
|
|
622
|
+
download_url = f"https://bench.boldsystems.org{data_url}&uid={uid}"
|
|
623
|
+
|
|
624
|
+
st.write(f"{datetime.datetime.now():%H:%M:%S}: Downloading latest database from {download_url}.")
|
|
625
|
+
print(f"{datetime.datetime.now():%H:%M:%S}: Downloading latest database from {download_url}.")
|
|
626
|
+
st.write(f"{datetime.datetime.now():%H:%M:%S}: Storing latest database as '{parquet_path}'.")
|
|
627
|
+
print(f"{datetime.datetime.now():%H:%M:%S}: Storing latest database as '{parquet_path}'.")
|
|
628
|
+
|
|
629
|
+
progress_bar = st.progress(0.0, text="Downloading public database...")
|
|
630
|
+
status = st.empty()
|
|
631
|
+
with requests.get(download_url, stream=True) as response:
|
|
632
|
+
response.raise_for_status()
|
|
633
|
+
total_size = int(response.headers.get("content-length", 0))
|
|
634
|
+
downloaded = 0
|
|
635
|
+
with open(parquet_path, "wb") as f:
|
|
636
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
637
|
+
if chunk:
|
|
638
|
+
f.write(chunk)
|
|
639
|
+
downloaded += len(chunk)
|
|
640
|
+
if total_size > 0:
|
|
641
|
+
progress = min(downloaded / total_size, 1.0)
|
|
642
|
+
progress_bar.progress(progress)
|
|
643
|
+
status.text(f"{downloaded / 1024 ** 2:.1f} MB / {total_size / 1024 ** 2:.1f} MB")
|
|
644
|
+
progress_bar.progress(1.0)
|
|
645
|
+
status.text("Download complete.")
|
|
646
|
+
|
|
647
|
+
if database_path.is_file():
|
|
648
|
+
database_path.unlink()
|
|
649
|
+
st.write(f"{datetime.datetime.now():%H:%M:%S}: Outdated database successfully removed.")
|
|
650
|
+
|
|
651
|
+
if not parquet_path.is_file():
|
|
652
|
+
st.write(f"{datetime.datetime.now():%H:%M:%S}: Could not find '{parquet_path}'.")
|
|
653
|
+
return
|
|
654
|
+
|
|
655
|
+
st.write(f"{datetime.datetime.now():%H:%M:%S}: Building new database.")
|
|
656
|
+
|
|
657
|
+
with duckdb.connect(database_path) as con:
|
|
658
|
+
con.execute(f"""
|
|
659
|
+
CREATE TABLE bold_public
|
|
660
|
+
AS SELECT
|
|
661
|
+
processid, sex, life_stage, inst,
|
|
662
|
+
"country/ocean", identified_by,
|
|
663
|
+
identification_method, coord, nuc, marker_code
|
|
664
|
+
FROM read_parquet('{parquet_path}')
|
|
665
|
+
""")
|
|
666
|
+
|
|
667
|
+
st.success(f"{datetime.datetime.now():%H:%M:%S}: New database saved at {database_path}.")
|
|
668
|
+
|
|
669
|
+
if parquet_path.is_file():
|
|
670
|
+
parquet_path.unlink()
|
|
671
|
+
|
|
672
|
+
def run_boldigger3_identification(available_fasta_files, bold_modes, bold_databases, db_path):
|
|
559
673
|
|
|
560
674
|
st.info('Starting BOLDigger3! Please refer to the terminal for live outputs!')
|
|
561
675
|
print('')
|
|
@@ -575,22 +689,15 @@ def run_boldigger3(available_fasta_files, bold_modes, bold_databases):
|
|
|
575
689
|
thresholds.append(50)
|
|
576
690
|
|
|
577
691
|
# Collect input values
|
|
578
|
-
query_fasta = str(available_fasta_files[st.session_state['bold_query_fasta']])
|
|
692
|
+
query_fasta = Path(str(available_fasta_files[st.session_state['bold_query_fasta']]))
|
|
579
693
|
mode = bold_modes[st.session_state['bold_mode']]
|
|
580
694
|
db = bold_databases[st.session_state['bold_database']]
|
|
581
695
|
|
|
582
|
-
# download the current metadata from BOLD
|
|
583
|
-
metadata_download.main()
|
|
584
|
-
|
|
585
696
|
# run the id engine
|
|
586
|
-
id_engine.main(
|
|
587
|
-
query_fasta,
|
|
588
|
-
db,
|
|
589
|
-
mode,
|
|
590
|
-
)
|
|
697
|
+
id_engine.main(query_fasta, db, mode)
|
|
591
698
|
|
|
592
699
|
# add additional data via the metadata
|
|
593
|
-
add_metadata.main(query_fasta)
|
|
700
|
+
add_metadata.main(query_fasta, db_path)
|
|
594
701
|
|
|
595
702
|
# select the top hit
|
|
596
703
|
select_top_hit.main(query_fasta, thresholds)
|
|
@@ -680,7 +787,7 @@ def main():
|
|
|
680
787
|
if f.is_dir() and "_apscale" in f.name
|
|
681
788
|
]
|
|
682
789
|
|
|
683
|
-
if st.button(label='Remember project folder', key='remember_project_folder',use_container_width=True):
|
|
790
|
+
if st.button(label='Remember project folder', key='remember_project_folder', use_container_width=True):
|
|
684
791
|
script_path = Path(__file__).resolve()
|
|
685
792
|
user_data_txt = script_path.parent / '_user_data' / 'user_data.txt'
|
|
686
793
|
user_data_txt.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -991,7 +1098,6 @@ def main():
|
|
|
991
1098
|
update_settings_file(settings_xlsx, settings_dfs)
|
|
992
1099
|
run_apscale(st.session_state['run_apscale_mode'], project_folder, modules_to_run)
|
|
993
1100
|
|
|
994
|
-
|
|
995
1101
|
############################################################################################################
|
|
996
1102
|
st.markdown("---")
|
|
997
1103
|
st.header("APSCALE BLAST")
|
|
@@ -1037,25 +1143,33 @@ def main():
|
|
|
1037
1143
|
st.header("BOLDigger3")
|
|
1038
1144
|
st.subheader('Settings')
|
|
1039
1145
|
# General settings
|
|
1146
|
+
available_databases = {Path(i).name:Path(i) for i in glob.glob(str(path_to_projects / 'APSCALE_databases' / '*.duckdb'))}
|
|
1040
1147
|
with st.expander("🗄️ Database & Operating Mode", expanded=False):
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1148
|
+
col1, col2, col3 = st.columns(3)
|
|
1149
|
+
with col1:
|
|
1150
|
+
boldigger_db_file = st.selectbox(label='Local BOLD database file', key='boldigger_db_file', options=list(available_databases.keys()))
|
|
1151
|
+
st.selectbox(label='Query FASTA', key='bold_query_fasta', options=list(available_fasta_files.keys()))
|
|
1152
|
+
with col2:
|
|
1153
|
+
bold_modes = {
|
|
1154
|
+
'Rapid Species Search': 1,
|
|
1155
|
+
'Genus and Species Search': 2,
|
|
1156
|
+
'Exhaustive Search': 3
|
|
1157
|
+
}
|
|
1158
|
+
st.selectbox(label='Operating mode', key='bold_mode', options=list(bold_modes.keys()))
|
|
1159
|
+
bold_databases = {
|
|
1160
|
+
'ANIMAL LIBRARY (PUBLIC)': 1,
|
|
1161
|
+
'ANIMAL SPECIES-LEVEL LIBRARY (PUBLIC + PRIVATE)': 2,
|
|
1162
|
+
'ANIMAL LIBRARY (PUBLIC+PRIVATE)': 3,
|
|
1163
|
+
'VALIDATED CANADIAN ARTHROPOD LIBRARY': 4,
|
|
1164
|
+
'PLANT LIBRARY (PUBLIC)': 5,
|
|
1165
|
+
'FUNGI LIBRARY (PUBLIC)': 6,
|
|
1166
|
+
'ANIMAL SECONDARY MARKERS (PUBLIC)': 7,
|
|
1167
|
+
'VALIDATED ANIMAL RED LIST LIBRARY': 8
|
|
1168
|
+
}
|
|
1169
|
+
st.selectbox(label='BOLD database', key='bold_database', options=list(bold_databases.keys()))
|
|
1170
|
+
with col3:
|
|
1171
|
+
st.text_input("Enter BOLD user name", key="bold_user")
|
|
1172
|
+
st.text_input("Enter BOLD password", type="password", key="bold_password")
|
|
1059
1173
|
# Thresholds
|
|
1060
1174
|
with st.expander("⚖️ Thresholds", expanded=False):
|
|
1061
1175
|
col1, col2 = st.columns(2)
|
|
@@ -1068,8 +1182,21 @@ def main():
|
|
|
1068
1182
|
st.text_input(label='Order (%)', key='bold_order', value=85)
|
|
1069
1183
|
|
|
1070
1184
|
st.subheader('Run BOLDigger3')
|
|
1071
|
-
if st.
|
|
1072
|
-
|
|
1185
|
+
if not st.session_state['boldigger_db_file']:
|
|
1186
|
+
st.info('No local BOLD database file found: Latest Database file will be downloaded.')
|
|
1187
|
+
|
|
1188
|
+
if st.button(f'Download latest BOLD database', use_container_width=True):
|
|
1189
|
+
if st.session_state['bold_user'] and st.session_state['bold_password']:
|
|
1190
|
+
bold_download_folder = path_to_projects / 'APSCALE_databases'
|
|
1191
|
+
run_boldigger3_db_download(bold_download_folder, st.session_state['bold_user'], st.session_state['bold_password'])
|
|
1192
|
+
else:
|
|
1193
|
+
st.error('Please provide a BOLD user name and password.')
|
|
1194
|
+
if st.session_state['boldigger_db_file']:
|
|
1195
|
+
if st.button(f'Start taxonomic assignment against BOLD', use_container_width=True):
|
|
1196
|
+
db_path = available_databases[st.session_state['boldigger_db_file']]
|
|
1197
|
+
run_boldigger3_identification(available_fasta_files, bold_modes, bold_databases, db_path)
|
|
1198
|
+
else:
|
|
1199
|
+
st.info('Please download the latest BOLD database first.')
|
|
1073
1200
|
|
|
1074
1201
|
############################################################################################################
|
|
1075
1202
|
st.markdown("---")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apscale_gui
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Summary: Advanced Pipeline for Simple yet Comprehensive AnaLysEs of DNA metabarcoding data - Graphical User Interface
|
|
5
5
|
Home-page: https://github.com/TillMacher/apscale_gui
|
|
6
6
|
Author: Till-Hendrik Macher
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
|
5
5
|
|
|
6
6
|
setuptools.setup(
|
|
7
7
|
name="apscale_gui",
|
|
8
|
-
version="3.
|
|
8
|
+
version="3.3.0",
|
|
9
9
|
author="Till-Hendrik Macher",
|
|
10
10
|
author_email="macher@uni-trier.de",
|
|
11
11
|
description="Advanced Pipeline for Simple yet Comprehensive AnaLysEs of DNA metabarcoding data - Graphical User Interface",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|