Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/sphinx-docs/source/user/menu_bar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ The File option allows you load data into *SasView* for analysis, or to save the
Data can be loaded one file at a time, or by selecting multiple files, or by loading an entire folder of
files (in which case *SasView* will attempt to make an intelligent guess as to what to load based on the
file formats it recognises in the folder!). Data can also be loaded by dragging and dropping files directly
onto Data Explorer.
onto Data Explorer. Additionally, datasets can be downloaded directly from the SASBDB (Small Angle Scattering
Biological Data Bank) using **File > Load from SASBDB...** (see :ref:`SASBDB_Download` for details).

A *SasView* session can also be saved and reloaded as an 'Analysis' (an individual model fit or invariant
calculation, etc), or as a 'Project' (everything you have done since starting your *SasView* session).
Expand Down
2 changes: 2 additions & 0 deletions docs/sphinx-docs/source/user/tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ Tools & Utilities

MuMag Tool <qtgui/Utilities/MuMag/mumag_help>

SASBDB Download <qtgui/Utilities/SASBDB/sasbdb_download_help>

19 changes: 19 additions & 0 deletions src/sas/qtgui/MainWindow/GuiManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ def addTriggers(self):
# File
self._workspace.actionLoadData.triggered.connect(self.actionLoadData)
self._workspace.actionLoad_Data_Folder.triggered.connect(self.actionLoad_Data_Folder)
self._workspace.actionLoad_SASBDB.triggered.connect(self.actionLoad_SASBDB)
self._workspace.actionOpen_Project.triggered.connect(self.actionOpen_Project)
self._workspace.actionOpen_Analysis.triggered.connect(self.actionOpen_Analysis)
self._workspace.actionSave.triggered.connect(self.actionSave_Project)
Expand Down Expand Up @@ -765,6 +766,24 @@ def actionLoad_Data_Folder(self):
"""
self.filesWidget.loadFolder()

def actionLoad_SASBDB(self):
"""
Menu File/Load from SASBDB

Opens a dialog to download and load a dataset from SASBDB.
"""
from sas.qtgui.Utilities.SASBDB.sasbdb_loader import load_downloaded_dataset
from sas.qtgui.Utilities.SASBDB.SASBDBDownloadDialog import SASBDBDownloadDialog

dialog = SASBDBDownloadDialog(parent=self._workspace)
if dialog.exec():
load_downloaded_dataset(
self.filesWidget,
self._workspace,
dialog.getDownloadedFilepath(),
dialog.getDatasetInfo(),
)

def actionOpen_Project(self):
"""
Menu Open Project
Expand Down
9 changes: 9 additions & 0 deletions src/sas/qtgui/MainWindow/UI/MainWindowUI.ui
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
</property>
<addaction name="actionLoadData"/>
<addaction name="actionLoad_Data_Folder"/>
<addaction name="actionLoad_SASBDB"/>
<addaction name="separator"/>
<addaction name="actionOpen_Project"/>
<addaction name="actionOpen_Analysis"/>
Expand Down Expand Up @@ -310,6 +311,14 @@
<string>Load Data Folder</string>
</property>
</action>
<action name="actionLoad_SASBDB">
<property name="text">
<string>Load from SASBDB...</string>
</property>
<property name="toolTip">
<string>Download and load dataset from SASBDB</string>
</property>
</action>
<action name="actionOpen_Project">
<property name="text">
<string>Open Project</string>
Expand Down
7 changes: 5 additions & 2 deletions src/sas/qtgui/Utilities/GuiUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from sas.qtgui.Plotting.Plottables import Chisq, Plottable, PlottableFit1D, PlottableTheory1D, Text, View
from sas.qtgui.Plotting.PlotterData import Data1D, Data2D, DataRole
from sas.qtgui.Utilities.BackgroundColor import BG_DEFAULT, BG_WARNING
from sas.qtgui.Utilities.SASBDB.sasbdb_display import append_sasbdb_data_summary
from sas.sascalc.fit.AbstractFitEngine import FitData1D, FitData2D, FResult
from sas.system import HELP_SYSTEM
from sas.system.user import PATH_LIKE
Expand Down Expand Up @@ -549,7 +550,8 @@ def retrieveData1d(data):
#logger.error(msg)
raise ValueError(msg)

text = data.__str__()
text = append_sasbdb_data_summary(data.__str__(), data)

text += 'Data Min Max:\n'
text += 'X_min = %s: X_max = %s\n' % (xmin, max(data.x))
text += 'Y_min = %s: Y_max = %s\n' % (ymin, max(data.y))
Expand Down Expand Up @@ -593,7 +595,8 @@ def retrieveData2d(data):
msg = "Incorrect type passed to retrieveData2d"
raise AttributeError(msg)

