Skip to content

Commit

Permalink
Merge pull request #5 from DUNE-DAQ/hwallace/interface_patches
Browse files Browse the repository at this point in the history
Patches to shifter interface
  • Loading branch information
henry-wallace-phys authored Feb 13, 2025
2 parents 202e933 + 470e26b commit a2786ee
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 84 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"rich",
],
extras_require={"develop": ["ipdb", "ipython" "black"]},
package_data={"": ["*.tcss", "*.json"]},
package_data={"": ["*.tcss", "*.yml"]},
)
9 changes: 8 additions & 1 deletion src/cider/apps/shifter_view.tcss
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,15 @@ SelectCurrent{
width: 100%;
height: auto;
padding: 1;
background: $error;
text-style: bold;
layer: overlay;
content-align: center middle;
}

.popup_failure{
background: $error;
}

.popup_success{
background: $success
}
18 changes: 8 additions & 10 deletions src/cider/configuration/np02_configuration.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
# Triggers
TriggerMap:
TPG Enabled CRP4:
TPG Enabled CRP 4 and 5:
subsystems:
- id: tp_generation_enabled
type: attribute
class: ReadoutApplication
affected_objects: [runp02srv001eth0, runp02srv003eth1]
enabled_state: true
disabled_state: false
enabled: true

TPG Enabled CRP5:
subsystems:
disabled_state: false
- id: tp_generation_enabled
type: attribute
class: ReadoutApplication
affected_objects: [runp02srv002eth0, runp02srv003eth0]
enabled_state: true
disabled_state: false



enabled: true

TPG Enabled APA:
Expand All @@ -31,12 +28,12 @@ TriggerMap:
disabled_state: false
enabled: true

TA Enabled:
TPG Enabled PDS:
subsystems:
- id: ta_generation_enabled
- id: tp_generation_enabled
type: attribute
class: ReadoutApplication
affected_objects: null
affected_objects: [runp04srv026flx4]
enabled_state: true
disabled_state: false
enabled: true
Expand All @@ -50,6 +47,7 @@ DetectorSystemMap:
id: crp4-segment
enabled_state: true
disabled_state: false


enabled: true

Expand Down
33 changes: 21 additions & 12 deletions src/cider/screens/help_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,27 @@ def message(self):
"""\
[bold]Hello and welcome to the DAQ Shifter interface!![/bold]
To get started, please select a file from the dropdown menu and then select a session.
The configuration will be copied, and you can start enabling/disabling things in the detector.
Currently, 3 options are available:
- [bold]Detector Subsystem[/bold]
- [bold]Dataflow Applications[/bold]
- [bold]Triggers[/bold]
You can enable/disable these options by clicking on the buttons.
When you're happy, you can save/copy + quit the configuration editor and run it through DRUNC.
In addition, you can reset all changes by pressing the reset button.
To get started, please select a file from the dropdown menu and then select a session to modify. Press "open" to load the session.
Currently there are 3 categories of objects that can be enabled or disabled:
- [bold]Detector subsystems[/bold]: For example the APAs, PDS, etc.
- [bold]The Trigger System[/bold]: Triggers to enable/disable including trigger primitive generation
- [bold]Dataflow applications[/bold]: Objects that control dataflow
To disable/enable items simply press the buttons on the left side of the screen. Each set of objects is given its own tab.
In addition, we provide 3 views of the detector configuration, although this is mostly intended for expert use.
- [bold]Configuration view[/bold]: View a tree describing detector configuration
- [bold]Detector system view[/bold]: Summary of detector subsystems which are enabled/disabled
- [bold]Trigger View[/bold]: A summary of triggers/trigger objects which are enabled/disabled
Once you have made the desired changes, press the "Create" button to save the configuration. By default the current configuration is saved in the <RUN FOLDER>/current_config directory.
Older configurations are automatically moved to <RUN FOLDER>/old_configs/run_<DATE> when a new configuration is saved.
If you are unhappy with changes + want to revert to the original configuration, press the "Reset" button.
Finally to quit the interface, press the "Quit" button. The configuration can be run in drunc using the command provided after quitting.
If you have any questions, please contact the DAQ shifter on duty. Enjoy your shift!gi
"""
)

