Skip to content

Commit fd23254

Browse files
Merge remote-tracking branch 'origin/main' into fix-update-of-first-classifier
2 parents 46d4feb + b0af1aa commit fd23254

26 files changed

+158
-50
lines changed

.bumpversion.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.bumpversion]
2-
current_version = "1.9.3-dev1"
2+
current_version = "1.9.3-dev2"
33
parse = """(?x)
44
(?P<major>0|[1-9]\\d*)\\.
55
(?P<minor>0|[1-9]\\d*)\\.

.github/workflows/pip_installation.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
on:
99
push:
1010
branches: [ main ]
11+
schedule:
12+
- cron: "0 0 * * *" # daily at midnight, to get feedback on the loose version
1113
workflow_dispatch:
1214

1315
name: Pip install + unit tests

alphadia/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!python
22

3-
__version__ = "1.9.3-dev1"
3+
__version__ = "1.9.3-dev2"

alphadia/cli.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,11 @@ def _get_raw_path_list_from_args_and_config(
176176
if re.search(args.regex, os.path.basename(f)) is not None
177177
]
178178
len_after = len(raw_path_list)
179-
print(f"Removed {len_before - len_after} of {len_before} files.")
179+
180+
if len_removed := len_before - len_after:
181+
print(
182+
f"Ignoring {len_removed} / {len_before} file(s) from arguments list due to --regex."
183+
)
180184

181185
return raw_path_list
182186

alphadia/constants/default.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
version: 1
33

44
# These values are typically filled via CLI parameters
5+
workflow_name: null
56
output_directory: null
67
library_path: null
78
raw_paths: []

alphadia/exceptions.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,16 @@ def __str__(self):
2727
class BusinessError(CustomError):
2828
"""Custom error class for 'business' errors.
2929
30-
A 'business' error is an error that is caused by the input (data, configuration, ...) and not by a
31-
malfunction in alphaDIA.
30+
A 'business' error is an error that is caused during processing the input (data, configuration, ...) and not by a
31+
malfunction in AlphaDIA.
32+
"""
33+
34+
35+
class UserError(CustomError):
36+
"""Custom error class for 'user' errors.
37+
38+
A 'user' error is an error that is caused by the incompatible user input (data, configuration, ...) and not by a
39+
malfunction in AlphaDIA.
3240
"""
3341

3442

@@ -64,6 +72,19 @@ class NotDiaDataError(BusinessError):
6472
_msg = "Could not find cycle shape. Please check if this is a valid DIA data set."
6573

6674

75+
class NoLibraryAvailableError(UserError):
76+
"""Raise when no library is available."""
77+
78+
_error_code = "NO_LIBRARY_AVAILABLE"
79+
80+
_msg = "No spectral library available."
81+
82+
_detail_msg = """No spectral library available.
83+
84+
Either provide a spectral library file (via GUI, config or command line parameter),
85+
or provide a FASTA file and set the "Predict Library" (GUI) / 'library_prediction.predict' (config) flag."""
86+
87+
6788
class ConfigError(BusinessError):
6889
"""Raise when something is wrong with the provided configuration."""
6990

@@ -73,22 +94,29 @@ class ConfigError(BusinessError):
7394
_key = ""
7495
_config_name = ""
7596

76-
def __init__(self, key: str, config_name: str):
97+
def __init__(self, key: str, value: str, config_name: str):
7798
self._key = key
99+
self._value = value
78100
self._config_name = config_name
79101

80102

81103
class KeyAddedConfigError(ConfigError):
82104
"""Raise when a key should be added to a config."""
83105

84-
def __init__(self, key: str, config_name: str):
85-
super().__init__(key, config_name)
86-
self._detail_msg = f"Defining new keys is not allowed when updating a config: key='{self._key}', config_name='{self._config_name}'"
106+
def __init__(self, key: str, value: str, config_name: str):
107+
super().__init__(key, value, config_name)
108+
self._detail_msg = (
109+
f"Defining new keys is not allowed when updating a config: "
110+
f"key='{self._key}', value='{self._value}', config_name='{self._config_name}'"
111+
)
87112

88113

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

92-
def __init__(self, key: str, config_name: str, extra_msg: str):
93-
super().__init__(key, config_name)
94-
self._detail_msg = f"Types of values must match default config: key='{self._key}', config_name='{self._config_name}', types='{extra_msg}'"
117+
def __init__(self, key: str, value: str, config_name: str, extra_msg: str):
118+
super().__init__(key, value, config_name)
119+
self._detail_msg = (
120+
f"Types of values must match default config: "
121+
f"key='{self._key}', value='{self._value}', config_name='{self._config_name}', types='{extra_msg}'"
122+
)

alphadia/search_step.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from alphadia import libtransform, outputtransform
1212
from alphadia.constants.keys import ConfigKeys
13-
from alphadia.exceptions import CustomError
13+
from alphadia.exceptions import CustomError, NoLibraryAvailableError
1414
from alphadia.workflow import peptidecentric, reporting
1515
from alphadia.workflow.base import WorkflowBase
1616
from alphadia.workflow.config import (
@@ -271,7 +271,8 @@ def get_run_data(self) -> Generator[tuple[str, str, SpecLibFlat]]:
271271
"""Generator for raw data and spectral library."""
272272

273273
if self.spectral_library is None:
274-
raise ValueError("no spectral library loaded")
274+
# TODO: check alternative: more fine-grained errors could be raised on the level of search_plan
275+
raise NoLibraryAvailableError()
275276

276277
# iterate over raw files and yield raw data and spectral library
277278
for i, raw_location in enumerate(self.raw_path_list):
@@ -340,9 +341,13 @@ def _process_raw_file(
340341

341342
if self.config["general"]["reuse_quant"]:
342343
if os.path.exists(psm_location) and os.path.exists(frag_location):
343-
logger.info(f"Found existing quantification for {raw_name}")
344+
logger.info(
345+
f"reuse_quant: found existing quantification for {raw_name}, skipping processing .."
346+
)
344347
return workflow
345-
logger.info(f"No existing quantification found for {raw_name}")
348+
logger.info(
349+
f"reuse_quant: no existing quantification found for {raw_name}, proceeding with processing .."
350+
)
346351

347352
workflow.load(dia_path, speclib)
348353

alphadia/workflow/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def __init__(
5656
self._quant_path: str = quant_path or os.path.join(
5757
config[ConfigKeys.OUTPUT_DIRECTORY], QUANT_FOLDER_NAME
5858
)
59-
logger.info(f"Saving quantification results to {self._quant_path}")
59+
logger.info(f"Quantification results path: {self._quant_path}")
6060

6161
self._config: Config = config
6262
self.reporter: reporting.Pipeline | None = None

alphadia/workflow/config.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def _update(
166166
"""
167167
for key, update_value in update_config.items():
168168
if key not in target_config:
169-
raise KeyAddedConfigError(key, config_name)
169+
raise KeyAddedConfigError(key, update_value, config_name)
170170

