diff --git a/GUI_draft_live.py b/GUI_draft_live.py
index 064c80da0c6a4fac5094f54d3e54b1cb14b0d63d..edb8741ab4c0d21b9ce1b8dee262eb196c45d94a 100644
--- a/GUI_draft_live.py
+++ b/GUI_draft_live.py
@@ -9,12 +9,17 @@ from PyQt5.QtWidgets import (
     QApplication, QMainWindow, QGraphicsView, QGraphicsScene,
     QGraphicsEllipseItem, QGraphicsPixmapItem, QPushButton,
     QHBoxLayout, QVBoxLayout, QWidget, QFileDialog, QGraphicsTextItem,
-    QSlider, QLabel
+    QSlider, QLabel, QCheckBox, QGridLayout, QSizePolicy
 )
-from PyQt5.QtGui import QPixmap, QPen, QBrush, QColor, QFont
+from PyQt5.QtGui import QPixmap, QPen, QBrush, QColor, QFont, QImage
 from PyQt5.QtCore import Qt, QRectF, QSize
 
-from live_wire import compute_cost_image, find_path
+# Make sure the following imports exist in live_wire.py (or similar):
+#   from skimage import exposure
+#   from skimage.filters import gaussian
+#   def preprocess_image(image, sigma=3, clip_limit=0.01): ...
+
+from live_wire import compute_cost_image, find_path, preprocess_image
 
 
 # ------------------------------------------------------------------------
@@ -28,6 +33,9 @@ class PanZoomGraphicsView(QGraphicsView):
         self._panning = False
         self._pan_start = None
 
+        # Let it expand in layouts
+        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+
     def wheelEvent(self, event):
         """
         Zoom in/out with mouse wheel.
@@ -72,15 +80,9 @@ class PanZoomGraphicsView(QGraphicsView):
 
 # ------------------------------------------------------------------------
 # A specialized PanZoomGraphicsView for the circle editor
-#    - Only pan if user did NOT click on the draggable circle
-#    - If the mouse is over the circle item, scrolling changes radius
 # ------------------------------------------------------------------------
 class CircleEditorGraphicsView(PanZoomGraphicsView):
     def __init__(self, circle_editor_widget, parent=None):
-        """
-        :param circle_editor_widget: Reference to the parent CircleEditorWidget
-                                     so we can communicate (e.g. update slider).
-        """
         super().__init__(parent)
         self._circle_editor_widget = circle_editor_widget
 
@@ -116,7 +118,7 @@ class CircleEditorGraphicsView(PanZoomGraphicsView):
             if isinstance(it, DraggableCircleItem):
                 # Scroll up -> increase radius, scroll down -> decrease
                 delta = event.angleDelta().y()
-                # each wheel "notch" is typically 120, so let's do small steps
+                # each wheel "notch" is typically 120
                 step = 1 if delta > 0 else -1
 
                 old_r = it.radius()
@@ -232,7 +234,7 @@ class CircleEditorWidget(QWidget):
         Called by CircleEditorGraphicsView when the user scrolls on the circle item.
         We sync the slider to the new radius.
         """
-        self._slider.blockSignals(True)  # to avoid recursively calling set_radius
+        self._slider.blockSignals(True)
         self._slider.setValue(new_radius)
         self._slider.blockSignals(False)
 
@@ -347,8 +349,12 @@ class ImageGraphicsView(PanZoomGraphicsView):
         self.cost_image_original = None
         self.cost_image = None
 
-        # Rainbow toggle
-        self._rainbow_enabled = True
+        # Rainbow toggle => start with OFF
+        self._rainbow_enabled = False
+
+        # Smoothing parameters
+        self._savgol_window_length = 7
+        self._savgol_polyorder = 1
 
     def set_rainbow_enabled(self, enabled: bool):
         """Enable/disable rainbow mode, then rebuild the path."""
@@ -360,6 +366,29 @@ class ImageGraphicsView(PanZoomGraphicsView):
         self._rainbow_enabled = not self._rainbow_enabled
         self._rebuild_full_path()
 
+    def set_savgol_window_length(self, wlen: int):
+        """
+        Set the window length for the Savitzky-Golay filter and update polyorder
+        based on window_length_polyorder_ratio.
+        """
+        # SavGol requires window_length to be odd and >= 3
+        if wlen < 3:
+            wlen = 3
+        if wlen % 2 == 0:
+            wlen += 1
+
+        self._savgol_window_length = wlen
+
+        # polyorder is nearest integer to (window_length / 7)
+        # but must be >= 1 and < window_length
+        p = round(wlen / 7.0)
+        p = max(1, p)
+        if p >= wlen:
+            p = wlen - 1
+        self._savgol_polyorder = p
+
+        self._rebuild_full_path()
+
     # --------------------------------------------------------------------
     # LOADING
     # --------------------------------------------------------------------
