99import logging
1010from functools import partial
1111from pathlib import Path
12+ import re
1213from typing import TYPE_CHECKING
1314
1415from omc3 .sbs_propagation import segment_by_segment
@@ -71,7 +72,7 @@ def connect_signals(self):
7172 view .add_settings_to_menu (
7273 menu = "View" ,
7374 settings = self .settings .plotting ,
74- hook = partial (self .plot , weak = True ), # update plots if possible
75+ hook = partial (self .plot , fail_ok = True ), # update plots if possible
7576 )
7677
7778 # Measurements -------------------------------------------------------------
@@ -488,10 +489,6 @@ def segment_selection_changed(self, segments: Sequence[SegmentItemModel] | None
488489 return
489490
490491 self .set_segment_interaction_buttons_enabled (True )
491- if len (segments ) > 1 :
492- LOGGER .debug ("More than one segment selected. Clearing Plots." )
493- return
494-
495492 self .plot ()
496493
497494 @Slot ()
@@ -524,7 +521,8 @@ def add_default_segements_to_measurement(self, measurement: OpticsMeasurement):
524521 segment = SegmentDataModel (measurement , * segment_tuple )
525522 segment .start = f"{ segment .start } .B{ measurement .beam } "
526523 segment .end = f"{ segment .end } .B{ measurement .beam } "
527- measurement .try_add_segment (segment )
524+ measurement .try_add_segment (segment , silent = True )
525+ return
528526
529527 # TODO: Implement for other accelerators
530528 LOGGER .error (f"No beam found in measurement { measurement .display ()} . Cannot add default segments." )
@@ -543,6 +541,7 @@ def new_segment(self):
543541
544542 LOGGER .debug ("Opening edit dialog for a new segment." )
545543 dialog = SegmentDialog (parent = view )
544+ dialog .validate_only_modified = False
546545 if dialog .exec_ () == dialog .Rejected :
547546 LOGGER .debug ("Segment dialog cancelled." )
548547 return
@@ -579,7 +578,7 @@ def copy_segment(self, segments: Sequence[SegmentItemModel] | None = None):
579578 return
580579
581580 for segment_item in segments :
582- new_segment_name = f"{ segment_item .name } - Copy "
581+ new_segment_name = f"{ segment_item .name } _copy "
583582 for measurement in selected_measurements :
584583 # Check if copied segment name already exists in one of the measurements
585584 try :
@@ -597,6 +596,7 @@ def copy_segment(self, segments: Sequence[SegmentItemModel] | None = None):
597596 for segment in segment_item .segments :
598597 new_segment = segment .copy ()
599598 new_segment .name = new_segment_name
599+ new_segment .measurement = measurement
600600 measurement .try_add_segment (new_segment )
601601
602602 self .measurement_selection_changed (selected_measurements )
@@ -619,16 +619,12 @@ def remove_segment(self, segments: Sequence[SegmentItemModel] | None = None):
619619 return
620620
621621 LOGGER .debug (f"Removing { len (segments )} segments." )
622- selected_measurements = view .get_selected_measurements ()
623- if not selected_measurements :
624- LOGGER .error ("Please select at least one measurement." )
625- return
626622
627- for measurement in selected_measurements :
628- for segment_item in segments :
629- measurement .try_remove_segment ( segment_item . name )
630-
631- self .measurement_selection_changed (selected_measurements )
623+ for segment_item in segments :
624+ for segment_data in segment_item . segments :
625+ segment_data . measurement .remove_segment ( segment_data )
626+
627+ self .measurement_selection_changed (view . get_selected_measurements () )
632628
633629 @Slot ()
634630 def load_segments (self ):
@@ -749,7 +745,7 @@ def clear_all():
749745 # -------------------------------------
750746
751747# Plotting ---------------------------------------------------------------------
752- def plot (self , weak : bool = False ):
748+ def plot (self , fail_ok : bool = False ):
753749 """ Trigger a plot update with the currently selected segments. """
754750 view : SbSWindow = self ._view
755751 settings : PlotSettings = self .settings .plotting
@@ -763,14 +759,27 @@ def plot(self, weak: bool = False):
763759 widget .set_connect_y (settings .connect_y )
764760
765761 segments = view .get_selected_segments ()
766- if len (segments ) != 1 :
767- if not weak :
762+ if not len (segments ):
763+ if not fail_ok :
768764 LOGGER .error ("Please select exactly one segment to plot." )
769765 return
770766
771- self .clear_plots ()
767+
768+ segments_data : list [SegmentDataModel ] = [s_data for s in segments for s_data in s .segments if s_data .has_run ()]
769+ if not len (segments_data ):
770+ if not fail_ok :
771+ LOGGER .error ("Please run at least one segment before plotting." )
772+ return
773+
774+ if settings .same_start :
775+ starts = {re .sub (r"\.B[12]$" , "" , s .start , flags = re .IGNORECASE ) for s in segments_data }
776+ if len (starts ) > 1 :
777+ if not fail_ok :
778+ LOGGER .error ("Please select segments with the same starting element." )
779+ return
772780
773- segments_data : list [SegmentDataModel ] = segments [0 ].segments
781+ self .clear_plots ()
782+
774783 plot_segment_data (
775784 widget = widget ,
776785 definition = definition ,
@@ -795,5 +804,5 @@ def show_settings(self):
795804 menu = "View" ,
796805 settings = self .settings .plotting ,
797806 )
798- self .plot (weak = True )
807+ self .plot (fail_ok = True )
799808
0 commit comments