171171
target_value = target_config[key]
172172
tracking_value = tracking_dict[key]
@@ -180,7 +180,10 @@ def _update(
180180
)
181181
):
182182
raise TypeMismatchConfigError(
183-
key, config_name, f"{type(update_value)} != {type(target_value)}"
183+
key,
184+
update_value,
185+
config_name,
186+
f"{type(update_value)} != {type(target_value)}",
184187
)
185188

186189
if isinstance(target_value, dict):

alphadia/workflow/manager.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,9 @@ def load_classifier_store(self, path: None | str = None):
820820

821821
if classifier_hash not in self.classifier_store:
822822
classifier = deepcopy(self.classifier_base)
823-
classifier.from_state_dict(torch.load(os.path.join(path, file)))
823+
classifier.from_state_dict(
824+
torch.load(os.path.join(path, file), weights_only=False)
825+
)
824826
self.classifier_store[classifier_hash].append(classifier)
825827

826828
def get_classifier(self, available_columns: list, version: int = -1):

alphadia/workflow/reporting.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import warnings
1010
from datetime import datetime, timedelta
1111
from io import BytesIO
12+
from pathlib import Path
1213

1314
# alphadia imports
1415
# alpha family imports
@@ -108,9 +109,7 @@ def format(self, record: logging.LogRecord):
108109
return f"{elapsed} {self.formatter[record.levelno].format(record)}"
109110

110111

111-
def init_logging(
112-
log_folder: str = None, log_level: int = logging.INFO, overwrite: bool = True
113-
):
112+
def init_logging(log_folder: str = None, log_level: int = logging.INFO):
114113
"""Initialize the default logger.
115114
Sets the formatter and the console and file handlers.
116115
@@ -122,9 +121,6 @@ def init_logging(
122121
123122
log_level : int, default logging.INFO
124123
Log level to use. Can be logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR or logging.CRITICAL.
125-
126-
overwrite : bool, default True
127-
Whether to overwrite the log file if it already exists.
128124
"""
129125