@@ -407,7 +436,7 @@ class ImageGraphicsView(PanZoomGraphicsView):
 
     def _add_guide_point(self, x, y):
         x_clamped = self._clamp(x, self.dot_radius, self._img_w - self.dot_radius)
-        y_clamped = self._clamp(y, self.dot_radius, self._img_h - self.dot_radius)
+        y_clamped = self._clamp(y, self.dot_radius, self._img_w - self.dot_radius)
 
         self._revert_cost_to_original()
 
@@ -553,9 +582,14 @@ class ImageGraphicsView(PanZoomGraphicsView):
                 if len(sub_xy) > 1:
                     big_xy.extend(sub_xy[1:])
 
-        if len(big_xy) >= 7:
+        if len(big_xy) >= self._savgol_window_length:
             arr_xy = np.array(big_xy)
-            smoothed = savgol_filter(arr_xy, window_length=7, polyorder=1, axis=0)
+            smoothed = savgol_filter(
+                arr_xy,
+                window_length=self._savgol_window_length,
+                polyorder=self._savgol_polyorder,
+                axis=0
+            )
             big_xy = smoothed.tolist()
 
         self._full_path_xy = big_xy[:]
@@ -605,7 +639,7 @@ class ImageGraphicsView(PanZoomGraphicsView):
         return QColor.fromHsv(hue, saturation, value)
 
     # --------------------------------------------------------------------
-    # MOUSE EVENTS (with pan & zoom from PanZoomGraphicsView)
+    # MOUSE EVENTS
     # --------------------------------------------------------------------
     def mousePressEvent(self, event):
         if event.button() == Qt.LeftButton:
@@ -750,6 +784,113 @@ class ImageGraphicsView(PanZoomGraphicsView):
         return self._full_path_xy
 
 
+# ------------------------------------------------------------------------
+# Advanced Settings Widget
+# ------------------------------------------------------------------------
+class AdvancedSettingsWidget(QWidget):
+    def __init__(self, main_window, parent=None):
+        super().__init__(parent)
+        self._main_window = main_window  # to call e.g. main_window.open_circle_editor()
+
+        main_layout = QVBoxLayout()
+        self.setLayout(main_layout)
+
+        # A small grid for the controls (buttons/sliders)
+        controls_layout = QGridLayout()
+
+        # 1) Rainbow toggle
+        self.btn_toggle_rainbow = QPushButton("Toggle Rainbow")
+        self.btn_toggle_rainbow.clicked.connect(self._on_toggle_rainbow)
+        controls_layout.addWidget(self.btn_toggle_rainbow, 0, 0)
+
+        # 2) Circle editor
+        self.btn_circle_editor = QPushButton("Open Circle Editor")
+        self.btn_circle_editor.clicked.connect(self._main_window.open_circle_editor)
+        controls_layout.addWidget(self.btn_circle_editor, 0, 1)
+
+        # 3) Line smoothing slider + label
+        lab_smoothing = QLabel("Line smoothing (SavGol window_length)")
+        controls_layout.addWidget(lab_smoothing, 1, 0)
+        self.line_smoothing_slider = QSlider(Qt.Horizontal)
+        self.line_smoothing_slider.setRange(3, 51)  # allow from 3 to 51
+        self.line_smoothing_slider.setValue(7)      # default
+        self.line_smoothing_slider.valueChanged.connect(self._on_line_smoothing_slider)
+        controls_layout.addWidget(self.line_smoothing_slider, 1, 1)
+
+        # 4) Contrast slider + label
+        lab_contrast = QLabel("Contrast (clip_limit)")
+        controls_layout.addWidget(lab_contrast, 2, 0)
+        self.contrast_slider = QSlider(Qt.Horizontal)
+        self.contrast_slider.setRange(0, 100)  # 0..100 => 0..1 with step of 0.01
+        self.contrast_slider.setValue(1)       # default is 0.01
+        self.contrast_slider.valueChanged.connect(self._on_contrast_slider)
+        controls_layout.addWidget(self.contrast_slider, 2, 1)
+
+        main_layout.addLayout(controls_layout)
+
+        # Now a horizontal layout for the two images
+        images_layout = QHBoxLayout()
+
+        # Contrasted blurred
+        self.label_contrasted_blurred = QLabel()
+        self.label_contrasted_blurred.setText("CONTRASTED BLURRED IMG")
+        self.label_contrasted_blurred.setAlignment(Qt.AlignCenter)
+        self.label_contrasted_blurred.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+        self.label_contrasted_blurred.setScaledContents(True)
+        images_layout.addWidget(self.label_contrasted_blurred)
+
+        # Cost image
+        self.label_cost_image = QLabel()
+        self.label_cost_image.setText("Current COST IMAGE")
+        self.label_cost_image.setAlignment(Qt.AlignCenter)
+        self.label_cost_image.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+        self.label_cost_image.setScaledContents(True)
+        images_layout.addWidget(self.label_cost_image)
+
+        main_layout.addLayout(images_layout)
+
+    def _on_toggle_rainbow(self):
+        self._main_window.toggle_rainbow()
+
+    def _on_line_smoothing_slider(self, value):
+        self._main_window.image_view.set_savgol_window_length(value)
+
+    def _on_contrast_slider(self, value):
+        clip_limit = value / 100.0
+        self._main_window.update_contrast(clip_limit)
+
+    def update_displays(self, contrasted_img_np, cost_img_np):
+        """
+        Called by main_window to refresh the two images in the advanced panel.
+        contrasted_img_np = the grayscaled blurred+contrasted image as float or 0-1 array
+        cost_img_np = the current cost image (numpy array)
+        """
+        cb_pix = self._np_array_to_qpixmap(contrasted_img_np)
+        cost_pix = self._np_array_to_qpixmap(cost_img_np, normalize=True)
+
+        if cb_pix is not None:
+            self.label_contrasted_blurred.setPixmap(cb_pix)
+        if cost_pix is not None:
+            self.label_cost_image.setPixmap(cost_pix)
+
+    def _np_array_to_qpixmap(self, arr, normalize=False):
+        if arr is None:
+            return None
+        arr_ = arr.copy()
+        if normalize:
+            mn, mx = arr_.min(), arr_.max()
+            if abs(mx - mn) < 1e-12:
+                arr_[:] = 0
+            else:
+                arr_ = (arr_ - mn) / (mx - mn)
+        arr_ = np.clip(arr_, 0, 1)
+        arr_255 = (arr_ * 255).astype(np.uint8)
+
+        h, w = arr_255.shape
+        qimage = QImage(arr_255.data, w, h, w, QImage.Format_Grayscale8)
+        return QPixmap.fromImage(qimage)
+
+
 # ------------------------------------------------------------------------
 # Main Window
 # ------------------------------------------------------------------------
