Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,31 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.3.1] - 2026-02-26 : https://github.com/BU-ISCIII/buisciii-tools/releases/tag/2.3.1

### Credits

- [Pau Pascual](https://github.com/PauPascualMas)
- [Victor Lopez](https://github.com/victor5lm)

### Template fixes and updates

- Modified `create_assembly_stats.R` to group by sample in viralrecon template [#631](https://github.com/BU-ISCIII/buisciii-tools/pull/631).
- Fixed error handling in finish module and automatic logging for new_service [#632](https://github.com/BU-ISCIII/buisciii-tools/pull/632).
- Solved symlink path for TBProfiler results lablog [#634](https://github.com/BU-ISCIII/buisciii-tools/pull/634)


### Modules

#### Added enhancements

#### Fixes

#### Changed

#### Removed

### Requirements

## [2.3.0] - 2025-02-09 : https://github.com/BU-ISCIII/buisciii-tools/releases/tag/2.3.0

Expand Down
162 changes: 89 additions & 73 deletions buisciii/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def run_buisciii():
highlight=False,
)

__version__ = "2.3.0"
__version__ = "2.3.1"
stderr.print(
"[grey39] BUISCIII-tools version {}".format(__version__), highlight=False
)
Expand Down Expand Up @@ -140,7 +140,9 @@ def setup_automatic_logging(service_path, resolution_id, command_name, conf):
try:
# Path verification
if command_name == "new_service" and not os.path.exists(service_path):
stderr.print(f"[red]Service path does not exist: {service_path}!")
stderr.print(
f"[red]Service path does not exist: {service_path}! Please check the service folder was created correctly."
)
sys.exit(1)

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
Expand Down Expand Up @@ -628,80 +630,94 @@ def finish(ctx, resolution, path, ask_path, sftp_folder, tmp_dir):
if resolution is None:
resolution = buisciii.utils.prompt_resolution_id()

clean_tmp_dir = tmp_dir
if tmp_dir == "/scratch/bi/":
clean_tmp_dir = "/data/ucct/bi/scratch_tmp/bi"
debug = ctx.obj.get("debug", False)
try:
clean_tmp_dir = tmp_dir
if tmp_dir == "/scratch/bi/":
clean_tmp_dir = "/data/ucct/bi/scratch_tmp/bi"

conf = buisciii.config_json.ConfigJson()
conf_api = conf.get_configuration("xtutatis_api_settings")
rest_api = buisciii.drylab_api.RestServiceApi(
conf_api["server"],
conf_api["api_url"],
ctx.obj["api_user"],
ctx.obj["api_password"],
)
resolution_info = rest_api.get_request(
request_info="service-data", safe=True, resolution=resolution
)
service_folder = resolution_info["resolutions"][0]["resolution_full_number"]
service_path = os.path.join(
buisciii.utils.get_service_paths(
conf, "services_and_colaborations", resolution_info, "non_archived_path"
),
service_folder,
)
conf = buisciii.config_json.ConfigJson()
conf_api = conf.get_configuration("xtutatis_api_settings")
rest_api = buisciii.drylab_api.RestServiceApi(
conf_api["server"],
conf_api["api_url"],
ctx.obj["api_user"],
ctx.obj["api_password"],
)
resolution_info = rest_api.get_request(
request_info="service-data", safe=True, resolution=resolution
)
service_folder = resolution_info["resolutions"][0]["resolution_full_number"]
service_path = os.path.join(
buisciii.utils.get_service_paths(
conf, "services_and_colaborations", resolution_info, "non_archived_path"
),
service_folder,
)

if not ctx.obj.get("manual_log_file"):
setup_automatic_logging(service_path, resolution, "finish", ctx.obj["conf"])

print("Starting cleaning scratch directory: " + clean_tmp_dir)
clean_scratch = buisciii.clean.CleanUp(
resolution,
clean_tmp_dir,
ask_path,
"clean",
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
clean_scratch.handle_clean()
print("Starting copy from scratch directory: " + tmp_dir + " to service directory.")
copy_scratch2service = buisciii.scratch.Scratch(
resolution,
path,
tmp_dir,
"scratch_to_service",
ask_path,
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
copy_scratch2service.handle_scratch()
print("Starting renaming of the service directory.")
rename_databi = buisciii.clean.CleanUp(
resolution,
path,
ask_path,
"rename",
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
rename_databi.handle_clean()
print("Starting copy of the service directory to the SFTP folder")
copy_sftp = buisciii.copy_sftp.CopySftp(
resolution,
path,
ask_path,
sftp_folder,
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
copy_sftp.copy_sftp()
if not ctx.obj.get("manual_log_file"):
setup_automatic_logging(service_path, resolution, "finish", ctx.obj["conf"])

print("Starting cleaning scratch directory: " + clean_tmp_dir)
clean_scratch = buisciii.clean.CleanUp(
resolution,
clean_tmp_dir,
ask_path,
"clean",
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
clean_scratch.handle_clean()
print(
"Starting copy from scratch directory: "
+ tmp_dir
+ " to service directory."
)
copy_scratch2service = buisciii.scratch.Scratch(
resolution,
path,
tmp_dir,
"scratch_to_service",
ask_path,
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
copy_scratch2service.handle_scratch()
print("Starting renaming of the service directory.")
rename_databi = buisciii.clean.CleanUp(
resolution,
path,
ask_path,
"rename",
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
rename_databi.handle_clean()
print("Starting copy of the service directory to the SFTP folder")
copy_sftp = buisciii.copy_sftp.CopySftp(
resolution,
path,
ask_path,
sftp_folder,
ctx.obj["api_user"],
ctx.obj["api_password"],
ctx.obj["conf"],
)
copy_sftp.copy_sftp()

print("Service correctly stored in the SFTP folder")
print("Remember to generate delivery docs after setting delivery in iSkyLIMS!")
print("Service correctly stored in the SFTP folder")
print("Remember to generate delivery docs after setting delivery in iSkyLIMS!")
except Exception as e:
if debug:
log.exception(f"EXCEPTION FOUND: {e}")
raise
else:
log.exception(f"EXCEPTION FOUND: {e}")
stderr.print(f"EXCEPTION FOUND: {e}")
sys.exit(1)


# CREATE DOCS IN BIOINFO_DOC
Expand Down
4 changes: 2 additions & 2 deletions buisciii/new_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,10 @@ def create_new_service(self):
Run the whole service creation workflow.
"""
if len(self.service_samples) > 0:
if self.setup_logging_cb is not None:
self.setup_logging_cb(self.full_path)
self.check_md5()
self.create_folder()
if self.setup_logging_cb is not None:
self.setup_logging_cb(self.full_path)
self.copy_template()
self.create_samples_id()
self.create_symbolic_links()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ mkdir -p $DELIVERY_FOLDER/tbprofiler

cd $DELIVERY_FOLDER/tbprofiler

ln -s ../../../ANALYSIS/*TBPROFILER/results/tbprofiler.* .
ln -s ../../../ANALYSIS/*TBPROFILER/tbprofiler.* .
26 changes: 24 additions & 2 deletions buisciii/templates/viralrecon/ANALYSIS/create_assembly_stats.R
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,30 @@ df_final[, columnas_ch] <- apply(df_final[, columnas_ch], 2, function(x) as.char
columnas_nu <- as.vector(6:length(colnames(df_final)))
df_final[, columnas_nu] <- apply(df_final[, columnas_nu], 2, function(x) as.numeric(as.character(x)))

# group by sample
df_grouped <- df_final %>%
group_by(sample) %>%
summarise(
run = first(run),
user = first(user),
host = first(host),

Virussequence = paste(unique(Virussequence), collapse = ","),

totalreads = first(totalreads),
readshostR1 = first(readshostR1),
readshost = first(readshost),
`%readshost` = first(`%readshost`),
`Non-host-reads` = first(`Non-host-reads`),
`%Non-host-reads` = first(`%Non-host-reads`),
Contigs = if (all(is.na(Contigs))) NA else max(Contigs, na.rm = TRUE),
Largest_contig = if (all(is.na(Largest_contig))) NA else max(Largest_contig, na.rm = TRUE),
`%Genome_fraction` = if (all(is.na(`%Genome_fraction`))) NA else max(`%Genome_fraction`, na.rm = TRUE),
.groups = "drop"
)

# Write table csv
write.table(df_final, "assembly_stats.csv", row.names = F, col.names = T, sep = "\t", quote = F)
write.table(df_grouped, "assembly_stats.csv", row.names = F, col.names = T, sep = "\t", quote = F)

# Write table xlsx
write_xlsx(df_final, "assembly_stats.xlsx", format_headers = F)
write_xlsx(df_grouped, "assembly_stats.xlsx", format_headers = F)
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "buisciii-tools"
version = "2.3.0"
version = "2.3.1"
dynamic = ["dependencies"]

authors = [
Expand All @@ -22,7 +22,8 @@ authors = [
{name = "Alejandro Bernabeu", email = "abernabeu@isciii.es"},
{name = "Alba Talavera", email = "alba.talavera@externos.isciii.es"},
{name = "Magdalena Matito", email = "mmatito@externos.isciii.es"},
{name = "Pau Pascual", email = "ppascual@externos.isciii.es"}
{name = "Pau Pascual", email = "ppascual@externos.isciii.es"},
{name = "Enrique Sapena Ventura", email = "enrique.sapena@isciii.es"}
]

maintainers = [
Expand All @@ -40,7 +41,8 @@ maintainers = [
{name = "Alejandro Bernabeu", email = "abernabeu@isciii.es"},
{name = "Alba Talavera", email = "alba.talavera@externos.isciii.es"},
{name = "Magdalena Matito", email = "mmatito@externos.isciii.es"},
{name = "Pau Pascual", email = "ppascual@externos.isciii.es"}
{name = "Pau Pascual", email = "ppascual@externos.isciii.es"},
{name = "Enrique Sapena Ventura", email = "enrique.sapena@isciii.es"}
]

description = "Tools for managing and resolution of buisciii services."
Expand Down