Skip to content

Commit

Permalink
Added functionality for user input
Browse files Browse the repository at this point in the history
  • Loading branch information
omokshyna committed Nov 1, 2023
1 parent 4d30d73 commit 4faa081
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 21 deletions.
107 changes: 89 additions & 18 deletions library_spectra_validation/library_handler.py
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)



6 changes: 3 additions & 3 deletions library_spectra_validation/tests/test_spectra_loading.py
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")

0 comments on commit 4faa081

Please sign in to comment.