@@ -759,19 +900,25 @@ class MainWindow(QMainWindow):
         self.setWindowTitle("Test GUI")
 
         self._last_loaded_pixmap = None
-        self._circle_radius_for_later_use = 0
+        self._circle_calibrated_radius = 6
+        self._last_loaded_file_path = None
 
-        # Original main widget
+        # For the contrast slider
+        self._current_clip_limit = 0.01
+
+        # Outer widget + layout
         self._main_widget = QWidget()
-        self._main_layout = QVBoxLayout(self._main_widget)
+        self._main_layout = QHBoxLayout(self._main_widget)  # horizontal so we can place advanced on the right
+        self._left_panel = QVBoxLayout()  # for the image & row of buttons
+        self._main_layout.addLayout(self._left_panel)
+        self.setCentralWidget(self._main_widget)
 
         # Image view
         self.image_view = ImageGraphicsView()
-        self._main_layout.addWidget(self.image_view)
+        self._left_panel.addWidget(self.image_view)
 
         # Button row
         btn_layout = QHBoxLayout()
-
         self.btn_load_image = QPushButton("Load Image")
         self.btn_load_image.clicked.connect(self.load_image)
         btn_layout.addWidget(self.btn_load_image)
@@ -784,36 +931,41 @@ class MainWindow(QMainWindow):
         self.btn_clear_points.clicked.connect(self.clear_points)
         btn_layout.addWidget(self.btn_clear_points)
 
-        self.btn_toggle_rainbow = QPushButton("Toggle Rainbow")
-        self.btn_toggle_rainbow.clicked.connect(self.toggle_rainbow)
-        btn_layout.addWidget(self.btn_toggle_rainbow)
-
-        # New circle editor button
-        self.btn_open_editor = QPushButton("Open Circle Editor")
-        self.btn_open_editor.clicked.connect(self.open_circle_editor)
-        btn_layout.addWidget(self.btn_open_editor)
+        # "Advanced Settings" button
+        self.btn_advanced = QPushButton("Advanced Settings")
+        self.btn_advanced.setCheckable(True)
+        self.btn_advanced.clicked.connect(self._toggle_advanced_settings)
+        btn_layout.addWidget(self.btn_advanced)
 
-        self._main_layout.addLayout(btn_layout)
-        self.setCentralWidget(self._main_widget)
+        self._left_panel.addLayout(btn_layout)
 
-        self.resize(900, 600)
+        # Create advanced settings widget (hidden by default)
+        self._advanced_widget = AdvancedSettingsWidget(self)
+        self._advanced_widget.hide()
+        self._main_layout.addWidget(self._advanced_widget)
 