130126
global __is_initiated__
@@ -147,20 +143,39 @@ def init_logging(
147143
if log_folder is not None:
148144
os.makedirs(log_folder, exist_ok=True)
149145

150-
log_name = os.path.join(log_folder, "log.txt")
151-
# check if log file exists
152-
if os.path.exists(log_name) and overwrite:
153-
# if it does, delete it
154-
os.remove(log_name)
146+
log_file_path = os.path.join(log_folder, "log.txt")
147+
148+
moved_log_file_path = _move_old_logs(log_file_path)
149+
155150
# create file handler which logs even debug messages
156-
fh = logging.FileHandler(log_name, encoding="utf-8")
151+
fh = logging.FileHandler(log_file_path, encoding="utf-8")
157152
fh.setLevel(log_level)
158153
fh.setFormatter(DefaultFormatter(use_ansi=False))
159154
logger.addHandler(fh)
160155

156+
if moved_log_file_path:
157+
logger.info(f"Moved old log file {log_file_path} to {moved_log_file_path}")
158+
161159
__is_initiated__ = True
162160

163161

162+
def _move_old_logs(log_file_path: str) -> str | None:
163+
"""Move old log files to a new name with an incrementing number."""
164+
old_path = Path(log_file_path)
165+
new_path = old_path
166+
167+
n = -1
168+
while new_path.exists():
169+
n += 1
170+
new_path = old_path.parent / f"{old_path.stem}.{n}.bkp{old_path.suffix}"
171+
172+
if n != -1:
173+
Path(log_file_path).rename(new_path)
174+
return str(new_path)
175+
176+
return None
177+
178+
164179
class Backend:
165180
"""Generic backend for logging metrics, plots and strings.
166181

docs/guides/libfree-gui.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Also ensure the right execution engine has been selected and your version is up
99
<img src="../_static/images/libfree-gui/initial_engine.png" width="100%" height="auto">
1010

1111
## 2. Project Structure
12-
We will be performing two DIA searches: a first search for library generation and a second search for joined quantification. To accommodate this, we prepare the project directory to have a `first_pass` and a `second_pass` folder. You can change the project path in the `Output Files` tab
12+
We will be performing two DIA searches: a first search for library generation and a second search for joined quantification. To accommodate this, we prepare the project directory to have a `first_pass` and a `second_pass` folder,
13+
which can then be selected in the `Output Files` tab.
1314
<img src="../_static/images/libfree-gui/initial_folders.png" width="100%" height="auto">
1415

1516
## 3. First search
@@ -30,7 +31,9 @@ Keeping track of optimized mass tolerance values for different instrument setups
3031

3132
<img src="../_static/images/libfree-gui/first_settings.png" width="100%" height="auto">
3233

33-
Start the first search by clicking the "Run Workflow" button. This will take between one and two hours depending on your system.
34+
3. In the "Output Files" tab, select the `first_pass` folder as the output directory.
35+
36+
4. Start the first search by clicking the "Run Workflow" button. This will take between one and two hours depending on your system.
3437

3538
## 4. Second search
3639
For the second search, we will use the library generated in the first search to quantify precursors across samples. Load all raw files as previously but remove the FASTA file. Instead, select the `speclib.mbr.hdf` as the spectral library.
@@ -40,6 +43,8 @@ For the second search, configure the `thread_count`, `target_ms1_tolerance`, and
4043

4144
<img src="../_static/images/libfree-gui/second_settings.png" width="100%" height="auto">
4245

46+
In the "Output Files" tab, select the `second_pass` folder as the output directory.
47+
4348
Finally, start the search as before. This search will take only around 2 minutes per file.
4449

4550
## 5. Results

docs/installation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ The GUI can then be started by typing
108108
npm run dev
109109
```
110110

111+
Ignore the error message telling you that the `BundledExecutionEngine` is not available
112+
In order to use the locally installed version, select the `CMDExecutionEngine`in the top bar.
113+
114+
By default, this looks for an AlphaDIA installation in a conda environment called `alphadia`.
115+
If you want to use a different environment, locate the `profile.json` file
116+
(MacOS: via "Electron" -> "Settings" in the top menu, e.g. `~/Library/Application Support/alphadia/profile.json`)
117+
and adjust `CMDExecutionEngine.envName`.
118+
111119
## Docker Installation
112120
The containerized version can be used to run alphaDIA e.g. on cloud platforms.
113121
It can be used to run alphaDIA for multiple input files, as well as for single files only

gui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "alphadia",
33
"productName": "alphadia-gui",
4-
"version": "1.9.3-dev1",
4+
"version": "1.9.3-dev2",
55
"description": "Graphical user interface for DIA data analysis",
66
"main": "dist/electron.js",
77
"homepage": "./",

gui/src/main/modules/engine.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ function hasBinary(binaryPath){
307307
return new Promise((resolve, reject) => {
308308
fs.access(binaryPath, fs.constants.X_OK, (err) => {
309309
if (err) {
310-
reject("hasBinary: Binary " + binaryPath + " not found or not executable.")
310+
reject("BundledExecutionEngine: Binary " + binaryPath + " not found or not executable." +
311+
"\n\nYou may use the CMDExecutionEngine instead.")
311312
} else {
312313
resolve()
313314
}
@@ -367,8 +368,8 @@ class BundledExecutionEngine extends BaseExecutionEngine {
367368
BrowserWindow.getFocusedWindow(),
368369
{
369370
type: 'error',
370-
title: 'Error while checking availability of bundled alphaDIA',
371-
message: `Could not start bundled alphaDIA. ${err}`,
371+
title: 'Error while checking availability of bundled AlphaDIA',
372+
message: `Could not start bundled AlphaDIA.\n${err}`,
372373
}).catch((err) => {
373374
console.log(err)
374375
})

gui/src/main/modules/profile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const path = require("path")
33
const { app, shell, BrowserWindow} = require("electron")
44
const { dialog } = require('electron')
55

6-
const VERSION = "1.9.3-dev1"
6+
const VERSION = "1.9.3-dev2"
77

88
const Profile = class {
99

gui/src/main/modules/workflows.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function validateWorkflow(workflow) {
7676

7777
function workflowToConfig(workflow) {
7878

79-
let output = {name: workflow.name}
79+
let output = {workflow_name: workflow.name}
8080

8181
if (workflow.library.path != "") {
8282
output["library_path"] = workflow.library.path

gui/src/renderer/pages/Home.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const VersionCard = () => {
5555
let currentActiveVersion = profile.executionEngines[profile.activeIdx].versions.filter((versionEntry) => versionEntry.name === "alphadia")[0].version
5656
versionOutput = currentActiveVersion
5757

58-
if (currentActiveVersion != "1.2.0") {
58+
if (currentActiveVersion != "1.2.0") { // TODO fix
5959
updateOutput = (
6060
<Stack direction="row" alignItems="center" gap={1}>
6161
<CheckIcon sx={{color:"rgb(75, 211, 26)"}}/>

misc/pip_install.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#!/bin/bash
2+
### Install the package with a given type in a defined conda environment with a define python version,
3+
### and call it to check if it works
4+
### example usage:
5+
### ./pip_install.sh stable my_env 3.9
16
set -e -u
27

38
INSTALL_TYPE=$1 # stable, loose, etc..

release/linux/control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: alphadia
2-
Version: 1.9.3-dev1
2+
Version: 1.9.3-dev2
33
Architecture: all
44
Maintainer: Mann Labs <opensource@alphapept.com>
55
Description: alphadia

release/macos/build_package_macos.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ set -e -u
77
# Set up package name and version
88
PACKAGE_NAME="alphadia"
99
APP_NAME="alphadia"
10-
PACKAGE_VERSION="1.9.3-dev1"
10+
PACKAGE_VERSION="1.9.3-dev2"
1111
PKG_FOLDER="dist/$APP_NAME.app"
1212

13-
# BUILD_NAME is taken from environment variables, e.g. alphadia-1.9.3-dev1-macos-darwin-arm64 or alphadia-1.9.3-dev1-macos-darwin-x64
13+
# BUILD_NAME is taken from environment variables, e.g. alphadia-1.9.3-dev2-macos-darwin-arm64 or alphadia-1.9.3-dev2-macos-darwin-x64
1414
rm -rf ${BUILD_NAME}.pkg
1515

1616
# Cleanup the package folder

0 commit comments

Comments
 (0)