text = data.__str__()
text = append_sasbdb_data_summary(data.__str__(), data)

text += 'Data Min Max:\n'
text += 'I_min = %s\n' % min(data.data)
text += 'I_max = %s\n\n' % max(data.data)
Expand Down
90 changes: 90 additions & 0 deletions src/sas/qtgui/Utilities/SASBDB/SASBDBDownloadDialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""
SASBDB Dataset Download Dialog.
"""

import logging
import os
import tempfile

from PySide6 import QtWidgets

from .sasbdb_api import SASBDBDatasetInfo, downloadDataset, validateDatasetId
from .sasbdb_display import metadata_summary
from .UI.SASBDBDownloadDialogUI import Ui_SASBDBDownloadDialogUI

logger = logging.getLogger(__name__)


class SASBDBDownloadDialog(QtWidgets.QDialog, Ui_SASBDBDownloadDialogUI):
"""Dialog for downloading datasets from SASBDB."""

def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.downloaded_filepath: str | None = None
self.dataset_info: SASBDBDatasetInfo | None = None

self.cmdDownload.clicked.connect(self.onDownload)
self.cmdCancel.clicked.connect(self.reject)
self.cmdHelp.clicked.connect(self.onHelp)
self.txtDatasetId.returnPressed.connect(self.onDownload)
self.txtDatasetId.setFocus()

def onDownload(self):
dataset_id = self.txtDatasetId.text().strip()
if not dataset_id:
self._showError("Please enter a dataset identifier.")
return

normalized_id, validation_error = validateDatasetId(dataset_id)
if validation_error:
self._showError(validation_error)
return

self._set_busy(True)
self.lblStatus.setText("Downloading dataset...")

try:
filepath, dataset_info = downloadDataset(normalized_id, tempfile.gettempdir())
self.dataset_info = dataset_info

if filepath and os.path.exists(filepath):
self.downloaded_filepath = filepath
summary = metadata_summary(dataset_info) if dataset_info else ""
status = f"Successfully downloaded dataset {normalized_id}"
if summary:
status += f"\n{summary}"
self.lblStatus.setText(status)
self.accept()
else:
self._showError(
f"Failed to download dataset {normalized_id}.\n"
"Please check the dataset identifier and try again."
)
except Exception as e:
logger.error(f"Error downloading dataset {normalized_id}: {e}", exc_info=True)
self._showError(f"Error downloading dataset:\n{e}")
finally:
self._set_busy(False)

def _set_busy(self, busy: bool):
self.cmdDownload.setEnabled(not busy)
self.cmdCancel.setEnabled(not busy)
self.progressBar.setVisible(busy)
if busy:
self.progressBar.setRange(0, 0)
QtWidgets.QApplication.processEvents()

def _showError(self, message: str):
self.lblStatus.setText(f"<span style='color: red;'>{message}</span>")
QtWidgets.QMessageBox.warning(self, "Download Error", message)

def getDownloadedFilepath(self) -> str | None:
return self.downloaded_filepath

def getDatasetInfo(self) -> SASBDBDatasetInfo | None:
return self.dataset_info

def onHelp(self):
from sas.qtgui.Utilities import GuiUtils
GuiUtils.showHelp("user/qtgui/Utilities/SASBDB/sasbdb_download_help.html")
123 changes: 123 additions & 0 deletions src/sas/qtgui/Utilities/SASBDB/UI/SASBDBDownloadDialogUI.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SASBDBDownloadDialogUI</class>
<widget class="QDialog" name="SASBDBDownloadDialogUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>200</height>
</rect>
</property>
<property name="windowTitle">
<string>Load from SASBDB</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lblInstructions">
<property name="text">
<string>Enter SASBDB Dataset Identifier:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtDatasetId">
<property name="placeholderText">
<string>e.g., SASDN24</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblStatus">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="visible">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cmdDownload">
<property name="text">
<string>Download and Load</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cmdHelp">
<property name="text">
<string>Help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cmdCancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>cmdCancel</sender>
<signal>clicked()</signal>
<receiver>SASBDBDownloadDialogUI</receiver>
<slot>reject()</slot>
</connection>
</connections>
</ui>

4 changes: 4 additions & 0 deletions src/sas/qtgui/Utilities/SASBDB/UI/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
UI components for SASBDB utilities.
"""

7 changes: 7 additions & 0 deletions src/sas/qtgui/Utilities/SASBDB/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
SASBDB (Small Angle Scattering Biological Data Bank) utilities.

This package provides functionality for interacting with SASBDB,
including downloading datasets and exporting data to SASBDB format.
"""

Loading
Loading