-        # We keep references for old/new
+        self.resize(1000, 600)
         self._old_central_widget = None
         self._editor = None
 
+    def _toggle_advanced_settings(self, checked):
+        if checked:
+            self._advanced_widget.show()
+        else:
+            self._advanced_widget.hide()
+        # Ask Qt to re-layout the window so it can expand/shrink as needed:
+        self.adjustSize()
+
     def open_circle_editor(self):
         """Removes the current central widget, replaces with circle editor."""
         if not self._last_loaded_pixmap:
             print("No image loaded yet! Cannot open circle editor.")
             return
 
-        # Step 1: take the old widget out of QMainWindow ownership
         old_widget = self.takeCentralWidget()
         self._old_central_widget = old_widget
 
-        # Step 2: create the editor
-        init_radius = 20
+        init_radius = self._circle_calibrated_radius
         editor = CircleEditorWidget(
             pixmap=self._last_loaded_pixmap,
             init_radius=init_radius,
@@ -821,31 +973,36 @@ class MainWindow(QMainWindow):
         )
         self._editor = editor
 
-        # Step 3: set the new editor as the central widget
         self.setCentralWidget(editor)
 
     def _on_circle_editor_done(self, final_radius):
-        self._circle_radius_for_later_use = final_radius
+        self._circle_calibrated_radius = final_radius
         print(f"Circle Editor done. Radius = {final_radius}")
 
-        # Take the editor out
+        if self._last_loaded_file_path:
+            cost_img = compute_cost_image(
+                self._last_loaded_file_path,
+                self._circle_calibrated_radius,
+                clip_limit=self._current_clip_limit
+            )
+            self.image_view.cost_image_original = cost_img
+            self.image_view.cost_image = cost_img.copy()
+            self.image_view._apply_all_guide_points_to_cost()
+            self.image_view._rebuild_full_path()
+            self._update_advanced_images()
+
         editor_widget = self.takeCentralWidget()
         if editor_widget is not None:
             editor_widget.setParent(None)
 
-        # Put back the old widget
         if self._old_central_widget is not None:
             self.setCentralWidget(self._old_central_widget)
             self._old_central_widget = None
 
-        # We can delete the editor if we like
         if self._editor is not None:
             self._editor.deleteLater()
             self._editor = None
 
-    # --------------------------------------------------------------------
-    # Existing Functions
-    # --------------------------------------------------------------------
     def toggle_rainbow(self):
         self.image_view.toggle_rainbow()
 
@@ -858,15 +1015,60 @@ class MainWindow(QMainWindow):
         )
         if file_path:
             self.image_view.load_image(file_path)
-            cost_img = compute_cost_image(file_path)
+
+            cost_img = compute_cost_image(
+                file_path,
+                self._circle_calibrated_radius,
+                clip_limit=self._current_clip_limit
+            )
             self.image_view.cost_image_original = cost_img
             self.image_view.cost_image = cost_img.copy()
 
-            # Store a pixmap to reuse
             pm = QPixmap(file_path)
             if not pm.isNull():
                 self._last_loaded_pixmap = pm
 
+            self._last_loaded_file_path = file_path
+            self._update_advanced_images()
+
+    def update_contrast(self, clip_limit):
+        self._current_clip_limit = clip_limit
+        if self._last_loaded_file_path:
+            cost_img = compute_cost_image(
+                self._last_loaded_file_path,
+                self._circle_calibrated_radius,
+                clip_limit=clip_limit
+            )
+            self.image_view.cost_image_original = cost_img
+            self.image_view.cost_image = cost_img.copy()
+            self.image_view._apply_all_guide_points_to_cost()
+            self.image_view._rebuild_full_path()
+
+        self._update_advanced_images()
+
+    def _update_advanced_images(self):
+        if not self._last_loaded_pixmap:
+            return
+
+        pm_np = self._qpixmap_to_gray_float(self._last_loaded_pixmap)
+        contrasted_blurred = preprocess_image(
+            pm_np,
+            sigma=3,
+            clip_limit=self._current_clip_limit
+        )
+        cost_img_np = self.image_view.cost_image
+        self._advanced_widget.update_displays(contrasted_blurred, cost_img_np)
+
+    def _qpixmap_to_gray_float(self, qpix):
+        img = qpix.toImage()
+        img = img.convertToFormat(QImage.Format_ARGB32)
+        ptr = img.bits()
+        ptr.setsize(img.byteCount())
+        arr = np.frombuffer(ptr, np.uint8).reshape((img.height(), img.width(), 4))
+        rgb = arr[..., :3].astype(np.float32)
+        gray = rgb.mean(axis=2) / 255.0
+        return gray
+
     def export_path(self):
         full_xy = self.image_view.get_full_path_xy()
         if not full_xy: