Skip to content

Commit

Permalink
Merge pull request #32 from mmzdouc/dev_mmz
Browse files Browse the repository at this point in the history
v0.3.1
  • Loading branch information
mmzdouc authored Jun 5, 2024
2 parents 00eab95 + 727a89b commit dfacf62
Show file tree
Hide file tree
Showing 19 changed files with 72 additions and 59 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

N/A

## [0.3.1] 05-06-2024

### Changed

- Loosened typing restrictions for Feature and Sample object attributes: area and height (intensity) now accept float values.

### Removed
- [Breaking change] Removed toggle 'nonbiological' from 'FragmentAnnotator' and from parameters file; 'nonbiological' fragment annotation is now performed automatically

### Security

- Instead of full file paths, only filenames are now written to the 'out.fermo.session.json' file

## [0.3.0] 03-06-2024

### Changed
Expand Down
3 changes: 1 addition & 2 deletions example_data/case_study_parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
},
"neutral_loss_annotation": {
"activate_module": true,
"mass_dev_ppm": 10.0,
"nonbiological": true
"mass_dev_ppm": 10.0
},
"fragment_annotation": {
"activate_module": true,
Expand Down
4 changes: 0 additions & 4 deletions fermo_core/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,6 @@
"type": "number",
"minimum": 0.0,
"maximum": 100.0
},
"nonbiological": {
"title": "(Optional): Specifies whether neutral losses should be compared to losses originating from synthetic molecules.",
"type": "boolean"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Organize the calling of annotation modules.
Copyright (c) 2022-2024 Mitja Maximilian Zdouc, PhD
Copyright (c) 2022 to present Mitja Maximilian Zdouc, PhD
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -122,7 +122,7 @@ def _eval_as_results_file() -> bool:
self.run_as_kcb_cosine_annotation,
),
(
_eval_as_results_file,
_eval_as_results_file(),
self.run_as_kcb_deepscore_annotation,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ def annotate_feature_pos(self: Self, f_id: int):
feature = self.validate_nonribosomal_losses(feature)
feature = self.validate_glycoside_losses(feature)
feature = self.validate_gen_bio_pos_losses(feature)
if self.params.NeutralLossParameters.nonbiological is True:
feature = self.validate_gen_other_pos_losses(feature)
feature = self.validate_gen_other_pos_losses(feature)

self.features.modify(f_id, feature)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import logging

import numpy as np
import pandas as pd
from pydantic import BaseModel

Expand Down Expand Up @@ -102,16 +103,25 @@ def set_rt_range(self):
)
return self

def set_fwhm(self, fwhm: float):
def set_fwhm(self, fwhm: float, s_id: str):
"""Set attribute
Arguments:
fwhm: the feature with at half maximum intensity of the peak
s_id: a sample ID
"""
self.feature.fwhm = fwhm
if np.isnan(np.sum(fwhm)):
logger.warning(
f"'FeatureBuilder': feature '{self.feature.f_id}' has no valid FWHM "
f"in sample '{s_id}'. Set value to '0.0'."
)
self.feature.fwhm = 0.0
else:
self.feature.fwhm = float(fwhm)

return self

def set_intensity(self, intensity: int):
def set_intensity(self, intensity: float):
"""Set attribute
Arguments:
Expand All @@ -120,7 +130,7 @@ def set_intensity(self, intensity: int):
self.feature.intensity = intensity
return self

def set_rel_intensity(self, intensity: int, max_intensity: int):
def set_rel_intensity(self, intensity: float, max_intensity: float):
"""Calculate and set attribute for relative intensity
Arguments:
Expand All @@ -130,7 +140,7 @@ def set_rel_intensity(self, intensity: int, max_intensity: int):
self.feature.rel_intensity = round((intensity / max_intensity), 2)
return self

def set_area(self, area: int):
def set_area(self, area: float):
"""Set attribute
Arguments:
Expand All @@ -139,7 +149,7 @@ def set_area(self, area: int):
self.feature.area = area
return self

def set_rel_area(self, area: int, max_area: int):
def set_rel_area(self, area: float, max_area: float):
"""Calculate and set attribute for relative area
Arguments:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def construct_mzmine3(row: pd.Series) -> Feature:
return (
FeatureBuilder()
.set_f_id(int(row["id"]))
.set_area(int(row["area"]))
.set_area(float(row["area"]))
.set_mz(float(row["mz"]))
.set_rt(float(row["rt"]))
.set_rt_start(float(row["rt_range:min"]))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ def construct_mzmine3(
FeatureBuilder()
.set_f_id(int(row["id"]))
.set_mz(float(row["mz"]))
.set_fwhm(float(row[f"datafile:{s_id}:fwhm"]))
.set_intensity(int(row[f"datafile:{s_id}:intensity_range:max"]))
.set_fwhm(float(row[f"datafile:{s_id}:fwhm"]), s_id)
.set_intensity(float(row[f"datafile:{s_id}:intensity_range:max"]))
.set_rt_start(float(row[f"datafile:{s_id}:rt_range:min"]))
.set_rt_stop(float(row[f"datafile:{s_id}:rt_range:max"]))
.set_rt(float(row[f"datafile:{s_id}:rt"]))
.set_area(int(row[f"datafile:{s_id}:area"]))
.set_area(float(row[f"datafile:{s_id}:area"]))
.set_rt_range()
.set_rel_intensity(
row[f"datafile:{s_id}:intensity_range:max"], max_intensity
Expand Down
14 changes: 7 additions & 7 deletions fermo_core/data_processing/builder_feature/dataclass_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,16 +282,16 @@ class SampleInfo(BaseModel):
Attributes:
s_id: identifier of sample
value: an integer indicating the respective value (area or height)
value: indicating the respective value (area or height)
"""

s_id: str
value: int
value: float

def to_json(self: Self) -> dict:
return {
"s_id": str(self.s_id),
"value": int(self.value),
"value": float(self.value),
}


Expand Down Expand Up @@ -374,9 +374,9 @@ class Feature(BaseModel):
trace_rt: Optional[tuple] = None
trace_int: Optional[tuple] = None
fwhm: Optional[float] = None
intensity: Optional[int] = None
intensity: Optional[float] = None
rel_intensity: Optional[float] = None
area: Optional[int] = None
area: Optional[float] = None
rel_area: Optional[float] = None
Spectrum: Optional[Any] = None
samples: Optional[set] = None
Expand Down Expand Up @@ -405,9 +405,9 @@ def to_json(self: Self) -> dict:
("trace_rt", self.trace_rt, list),
("trace_int", self.trace_int, list),
("fwhm", self.fwhm, float),
("intensity", self.intensity, int),
("intensity", self.intensity, float),
("rel_intensity", self.rel_intensity, float),
("area", self.area, int),
("area", self.area, float),
("rel_area", self.rel_area, float),
("samples", self.samples, list),
("blank", self.blank, bool),
Expand Down
8 changes: 4 additions & 4 deletions fermo_core/data_processing/builder_sample/dataclass_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ class Sample(BaseModel):
features: Optional[dict] = None
feature_ids: Optional[set] = None
networks: Optional[dict] = None
max_intensity: Optional[int] = None
max_area: Optional[int] = None
max_intensity: Optional[float] = None
max_area: Optional[float] = None
Scores: Optional[Scores] = None

def to_json(self: Self) -> dict:
Expand All @@ -84,8 +84,8 @@ def to_json(self: Self) -> dict:
attributes = (
("s_id", self.s_id, str),
("feature_ids", self.feature_ids, list),
("max_intensity", self.max_intensity, int),
("max_area", self.max_area, int),
("max_intensity", self.max_intensity, float),
("max_area", self.max_area, float),
)

json_dict = {}
Expand Down
3 changes: 0 additions & 3 deletions fermo_core/input_output/core_module_parameter_managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,11 @@ class NeutralLossParameters(BaseModel):
Attributes:
activate_module: bool to indicate if module should be executed.
mass_dev_ppm: The estimated maximum mass deviation in ppm.
nonbiological: Switch on comparison against losses in 'generic_other_pos.csv'
module_passed: indicates that the module ran without errors
"""

activate_module: bool = True
mass_dev_ppm: PositiveFloat = 10.0
nonbiological: bool = False
module_passed: bool = False

@model_validator(mode="after")
Expand All @@ -86,7 +84,6 @@ def to_json(self: Self) -> dict:
return {
"activate_module": self.activate_module,
"mass_dev_ppm": float(self.mass_dev_ppm),
"nonbiological": self.nonbiological,
"module_passed": self.module_passed,
}
else:
Expand Down
16 changes: 8 additions & 8 deletions fermo_core/input_output/input_file_parameter_managers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Organizes classes that handle and validate input file parameter.
Copyright (c) 2022-2023 Mitja Maximilian Zdouc, PhD
Copyright (c) 2022 to present Mitja Maximilian Zdouc, PhD
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -74,7 +74,7 @@ def validate_polarity_format(self):
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
return {
"filepath": str(self.filepath.resolve()),
"filepath": str(self.filepath.name),
"format": str(self.format),
"polarity": str(self.polarity),
}
Expand Down Expand Up @@ -119,7 +119,7 @@ def validate_rel_int_range(self):
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
return {
"filepath": str(self.filepath.resolve()),
"filepath": str(self.filepath.name),
"format": self.format,
"rel_int_from": self.rel_int_from,
}
Expand Down Expand Up @@ -170,7 +170,7 @@ def validate_phenotype_format(self):
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
return {
"filepath": str(self.filepath.resolve()),
"filepath": str(self.filepath.name),
"format": str(self.format),
}

Expand Down Expand Up @@ -224,7 +224,7 @@ def validate_group_metadata_format(self):
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
return {
"filepath": str(self.filepath.resolve()),
"filepath": str(self.filepath.name),
"format": str(self.format),
}

Expand Down Expand Up @@ -261,7 +261,7 @@ def validate_spectral_library_format(self):
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
return {
"filepath": str(self.filepath.resolve()),
"filepath": str(self.filepath.name),
"format": str(self.format),
}

Expand Down Expand Up @@ -290,7 +290,7 @@ def validate_ms2query_result_format(self):
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
return {
"filepath": str(self.filepath.resolve()),
"filepath": str(self.filepath.name),
"score_cutoff": self.score_cutoff,
}

Expand All @@ -312,6 +312,6 @@ class AsResultsParameters(BaseModel):
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
return {
"directory_path": str(self.directory_path.resolve()),
"directory_path": str(self.directory_path.name),
"similarity_cutoff": self.similarity_cutoff,
}
4 changes: 3 additions & 1 deletion fermo_core/input_output/output_file_parameter_managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ def _create_output_dir():
def to_json(self: Self) -> dict:
"""Convert attributes to json-compatible ones."""
try:
return {"directory_path": str(self.directory_path.resolve())}
return {
"directory_path": f"{self.directory_path.parent.name}/{self.directory_path.name}"
}
except AttributeError:
return {"directory_path": "not specified"}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "fermo_core"
version = "0.3.0"
version = "0.3.1"
description = "Data processing/analysis functionality of metabolomics dashboard FERMO"
readme = "README.md"
requires-python = ">=3.11,<3.12"
Expand Down
3 changes: 1 addition & 2 deletions tests/test_data/test.parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
},
"neutral_loss_annotation": {
"activate_module": true,
"mass_dev_ppm": 10.0,
"nonbiological": true
"mass_dev_ppm": 10.0
},
"fragment_annotation": {
"activate_module": true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import numpy as np
from pathlib import Path

import numpy as np
import pytest

from fermo_core.data_analysis.annotation_manager.class_neutral_loss_annotator import (
NeutralLossAnnotator,
)
from fermo_core.data_processing.class_repository import Repository
from fermo_core.data_processing.builder_feature.dataclass_feature import (
Feature,
NeutralLoss,
)
from fermo_core.data_processing.class_repository import Repository
from fermo_core.data_processing.class_stats import Stats
from fermo_core.input_output.class_parameter_manager import ParameterManager
from fermo_core.input_output.input_file_parameter_managers import MsmsParameters
from fermo_core.input_output.core_module_parameter_managers import NeutralLossParameters
from fermo_core.input_output.input_file_parameter_managers import PeaktableParameters
from fermo_core.input_output.input_file_parameter_managers import (
MsmsParameters,
PeaktableParameters,
)
from fermo_core.utils.utility_method_manager import UtilityMethodManager as Utils


Expand Down Expand Up @@ -49,7 +52,6 @@ def annotator_pos():
format="mzmine3",
polarity="positive",
)
params.NeutralLossParameters = NeutralLossParameters(nonbiological=True)
return NeutralLossAnnotator(
features=features, samples=Repository(), params=params, stats=stats
)
Expand Down Expand Up @@ -86,7 +88,6 @@ def annotator_neg():
format="mzmine3",
polarity="negative",
)
params.NeutralLossParameters = NeutralLossParameters(nonbiological=True)
return NeutralLossAnnotator(
features=features, samples=Repository(), params=params, stats=stats
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def test_set_rt_range_invalid():


def test_set_fwhm_valid():
feature1 = FeatureBuilder().set_fwhm(12.34).get_result()
feature1 = FeatureBuilder().set_fwhm(12.34, "sample1").get_result()
assert feature1.fwhm == 12.34


Expand Down
Loading

0 comments on commit dfacf62

Please sign in to comment.