Skip to content
Snippets Groups Projects
Commit 7f9378c8 authored by Maeva Pourpoint's avatar Maeva Pourpoint
Browse files

Add "Same as run *" functionality to the Runs tab. Ref #12.

parent 75e3d53a
No related branches found
No related tags found
1 merge request!27Feedback from data group
Pipeline #2125 passed with stage
in 5 minutes and 13 seconds
...@@ -19,6 +19,7 @@ from lemi2seed.gui_widgets import (load_ui, BaseWidget, NetWidgets, ...@@ -19,6 +19,7 @@ from lemi2seed.gui_widgets import (load_ui, BaseWidget, NetWidgets,
get_channel_widgets) get_channel_widgets)
from lemi2seed.lemi_metadata import LemiMetadata from lemi2seed.lemi_metadata import LemiMetadata
from lemi2seed.logging import parse_config_ini, setup_logger from lemi2seed.logging import parse_config_ini, setup_logger
from lemi2seed.metadata_category import MSG_MAP
from lemi2seed.metadata_conversion import write_stationxml from lemi2seed.metadata_conversion import write_stationxml
from lemi2seed.utils import get_e_ids, get_run_list, NUM_E_CHA_MAX from lemi2seed.utils import get_e_ids, get_run_list, NUM_E_CHA_MAX
...@@ -165,6 +166,12 @@ class LemiWindow(*load_ui('mainwindow.ui')): ...@@ -165,6 +166,12 @@ class LemiWindow(*load_ui('mainwindow.ui')):
if filename: if filename:
self.lemi_md.save_md(filename) self.lemi_md.save_md(filename)
def get_run_widgets(self, run_id):
return getattr(self, f'run_{run_id}_widgets')
def set_run_widgets(self, run_id, val):
setattr(self, f'run_{run_id}_widgets', val)
def set_num_runs_form(self): def set_num_runs_form(self):
""" """
Set up number of runs form. There is one form for all runs. This form Set up number of runs form. There is one form for all runs. This form
...@@ -204,11 +211,78 @@ class LemiWindow(*load_ui('mainwindow.ui')): ...@@ -204,11 +211,78 @@ class LemiWindow(*load_ui('mainwindow.ui')):
layout_run_starttime.setFormAlignment(QtCore.Qt.AlignLeft) layout_run_starttime.setFormAlignment(QtCore.Qt.AlignLeft)
return layout_run_starttime return layout_run_starttime
def get_run_widgets(self, run_id): def submit_run_cha_md(self, run_id, elec_bool=False, mag_bool=False):
return getattr(self, f'run_{run_id}_widgets') """
Submit run and channel metadata entries provided by the user up to this
point before checking validity of metadata fields to be copied.
Submit policy set in BaseWidget is Manual.
"""
# -- Run --
run = self.get_run_widgets(run_id)
run.mapper.submit()
# -- Electric --
if elec_bool:
name = f'run_{run_id}_num_e_pairs'
num_e_pairs_submit = getattr(self, name, NUM_E_CHA_MAX)
for ind in range(1, num_e_pairs_submit + 1):
e_pair = self.get_elec_pair_widgets(run_id, ind)
e_pair.mapper.submit()
# -- Magnetic --
if mag_bool:
mag = self.get_mag_widgets(run_id)
mag.mapper.submit()
def set_run_widgets(self, run_id, val): def check_before_reset(self, run_id_same_as, run_id, type_):
setattr(self, f'run_{run_id}_widgets', val) """
Check/Validate metadata fields for both runs before copying electric or
magnetic metadata fields from one run to the other.
"""
cha_type = MSG_MAP[type_.capitalize()]
logger.info(f"{'-'*20} Checking metadata fields for run '{run_id_same_as}' "
f"before copying {cha_type} metadata fields from run "
f"'{run_id_same_as}' to run '{run_id}'. Any incomplete or "
"invalid metadata fields may prevent the auto-filling "
"process from succesfully completing. Look for potential"
f"error messages below {'-'*20}.")
self.validate_run(run_id_same_as)
if cha_type != 'run':
validate_method = f"validate_{type_}"
methodcaller(validate_method, run_id_same_as)(self)
logger.info(f"{'-'*20} End of metadata field checks for run "
f"'{run_id_same_as}' {'-'*20}.")
def reset_run_model(self, run_id_same_as, run_id):
"""
Reset current run metadata model based on a user-selected run id.
Called when selecting the "Same as run" option for run_id > a.
"""
self.submit_run_cha_md(run_id_same_as)
self.check_before_reset(run_id_same_as, run_id, 'run')
md = self.lemi_md.for_gui
key = f'Run_{run_id}'
key_same_as = f'Run_{run_id_same_as}'
md['Run'][key].update(md['Run'][key_same_as])
model = TreeModel(("Field", "Value"), md)
run = self.get_run_widgets(run_id)
run.set_model(model, f'Run_{run_id}')
def set_cha_same_as_forms(self, cha_type, run_id):
"""
Set up "same as run" form.
Called when there is more than one run and selecting the "Same as run option.
"""
run_ids = self.run_list[:self.run_list.index(run_id)]
layout_same_as = QtWidgets.QFormLayout()
uiRunIdSameAs = QtWidgets.QComboBox()
uiRunIdSameAs.addItems(run_ids)
for ind, id in enumerate(run_ids):
tip_msg = (f'Same {cha_type} metadata field values as Run {id}.')
uiRunIdSameAs.setItemData(ind, tip_msg, QtCore.Qt.ToolTipRole)
reset_method = f'reset_{cha_type}_model'
uiRunIdSameAs.textActivated.connect(lambda text, val=run_id: methodcaller(reset_method, text, val)(self))
layout_same_as.addRow('Same as run', uiRunIdSameAs)
layout_same_as.setFormAlignment(QtCore.Qt.AlignLeft)
return layout_same_as
def set_run_editor_forms(self): def set_run_editor_forms(self):
"""Set up run editor form. There is one form per run id.""" """Set up run editor form. There is one form per run id."""
...@@ -220,9 +294,14 @@ class LemiWindow(*load_ui('mainwindow.ui')): ...@@ -220,9 +294,14 @@ class LemiWindow(*load_ui('mainwindow.ui')):
self.sta_widgets.uiRunsEditor.addWidget(uiTabs) self.sta_widgets.uiRunsEditor.addWidget(uiTabs)
for run_id in self.run_list: for run_id in self.run_list:
uiRun = QtWidgets.QWidget() uiRun = QtWidgets.QWidget()
layout_run = QtWidgets.QVBoxLayout() layout_run_option = QtWidgets.QHBoxLayout()
layout_run_starttime = self.set_run_starttime_form(run_id) layout_run_starttime = self.set_run_starttime_form(run_id)
layout_run.addLayout(layout_run_starttime) layout_run_option.addLayout(layout_run_starttime)
if run_id != 'a':
layout_run_same_as = self.set_cha_same_as_forms('run', run_id)
layout_run_option.addLayout(layout_run_same_as)
layout_run = QtWidgets.QVBoxLayout()
layout_run.addLayout(layout_run_option)
layout_run.addSpacing(5) layout_run.addSpacing(5)
self.set_run_widgets(run_id, RunWidgets(self)) self.set_run_widgets(run_id, RunWidgets(self))
layout_run.addWidget(self.get_run_widgets(run_id)) layout_run.addWidget(self.get_run_widgets(run_id))
...@@ -322,56 +401,18 @@ class LemiWindow(*load_ui('mainwindow.ui')): ...@@ -322,56 +401,18 @@ class LemiWindow(*load_ui('mainwindow.ui')):
electrode pairs can be infered from the 'components recorded' metadata electrode pairs can be infered from the 'components recorded' metadata
field. field.
""" """
e_comps = self.lemi_md.get_comps_rec('E', run_id, msg=False) if self.lemi_md.run else [] e_comps = self.lemi_md.get_comps_rec('E', run_id) if self.lemi_md.run else []
num_e_pairs = len(e_comps) num_e_pairs = len(e_comps)
uiNumEPairs = getattr(self, f'run_{run_id}_num_e_pairs_widgets') uiNumEPairs = getattr(self, f'run_{run_id}_num_e_pairs_widgets')
uiNumEPairs.setCurrentIndex(VALID_NUM_E_PAIRS.index(num_e_pairs)) uiNumEPairs.setCurrentIndex(VALID_NUM_E_PAIRS.index(num_e_pairs))
self.update_elec_pair_forms(num_e_pairs, run_id) self.update_elec_pair_forms(num_e_pairs, run_id)
def submit_run_cha_md(self, run_list, elec_bool=False, mag_bool=False):
"""Submit run and channel metadata entries."""
for run_id in run_list:
# -- Run --
run = self.get_run_widgets(run_id)
run.mapper.submit()
# -- Electric --
if elec_bool:
name = f'run_{run_id}_num_e_pairs'
num_e_pairs_submit = getattr(self, name, NUM_E_CHA_MAX)
for ind in range(1, num_e_pairs_submit + 1):
e_pair = self.get_elec_pair_widgets(run_id, ind)
e_pair.mapper.submit()
# -- Magnetic --
if mag_bool:
mag = self.get_mag_widgets(run_id)
mag.mapper.submit()
def check_before_reset(self, run_id_same_as, run_id, type_):
"""
Check/Validate metadata fields for both runs before copying electric or
magnetic metadata fields from one run to the other.
"""
cha_type = 'electric' if type_ == 'elec' else 'magnetic'
logger.info(f"{'-'*20} Checking metadata fields for runs '{run_id_same_as}' "
f"and '{run_id}' before copying {cha_type} metadata fields "
f"from run '{run_id_same_as}' to run '{run_id}'. Any "
"incomplete or invalid metadata fields may prevent the "
"auto-filling process from succesfully completing. Look "
f"for potential error messages below {'-'*20}.")
self.validate_run(run_id_same_as)
self.validate_run(run_id)
validate_method = f"validate_{type_}"
methodcaller(validate_method, run_id_same_as)(self)
logger.info(f"{'-'*20} End of metadata field checks for runs "
f"'{run_id_same_as}' and '{run_id}' {'-'*20}.")
def reset_elec_model(self, run_id_same_as, run_id): def reset_elec_model(self, run_id_same_as, run_id):
""" """
Reset current electric metadata model for a given run id. Reset current electric metadata model based on a user-selected run id.
Called when there is more than one run and selecting the "Same as run" Called when selecting the "Same as run" option for run_id > a.
option for run_id > a.
""" """
self.submit_run_cha_md([run_id_same_as, run_id], elec_bool=True) self.submit_run_cha_md(run_id_same_as, elec_bool=True)
self.check_before_reset(run_id_same_as, run_id, 'elec') self.check_before_reset(run_id_same_as, run_id, 'elec')
md = self.lemi_md.for_gui md = self.lemi_md.for_gui
for ind_cha in range(1, NUM_E_CHA_MAX + 1): for ind_cha in range(1, NUM_E_CHA_MAX + 1):
...@@ -383,25 +424,6 @@ class LemiWindow(*load_ui('mainwindow.ui')): ...@@ -383,25 +424,6 @@ class LemiWindow(*load_ui('mainwindow.ui')):
e_pair = self.get_elec_pair_widgets(run_id, ind_cha) e_pair = self.get_elec_pair_widgets(run_id, ind_cha)
e_pair.set_model(model, f'Run_{run_id}_Elec_Pair_{ind_cha}') e_pair.set_model(model, f'Run_{run_id}_Elec_Pair_{ind_cha}')
def set_cha_same_as_forms(self, cha_type, run_id):
"""
Set up "same as run" form.
Called when there is more than one run and selecting the "Same as run"
option for run id > a.
"""
run_ids = self.run_list[:self.run_list.index(run_id)]
layout_elec_same_as = QtWidgets.QFormLayout()
uiRunIdSameAs = QtWidgets.QComboBox()
uiRunIdSameAs.addItems(run_ids)
for ind, id in enumerate(run_ids):
tip_msg = (f'Same metadata field values as Run {id}.')
uiRunIdSameAs.setItemData(ind, tip_msg, QtCore.Qt.ToolTipRole)
reset_method = f'reset_{cha_type}_model'
uiRunIdSameAs.textActivated.connect(lambda text, val=run_id: methodcaller(reset_method, text, val)(self))
layout_elec_same_as.addRow('Same as run', uiRunIdSameAs)
layout_elec_same_as.setFormAlignment(QtCore.Qt.AlignLeft)
return layout_elec_same_as
def set_elec_editor_forms(self, ElecWidgets): def set_elec_editor_forms(self, ElecWidgets):
""" """
Set up the electric editor form for all runs. Set up the electric editor form for all runs.
...@@ -436,11 +458,10 @@ class LemiWindow(*load_ui('mainwindow.ui')): ...@@ -436,11 +458,10 @@ class LemiWindow(*load_ui('mainwindow.ui')):
def reset_mag_model(self, run_id_same_as, run_id): def reset_mag_model(self, run_id_same_as, run_id):
""" """
Reset current magnetic metadata model for a given run id. Reset current magnetic metadata model based on a user-selected run id.
Called when there is more than one run and selecting the "Same as run" Called when selecting the "Same as run" option for run_id > a.
option for run_id > a.
""" """
self.submit_run_cha_md([run_id_same_as, run_id], mag_bool=True) self.submit_run_cha_md(run_id_same_as, mag_bool=True)
self.check_before_reset(run_id_same_as, run_id, 'mag') self.check_before_reset(run_id_same_as, run_id, 'mag')
md = self.lemi_md.for_gui md = self.lemi_md.for_gui
key = f'Run_{run_id}_Mag' key = f'Run_{run_id}_Mag'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment