-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
92 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,107 @@ | ||
from matchms.importing import load_spectra | ||
from matchms.filtering.SpectrumProcessor import SpectrumProcessor | ||
from filters import PRIMARY_FILTERS | ||
from validation_pipeline import Modification, SpectrumRepairer, SpectrumValidator | ||
|
||
class LibraryHandler: | ||
"""Stores the 3 different types of spectra. Correct, repaired, wrong. | ||
Has internal organization using spectrum ids""" | ||
|
||
def __init__(self, f, pipeline): | ||
#todo modify default pipeline | ||
def __init__(self, f): | ||
metadata_field_harmonization = SpectrumProcessor(predefined_pipeline=None, | ||
additional_filters=PRIMARY_FILTERS) | ||
self.spectra = metadata_field_harmonization.process_spectrums(load_spectra(f)) | ||
self.pipeline = pipeline | ||
self.spectra_dictionary = { | ||
'valid': None, #[id1, id2,...] | ||
'repaired': None, #[id1:[modifications],..] | ||
'invalid': None #also a dictionary | ||
} | ||
self.modifications = {} #todo change to Modifications class | ||
self.spectrum_repairer = SpectrumRepairer() | ||
self.spectrum_validator = SpectrumValidator() | ||
self.validated_spectra = [] | ||
self.nonvalidated_spectra = [] | ||
self.modifications = {} | ||
self.failed_requirements = {} | ||
|
||
def clean_and_validate_spectrum(self, spectrum_id): | ||
spectrum = self.spectra[spectrum_id] | ||
modifications = self.pipeline.run(spectrum) | ||
spectrum_id.update_spectra_dictionary(spectrum_id, modifications) | ||
self.modifications.append(modifications) | ||
self.modifications[spectrum_id] = self.spectrum_repairer.process_spectrum_store_modifications(spectrum) | ||
self.failed_requirements[spectrum_id] = self.spectrum_validator.process_spectrum_store_failed_filters(spectrum) | ||
self.update_spectra_lists(spectrum_id) | ||
|
||
def update_spectra_dictionary(self, spectrum_id, modifications): | ||
self.spectra_dictionary[modifications["spectra_quality"]["updated"]].append(spectrum_id) #valid, repaired,... | ||
if ((modifications["spectra_quality"]["updated"] != None) & | ||
(modifications["spectra_quality"]["updated"] != modifications["spectra_quality"]["previous"])): | ||
self.spectra_dictionary[modifications["spectra_quality"]["previous"]].remove(spectrum_id) | ||
def update_spectra_lists(self, spectrum_id): | ||
if len(self.failed_requirements[spectrum_id]) == 0: | ||
self.validated_spectra.append(spectrum_id) | ||
self.nonvalidated_spectra.pop(spectrum_id) #todo populate with all ids after loading! | ||
# todo in case user modifies do the opposite | ||
|
||
def pass_user_validation_info(self, spectrum_id): | ||
''' | ||
This function is called only for nonvalidated spectra | ||
''' | ||
assert spectrum_id in self.nonvalidated_spectra | ||
|
||
modifications = self.modifications[spectrum_id] | ||
failed_requirements = self.failed_requirements[spectrum_id] | ||
|
||
return modifications, failed_requirements, self.spectra[spectrum_id] | ||
|
||
def user_approve_repair(self, field_name, approved_all: bool, rejected_all: bool, spectrum_id): | ||
''' | ||
This function allows user to accept or decline all or part of modifications | ||
''' | ||
modifications = self.modifications[spectrum_id] | ||
if approved_all: | ||
for modification in modifications: | ||
if modification.metadata_field == field_name: | ||
# self.modifications[spectrum_id].pop(modification) #todo test this!! | ||
self.modifications[spectrum_id].validated_by_user = True | ||
#if user rejects the changes | ||
#todo implement the case when user rejects not all changes | ||
elif rejected_all: | ||
for modification in modifications: | ||
#todo should we use before/original/first modification | ||
self.spectra[spectrum_id].get(modification.metadata_field).set(modification.before) | ||
modifications.pop(spectrum_id) | ||
self.failed_requirements[spectrum_id] = self.spectrum_validator.process_spectrum_store_failed_filters(self.spectra[spectrum_id]) | ||
self.update_spectra_lists(spectrum_id) | ||
else: | ||
#todo implement!!!! | ||
#only the last one | ||
return None | ||
|
||
|
||
def user_metadata_change(self, field_name, user_input, spectrum_id): | ||
''' | ||
This function takes user defined metadata and rewrites the required field in spectra | ||
The info on user-defined modifications is added to modifications dictionary and mandatory | ||
validation is rerun. | ||
''' | ||
self.spectra[spectrum_id].set(field_name, user_input) #todo this is correct, fix everywhere | ||
#todo add user-defined modification to modifications list | ||
self.modifications[spectrum_id].append("User-defined modification in the field " + | ||
field_name + | ||
". Value changed to " + | ||
user_input) | ||
self.failed_requirements[spectrum_id] = self.spectrum_validator.process_spectrum_store_failed_filters(self.spectra[spectrum_id]) | ||
|
||
def user_rerun_repair(self, spectrum_id, rerun: bool): | ||
''' | ||
The function behind user's choice to rerun the repairment and validation | ||
Should be linked to a button in a dashboard | ||
''' | ||
if rerun: #todo do we even need it?? | ||
self.modifications[spectrum_id] = self.spectrum_repairer.process_spectrum_store_modifications(self.spectra[spectrum_id]) | ||
self.failed_requirements[spectrum_id] = self.spectrum_validator.process_spectrum_store_failed_filters(self.spectra[spectrum_id]) | ||
|
||
def run(self): | ||
#first check | ||
for spectrum_id in range(len(self.spectra)): | ||
self.clean_and_validate_spectrum(spectrum_id) | ||
# iterate over all failed requirements | ||
# it's almost streamlit | ||
# for the dashboard run should use spectrum id | ||
for spectrum_id in range(len(self.spectra)): | ||
self.clean_and_validate_spectrum(spectrum_id) | ||
if len(self.failed_requirements[spectrum_id]) != 0: | ||
self.pass_user_validation_info(spectrum_id) | ||
#todo should we grab here state variable from streamlit - accept or change | ||
# self.user_approve_repair(spectrum_id) | ||
# self.user_metadat_change(spectrum_id) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from library_spectra_validation.library_handler import LibraryHandler | ||
|
||
def test_load_spectra(): | ||
"""This is a first test that is not functional yet, to test the CI pipeline""" | ||
print("test_succesfull") | ||
assert True | ||
library_handler = LibraryHandler("./examples/test_case_correct.mgf") |