Expand Down
5 changes: 4 additions & 1 deletion src/cider/screens/quit_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ def on_button_pressed(self, event: Button.Pressed) -> None:
options = main_screen.query_one("OptionPanel")
if event.button.id == "quit_screen_savequit_button":
# HACK: This is a hack to save correctly
options.save_copy()
options.save_main()
options.save_backup()
self._saved_configuration_name = options.saved_configuration

self.app.exit(self.message())
Expand All @@ -79,7 +80,9 @@ def on_button_pressed(self, event: Button.Pressed) -> None:
if options.saved_configuration is None:
self.app.exit("[bold red]Exited without saving.")
else:
options.save_backup()
self._saved_configuration_name = options.saved_configuration
# To be sure!
self.app.exit(self.message(True))
else:
self.app.pop_screen()
60 changes: 39 additions & 21 deletions src/cider/screens/shifter_view_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from textual.css.query import NoMatches
from textual.reactive import reactive


from cider.interfaces.controller.config_wrapper import ConfigurationWrapper
from cider.widgets.single_component_panel import SingleComponentEnableDisablePanel
from cider.widgets.multicomponent_panel import MultiComponentEnableDisablePanel
Expand All @@ -15,26 +14,15 @@
from cider.utils.consolidate_file import ConsolidateFile
from cider.utils.daq_conf_tree import DaqConfTree, ComponentLevelTree


from pathlib import Path
import os
import yaml


class PopupMessage(Static):
"""A custom widget for displaying pop-up messages."""

def on_mount(self):
# Automatically remove the pop-up after 3 seconds
self.set_timer(10.0, self.remove_popup)

def remove_popup(self):
"""Remove the pop-up from the DOM."""
self.remove()
from cider.widgets.popup_message import PopupMessage


class ShifterViewScreen(Screen):

TMP_CONFIG = Path(f"/tmp/shifter_configs-{os.getlogin()}/tmp_config.data.xml")

changed_session = False
Expand Down Expand Up @@ -64,6 +52,9 @@ def __init__(
self._config_folder = config_folder
self._output_directory = output_directory

self._configuration = None
self._session = None

def compose(self):
"""
Generate the screen layout
Expand All @@ -73,7 +64,7 @@ def compose(self):

with Grid(id="enable_disable_panel_container"):
with TabbedContent(id="selection_tabs"):
with TabPane("Detector Component", id="detector_subsystem_tab"):
with TabPane("Detector Subsystems", id="detector_subsystem_tab"):
yield MultiComponentEnableDisablePanel(
None,
None,
Expand Down Expand Up @@ -102,7 +93,7 @@ def compose(self):
id="systematic_map_tabs",
classes="systematic_map_tabs",
):
with TabPane("Detector View", id="full_system_map_tab"):
with TabPane("Configuration View", id="full_system_map_tab"):
yield ScrollableContainer(
Static(
DaqConfTree(None, None).print_tree(),
Expand All @@ -111,6 +102,18 @@ def compose(self):
id="tree_view_full_container",
classes="tree_view_full_container",
)
with TabPane("Detector System View", id="det_system_tab"):
yield ScrollableContainer(
Static(
ComponentLevelTree(
None, None, self.detector_system_map
).print_tree(),
id="tree_view_det",
),
id="det_view_trigger_container",
)


with TabPane("Trigger View", id="trigger_system_tab"):
yield ScrollableContainer(
Static(
Expand Down Expand Up @@ -156,7 +159,7 @@ def show_popup(self, message: str):
self.remove_popup()

# Create and mount the pop-up
popup = PopupMessage(message, classes="popup")
popup = PopupMessage(message, classes="popup popup_failure")
self.query_one("#main_container").mount(popup)

def remove_popup(self):
Expand Down Expand Up @@ -200,6 +203,10 @@ def open_new_file(self):
if not session_name or not buffer_config:
pass

self._configuration = buffer_config
self._session = session_name


for a in self.query("EnableDisablePanel"):
a.open_new_session(buffer_config, session_name)
a.refresh(recompose=True)
Expand All @@ -209,20 +216,31 @@ def open_new_file(self):

def on_enable_disable_panel_changed(self, message: EnableDisablePanel.Changed):
for a in self.query("EnableDisablePanel"):
a.refresh(recompose=True)

a.update_button_styles()
self.update_trees(message.configuration, message.session)

def update_trees(self, configuration: ConfigurationWrapper, session: str):
main_tree = DaqConfTree(configuration, session)
self.query_one("#tree_view_full").update(main_tree.print_tree())
# For trigger info we need to hack
disabled = main_tree.disabled_objs

# We can also do a component level tree

detector_states = self.query_one("#detector_subsystem_panel").get_full_state_info()
detector_tree = ComponentLevelTree(
configuration, session, detector_states, "Detector Systems", disabled
)

self.query_one("#tree_view_det").update(detector_tree.print_tree())


# We also want trigger states
trigger_states = self.query_one("#trigger_panel").get_full_state_info()

trigger_tree = ComponentLevelTree(
configuration, session, trigger_states, disabled
configuration, session, trigger_states, "Triggers", disabled
)


self.query_one("#tree_view_trigger").update(trigger_tree.print_tree())
21 changes: 15 additions & 6 deletions src/cider/utils/daq_conf_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,18 @@ def __init__(
configuration: ConfigurationWrapper | None = None,
session: str | None = None,
system_info: dict = {},
label: str = "",
disabled_items=[],
):
self._system_info = system_info
self._disabled_items = disabled_items
self._extractor = SystemInfoExtractor(configuration, session)

self._label = label

super().__init__(configuration, session)

def generate_tree(self):
self._tree = Tree("[bold deep_pink4] Triggers")
self._tree = Tree(f"[bold deep_pink4] {self._label}")

trigger_labels = list(self._system_info.keys())

Expand All @@ -193,9 +195,16 @@ def generate_tree(self):

# Okay now we can grab each component

specific_comps = GetObjectsInSessionAction(self._configuration)(
session_dal, subsystem["class"], subsystem["affected_objects"]
)
if subsystem['type']=='attribute':
specific_comps = GetObjectsInSessionAction(self._configuration)(
session_dal, subsystem["class"], subsystem["affected_objects"]
)

system_name = subsystem['id']

else:
specific_comps = [ca.GetDalObjectAction(self._configuration)(subsystem["id"], subsystem["class"])]
system_name = ""

for c in specific_comps:
if enabled and c not in self._disabled_items:
Expand All @@ -206,7 +215,7 @@ def generate_tree(self):
text = "[bold]DISABLED"

trigger_tree.add(
f"[{colour}]{ca.GetAttributeAction(self._configuration)(c, 'id')} {text}"
f"[{colour}]{ca.GetAttributeAction(self._configuration)(c, 'id')} {system_name} {text}"
)

return self._tree
19 changes: 19 additions & 0 deletions src/cider/widgets/enable_disable_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def on_button_pressed(self, event: Button.Pressed):
return

self._button_action(objs_affected, button_name)
self.update_button_styles()
self.post_message(self.Changed(self._configuration, self._session_name))

def _button_action(self, objs_affected, button_name):
Expand Down Expand Up @@ -145,3 +146,21 @@ def get_current_states(self):

def get_full_state_info(self):
return self._button_list

def update_button_styles(self):
"""Update the styles of the buttons based on their current state."""
for button, information in self._button_list.items():
button_id = button.replace(" ", "_") + "_button"
try:
button_widget = self.query_one(f"#{button_id}", Button)
except:
return

if self.check_is_disabled(button, information):
button_widget.remove_class("detector_subsystem_button_enabled")
button_widget.add_class("detector_subsystem_button_disabled")
button_widget.label = f"{button} (Disabled)"
else:
button_widget.remove_class("detector_subsystem_button_disabled")
button_widget.add_class("detector_subsystem_button_enabled")
button_widget.label = f"{button} (Enabled)"
Loading

0 comments on commit a2786ee

Please sign in to comment.