Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change config handling #410

Open
wants to merge 24 commits into
base: refactor_config
Choose a base branch
from
Open
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
74 changes: 35 additions & 39 deletions alphadia/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@

import alphadia
from alphadia import utils
from alphadia.constants.keys import ConfigKeys
from alphadia.exceptions import CustomError
from alphadia.search_plan import SearchPlan
from alphadia.workflow import reporting

logger = logging.getLogger()

epilog = "Parameters passed via CLI will overwrite parameters from config file (except for '--file': will be merged)."

parser = argparse.ArgumentParser(description="Search DIA experiments with alphaDIA")
parser = argparse.ArgumentParser(
description="Search DIA experiments with alphaDIA", epilog=epilog
)
parser.add_argument(
"--version",
"-v",
Expand All @@ -32,17 +36,19 @@
)
parser.add_argument(
"--output",
"--output-directory",
"-o",
type=str,
help="Output directory",
help="Output directory.",
nargs="?",
default=None,
)
parser.add_argument(
"--file",
"--raw-path",
"-f",
type=str,
help="Raw data input files.",
help="Path to raw data input file. Can be passed multiple times.",
action="append",
default=[],
)
Expand All @@ -58,43 +64,46 @@
"--regex",
"-r",
type=str,
help="Regex to match raw files in directory.",
help="Regex to match raw files in 'directory'.",
nargs="?",
default=".*",
)
parser.add_argument(
"--library",
"--library-path",
"-l",
type=str,
help="Spectral library.",
help="Path to spectral library file.",
nargs="?",
default=None,
)
parser.add_argument(
"--fasta",
help="Fasta file(s) used to generate or annotate the spectral library.",
"--fasta-path",
help="Path to fasta file used to generate or annotate the spectral library. Can be passed multiple times.",
action="append",
default=[],
)
parser.add_argument(
"--config",
"-c",
type=str,
help="Config yaml which will be used to update the default config.",
help="Path to config yaml file which will be used to update the default config.",
nargs="?",
default=None,
)
parser.add_argument(
"--config-dict",
type=str,
help="Python Dict which will be used to update the default config.",
help="Python dictionary which will be used to update the default config.",
nargs="?",
default="{}",
)
parser.add_argument(
"--quant-dir",
"--quant-dir", # TODO deprecate
"--quant-directory",
type=str,
help="Directory to save the quantification results (psm & frag parquet files) to be reused in a distributed search",
help="Directory to save the quantification results (psm & frag parquet files) to be reused in a distributed search.",
nargs="?",
default=None,
)
Expand Down Expand Up @@ -144,7 +153,7 @@ def _get_raw_path_list_from_args_and_config(
list: A list of file paths that match the specified regex pattern.
"""

raw_path_list = config.get("raw_path_list", [])
raw_path_list = config.get(ConfigKeys.RAW_PATHS, [])
raw_path_list += args.file

if (config_directory := config.get("directory")) is not None:
Expand All @@ -168,17 +177,6 @@ def _get_raw_path_list_from_args_and_config(
return raw_path_list


def _get_fasta_list_from_args_and_config(
args: argparse.Namespace, config: dict
) -> list:
"""Parse fasta file list from command line arguments and config file, merging them if both are given."""

fasta_path_list = config.get("fasta_list", [])
fasta_path_list += args.fasta

return fasta_path_list


def run(*args, **kwargs):
# parse command line arguments
args, unknown = parser.parse_known_args()
Expand All @@ -199,33 +197,31 @@ def run(*args, **kwargs):
)
if output_directory is None:
parser.print_help()
print("No output directory specified.")

print("No output directory specified. Please do so via CL-argument or config.")
return
reporting.init_logging(output_directory)

quant_dir = _get_from_args_or_config(
args, user_config, args_key="quant_dir", config_key="quant_dir"
)
raw_path_list = _get_raw_path_list_from_args_and_config(args, user_config)
library_path = _get_from_args_or_config(
args, user_config, args_key="library", config_key="library"
)
fasta_path_list = _get_fasta_list_from_args_and_config(args, user_config)
# TODO revisit the multiple sources of raw files (cli, config, regex, ...)
raw_paths = _get_raw_path_list_from_args_and_config(args, user_config)
cli_params_config = {
**({ConfigKeys.RAW_PATHS: raw_paths} if raw_paths else {}),
**({ConfigKeys.LIBRARY_PATH: args.library} if args.library is not None else {}),
**({ConfigKeys.FASTA_PATHS: args.library} if args.fasta else {}),
**(
{ConfigKeys.QUANT_DIRECTORY: args.library}
if args.quant_dir is not None
else {}
),
}

# TODO rename all output_directory, output_folder => output_path, quant_dir->quant_path (except cli parameter)

# important to suppress matplotlib output
matplotlib.use("Agg")

try:
SearchPlan(
output_directory,
raw_path_list=raw_path_list,
library_path=library_path,
fasta_path_list=fasta_path_list,
config=user_config,
quant_path=quant_dir,
).run_plan()
SearchPlan(output_directory, user_config, cli_params_config).run_plan()

except Exception as e:
if isinstance(e, CustomError):
Expand Down
22 changes: 12 additions & 10 deletions alphadia/constants/default.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# configuration for the extraction plan
version: 1

library: null
# These values are typically filled via CLI parameters
output_directory: null
raw_path_list: []
output: null
library_path: null
raw_paths: []
fasta_paths: []
quant_directory: null

general:
thread_count: 10
Expand Down Expand Up @@ -62,31 +64,31 @@ library_prediction:
# composition: H(-2)2H(8)13C(2)
custom_modifications:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternatively: allow to add keys for the custom_modifications key

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update: now that we can overwrite lists, the original format can be used again

# Dimethyl @K channel decoy
Dimethyl:d12@K:
- name: Dimethyl:d12@K
composition: H(-2)2H(8)13C(2)

# Dimethyl @Any_N-term channel decoy
Dimethyl:d12@Any_N-term:
- name: Dimethyl:d12@Any_N-term
composition: H(-2)2H(8)13C(2)

# Dimethyl @Protein_N-term channel decoy
Dimethyl:d12@Protein_N-term:
- name: Dimethyl:d12@Protein_N-term
composition: H(-2)2H(8)13C(2)

# mTRAQ @K channel decoy
mTRAQ:d12@K:
- name: mTRAQ:d12@K
composition: H(12)C(1)13C(10)15N(2)O(1)

# mTRAQ @Any_N-term channel decoy
mTRAQ:d12@Any_N-term:
- name: mTRAQ:d12@Any_N-term
composition: H(12)C(1)13C(14)15N(2)O(1)

# mTRAQ @Protein_N-term channel decoy
mTRAQ:d12@Protein_N-term:
- name: mTRAQ:d12@Protein_N-term
composition: H(12)C(1)13C(14)15N(2)O(1)

# SILAC heavy @K channel decoy
Label:13C(12)@K:
- name: Label:13C(12)@K
composition: C(12)

search:
Expand Down
10 changes: 10 additions & 0 deletions alphadia/constants/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,13 @@ class StatOutputKeys(metaclass=ConstantsClass):
MS2_ERROR = "ms2_error"
RT_ERROR = "rt_error"
MOBILITY_ERROR = "mobility_error"


class ConfigKeys(metaclass=ConstantsClass):
"""String constants for accessing the config."""

OUTPUT_DIRECTORY = "output_directory"
LIBRARY_PATH = "library_path"
RAW_PATHS = "raw_paths"
FASTA_PATHS = "fasta_paths"
QUANT_DIRECTORY = "quant_directory"
3 changes: 3 additions & 0 deletions alphadia/constants/multistep.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ transfer:
enabled: True

# override settings that could have been set by the user:
quant_directory: null
general:
save_library: False
reuse_quant: False
Expand All @@ -23,6 +24,7 @@ library:
# predict: True

# override settings that could have been set by the user:
quant_directory: null
general:
save_library: False
reuse_quant: False
Expand All @@ -37,6 +39,7 @@ mbr:
search:
target_num_candidates: 5
# override settings that could have been set by the user:
quant_directory: null
general:
reuse_quant: False
library_prediction:
Expand Down
33 changes: 33 additions & 0 deletions alphadia/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ def msg(self):
def detail_msg(self):
return self._detail_msg

def __str__(self):
return f"{self._error_code}: {self._msg} {self._detail_msg}"


class BusinessError(CustomError):
"""Custom error class for 'business' errors.
Expand Down Expand Up @@ -59,3 +62,33 @@ class NotDiaDataError(BusinessError):
_error_code = "NOT_DIA_DATA"

_msg = "Could not find cycle shape. Please check if this is a valid DIA data set."


class ConfigError(BusinessError):
"""Raise when something is wrong with the provided configuration."""

_error_code = "CONFIG_ERROR"

_msg = "Malformed configuration file(s)."
_key = ""
_config_name = ""

def __init__(self, key: str, config_name: str):
self._key = key
self._config_name = config_name


class KeyAddedConfigError(ConfigError):
"""Raise when a key is added to a config."""

def __init__(self, key: str, config_name: str):
super().__init__(key, config_name)
self._detail_msg = f"Adding keys is not supported: key='{self._key}', configuration='{self._config_name}'"


class TypeMismatchConfigError(ConfigError):
"""Raise when the type of a value does not match the default type."""

def __init__(self, key: str, config_name: str, extra_msg: str):
super().__init__(key, config_name)
self._detail_msg = f"Type mismatch for key: key='{self._key}', configuration='{self._config_name}', types='{extra_msg}'"
4 changes: 2 additions & 2 deletions alphadia/libtransform.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ def __call__(self, *args: typing.Any) -> typing.Any:
return self.forward(*args)
else:
logger.critical(
f"Input {input} failed validation for {self.__class__.__name__}"
f"Input {args} failed validation for {self.__class__.__name__}"
mschwoer marked this conversation as resolved.
Show resolved Hide resolved
)
raise ValueError(
f"Input {input} failed validation for {self.__class__.__name__}"
f"Input {args} failed validation for {self.__class__.__name__}"
)

def validate(self, *args: typing.Any) -> bool:
Expand Down
Loading
Loading