Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
50e44d7
fgumi module added
jfallmann Apr 22, 2026
4104964
fgumi module update
jfallmann Apr 22, 2026
38213d0
tests and documentation
jfallmann Apr 23, 2026
71297db
gracefully exit if no samples found
jfallmann Apr 23, 2026
888d4d8
docs update
jfallmann Apr 23, 2026
1d43280
fgumi zipper fix
jfallmann Apr 23, 2026
900fdb6
fgumi ref dict if not availbale
jfallmann Apr 23, 2026
84ec08f
sorting by name before fgumi zipper
jfallmann Apr 23, 2026
c1c0cc5
sorting before index
jfallmann Apr 23, 2026
b07955b
fgumi update
jfallmann Apr 24, 2026
0d8460f
fgumi update
jfallmann Apr 24, 2026
ffb8e3d
fgumi nf split/update
jfallmann Apr 24, 2026
cbc335f
counttable verbosity fix
jfallmann Apr 24, 2026
2e13a34
docs fix
jfallmann Apr 27, 2026
6a0d2aa
counttable build from nf dedup fix
jfallmann Apr 27, 2026
6ad833b
fix in output path generation, we never split QC
jfallmann Apr 27, 2026
1a2bc9f
split in pre and postqc workflows
jfallmann Apr 27, 2026
4e2e208
merge QC into one stage
jfallmann Apr 27, 2026
3e8d4ee
nf merge qc fix
jfallmann Apr 27, 2026
411fcc9
deterministic qc order
jfallmann Apr 27, 2026
490b27b
nf key fix
jfallmann Apr 27, 2026
160b107
enable samplesheet injection into config json
jfallmann Apr 27, 2026
d7fc104
samplesheet update
jfallmann May 4, 2026
9499a43
config updates
jfallmann May 4, 2026
f272103
configurator update wip
jfallmann May 4, 2026
8184538
rustqc container recipe
jfallmann May 5, 2026
7ddd429
web_config update
jfallmann May 5, 2026
3b8ee83
readme update
jfallmann May 5, 2026
c040c49
webconfig
jfallmann May 5, 2026
9716a84
oras registry cli update
jfallmann May 5, 2026
767d842
conda env updates for snakemake/nextflow
jfallmann May 5, 2026
8b29d88
Lane split aware fastq handling, monsda now auto-merges samples acros…
jfallmann May 6, 2026
efc65f7
nf version fix
jfallmann May 6, 2026
b0a95c9
snakemake profile update
jfallmann May 8, 2026
1d85ff5
nextflow profile update
jfallmann May 8, 2026
633a5e2
added umicollapse as drop-in replacement for umi_tools dedup
jfallmann May 8, 2026
90864af
rustqc dedup after remove fix
jfallmann May 8, 2026
d0bfb4f
parallelized lane merge, cleanup
jfallmann May 11, 2026
1714486
salmon config fixes
jfallmann May 19, 2026
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
88 changes: 85 additions & 3 deletions MONSDA/Configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@
os.sep.join(["lib", pythonversion, "site-packages", "MONSDA"]), "share"
)
except:
installpath = os.path.cwd()
installpath = os.getcwd()

configpath = os.path.join(installpath, "MONSDA", "configs")
current_path = os.getcwd()
dir_path = os.path.dirname(os.path.realpath(__file__))
os.chdir(dir_path)

template = load_configfile(os.sep.join([configpath, "template_base_commented.json"]))
none_workflow_keys = ["WORKFLOWS", "BINS", "MAXTHREADS", "SETTINGS", "VERSION"]
Expand Down Expand Up @@ -70,6 +68,13 @@
help="takes configuration file to modify",
)

parser.add_argument(
"--samplesheet",
type=str,
default=False,
help="CSV or TSV samplesheet to populate SETTINGS and condition tree for new configs/projects",
)

args = parser.parse_args()


Expand Down Expand Up @@ -315,6 +320,21 @@ def get_conditions_from_dict(root, keylist=[]):
keylist.pop()


