// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "JFJochViewerWindow.h" #include #include #include "JFJochImageReadingWorker.h" #include "widgets/JFJochDiffractionImage.h" #include "JFJochViewerSidePanel.h" #include "JFJochViewerStatusBar.h" #include "../common/CUDAWrapper.h" #include "windows/JFJochViewerImageListWindow.h" #include "windows/JFJochViewerMetadataWindow.h" #include "dbus/JFJochViewerAdaptor.h" #include "windows/JFJochViewerProcessingWindow.h" #include "windows/JFJochViewerSpotListWindow.h" #include "windows/JFJochViewerReflectionListWindow.h" #include "windows/JFJochCalibrationWindow.h" #include "toolbar/JFJochViewerToolbarDisplay.h" #include "toolbar/JFJochViewerToolbarImage.h" JFJochViewerWindow::JFJochViewerWindow(QWidget *parent, bool dbus, const QString &file) : QMainWindow(parent) { menuBar = new JFJochViewerMenu(this); setMenuBar(menuBar); auto toolBarImage = new JFJochViewerToolbarImage(this); addToolBar(toolBarImage); auto toolBarDisplay = new JFJochViewerToolbarDisplay(this); addToolBar(toolBarDisplay); auto statusbar = new JFJochViewerStatusBar(this); setStatusBar(statusbar); setStyleSheet(stylesheet); setWindowTitle("Jungfraujoch image viewer"); resize(1200, 1200); SpotFindingSettings spot_finding_settings = DiffractionExperiment::DefaultDataProcessingSettings(); spot_finding_settings.high_resolution_limit = 1.5; spot_finding_settings.indexing = true; IndexingSettings indexing_settings; indexing_settings.IndexingThreads(1); indexing_settings.Algorithm(IndexingAlgorithmEnum::Auto); if (get_gpu_count() == 0) { indexing_settings.Algorithm(IndexingAlgorithmEnum::FFTW); indexing_settings.FFT_NumVectors(8 * 1024); } indexing_settings.GeomRefinementAlgorithm(GeomRefinementAlgorithmEnum::BeamCenter); DiffractionExperiment experiment; experiment.ImportIndexingSettings(indexing_settings); experiment.DetectIceRings(true); auto v_splitter = new QSplitter(this); setCentralWidget(v_splitter); v_splitter->setOrientation(Qt::Vertical); auto h_splitter = new QSplitter(this); h_splitter->setOrientation(Qt::Horizontal); v_splitter->addWidget(h_splitter); auto viewer = new JFJochDiffractionImage(this); viewer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); h_splitter->addWidget(viewer); auto side_panel = new JFJochViewerSidePanel(this); auto side_panel_scroll = new QScrollArea(this); side_panel_scroll->setWidget(side_panel); side_panel_scroll->setWidgetResizable(true); side_panel_scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); side_panel_scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); side_panel_scroll->setMinimumWidth(200); side_panel_scroll->setMaximumWidth(500); side_panel_scroll->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); h_splitter->addWidget(side_panel_scroll); dataset_info = new JFJochViewerDatasetInfo(this); dataset_info->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); v_splitter->addWidget(dataset_info); reading_worker = new JFJochImageReadingWorker(spot_finding_settings, experiment); reading_thread = new QThread(this); reading_worker->moveToThread(reading_thread); reading_thread->start(); auto tableWindow = new JFJochViewerImageListWindow(this); auto metadataWindow = new JFJochViewerMetadataWindow(this); auto spotWindow = new JFJochViewerSpotListWindow(this); auto reflectionWindow = new JFJochViewerReflectionListWindow(this); auto processingWindow = new JFJochViewerProcessingWindow(spot_finding_settings, indexing_settings, this); auto calibrationWindow = new JFJochCalibrationWindow(this); menuBar->AddWindowEntry(tableWindow, "Image list"); menuBar->AddWindowEntry(spotWindow, "Spot list"); menuBar->AddWindowEntry(reflectionWindow, "Reflection list"); menuBar->AddWindowEntry(metadataWindow, "Metadata edit"); menuBar->AddWindowEntry(processingWindow, "Image processing settings"); menuBar->AddWindowEntry(calibrationWindow, "Calibration image viewer"); if (dbus) { QDBusConnection connection = QDBusConnection::sessionBus(); if (!connection.registerService("ch.psi.jfjoch_viewer")) { qWarning("Failed to register D-Bus service: %s", qPrintable(connection.lastError().message())); } else { if (!connection.registerObject("/", this)) { qFatal("Failed to register D-Bus object: %s", qPrintable(connection.lastError().message())); } } } connect(this, &JFJochViewerWindow::LoadFileRequest, reading_worker, &JFJochImageReadingWorker::LoadFile); connect(this, &JFJochViewerWindow::LoadImageRequest, reading_worker, &JFJochImageReadingWorker::LoadImage); connect(menuBar, &JFJochViewerMenu::fileOpenSelected, reading_worker, &JFJochImageReadingWorker::LoadFile); connect(menuBar, &JFJochViewerMenu::fileCloseSelected, reading_worker, &JFJochImageReadingWorker::CloseFile); connect(reading_worker, &JFJochImageReadingWorker::imageLoaded, viewer, &JFJochDiffractionImage::loadImage); connect(reading_worker, &JFJochImageReadingWorker::imageLoaded, side_panel, &JFJochViewerSidePanel::loadImage); connect(reading_worker, &JFJochImageReadingWorker::imageStatsUpdated, side_panel, &JFJochViewerSidePanel::loadImage); connect(reading_worker, &JFJochImageReadingWorker::imageNumberChanged, toolBarImage, &JFJochViewerToolbarImage::setImageNumber); connect(toolBarImage, &JFJochViewerToolbarImage::loadImage, reading_worker, &JFJochImageReadingWorker::LoadImage); connect(toolBarDisplay, &JFJochViewerToolbarDisplay::setForeground, viewer, &JFJochDiffractionImage::changeForeground); connect(toolBarDisplay, &JFJochViewerToolbarDisplay::setBackground, viewer, &JFJochDiffractionImage::changeBackground); connect(toolBarDisplay, &JFJochViewerToolbarDisplay::setAutoForeground, viewer, &JFJochDiffractionImage::setAutoForeground); connect(toolBarDisplay, &JFJochViewerToolbarDisplay::colorMapChanged, viewer, &JFJochDiffractionImage::setColorMap); connect(viewer, &JFJochDiffractionImage::foregroundChanged, toolBarDisplay, &JFJochViewerToolbarDisplay::updateForeground); connect(viewer, &JFJochDiffractionImage::roiBoxUpdated, reading_worker, &JFJochImageReadingWorker::SetROIBox); connect(viewer, &JFJochDiffractionImage::roiCircleUpdated, reading_worker, &JFJochImageReadingWorker::SetROICircle); connect(viewer, &JFJochDiffractionImage::roiBoxUpdated, side_panel, &JFJochViewerSidePanel::SetROIBox); connect(viewer, &JFJochDiffractionImage::roiCircleUpdated, side_panel, &JFJochViewerSidePanel::SetROICircle); connect(side_panel, &JFJochViewerSidePanel::ROIBoxConfigured, reading_worker, &JFJochImageReadingWorker::SetROIBox); connect(side_panel, &JFJochViewerSidePanel::ROICircleConfigured, reading_worker, &JFJochImageReadingWorker::SetROICircle); connect(side_panel, &JFJochViewerSidePanel::ROIBoxConfigured, viewer, &JFJochDiffractionImage::SetROIBox); connect(side_panel, &JFJochViewerSidePanel::ROICircleConfigured, viewer, &JFJochDiffractionImage::SetROICircle); connect(side_panel, &JFJochViewerSidePanel::AddROIToUserMask, reading_worker, &JFJochImageReadingWorker::AddROIToUserMask); connect(side_panel, &JFJochViewerSidePanel::SubtractROIFromUserMask, reading_worker, &JFJochImageReadingWorker::SubtractROIFromUserMask); connect(menuBar, &JFJochViewerMenu::clearUserMaskSelected, reading_worker, &JFJochImageReadingWorker::ClearUserMask); connect(menuBar, &JFJochViewerMenu::saveUserMaskTiffSelected, reading_worker, &JFJochImageReadingWorker::SaveUserMaskTIFF); connect(menuBar, &JFJochViewerMenu::uploadUserMaskSelected, reading_worker, &JFJochImageReadingWorker::UploadUserMask); connect(reading_worker, &JFJochImageReadingWorker::datasetLoaded, dataset_info, &JFJochViewerDatasetInfo::datasetLoaded); connect(reading_worker, &JFJochImageReadingWorker::imageLoaded, dataset_info, &JFJochViewerDatasetInfo::imageLoaded); connect(dataset_info, &JFJochViewerDatasetInfo::imageSelected, reading_worker, &JFJochImageReadingWorker::LoadImage); connect(reading_worker, &JFJochImageReadingWorker::datasetLoaded, tableWindow, &JFJochViewerImageListWindow::datasetLoaded); connect(reading_worker, &JFJochImageReadingWorker::datasetLoaded, spotWindow, &JFJochViewerSpotListWindow::datasetLoaded); connect(reading_worker, &JFJochImageReadingWorker::datasetLoaded, metadataWindow, &JFJochViewerMetadataWindow::datasetLoaded); connect(reading_worker, &JFJochImageReadingWorker::imageLoaded, tableWindow, &JFJochViewerImageListWindow::imageLoaded); connect(reading_worker, &JFJochImageReadingWorker::imageLoaded, spotWindow, &JFJochViewerSpotListWindow::imageLoaded); connect(tableWindow, &JFJochViewerImageListWindow::imageSelected, reading_worker, &JFJochImageReadingWorker::LoadImage); connect(reading_worker, &JFJochImageReadingWorker::setToolbarMode, toolBarImage, &JFJochViewerToolbarImage::setAutoloadMode); connect(side_panel, &JFJochViewerSidePanel::analyze, reading_worker, &JFJochImageReadingWorker::Analyze); connect(side_panel, &JFJochViewerSidePanel::findBeamCenter, reading_worker, &JFJochImageReadingWorker::FindCenter); connect(reading_worker, &JFJochImageReadingWorker::datasetLoaded, reflectionWindow, &JFJochViewerReflectionListWindow::datasetLoaded); connect(reading_worker, &JFJochImageReadingWorker::imageLoaded, reflectionWindow, &JFJochViewerReflectionListWindow::imageLoaded); connect(processingWindow, &JFJochViewerProcessingWindow::settingsChanged, reading_worker, &JFJochImageReadingWorker::UpdateSpotFindingSettings); connect(reflectionWindow, &JFJochHelperWindow::zoom, viewer, &JFJochDiffractionImage::centerOnSpot); connect(spotWindow, &JFJochHelperWindow::zoom, viewer, &JFJochDiffractionImage::centerOnSpot); connect(side_panel, &JFJochViewerSidePanel::showSpots, viewer, &JFJochDiffractionImage::showSpots); connect(side_panel, &JFJochViewerSidePanel::showPredictions, viewer, &JFJochDiffractionImage::showPredictions); connect(side_panel, &JFJochViewerSidePanel::autoResRings, viewer, &JFJochDiffractionImage::setResolutionRingAuto); connect(side_panel, &JFJochViewerSidePanel::setFeatureColor, viewer, &JFJochDiffractionImage::setFeatureColor); connect(side_panel, &JFJochViewerSidePanel::setFeatureColor, calibrationWindow, &JFJochCalibrationWindow::setFeatureColor); connect(side_panel, &JFJochViewerSidePanel::setSpotColor, viewer, &JFJochDiffractionImage::setSpotColor); connect(side_panel, &JFJochViewerSidePanel::showHighestPixels, viewer, &JFJochDiffractionImage::showHighestPixels); connect(side_panel, &JFJochViewerSidePanel::showSaturatedPixels, viewer, &JFJochDiffractionImage::showSaturation); connect(side_panel, &JFJochViewerSidePanel::setResRings, viewer, &JFJochDiffractionImage::setResolutionRing); connect(viewer, &JFJochDiffractionImage::writeStatusBar, statusbar, &JFJochViewerStatusBar::display); connect(metadataWindow, &JFJochViewerMetadataWindow::datasetUpdated, reading_worker, &JFJochImageReadingWorker::UpdateDataset); connect(reading_worker, &JFJochImageReadingWorker::setRings, side_panel, &JFJochViewerSidePanel::setResRings); connect(side_panel, &JFJochViewerSidePanel::highlightIceRings, viewer, &JFJochDiffractionImage::highlightIceRings); connect(calibrationWindow, &JFJochCalibrationWindow::loadCalibration, reading_worker, &JFJochImageReadingWorker::LoadCalibration); connect(reading_worker, &JFJochImageReadingWorker::datasetLoaded, calibrationWindow, &JFJochCalibrationWindow::datasetLoaded); connect(reading_worker, &JFJochImageReadingWorker::simpleImageLoaded, calibrationWindow, &JFJochCalibrationWindow::calibrationLoaded); if (!file.isEmpty()) LoadFile(file, 0, 1); } JFJochViewerWindow::~JFJochViewerWindow() { if (reading_thread && reading_thread->isRunning()) { reading_thread->quit(); reading_thread->wait(); } delete reading_worker; } void JFJochViewerWindow::LoadFile(const QString &filename, qint64 image_number, qint64 summation) { emit LoadFileRequest(filename, image_number, summation); } void JFJochViewerWindow::LoadImage(qint64 image_number, qint64 summation) { emit LoadImageRequest(image_number, summation); }