def get_conditions_from_settings(root, keylist=[]):
"""Yield condition paths from SETTINGS leaves that contain a SAMPLES key."""
if not isinstance(root, dict):
return
if "SAMPLES" in root and isinstance(root.get("SAMPLES"), list):
yield ":".join(keylist)
return
for k, v in root.items():
if not isinstance(v, dict):
continue
keylist.append(k)
yield from get_conditions_from_settings(v, keylist)
keylist.pop()


def getPathesFromDict(d, value=None):
def yield_func(d):
q = [(d, [])]
Expand Down Expand Up @@ -790,6 +810,8 @@ def create_condition_tree():
def add_sample_dirs(only_conditions=None):
pickle_unfinished("add_sample_dirs")
# project.current_func_arg = only_conditions
if args.samplesheet and only_conditions is None and project.mode in ["project", "config"]:
return assign_samplesheet()
if "FETCH" in project.workflowsDict.keys():
return assign_SRA(only_conditions)
print("\n FASTQ files:")
Expand Down Expand Up @@ -876,6 +898,58 @@ def add_sample_dirs(only_conditions=None):
return assign_samples(only_conditions)


def assign_samplesheet():
pickle_unfinished("assign_samplesheet")
prCyan("\n Sample Assignment: samplesheet\n")

samplesheet = str(args.samplesheet)
if not os.path.isfile(samplesheet):
prRed(f"Could not find samplesheet file: {samplesheet}")
exit(1)

cwd = os.getcwd()
try:
# Params initializes logging at import time via Utils.setup_logger and expects
# a writable LOGS/ directory in the current working directory.
os.makedirs(os.path.join(current_path, "LOGS"), exist_ok=True)
os.chdir(current_path)
from .Params import samplesheet_to_settings

sheet_settings = samplesheet_to_settings(samplesheet)
except Exception as e:
prRed(f"Failed to parse samplesheet '{samplesheet}': {e}")
exit(1)
finally:
os.chdir(cwd)

if not sheet_settings:
prRed(f"Samplesheet '{samplesheet}' did not produce SETTINGS entries")
exit(1)

project.settingsDict = decouple(sheet_settings)
project.conditionsDict = NestedDefaultDict()
project.samplesDict = NestedDefaultDict()

condition_paths = [
x.split(":") for x in get_conditions_from_settings(project.settingsDict)
]
if not condition_paths:
prRed(
"No condition leaves with SAMPLES found in parsed samplesheet SETTINGS"
)
exit(1)

for path in condition_paths:
setInDict(project.conditionsDict, path, {})

prGreen("Loaded condition tree and SETTINGS from samplesheet:")
print_dict(project.conditionsDict, gap=" ")
print("")
print_dict(project.settingsDict, gap=" ")
show_settings()
return select_conditioning()


def assign_SRA(only_conditions=None):
pickle_unfinished("assign_SRA")
prCyan("\n Sample Assignment: SRA Accession Numbers\n")
Expand Down Expand Up @@ -1882,6 +1956,14 @@ def main():
global guide
project = PROJECT()
guide = GUIDE()
if args.samplesheet:
if not str(args.samplesheet).lower().endswith((".csv", ".tsv", ".txt")):
print("Samplesheet flag requires a .csv/.tsv/.txt file")
exit()
args.samplesheet = os.path.abspath(args.samplesheet)
if not os.path.isfile(args.samplesheet):
print(f"Samplesheet file not found: {args.samplesheet}")
exit()
if args.test:
guide.testing = True
if args.config:
Expand Down
44 changes: 1 addition & 43 deletions MONSDA/Logger.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,5 @@
# Logger.py ---
#
# Filename: Logger.py
# Description:
# Author: Joerg Fallmann
# Maintainer:
# Created: Mon Aug 12 10:26:55 2019 (+0200)
# Version:
# Package-Requires: ()
# Last-Updated: Wed Apr 29 16:42:40 2020 (+0200)
# By: Joerg Fallmann
# Update #: 91
# URL:
# Doc URL:
# Keywords:
# Compatibility:
#
#

# Commentary:
#
#
#
#

# Change Log:
#
#
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
#
#


# Code:
import logging
Expand Down
Loading
Loading