From 2b06b7e931bade585f11389559dd59b58b3c706a Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Wed, 22 May 2024 14:52:28 -0500 Subject: [PATCH 01/25] Fixed bug where name is loaded but not used --- src/gstar/Annotation/RoiMaskGraphicsItem.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/gstar/Annotation/RoiMaskGraphicsItem.cpp b/src/gstar/Annotation/RoiMaskGraphicsItem.cpp index 2132edb..68b3e6f 100644 --- a/src/gstar/Annotation/RoiMaskGraphicsItem.cpp +++ b/src/gstar/Annotation/RoiMaskGraphicsItem.cpp @@ -104,6 +104,19 @@ RoiMaskGraphicsItem::RoiMaskGraphicsItem(QString name, QColor color, int alpha, { _mask->setPixelColor(itr.first, itr.second, color); } + bool found_name = false; + for (const auto& itr : m_data) + { + if (itr->getName() == DEF_STR_DISPLAY_NAME) + { + itr->setValue(name); + found_name = true; + } + } + if(false == found_name) + { + appendProperty(new AnnotationProperty(DEF_STR_DISPLAY_NAME, name)); + } } From ffb04a33cd84d9f2bd3c7d0ee59f037060488865 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 28 May 2024 09:11:23 -0500 Subject: [PATCH 02/25] started adding roi stats --- CMakeLists.txt | 3 ++ src/mvc/ImageSegROIDialog.cpp | 92 +++++++++++++++++++++++++++++++++- src/mvc/ImageSegROIDialog.h | 2 + src/mvc/MapsElementsWidget.cpp | 52 ++++++++++++++++++- src/mvc/MapsElementsWidget.h | 7 +++ src/mvc/MapsH5Model.cpp | 1 + 6 files changed, 155 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed44d69..bcd64b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,6 +233,9 @@ IF (MSVC) ${CMAKE_THREAD_LIBS_INIT} ws2_32.lib ) ELSEIF (UNIX) + #IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + # set_target_properties(uProbeX PROPERTIES MACOSX_BUNDLE TRUE) + #ENDIF() set_target_properties(uProbeX PROPERTIES COMPILE_FLAGS "-O3") target_link_libraries (uProbeX PRIVATE diff --git a/src/mvc/ImageSegROIDialog.cpp b/src/mvc/ImageSegROIDialog.cpp index 4cb0af2..3206f3b 100644 --- a/src/mvc/ImageSegROIDialog.cpp +++ b/src/mvc/ImageSegROIDialog.cpp @@ -11,9 +11,11 @@ #include #include #include +//#include // out in version 4.10 //--------------------------------------------------------------------------- static const QString STR_KMEANS = QString("KMeans"); +static const QString STR_DBSCAN = QString("DBSCAN"); static const QString STR_MANUAL = QString("Manual"); const int TAB_KMEANS = 0; @@ -47,6 +49,7 @@ ImageSegRoiDialog::ImageSegRoiDialog() : QDialog() _color_map.insert({ 15, QColor(Qt::black) }); _layout_map[STR_KMEANS] = _createKMeansLayout(); + _layout_map[STR_DBSCAN] = _createDBScanLayout(); _layout_map[STR_MANUAL] = _createManualLayout(); _next_color = 0; createLayout(); @@ -293,6 +296,84 @@ QWidget* ImageSegRoiDialog::_createKMeansLayout() //--------------------------------------------------------------------------- +QWidget* ImageSegRoiDialog::_createDBScanLayout() +{ + QVBoxLayout* layout = new QVBoxLayout(); +/* + QLabel* label = new QLabel("Number of Features:"); + _km_nfeatures = new QLineEdit(); + _km_nfeatures->setValidator(new QIntValidator(0, 10, this)); + _km_nfeatures->setText("2"); + + QHBoxLayout* hlayout = new QHBoxLayout(); + hlayout->addWidget(label); + hlayout->addWidget(_km_nfeatures); + layout->addItem(hlayout); + + label = new QLabel("Term Criteria:"); + _km_TermCriteria = new QComboBox(); + _km_TermCriteria->addItem("COUNT"); + _km_TermCriteria->addItem("EPS"); + _km_TermCriteria->addItem("COUNT + EPS"); + _km_TermCriteria->setCurrentIndex(2); // default to EPS + + hlayout = new QHBoxLayout(); + hlayout->addWidget(label); + hlayout->addWidget(_km_TermCriteria); + layout->addItem(hlayout); + + label = new QLabel("Centers:"); + _km_Centers = new QComboBox(); + _km_Centers->addItem("Random"); + _km_Centers->addItem("PP"); + _km_Centers->setCurrentIndex(0); // default to Random + + hlayout = new QHBoxLayout(); + hlayout->addWidget(label); + hlayout->addWidget(_km_Centers); + layout->addItem(hlayout); + + label = new QLabel("Attempts:"); + _km_attempts = new QLineEdit(); + _km_attempts->setValidator(new QIntValidator(0, 100, this)); + _km_attempts->setText("3"); + + hlayout = new QHBoxLayout(); + hlayout->addWidget(label); + hlayout->addWidget(_km_attempts); + layout->addItem(hlayout); + + label = new QLabel("MAX_Iter"); + _km_le_MAX_ITER = new QLineEdit(); + _km_le_MAX_ITER->setValidator(new QIntValidator(0, 10000, this)); + _km_le_MAX_ITER->setText("10"); + + hlayout = new QHBoxLayout(); + hlayout->addWidget(label); + hlayout->addWidget(_km_le_MAX_ITER); + layout->addItem(hlayout); + + label = new QLabel("Epsilon"); + _km_le_epsilon = new QLineEdit(); + _km_le_epsilon->setValidator(new QDoubleValidator()); + _km_le_epsilon->setText("1.0"); + + hlayout = new QHBoxLayout(); + hlayout->addWidget(label); + hlayout->addWidget(_km_le_epsilon); + layout->addItem(hlayout); + + _runBtn = new QPushButton("Run"); + connect(_runBtn, SIGNAL(pressed()), this, SLOT(onRun())); + layout->addWidget(_runBtn); +*/ + QWidget* widget = new QWidget(); + widget->setLayout(layout); + return widget; +} + +//--------------------------------------------------------------------------- + QWidget* ImageSegRoiDialog::_createManualLayout() { QHBoxLayout* hlayout; @@ -349,6 +430,7 @@ void ImageSegRoiDialog::createLayout() { _techTabs = new QTabWidget(); _techTabs->addTab(_layout_map[STR_KMEANS], STR_KMEANS); + _techTabs->addTab(_layout_map[STR_DBSCAN], STR_DBSCAN); _techTabs->addTab(_layout_map[STR_MANUAL], STR_MANUAL); _techTabs->setEnabled(false); connect(_techTabs, &QTabWidget::currentChanged, this, &ImageSegRoiDialog::onTabChanged); @@ -458,7 +540,7 @@ void ImageSegRoiDialog::onRun() } catch (std::exception& e) { - QMessageBox::critical(nullptr, "PythonRegionCaller Error", e.what()); + QMessageBox::critical(nullptr, "ImageSegROIDialog Error", e.what()); _acceptBtn->setEnabled(true); return; } @@ -478,6 +560,14 @@ void ImageSegRoiDialog::onRun() _int_img_widget->addRoiMask(roi); } } + else if(_techTabs->currentIndex() == 1) // DBSCAN + { + /* + int slices=8; + bool merge_small=true; + cv::Ptr< cv::ximgproc::ScanSegment > scanSeg = cv::ximgproc::createScanSegment(int_img.cols(), int_img.rows(), 1, slices=8, merge_small); + */ + } _acceptBtn->setEnabled(true); } diff --git a/src/mvc/ImageSegROIDialog.h b/src/mvc/ImageSegROIDialog.h index cf224fd..2ad6363 100644 --- a/src/mvc/ImageSegROIDialog.h +++ b/src/mvc/ImageSegROIDialog.h @@ -94,6 +94,8 @@ private slots: QWidget* _createKMeansLayout(); + QWidget* _createDBScanLayout(); + QWidget* _createManualLayout(); private: diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index e99af84..91da56f 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -426,11 +426,20 @@ void MapsElementsWidget::_appendRoiTab() SLOT(roiTreeDoubleClicked(const QModelIndex&))); */ //infoLayout->addWidget(m_annotationToolbar->getToolBar()); + + QHBoxLayout *roi_button_layout = new QHBoxLayout(); + QVBoxLayout* roiVbox = new QVBoxLayout(); _btn_roi_img_seg = new QPushButton("ROI Dialog"); connect(_btn_roi_img_seg, &QPushButton::released, this, &MapsElementsWidget::openImageSegDialog); - roiVbox->addWidget(_btn_roi_img_seg); + _btn_roi_stats = new QPushButton("ROI Statistics"); + connect(_btn_roi_stats, &QPushButton::released, this, &MapsElementsWidget::openRoiStatsWidget); + + roi_button_layout->addWidget(_btn_roi_img_seg); + roi_button_layout->addWidget(_btn_roi_stats); + + roiVbox->addItem(roi_button_layout); roiVbox->addWidget(m_roiTreeView); m_roiTreeTabWidget = new QWidget(this); @@ -621,6 +630,46 @@ void MapsElementsWidget::openImageSegDialog() //--------------------------------------------------------------------------- +void MapsElementsWidget::openRoiStatsWidget() +{ + if (_model != nullptr) + { + std::string analysis_text = _cb_analysis->currentText().toStdString(); + + data_struct::Fit_Count_Dict fit_counts; + _model->getAnalyzedCounts(analysis_text, fit_counts); + std::map>* scalers = _model->getScalers(); + if (scalers != nullptr) + { + for (auto& itr : *scalers) + { + fit_counts.insert(itr); + } + } + //_img_seg_diag.setImageData(fit_counts); + + // add any roi's that were loaded. + std::vector roi_list; + QImage i; + QColor q; + gstar::RoiMaskGraphicsItem item(i, q, 0); + if (m_treeModel != nullptr) + { + m_roiTreeModel->get_all_of_type(item.classId(), roi_list); + } + for (auto itr : roi_list) + { + // _img_seg_diag.append_roi((gstar::RoiMaskGraphicsItem*)(itr->duplicate())); + } + //m_roiTreeModel->clearAll(); + //_spectra_widget->deleteAllROISpectra(); + + //_roi_stats_diag->show(); + } +} + +//--------------------------------------------------------------------------- + void MapsElementsWidget::roiUpdated(gstar::RoiMaskGraphicsItem* ano, bool reload) { if (ano != nullptr && reload) @@ -868,6 +917,7 @@ void MapsElementsWidget::setModel(MapsH5Model* model) { int width = (int)m_imageViewWidget->scene()->width(); int height = (int)m_imageViewWidget->scene()->height(); + logI<< "Loading roi: "<< itr.first<<"\n"; gstar::RoiMaskGraphicsItem* roi = new gstar::RoiMaskGraphicsItem(QString(itr.first.c_str()), itr.second.color, itr.second.color_alpha, width, height, itr.second.pixel_list); insertAndSelectAnnotation(m_roiTreeModel, m_roiTreeView, m_roiSelectionModel, roi); if (itr.second.int_spec.count(_model->getDatasetName().toStdString()) > 0) diff --git a/src/mvc/MapsElementsWidget.h b/src/mvc/MapsElementsWidget.h index e419550..0333ea0 100644 --- a/src/mvc/MapsElementsWidget.h +++ b/src/mvc/MapsElementsWidget.h @@ -27,6 +27,7 @@ #include #include #include +#include using gstar::AbstractGraphicsItem; /*---------------------------------------------------------------------------*/ @@ -81,6 +82,8 @@ public slots: void openImageSegDialog(); + void openRoiStatsWidget(); + void roiUpdated(gstar::RoiMaskGraphicsItem* ano, bool reload); void onGridDialog(); @@ -207,6 +210,8 @@ public slots: ImageSegRoiDialog _img_seg_diag; + RoiStatisticsWidget* _roi_stats_diag; + float _min_contrast_perc; float _max_contrast_perc; @@ -221,6 +226,8 @@ public slots: QPushButton* _btn_roi_img_seg; + QPushButton* _btn_roi_stats; + QDockWidget* _counts_dock; QDockWidget* _intspectra_dock; diff --git a/src/mvc/MapsH5Model.cpp b/src/mvc/MapsH5Model.cpp index 5627862..06917f9 100644 --- a/src/mvc/MapsH5Model.cpp +++ b/src/mvc/MapsH5Model.cpp @@ -387,6 +387,7 @@ void MapsH5Model::loadAllRoiMaps() } } _map_rois[mroi.name] = mroi; + logI<< "Loading roi: "<< mroi.name<<"\n"; } if (resave) { From b4605731857e3b93b2677edf8d6f8ff0b32a5061 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 28 May 2024 09:17:01 -0500 Subject: [PATCH 03/25] added class --- src/mvc/RoiStatisticsWidget.cpp | 347 ++++++++++++++++++++++++++++++++ src/mvc/RoiStatisticsWidget.h | 115 +++++++++++ 2 files changed, 462 insertions(+) create mode 100644 src/mvc/RoiStatisticsWidget.cpp create mode 100644 src/mvc/RoiStatisticsWidget.h diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp new file mode 100644 index 0000000..0f1a9f2 --- /dev/null +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -0,0 +1,347 @@ +/*----------------------------------------------------------------------------- + * Copyright (c) 2024, UChicago Argonne, LLC + * See LICENSE file. + *---------------------------------------------------------------------------*/ + +#include + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +RoiStatisticsWidget::RoiStatisticsWidget() : QWidget() +{ + + _createLayout(); + +} + +//--------------------------------------------------------------------------- + +RoiStatisticsWidget::~RoiStatisticsWidget() +{ + +} + +//--------------------------------------------------------------------------- + +void append_roi(gstar::RoiMaskGraphicsItem* roi) +{ + +} + +//--------------------------------------------------------------------------- + +void RoiStatisticsWidget::setImageData(std::unordered_map>& img_data) +{ +/* + _img_list_model->clear(); + _img_data.clear(); + + //create save ordered vector by element Z number with K , L, M lines + std::vector element_lines; + for (std::string el_name : data_struct::Element_Symbols) + { + element_lines.push_back(el_name); + } + for (std::string el_name : data_struct::Element_Symbols) + { + element_lines.push_back(el_name + "_L"); + } + for (std::string el_name : data_struct::Element_Symbols) + { + element_lines.push_back(el_name + "_M"); + } + + std::vector final_counts_to_add_before_scalers; + final_counts_to_add_before_scalers.push_back(STR_COHERENT_SCT_AMPLITUDE); + final_counts_to_add_before_scalers.push_back(STR_COMPTON_AMPLITUDE); + final_counts_to_add_before_scalers.push_back(STR_SUM_ELASTIC_INELASTIC_AMP); + final_counts_to_add_before_scalers.push_back(STR_TOTAL_FLUORESCENCE_YIELD); + final_counts_to_add_before_scalers.push_back(STR_NUM_ITR); + final_counts_to_add_before_scalers.push_back(STR_RESIDUAL); + + std::vector scalers_to_add_first; + scalers_to_add_first.push_back(STR_SR_CURRENT); + scalers_to_add_first.push_back(STR_US_IC); + scalers_to_add_first.push_back(STR_DS_IC); + scalers_to_add_first.push_back(STR_ELT); + scalers_to_add_first.push_back(STR_ELAPSED_LIVE_TIME); + scalers_to_add_first.push_back(STR_ERT); + scalers_to_add_first.push_back(STR_ELAPSED_REAL_TIME); + scalers_to_add_first.push_back(STR_INPUT_COUNTS); + scalers_to_add_first.push_back(STR_ICR); + scalers_to_add_first.push_back("INCNT"); + scalers_to_add_first.push_back(STR_OUTPUT_COUNTS); + scalers_to_add_first.push_back(STR_OCR); + scalers_to_add_first.push_back("OUTCNT"); + scalers_to_add_first.push_back(STR_DEAD_TIME); + scalers_to_add_first.push_back("abs_cfg"); + scalers_to_add_first.push_back("abs_ic"); + scalers_to_add_first.push_back("H_dpc_cfg"); + scalers_to_add_first.push_back("V_dpc_cfg"); + scalers_to_add_first.push_back("DPC1_IC"); + scalers_to_add_first.push_back("DPC2_IC"); + scalers_to_add_first.push_back("dia1_dpc_cfg"); + scalers_to_add_first.push_back("dia2_dpc_cfg"); + scalers_to_add_first.push_back("CFG_1"); + scalers_to_add_first.push_back(STR_CFG_2); + scalers_to_add_first.push_back(STR_CFG_3); + scalers_to_add_first.push_back(STR_CFG_4); + scalers_to_add_first.push_back(STR_CFG_5); + scalers_to_add_first.push_back("CFG_6"); + scalers_to_add_first.push_back("CFG_7"); + scalers_to_add_first.push_back("CFG_8"); + scalers_to_add_first.push_back("CFG_9"); + + // insert in z order + for (std::string el_name : element_lines) + { + if (img_data.count(el_name) > 0) + { + _img_data[QString(el_name.c_str())] = img_data.at(el_name); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(el_name.c_str())); + _img_list_model->appendRow(item0); + + if (_image_size.isEmpty()) + { + _image_size = QSize(img_data.at(el_name).cols(), img_data.at(el_name).rows()); + } + img_data.erase(el_name); + } + + } + + // add end of element list that are not elements + for (auto& itr : final_counts_to_add_before_scalers) + { + if (img_data.count(itr) > 0) + { + _img_data[QString(itr.c_str())] = img_data.at(itr); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(itr.c_str())); + _img_list_model->appendRow(item0); + + img_data.erase(itr); + } + } + + // add scalers in certain order + for (auto& itr : scalers_to_add_first) + { + if (img_data.count(itr) > 0) + { + _img_data[QString(itr.c_str())] = img_data.at(itr); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(itr.c_str())); + _img_list_model->appendRow(item0); + + img_data.erase(itr); + } + } + + // add rest of scalers + for (auto& itr : img_data) + { + _img_data[QString(itr.first.c_str())] = img_data.at(itr.first); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(itr.first.c_str())); + _img_list_model->appendRow(item0); + } + + + */ +} + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +void ImageSegRoiDialog::_createLayout() +{ + /* + _techTabs = new QTabWidget(); + _techTabs->addTab(_layout_map[STR_KMEANS], STR_KMEANS); + _techTabs->addTab(_layout_map[STR_DBSCAN], STR_DBSCAN); + _techTabs->addTab(_layout_map[STR_MANUAL], STR_MANUAL); + _techTabs->setEnabled(false); + connect(_techTabs, &QTabWidget::currentChanged, this, &ImageSegRoiDialog::onTabChanged); + + _acceptBtn = new QPushButton("Accept"); + //_acceptBtn->setEnabled(false); + _cancelBtn = new QPushButton("Cancel"); + connect(_acceptBtn, SIGNAL(pressed()), this, SLOT(onAccept())); + connect(_cancelBtn, SIGNAL(pressed()), this, SLOT(onClose())); + + _img_list_model = new QStandardItemModel(); + _img_names_view = new QListView(); + _img_names_view->setModel(_img_list_model); + _img_names_view->setEditTriggers(QAbstractItemView::NoEditTriggers); + _img_names_view->setSelectionMode(QAbstractItemView::ExtendedSelection); + + connect(_img_list_model, &QStandardItemModel::itemChanged, this, &ImageSegRoiDialog::onImgSelection); + + _int_img_widget = new ImageSegWidget(); + + QHBoxLayout* mainLayout = new QHBoxLayout; + QVBoxLayout *leftLayout = new QVBoxLayout; + QHBoxLayout* optionLayout = new QHBoxLayout; + QHBoxLayout* buttonLayout = new QHBoxLayout; + + _chk_normalize_sum = new QCheckBox("Normalize before summing"); + connect(_chk_normalize_sum, &QCheckBox::stateChanged, this, &ImageSegRoiDialog::onNormalizeChanged); + + optionLayout->addWidget(_chk_normalize_sum); + + buttonLayout->addWidget(_acceptBtn); + buttonLayout->addWidget(_cancelBtn); + + leftLayout->addWidget(_img_names_view); + leftLayout->addItem(optionLayout); + leftLayout->addWidget(_techTabs); + leftLayout->addItem(buttonLayout); + + mainLayout->addItem(leftLayout); + mainLayout->addWidget(_int_img_widget); + + setLayout(mainLayout); + + setWindowTitle("ROI Image Segmentation"); + */ +} + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +void RoiStatisticsWidget::onClose() +{ + clear_all(); + close(); +} + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +void RoiStatisticsWidget::clear_all() +{ + //_int_img_widget->clearAllRoiMasks(); + _int_img_widget->deleteAllItems(); + //_cb_selected_roi->clear(); +} + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +/* +std::vector ImageSegRoiDialog::_generate_images(int num_images, cv::Mat& mat) +{ + std::vector images; + for (int i = 0; i < num_images; i++) + { + QImage image(mat.cols, mat.rows, QImage::Format_ARGB32); + image.setColorTable(*_selected_colormap); + images.emplace_back(image); + } + + for (int row = 0; row < mat.rows; row++) + { + for (int col = 0; col < mat.cols; col++) + { + //first clamp the data to max min + int idx = mat.at(row, col); + byte data = 255; + images[idx].setPixel(col, row, (uint)data); + } + } + return images; +} + +//--------------------------------------------------------------------------- + +QImage ImageSegRoiDialog::_generate_sum_image(cv::Mat& mat, ArrayXXr& bg_img, uchar alpha) +{ + + QImage background = _generate_img(bg_img).convertToFormat(QImage::Format_ARGB32_Premultiplied); + + QImage overlay(mat.cols, mat.rows, QImage::Format_ARGB32); + + for (int row = 0; row < mat.rows; row++) + { + for (int col = 0; col < mat.cols; col++) + { + //first clamp the data to max min + int color_idx = mat.at(row, col); + if (color_idx > _color_map.size()) + { + color_idx = color_idx % _color_map.size(); + } + QColor color_data = _color_map[color_idx]; + color_data.setAlpha(alpha); + + //QRgb val = background.pixel(col, row); + //val = color_data.rgba(); + overlay.setPixel(col, row, color_data.rgba()); + } + } + + QPainter p(&background); + //p.setCompositionMode(QPainter::CompositionMode_SourceOver); + p.setCompositionMode(QPainter::CompositionMode_Plus); + //p.setCompositionMode(QPainter::CompositionMode_Exclusion); + //p.setCompositionMode(QPainter::CompositionMode_DestinationIn); + p.drawImage(0, 0, overlay); + p.end(); + + return background; + +} +*/ +//--------------------------------------------------------------------------- + +void RoiStatisticsWidget::onNormalizeChanged(int a) +{ + onImgSelection(nullptr); +} + +//--------------------------------------------------------------------------- + +void RoiStatisticsWidget::onImgSelection(QStandardItem* item) +{ + ArrayXXr int_img; + bool is_checked = _get_img(int_img, _chk_normalize_sum->isChecked()); + + _techTabs->setEnabled(is_checked); + + if (is_checked) + { + _int_img_widget->setImageFromArray(int_img, *_selected_colormap); + } + else if (false == _image_size.isEmpty()) + { + clear_image(); + } +} + +//--------------------------------------------------------------------------- + +void RoiStatisticsWidget::clear_image() +{ + QImage image(_image_size, QImage::Format_ARGB32_Premultiplied); + image.fill(QColor(Qt::gray)); + _int_img_widget->setPixMap(QPixmap::fromImage(image.convertToFormat(QImage::Format_RGB32))); +} + +//--------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/mvc/RoiStatisticsWidget.h b/src/mvc/RoiStatisticsWidget.h new file mode 100644 index 0000000..93854ff --- /dev/null +++ b/src/mvc/RoiStatisticsWidget.h @@ -0,0 +1,115 @@ +/*----------------------------------------------------------------------------- + * Copyright (c) 2024, UChicago Argonne, LLC + * See LICENSE file. + *---------------------------------------------------------------------------*/ + +#ifndef Roi_Statistics_Widget_H +#define Roi_Statistics_Widget_H + +/*---------------------------------------------------------------------------*/ + +#include + +/*#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "data_struct/fit_parameters.h" +#include +#include +#include +#include "gstar/Annotation/RoiMaskGraphicsItem.h" +*/ +/*---------------------------------------------------------------------------*/ + +class RoiStatisticsWidget : public QWidget +{ + + Q_OBJECT + +public: + + /** + * Constructor. + */ + RoiStatisticsWidget(); + + /** + * Destructor. + */ + ~RoiStatisticsWidget(); + + void setImageData(std::unordered_map>& img_data); + + void clear_all(); + + void append_roi(gstar::RoiMaskGraphicsItem* roi); + +public slots: + + void onExport(); + + void onClose(); + +protected: + + void _createLayout(); + +private: +/* + QTabWidget* _techTabs; + + QPushButton* _runBtn; + QPushButton* _acceptBtn; + QPushButton* _cancelBtn; + + QListView* _img_names_view; + QStandardItemModel* _img_list_model; + QCheckBox* _chk_normalize_sum; + + ImageSegWidget* _int_img_widget; + + QVector* _selected_colormap; + + std::map _layout_map; + + std::map> _img_data; + + std::map _color_map; + + // kmeans controls + QComboBox* _km_TermCriteria; + QComboBox* _km_Centers; + QLineEdit* _km_le_MAX_ITER; + QLineEdit* _km_le_epsilon; + QLineEdit* _km_nfeatures; + QLineEdit* _km_attempts; + + QSize _image_size; + + //QComboBox* _cb_selected_roi; + + QPushButton* _manual_btn_add_roi; + QComboBox* _manual_cb_action; + QSpinBox* _manual_sp_brush_size; + QPushButton* _manual_invert_roi; + + int _next_color; + */ +}; + + +/*---------------------------------------------------------------------------*/ + +#endif /* RoiStatisticsWidget.h */ + +/*---------------------------------------------------------------------------*/ + From f7fb90d0a010be690dc1f2e1a56d5988fc6db9be Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 28 May 2024 12:05:03 -0500 Subject: [PATCH 04/25] started adding roi names and element names --- src/mvc/MapsElementsWidget.cpp | 23 +- src/mvc/RoiStatisticsWidget.cpp | 441 +++++++++++++------------------- src/mvc/RoiStatisticsWidget.h | 61 +---- 3 files changed, 195 insertions(+), 330 deletions(-) diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index 91da56f..e30739f 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -35,6 +35,7 @@ MapsElementsWidget::MapsElementsWidget(int rows, int cols, bool create_image_nav { _model = nullptr; + _roi_stats_diag = nullptr; _normalizer = nullptr; _calib_curve = nullptr; _min_contrast_perc = 0; @@ -634,6 +635,12 @@ void MapsElementsWidget::openRoiStatsWidget() { if (_model != nullptr) { + if (_roi_stats_diag == nullptr) + { + _roi_stats_diag = new RoiStatisticsWidget(); + } + _roi_stats_diag->clear_all(); + std::string analysis_text = _cb_analysis->currentText().toStdString(); data_struct::Fit_Count_Dict fit_counts; @@ -646,25 +653,19 @@ void MapsElementsWidget::openRoiStatsWidget() fit_counts.insert(itr); } } - //_img_seg_diag.setImageData(fit_counts); - // add any roi's that were loaded. std::vector roi_list; QImage i; - QColor q; - gstar::RoiMaskGraphicsItem item(i, q, 0); + QColor c; + gstar::RoiMaskGraphicsItem item(i, c, 0); if (m_treeModel != nullptr) { m_roiTreeModel->get_all_of_type(item.classId(), roi_list); } - for (auto itr : roi_list) - { - // _img_seg_diag.append_roi((gstar::RoiMaskGraphicsItem*)(itr->duplicate())); - } - //m_roiTreeModel->clearAll(); - //_spectra_widget->deleteAllROISpectra(); + + _roi_stats_diag->setData(fit_counts, roi_list); - //_roi_stats_diag->show(); + _roi_stats_diag->show(); } } diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp index 0f1a9f2..11a035c 100644 --- a/src/mvc/RoiStatisticsWidget.cpp +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -11,217 +11,223 @@ RoiStatisticsWidget::RoiStatisticsWidget() : QWidget() { + _base_header = { "ROI Name", "Element", "Cnt/s", "Min Cnts/s", "Max Cnts/s", "ug/cm2", "Min ug/cm2", "Max ug/cm2", "Mean", "Median", "Std Dev", "Area", "Num Spectra" }; - _createLayout(); + //create save ordered vector by element Z number with K , L, M lines + for (std::string el_name : data_struct::Element_Symbols) + { + _element_lines_list.push_back(el_name); + } + for (std::string el_name : data_struct::Element_Symbols) + { + _element_lines_list.push_back(el_name + "_L"); + } + for (std::string el_name : data_struct::Element_Symbols) + { + _element_lines_list.push_back(el_name + "_M"); + } -} + _final_counts_to_add_before_scalers.push_back(STR_COHERENT_SCT_AMPLITUDE); + _final_counts_to_add_before_scalers.push_back(STR_COMPTON_AMPLITUDE); + _final_counts_to_add_before_scalers.push_back(STR_SUM_ELASTIC_INELASTIC_AMP); + _final_counts_to_add_before_scalers.push_back(STR_TOTAL_FLUORESCENCE_YIELD); + _final_counts_to_add_before_scalers.push_back(STR_NUM_ITR); + _final_counts_to_add_before_scalers.push_back(STR_RESIDUAL); + + _scalers_to_add_first_list.push_back(STR_SR_CURRENT); + _scalers_to_add_first_list.push_back(STR_US_IC); + _scalers_to_add_first_list.push_back(STR_DS_IC); + _scalers_to_add_first_list.push_back(STR_ELT); + _scalers_to_add_first_list.push_back(STR_ELAPSED_LIVE_TIME); + _scalers_to_add_first_list.push_back(STR_ERT); + _scalers_to_add_first_list.push_back(STR_ELAPSED_REAL_TIME); + _scalers_to_add_first_list.push_back(STR_INPUT_COUNTS); + _scalers_to_add_first_list.push_back(STR_ICR); + _scalers_to_add_first_list.push_back("INCNT"); + _scalers_to_add_first_list.push_back(STR_OUTPUT_COUNTS); + _scalers_to_add_first_list.push_back(STR_OCR); + _scalers_to_add_first_list.push_back("OUTCNT"); + _scalers_to_add_first_list.push_back(STR_DEAD_TIME); + _scalers_to_add_first_list.push_back("abs_cfg"); + _scalers_to_add_first_list.push_back("abs_ic"); + _scalers_to_add_first_list.push_back("H_dpc_cfg"); + _scalers_to_add_first_list.push_back("V_dpc_cfg"); + _scalers_to_add_first_list.push_back("DPC1_IC"); + _scalers_to_add_first_list.push_back("DPC2_IC"); + _scalers_to_add_first_list.push_back("dia1_dpc_cfg"); + _scalers_to_add_first_list.push_back("dia2_dpc_cfg"); + _scalers_to_add_first_list.push_back("CFG_1"); + _scalers_to_add_first_list.push_back(STR_CFG_2); + _scalers_to_add_first_list.push_back(STR_CFG_3); + _scalers_to_add_first_list.push_back(STR_CFG_4); + _scalers_to_add_first_list.push_back(STR_CFG_5); + _scalers_to_add_first_list.push_back("CFG_6"); + _scalers_to_add_first_list.push_back("CFG_7"); + _scalers_to_add_first_list.push_back("CFG_8"); + _scalers_to_add_first_list.push_back("CFG_9"); -//--------------------------------------------------------------------------- -RoiStatisticsWidget::~RoiStatisticsWidget() -{ + _createLayout(); } //--------------------------------------------------------------------------- -void append_roi(gstar::RoiMaskGraphicsItem* roi) +RoiStatisticsWidget::~RoiStatisticsWidget() { } //--------------------------------------------------------------------------- -void RoiStatisticsWidget::setImageData(std::unordered_map>& img_data) +void RoiStatisticsWidget::setData(std::unordered_map>& img_data, std::vector& roi_list) { -/* - _img_list_model->clear(); - _img_data.clear(); - //create save ordered vector by element Z number with K , L, M lines - std::vector element_lines; - for (std::string el_name : data_struct::Element_Symbols) - { - element_lines.push_back(el_name); - } - for (std::string el_name : data_struct::Element_Symbols) - { - element_lines.push_back(el_name + "_L"); - } - for (std::string el_name : data_struct::Element_Symbols) - { - element_lines.push_back(el_name + "_M"); - } + int total = img_data.size() * roi_list.size(); + _table_widget->setRowCount(total); - std::vector final_counts_to_add_before_scalers; - final_counts_to_add_before_scalers.push_back(STR_COHERENT_SCT_AMPLITUDE); - final_counts_to_add_before_scalers.push_back(STR_COMPTON_AMPLITUDE); - final_counts_to_add_before_scalers.push_back(STR_SUM_ELASTIC_INELASTIC_AMP); - final_counts_to_add_before_scalers.push_back(STR_TOTAL_FLUORESCENCE_YIELD); - final_counts_to_add_before_scalers.push_back(STR_NUM_ITR); - final_counts_to_add_before_scalers.push_back(STR_RESIDUAL); - - std::vector scalers_to_add_first; - scalers_to_add_first.push_back(STR_SR_CURRENT); - scalers_to_add_first.push_back(STR_US_IC); - scalers_to_add_first.push_back(STR_DS_IC); - scalers_to_add_first.push_back(STR_ELT); - scalers_to_add_first.push_back(STR_ELAPSED_LIVE_TIME); - scalers_to_add_first.push_back(STR_ERT); - scalers_to_add_first.push_back(STR_ELAPSED_REAL_TIME); - scalers_to_add_first.push_back(STR_INPUT_COUNTS); - scalers_to_add_first.push_back(STR_ICR); - scalers_to_add_first.push_back("INCNT"); - scalers_to_add_first.push_back(STR_OUTPUT_COUNTS); - scalers_to_add_first.push_back(STR_OCR); - scalers_to_add_first.push_back("OUTCNT"); - scalers_to_add_first.push_back(STR_DEAD_TIME); - scalers_to_add_first.push_back("abs_cfg"); - scalers_to_add_first.push_back("abs_ic"); - scalers_to_add_first.push_back("H_dpc_cfg"); - scalers_to_add_first.push_back("V_dpc_cfg"); - scalers_to_add_first.push_back("DPC1_IC"); - scalers_to_add_first.push_back("DPC2_IC"); - scalers_to_add_first.push_back("dia1_dpc_cfg"); - scalers_to_add_first.push_back("dia2_dpc_cfg"); - scalers_to_add_first.push_back("CFG_1"); - scalers_to_add_first.push_back(STR_CFG_2); - scalers_to_add_first.push_back(STR_CFG_3); - scalers_to_add_first.push_back(STR_CFG_4); - scalers_to_add_first.push_back(STR_CFG_5); - scalers_to_add_first.push_back("CFG_6"); - scalers_to_add_first.push_back("CFG_7"); - scalers_to_add_first.push_back("CFG_8"); - scalers_to_add_first.push_back("CFG_9"); - - // insert in z order - for (std::string el_name : element_lines) + std::unordered_map done_map; + + int i = 0; + for (auto roi_itr : roi_list) { - if (img_data.count(el_name) > 0) + /* + _table_widget->setItem(i, 0, new QTableWidgetItem(QString::fromLatin1(itr.name.c_str(), itr.name.length()))); + _table_widget->setItem(i, 1, new QTableWidgetItem()); + _table_widget->setItem(i, 2, new QTableWidgetItem(QString::fromLatin1(itr.unit.c_str(), itr.unit.length()))); + _table_widget->setItem(i, 3, new QTableWidgetItem(QString::fromLatin1(itr.description.c_str(), itr.description.length()))); + */ + + // insert in z order + for (auto itr : _element_lines_list) { - _img_data[QString(el_name.c_str())] = img_data.at(el_name); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(el_name.c_str())); - _img_list_model->appendRow(item0); - - if (_image_size.isEmpty()) + if (img_data.count(itr) > 0) { - _image_size = QSize(img_data.at(el_name).cols(), img_data.at(el_name).rows()); + _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); + _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.c_str(), itr.length()))); + + /* + _img_data[QString(el_name.c_str())] = img_data.at(el_name); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(el_name.c_str())); + _img_list_model->appendRow(item0); + + if (_image_size.isEmpty()) + { + _image_size = QSize(img_data.at(el_name).cols(), img_data.at(el_name).rows()); + } + img_data.erase(el_name); + */ + done_map[itr] = 1; + i++; } - img_data.erase(el_name); - } - } + } + - // add end of element list that are not elements - for (auto& itr : final_counts_to_add_before_scalers) - { - if (img_data.count(itr) > 0) + // add end of element list that are not elements + for (auto itr : _final_counts_to_add_before_scalers) { - _img_data[QString(itr.c_str())] = img_data.at(itr); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(itr.c_str())); - _img_list_model->appendRow(item0); - - img_data.erase(itr); + if (img_data.count(itr) > 0) + { + _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); + _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.c_str(), itr.length()))); + + /* + _img_data[QString(itr.c_str())] = img_data.at(itr); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(itr.c_str())); + _img_list_model->appendRow(item0); + + img_data.erase(itr); + */ + done_map[itr] = 1; + i++; + } } - } - // add scalers in certain order - for (auto& itr : scalers_to_add_first) - { - if (img_data.count(itr) > 0) + // add scalers in certain order + for (auto itr : _scalers_to_add_first_list) { - _img_data[QString(itr.c_str())] = img_data.at(itr); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(itr.c_str())); - _img_list_model->appendRow(item0); - - img_data.erase(itr); + if (img_data.count(itr) > 0) + { + _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); + _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.c_str(), itr.length()))); + + /* + _img_data[QString(itr.c_str())] = img_data.at(itr); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(itr.c_str())); + _img_list_model->appendRow(item0); + + img_data.erase(itr); + */ + done_map[itr] = 1; + i++; + } } - } - // add rest of scalers - for (auto& itr : img_data) - { - _img_data[QString(itr.first.c_str())] = img_data.at(itr.first); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(itr.first.c_str())); - _img_list_model->appendRow(item0); + // add rest of scalers + for (auto itr : img_data) + { + if(done_map.count(itr.first) == 0) + { + _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); + _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.first.c_str(), itr.first.length()))); + + /* + _img_data[QString(itr.first.c_str())] = img_data.at(itr.first); + QStandardItem* item0 = new QStandardItem(false); + item0->setCheckable(true); + item0->setCheckState(Qt::Unchecked); + item0->setText(QString(itr.first.c_str())); + _img_list_model->appendRow(item0); + */ + i++; + } + } } - - - */ } //--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -void ImageSegRoiDialog::_createLayout() +void RoiStatisticsWidget::_createLayout() { - /* - _techTabs = new QTabWidget(); - _techTabs->addTab(_layout_map[STR_KMEANS], STR_KMEANS); - _techTabs->addTab(_layout_map[STR_DBSCAN], STR_DBSCAN); - _techTabs->addTab(_layout_map[STR_MANUAL], STR_MANUAL); - _techTabs->setEnabled(false); - connect(_techTabs, &QTabWidget::currentChanged, this, &ImageSegRoiDialog::onTabChanged); - - _acceptBtn = new QPushButton("Accept"); - //_acceptBtn->setEnabled(false); - _cancelBtn = new QPushButton("Cancel"); - connect(_acceptBtn, SIGNAL(pressed()), this, SLOT(onAccept())); - connect(_cancelBtn, SIGNAL(pressed()), this, SLOT(onClose())); - - _img_list_model = new QStandardItemModel(); - _img_names_view = new QListView(); - _img_names_view->setModel(_img_list_model); - _img_names_view->setEditTriggers(QAbstractItemView::NoEditTriggers); - _img_names_view->setSelectionMode(QAbstractItemView::ExtendedSelection); - - connect(_img_list_model, &QStandardItemModel::itemChanged, this, &ImageSegRoiDialog::onImgSelection); - - _int_img_widget = new ImageSegWidget(); - - QHBoxLayout* mainLayout = new QHBoxLayout; - QVBoxLayout *leftLayout = new QVBoxLayout; - QHBoxLayout* optionLayout = new QHBoxLayout; - QHBoxLayout* buttonLayout = new QHBoxLayout; - _chk_normalize_sum = new QCheckBox("Normalize before summing"); - connect(_chk_normalize_sum, &QCheckBox::stateChanged, this, &ImageSegRoiDialog::onNormalizeChanged); + _table_widget = new QTableWidget(1, _base_header.count()); + _table_widget->setHorizontalHeaderLabels(_base_header); - optionLayout->addWidget(_chk_normalize_sum); - - buttonLayout->addWidget(_acceptBtn); - buttonLayout->addWidget(_cancelBtn); + _btn_export = new QPushButton("Export"); + _btn_close = new QPushButton("Close"); + connect(_btn_export, &QPushButton::pressed, this, &RoiStatisticsWidget::onExport); + connect(_btn_close, &QPushButton::pressed, this, &RoiStatisticsWidget::onClose); - leftLayout->addWidget(_img_names_view); - leftLayout->addItem(optionLayout); - leftLayout->addWidget(_techTabs); - leftLayout->addItem(buttonLayout); + QVBoxLayout* mainLayout = new QVBoxLayout; + QHBoxLayout* buttonLayout = new QHBoxLayout; + + buttonLayout->addWidget(_btn_export); + buttonLayout->addWidget(_btn_close); - mainLayout->addItem(leftLayout); - mainLayout->addWidget(_int_img_widget); + mainLayout->addWidget(_table_widget); + mainLayout->addItem(buttonLayout); setLayout(mainLayout); - setWindowTitle("ROI Image Segmentation"); - */ + setWindowTitle("ROI Stats"); } //--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- +void RoiStatisticsWidget::onExport() +{ + +} //--------------------------------------------------------------------------- @@ -233,115 +239,10 @@ void RoiStatisticsWidget::onClose() //--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - void RoiStatisticsWidget::clear_all() { - //_int_img_widget->clearAllRoiMasks(); - _int_img_widget->deleteAllItems(); - //_cb_selected_roi->clear(); + //_table_widget->clear(); } //--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -/* -std::vector ImageSegRoiDialog::_generate_images(int num_images, cv::Mat& mat) -{ - std::vector images; - for (int i = 0; i < num_images; i++) - { - QImage image(mat.cols, mat.rows, QImage::Format_ARGB32); - image.setColorTable(*_selected_colormap); - images.emplace_back(image); - } - - for (int row = 0; row < mat.rows; row++) - { - for (int col = 0; col < mat.cols; col++) - { - //first clamp the data to max min - int idx = mat.at(row, col); - byte data = 255; - images[idx].setPixel(col, row, (uint)data); - } - } - return images; -} - -//--------------------------------------------------------------------------- - -QImage ImageSegRoiDialog::_generate_sum_image(cv::Mat& mat, ArrayXXr& bg_img, uchar alpha) -{ - - QImage background = _generate_img(bg_img).convertToFormat(QImage::Format_ARGB32_Premultiplied); - - QImage overlay(mat.cols, mat.rows, QImage::Format_ARGB32); - - for (int row = 0; row < mat.rows; row++) - { - for (int col = 0; col < mat.cols; col++) - { - //first clamp the data to max min - int color_idx = mat.at(row, col); - if (color_idx > _color_map.size()) - { - color_idx = color_idx % _color_map.size(); - } - QColor color_data = _color_map[color_idx]; - color_data.setAlpha(alpha); - - //QRgb val = background.pixel(col, row); - //val = color_data.rgba(); - overlay.setPixel(col, row, color_data.rgba()); - } - } - - QPainter p(&background); - //p.setCompositionMode(QPainter::CompositionMode_SourceOver); - p.setCompositionMode(QPainter::CompositionMode_Plus); - //p.setCompositionMode(QPainter::CompositionMode_Exclusion); - //p.setCompositionMode(QPainter::CompositionMode_DestinationIn); - p.drawImage(0, 0, overlay); - p.end(); - - return background; - -} -*/ -//--------------------------------------------------------------------------- - -void RoiStatisticsWidget::onNormalizeChanged(int a) -{ - onImgSelection(nullptr); -} - -//--------------------------------------------------------------------------- - -void RoiStatisticsWidget::onImgSelection(QStandardItem* item) -{ - ArrayXXr int_img; - bool is_checked = _get_img(int_img, _chk_normalize_sum->isChecked()); - - _techTabs->setEnabled(is_checked); - - if (is_checked) - { - _int_img_widget->setImageFromArray(int_img, *_selected_colormap); - } - else if (false == _image_size.isEmpty()) - { - clear_image(); - } -} - -//--------------------------------------------------------------------------- - -void RoiStatisticsWidget::clear_image() -{ - QImage image(_image_size, QImage::Format_ARGB32_Premultiplied); - image.fill(QColor(Qt::gray)); - _int_img_widget->setPixMap(QPixmap::fromImage(image.convertToFormat(QImage::Format_RGB32))); -} - //--------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/mvc/RoiStatisticsWidget.h b/src/mvc/RoiStatisticsWidget.h index 93854ff..e2be8ad 100644 --- a/src/mvc/RoiStatisticsWidget.h +++ b/src/mvc/RoiStatisticsWidget.h @@ -9,25 +9,14 @@ /*---------------------------------------------------------------------------*/ #include - -/*#include -#include +#include #include -#include -#include -#include -#include #include -#include -#include -#include -#include #include "data_struct/fit_parameters.h" -#include -#include -#include #include "gstar/Annotation/RoiMaskGraphicsItem.h" -*/ +#include "core/defines.h" +#include "data_struct/element_info.h" + /*---------------------------------------------------------------------------*/ class RoiStatisticsWidget : public QWidget @@ -47,7 +36,7 @@ class RoiStatisticsWidget : public QWidget */ ~RoiStatisticsWidget(); - void setImageData(std::unordered_map>& img_data); + void setData(std::unordered_map>& img_data, std::vector& roi_list); void clear_all(); @@ -64,46 +53,20 @@ public slots: void _createLayout(); private: -/* - QTabWidget* _techTabs; - - QPushButton* _runBtn; - QPushButton* _acceptBtn; - QPushButton* _cancelBtn; - - QListView* _img_names_view; - QStandardItemModel* _img_list_model; - QCheckBox* _chk_normalize_sum; - - ImageSegWidget* _int_img_widget; - - QVector* _selected_colormap; - - std::map _layout_map; - std::map> _img_data; + QTableWidget* _table_widget; - std::map _color_map; + QPushButton* _btn_export; - // kmeans controls - QComboBox* _km_TermCriteria; - QComboBox* _km_Centers; - QLineEdit* _km_le_MAX_ITER; - QLineEdit* _km_le_epsilon; - QLineEdit* _km_nfeatures; - QLineEdit* _km_attempts; + QPushButton* _btn_close; - QSize _image_size; + QStringList _base_header; - //QComboBox* _cb_selected_roi; + std::vector _element_lines_list; - QPushButton* _manual_btn_add_roi; - QComboBox* _manual_cb_action; - QSpinBox* _manual_sp_brush_size; - QPushButton* _manual_invert_roi; + std::vector _scalers_to_add_first_list; - int _next_color; - */ + std::vector _final_counts_to_add_before_scalers; }; From bac84d423ec251b56626ca4b2ad9a8d627abc86f Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 28 May 2024 15:24:56 -0500 Subject: [PATCH 05/25] Added more stats --- src/gstar/CountsStatsTransformer.cpp | 2 +- src/mvc/MapsElementsWidget.cpp | 2 +- src/mvc/RoiStatisticsWidget.cpp | 212 ++++++++++++++++++--------- src/mvc/RoiStatisticsWidget.h | 8 +- 4 files changed, 151 insertions(+), 73 deletions(-) diff --git a/src/gstar/CountsStatsTransformer.cpp b/src/gstar/CountsStatsTransformer.cpp index 5ebb484..8c6d2c6 100644 --- a/src/gstar/CountsStatsTransformer.cpp +++ b/src/gstar/CountsStatsTransformer.cpp @@ -73,7 +73,7 @@ void CountsStatsTransformer::setCounts(const data_struct::ArrayXXr& count _stdev += pow((counts(y,x) - _avg), 2); } } - _stdev = sqrtf(_stdev / cnts.size()); + _stdev = sqrtf(_stdev / (float)cnts.size()); std::sort(cnts.begin(), cnts.end(), [](float const& t1, float const& t2) { return t1 < t2; }); int idx = cnts.size() / 2; diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index e30739f..ff503d6 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -663,7 +663,7 @@ void MapsElementsWidget::openRoiStatsWidget() m_roiTreeModel->get_all_of_type(item.classId(), roi_list); } - _roi_stats_diag->setData(fit_counts, roi_list); + _roi_stats_diag->setData(fit_counts, roi_list, _normalizer, _calib_curve); _roi_stats_diag->show(); } diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp index 11a035c..83196c0 100644 --- a/src/mvc/RoiStatisticsWidget.cpp +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -6,12 +6,12 @@ #include //--------------------------------------------------------------------------- - +enum HEADER_NAME { ROI_Name=0, MapName=1, SumCnts=2, MeanCts=3, MedianCts=4, StdDevCts=5, SumUgcm2=6, MeanUg=7, MedianUg=8, StdDevUg=9, Area=10, MinCnts=11, MinPixel=12, MaxCnts=13, MaxPixel=14, Min_ugcm2=15, Max_ugcm2=16, Num_Spectra=17, TotalConcentrationCts=18, TotalConcentrationUg=19, TotalContentCts=20, TotalContentUg=21 }; //--------------------------------------------------------------------------- RoiStatisticsWidget::RoiStatisticsWidget() : QWidget() { - _base_header = { "ROI Name", "Element", "Cnt/s", "Min Cnts/s", "Max Cnts/s", "ug/cm2", "Min ug/cm2", "Max ug/cm2", "Mean", "Median", "Std Dev", "Area", "Num Spectra" }; + _base_header = { "ROI Name", "Map Name", "Sum Cnt/s", "Mean Cts/s", "Median Cts/s", "Std Dev Cts/s", "Sum ug/cm2", "Mean ug/cm2", "Median ug/cm2", "Std Dev ug/cm2", "Area", "Min Cnts/s", "Mix Pixel(x|y)", "Max Cnts/s", "Max Pixel (x|y)", "Min ug/cm2", "Max ug/cm2", "Num Spectra", "Total Concentration Cts/s (mean x # of pixels)", "Total Concentration ug/cm2", "Total Content Cts/s(mean x scan area with unit of femtogram 10^-15)", "Total Content ug/cm2" }; //create save ordered vector by element Z number with K , L, M lines for (std::string el_name : data_struct::Element_Symbols) @@ -80,7 +80,138 @@ RoiStatisticsWidget::~RoiStatisticsWidget() //--------------------------------------------------------------------------- -void RoiStatisticsWidget::setData(std::unordered_map>& img_data, std::vector& roi_list) +void RoiStatisticsWidget::_insert_item(QString roiName, + QString imgName, + const data_struct::ArrayXXr& img, + const std::vector>& roi_pixels, + int i, + data_struct::ArrayXXr* normalizer, + Calibration_curve* calib_curve) +{ + _table_widget->setItem(i, ROI_Name, new QTableWidgetItem(roiName)); + _table_widget->setItem(i, MapName, new QTableWidgetItem(imgName)); + double sum_cts = 0.0; + double min_cts = std::numeric_limits::max(); + double max_cts = std::numeric_limits::min(); + double std_dev_cts = 0.0; + double median_cts = 0.0; + double sum_ugcm2 = 0.0; + double min_ug = std::numeric_limits::max(); + double max_ug = std::numeric_limits::min(); + double std_dev_ug = 0.0; + double median_ug = 0.0; + + std::pair min_pixel; + std::pair max_pixel; + Eigen::ArrayXf cts_arr(roi_pixels.size()); + Eigen::ArrayXf ug_arr(roi_pixels.size()); + int j = 0; + double calib_val = 1.0; + bool hasNorm = false; + if (calib_curve != nullptr && normalizer != nullptr) + { + if( calib_curve->calib_curve.count(imgName.toStdString()) > 0 ) + { + calib_val = static_cast(calib_curve->calib_curve.at(imgName.toStdString())); + hasNorm = true; + } + } + + for(auto pitr : roi_pixels) + { + double val = img(pitr.first, pitr.second); + sum_cts += val; + min_cts = std::min(val,min_cts); + if(min_cts == val) + { + min_pixel = pitr; + } + max_cts = std::max(val,max_cts); + if(max_cts == val) + { + max_pixel = pitr; + } + cts_arr[j] = val; + if(hasNorm) + { + double ug = (val / (*normalizer)(pitr.first, pitr.second) / calib_val); + sum_ugcm2 += ug; + min_ug = std::min(ug,min_ug); + max_ug = std::max(ug,max_ug); + ug_arr[j] = ug; + } + j++; + } + double mean_cts = sum_cts / (double)roi_pixels.size(); + double mean_ug = sum_ugcm2 / (double)roi_pixels.size(); + for(auto pitr : roi_pixels) + { + double val = img(pitr.first, pitr.second); + std_dev_cts += pow((val - mean_cts), 2); + if(hasNorm) + { + double ug = (val / (*normalizer)(pitr.first, pitr.second) / calib_val); + std_dev_ug += pow((ug - mean_ug), 2); + } + } + std_dev_cts = sqrtf(std_dev_cts / (double)roi_pixels.size()); + if(hasNorm) + { + std_dev_ug = sqrtf(std_dev_ug / (double)roi_pixels.size()); + std::sort(ug_arr.begin(), ug_arr.end(), [](float const& t1, float const& t2) { return t1 < t2; }); + int idx = ug_arr.size() / 2; + median_ug = ug_arr(idx); + } + + std::sort(cts_arr.begin(), cts_arr.end(), [](float const& t1, float const& t2) { return t1 < t2; }); + int idx = cts_arr.size() / 2; + median_cts = cts_arr(idx); + + QString str_min_pixel = QString::number(min_pixel.first) + " | " + QString::number(min_pixel.second); + QString str_max_pixel = QString::number(max_pixel.first) + " | " + QString::number(max_pixel.second); + _table_widget->setItem(i, SumCnts, new QTableWidgetItem(QString::number(sum_cts))); + _table_widget->setItem(i, MinCnts, new QTableWidgetItem(QString::number(min_cts))); + _table_widget->setItem(i, MinPixel, new QTableWidgetItem(str_min_pixel)); + _table_widget->setItem(i, MaxCnts, new QTableWidgetItem(QString::number(max_cts))); + _table_widget->setItem(i, MaxPixel, new QTableWidgetItem(str_max_pixel)); + _table_widget->setItem(i, MeanCts, new QTableWidgetItem(QString::number(mean_cts))); + _table_widget->setItem(i, MedianCts, new QTableWidgetItem(QString::number(median_cts))); + _table_widget->setItem(i, StdDevCts, new QTableWidgetItem(QString::number(std_dev_cts))); + _table_widget->setItem(i, Num_Spectra, new QTableWidgetItem(QString::number(roi_pixels.size()))); + + if(hasNorm) + { + _table_widget->setItem(i, SumUgcm2, new QTableWidgetItem(QString::number(sum_ugcm2))); + _table_widget->setItem(i, Min_ugcm2, new QTableWidgetItem(QString::number(min_ug))); + _table_widget->setItem(i, Max_ugcm2, new QTableWidgetItem(QString::number(max_ug))); + _table_widget->setItem(i, MeanUg, new QTableWidgetItem(QString::number(mean_ug))); + _table_widget->setItem(i, MedianUg, new QTableWidgetItem(QString::number(median_ug))); + _table_widget->setItem(i, StdDevUg, new QTableWidgetItem(QString::number(std_dev_ug))); + } + else + { + _table_widget->setItem(i, SumUgcm2, new QTableWidgetItem(" ")); + _table_widget->setItem(i, Min_ugcm2, new QTableWidgetItem(" ")); + _table_widget->setItem(i, Max_ugcm2, new QTableWidgetItem(" ")); + _table_widget->setItem(i, MeanUg, new QTableWidgetItem(" ")); + _table_widget->setItem(i, MedianUg, new QTableWidgetItem(" ")); + _table_widget->setItem(i, StdDevUg, new QTableWidgetItem(" ")); + } + + +// Area, TotalConcentration, TotalContent + _table_widget->setItem(i, TotalConcentrationCts, new QTableWidgetItem(QString::number(mean_cts * (double)roi_pixels.size()))); + _table_widget->setItem(i, TotalConcentrationUg, new QTableWidgetItem(QString::number(mean_ug * (double)roi_pixels.size()))); + + +} + +//--------------------------------------------------------------------------- + +void RoiStatisticsWidget::setData(std::unordered_map>& img_data, + std::vector& roi_list, + data_struct::ArrayXXr* normalizer, + Calibration_curve* calib_curve) { int total = img_data.size() * roi_list.size(); @@ -91,107 +222,48 @@ void RoiStatisticsWidget::setData(std::unordered_mapsetItem(i, 0, new QTableWidgetItem(QString::fromLatin1(itr.name.c_str(), itr.name.length()))); - _table_widget->setItem(i, 1, new QTableWidgetItem()); - _table_widget->setItem(i, 2, new QTableWidgetItem(QString::fromLatin1(itr.unit.c_str(), itr.unit.length()))); - _table_widget->setItem(i, 3, new QTableWidgetItem(QString::fromLatin1(itr.description.c_str(), itr.description.length()))); - */ - + std::vector> roi_pixels; + roi_itr->to_roi_vec(roi_pixels); // insert in z order for (auto itr : _element_lines_list) { if (img_data.count(itr) > 0) { - _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); - _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.c_str(), itr.length()))); - - /* - _img_data[QString(el_name.c_str())] = img_data.at(el_name); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(el_name.c_str())); - _img_list_model->appendRow(item0); - - if (_image_size.isEmpty()) - { - _image_size = QSize(img_data.at(el_name).cols(), img_data.at(el_name).rows()); - } - img_data.erase(el_name); - */ + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), img_data.at(itr), roi_pixels, i, normalizer, calib_curve); done_map[itr] = 1; i++; } } - - // add end of element list that are not elements for (auto itr : _final_counts_to_add_before_scalers) { if (img_data.count(itr) > 0) { - _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); - _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.c_str(), itr.length()))); - - /* - _img_data[QString(itr.c_str())] = img_data.at(itr); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(itr.c_str())); - _img_list_model->appendRow(item0); - - img_data.erase(itr); - */ + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), img_data.at(itr), roi_pixels, i, normalizer, calib_curve); done_map[itr] = 1; i++; } } - // add scalers in certain order for (auto itr : _scalers_to_add_first_list) { if (img_data.count(itr) > 0) { - _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); - _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.c_str(), itr.length()))); - - /* - _img_data[QString(itr.c_str())] = img_data.at(itr); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(itr.c_str())); - _img_list_model->appendRow(item0); - - img_data.erase(itr); - */ + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), img_data.at(itr), roi_pixels, i, normalizer, calib_curve); done_map[itr] = 1; i++; } } - // add rest of scalers for (auto itr : img_data) { if(done_map.count(itr.first) == 0) { - _table_widget->setItem(i, 0, new QTableWidgetItem(roi_itr->getName())); - _table_widget->setItem(i, 1, new QTableWidgetItem(QString::fromLatin1(itr.first.c_str(), itr.first.length()))); - - /* - _img_data[QString(itr.first.c_str())] = img_data.at(itr.first); - QStandardItem* item0 = new QStandardItem(false); - item0->setCheckable(true); - item0->setCheckState(Qt::Unchecked); - item0->setText(QString(itr.first.c_str())); - _img_list_model->appendRow(item0); - */ + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.first.c_str(), itr.first.length()), itr.second, roi_pixels, i, normalizer, calib_curve); i++; } - } + } } } @@ -241,7 +313,7 @@ void RoiStatisticsWidget::onClose() void RoiStatisticsWidget::clear_all() { - //_table_widget->clear(); + _table_widget->setRowCount(0); } //--------------------------------------------------------------------------- diff --git a/src/mvc/RoiStatisticsWidget.h b/src/mvc/RoiStatisticsWidget.h index e2be8ad..9464399 100644 --- a/src/mvc/RoiStatisticsWidget.h +++ b/src/mvc/RoiStatisticsWidget.h @@ -16,6 +16,7 @@ #include "gstar/Annotation/RoiMaskGraphicsItem.h" #include "core/defines.h" #include "data_struct/element_info.h" +#include "mvc/MapsH5Model.h" /*---------------------------------------------------------------------------*/ @@ -36,7 +37,10 @@ class RoiStatisticsWidget : public QWidget */ ~RoiStatisticsWidget(); - void setData(std::unordered_map>& img_data, std::vector& roi_list); + void setData(std::unordered_map>& img_data, + std::vector& roi_list, + data_struct::ArrayXXr* normalizer, + Calibration_curve* calib_curve); void clear_all(); @@ -54,6 +58,8 @@ public slots: private: + void _insert_item(QString roiName, QString imgName, const data_struct::ArrayXXr& img, const std::vector>& roi_pixels, int i,data_struct::ArrayXXr* normalizer,Calibration_curve* calib_curve); + QTableWidget* _table_widget; QPushButton* _btn_export; From 880ac3762035ed985833deba9931befb1e1d56bf Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Wed, 29 May 2024 09:55:48 -0500 Subject: [PATCH 06/25] Fixed bug with roi stats flipping cols and rows. Added pref to prepend and append * for simpler file filter --- src/mvc/FileTabWidget.cpp | 10 +++++++++- src/mvc/MapsElementsWidget.cpp | 1 - src/mvc/RoiStatisticsWidget.cpp | 12 ++++++------ src/preferences/Preferences.cpp | 3 ++- src/preferences/Preferences.h | 1 + src/preferences/PreferencesDisplay.cpp | 7 +++++++ src/preferences/PreferencesDisplay.h | 2 ++ 7 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/mvc/FileTabWidget.cpp b/src/mvc/FileTabWidget.cpp index 9739a7c..4ef9e61 100644 --- a/src/mvc/FileTabWidget.cpp +++ b/src/mvc/FileTabWidget.cpp @@ -12,6 +12,7 @@ #include #include #include +#include /*---------------------------------------------------------------------------*/ @@ -271,7 +272,14 @@ void FileTabWidget::filterTextChanged(const QString &filter_text) _filter_line->setText(filter_text); if(filter_text.length() > 0) { - QRegularExpression re (QRegularExpression::wildcardToRegularExpression(filter_text)); + // if not strict then prepend and append '*' + QString filter_t = filter_text; + if(false == Preferences::inst()->getValue(STR_PRF_STRICT_REGEX).toBool()) + { + filter_t.prepend('*'); + filter_t.append('*'); + } + QRegularExpression re (QRegularExpression::wildcardToRegularExpression(filter_t)); for(int i=0; i < _file_list_model->rowCount(); i++) { diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index ff503d6..d6aa22a 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -662,7 +662,6 @@ void MapsElementsWidget::openRoiStatsWidget() { m_roiTreeModel->get_all_of_type(item.classId(), roi_list); } - _roi_stats_diag->setData(fit_counts, roi_list, _normalizer, _calib_curve); _roi_stats_diag->show(); diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp index 83196c0..1b92c86 100644 --- a/src/mvc/RoiStatisticsWidget.cpp +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -119,7 +119,7 @@ void RoiStatisticsWidget::_insert_item(QString roiName, for(auto pitr : roi_pixels) { - double val = img(pitr.first, pitr.second); + double val = img(pitr.second, pitr.first); sum_cts += val; min_cts = std::min(val,min_cts); if(min_cts == val) @@ -134,7 +134,7 @@ void RoiStatisticsWidget::_insert_item(QString roiName, cts_arr[j] = val; if(hasNorm) { - double ug = (val / (*normalizer)(pitr.first, pitr.second) / calib_val); + double ug = (val / (*normalizer)(pitr.second, pitr.first) / calib_val); sum_ugcm2 += ug; min_ug = std::min(ug,min_ug); max_ug = std::max(ug,max_ug); @@ -146,11 +146,11 @@ void RoiStatisticsWidget::_insert_item(QString roiName, double mean_ug = sum_ugcm2 / (double)roi_pixels.size(); for(auto pitr : roi_pixels) { - double val = img(pitr.first, pitr.second); + double val = img(pitr.second, pitr.first); std_dev_cts += pow((val - mean_cts), 2); if(hasNorm) { - double ug = (val / (*normalizer)(pitr.first, pitr.second) / calib_val); + double ug = (val / (*normalizer)(pitr.second, pitr.first) / calib_val); std_dev_ug += pow((ug - mean_ug), 2); } } @@ -167,8 +167,8 @@ void RoiStatisticsWidget::_insert_item(QString roiName, int idx = cts_arr.size() / 2; median_cts = cts_arr(idx); - QString str_min_pixel = QString::number(min_pixel.first) + " | " + QString::number(min_pixel.second); - QString str_max_pixel = QString::number(max_pixel.first) + " | " + QString::number(max_pixel.second); + QString str_min_pixel = QString::number(min_pixel.second) + " | " + QString::number(min_pixel.first); + QString str_max_pixel = QString::number(max_pixel.second) + " | " + QString::number(max_pixel.first); _table_widget->setItem(i, SumCnts, new QTableWidgetItem(QString::number(sum_cts))); _table_widget->setItem(i, MinCnts, new QTableWidgetItem(QString::number(min_cts))); _table_widget->setItem(i, MinPixel, new QTableWidgetItem(str_min_pixel)); diff --git a/src/preferences/Preferences.cpp b/src/preferences/Preferences.cpp index 2172b7c..5dc063d 100644 --- a/src/preferences/Preferences.cpp +++ b/src/preferences/Preferences.cpp @@ -61,7 +61,8 @@ Preferences::Preferences() {STR_PRF_SHOW_DATASET_ON_FILE_SELECT, QVariant()}, {STR_SEARCH_SUB_DIR_FOR_DATASETS, QVariant()}, {STR_GEOMETRY, QVariant()}, - {STR_WINDOWSTATE, QVariant()} + {STR_WINDOWSTATE, QVariant()}, + {STR_PRF_STRICT_REGEX, QVariant()} }; load(); } diff --git a/src/preferences/Preferences.h b/src/preferences/Preferences.h index adcdca4..19f2189 100644 --- a/src/preferences/Preferences.h +++ b/src/preferences/Preferences.h @@ -80,6 +80,7 @@ #define STR_COLOR_DOCK "ColorDock" #define STR_SCATTER_DOCK "ScatterDock" #define STR_EXTRA_DOCK "ExtraDock" +#define STR_PRF_STRICT_REGEX "StrictRegEx" /** * @brief Read and save preferences between application restarts, the vaule key diff --git a/src/preferences/PreferencesDisplay.cpp b/src/preferences/PreferencesDisplay.cpp index fdee992..4b9a197 100644 --- a/src/preferences/PreferencesDisplay.cpp +++ b/src/preferences/PreferencesDisplay.cpp @@ -65,6 +65,11 @@ PreferencesDisplay::PreferencesDisplay(QWidget* parent) : QWidget(parent) _ck_search_datasets = new QCheckBox(); _ck_search_datasets->setChecked(Preferences::inst()->getValue(STR_SEARCH_SUB_DIR_FOR_DATASETS).toBool()); + QLabel* lblStrictRegex = new QLabel("Strict Regular Expressions for file filter.\n True: The file filter string is unchanged.\n False: Prepend and append '*' to file filter."); + lblSearchDatasets->setFont(font); + _ck_strict_regex = new QCheckBox(); + _ck_strict_regex->setChecked(Preferences::inst()->getValue(STR_PRF_STRICT_REGEX).toBool()); + QFormLayout* mainLayout = new QFormLayout(); @@ -74,6 +79,7 @@ PreferencesDisplay::PreferencesDisplay(QWidget* parent) : QWidget(parent) mainLayout->addRow(lblUseDarkTheme, _cb_themes); mainLayout->addRow(lblShowDatasetOnSelect, _ck_show_dataset_on_select); mainLayout->addRow(lblSearchDatasets, _ck_search_datasets); + mainLayout->addRow(lblStrictRegex, _ck_strict_regex); connect(_cb_themes, &QComboBox::currentTextChanged, this, &PreferencesDisplay::themeChanged); @@ -135,6 +141,7 @@ void PreferencesDisplay::acceptChanges() Preferences::inst()->setValue(STR_PRF_DecimalPrecision, getDecimalPrecision()); Preferences::inst()->setValue(STR_PRF_SHOW_DATASET_ON_FILE_SELECT, _ck_show_dataset_on_select->isChecked()); Preferences::inst()->setValue(STR_SEARCH_SUB_DIR_FOR_DATASETS, _ck_search_datasets->isChecked()); + Preferences::inst()->setValue(STR_PRF_STRICT_REGEX, _ck_strict_regex->isChecked()); } /*---------------------------------------------------------------------------*/ diff --git a/src/preferences/PreferencesDisplay.h b/src/preferences/PreferencesDisplay.h index 08dee85..6f89f68 100644 --- a/src/preferences/PreferencesDisplay.h +++ b/src/preferences/PreferencesDisplay.h @@ -106,6 +106,8 @@ public slots: QCheckBox* _ck_show_dataset_on_select; QCheckBox* _ck_search_datasets; + + QCheckBox* _ck_strict_regex; }; /*---------------------------------------------------------------------------*/ From feb7a2ca4bd880801077bef181b4ecd22d71629a Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Wed, 29 May 2024 10:38:54 -0500 Subject: [PATCH 07/25] added export to csv function --- src/core/uProbeX.cpp | 9 +++++ src/core/uProbeX.h | 2 + src/mvc/MapsElementsWidget.cpp | 2 +- src/mvc/RoiStatisticsWidget.cpp | 65 ++++++++++++++++++++++++++++++++- src/mvc/RoiStatisticsWidget.h | 16 ++++++-- 5 files changed, 88 insertions(+), 6 deletions(-) diff --git a/src/core/uProbeX.cpp b/src/core/uProbeX.cpp index fc5d5e7..34a0865 100644 --- a/src/core/uProbeX.cpp +++ b/src/core/uProbeX.cpp @@ -230,6 +230,15 @@ void uProbeX::createMenuBar() connect(m_menuFile, SIGNAL(aboutToShow()), this, SLOT(menuBarEnable())); + // Batch menu + //m_menuBatch = new QMenu(tr("Batch Processing")); + //action = m_menuBatch->addAction("Per Pixel Processing"); + //connect(action, SIGNAL(triggered()), this, SLOT(perPixel())); + //action = "Export Images" + //action = "Roi Stats" + //m_menu->addMenu(m_menuBatch); + + // Stream menu m_menuStream = new QMenu(tr("Live Stream")); action = m_menuStream->addAction("Open Live Stream Viewer"); diff --git a/src/core/uProbeX.h b/src/core/uProbeX.h index 95cc709..e226b47 100644 --- a/src/core/uProbeX.h +++ b/src/core/uProbeX.h @@ -280,6 +280,8 @@ private slots: */ QMenu* m_menuStream; + QMenu* m_menuBatch; + /** * @brief Help menu */ diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index d6aa22a..e15a2a2 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -662,7 +662,7 @@ void MapsElementsWidget::openRoiStatsWidget() { m_roiTreeModel->get_all_of_type(item.classId(), roi_list); } - _roi_stats_diag->setData(fit_counts, roi_list, _normalizer, _calib_curve); + _roi_stats_diag->setData(_model->getDir(), _model->getDatasetName(), _cb_analysis->currentText(), _cb_normalize->currentText(), fit_counts, roi_list, _normalizer, _calib_curve); _roi_stats_diag->show(); } diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp index 1b92c86..008b800 100644 --- a/src/mvc/RoiStatisticsWidget.cpp +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -4,6 +4,8 @@ *---------------------------------------------------------------------------*/ #include +#include +#include //--------------------------------------------------------------------------- enum HEADER_NAME { ROI_Name=0, MapName=1, SumCnts=2, MeanCts=3, MedianCts=4, StdDevCts=5, SumUgcm2=6, MeanUg=7, MedianUg=8, StdDevUg=9, Area=10, MinCnts=11, MinPixel=12, MaxCnts=13, MaxPixel=14, Min_ugcm2=15, Max_ugcm2=16, Num_Spectra=17, TotalConcentrationCts=18, TotalConcentrationUg=19, TotalContentCts=20, TotalContentUg=21 }; @@ -208,7 +210,11 @@ void RoiStatisticsWidget::_insert_item(QString roiName, //--------------------------------------------------------------------------- -void RoiStatisticsWidget::setData(std::unordered_map>& img_data, +void RoiStatisticsWidget::setData(QDir model_dir, + QString dataset_name, + QString fitting_name, + QString normalizer_name, + std::unordered_map>& img_data, std::vector& roi_list, data_struct::ArrayXXr* normalizer, Calibration_curve* calib_curve) @@ -219,6 +225,24 @@ void RoiStatisticsWidget::setData(std::unordered_map done_map; + _export_dir = model_dir; + _export_dir.cdUp(); + _export_dir.cdUp(); + _export_dir.cd("output"); + + + QString filename = "roi_export_" + dataset_name + "_" + fitting_name + "_"; + if(normalizer != nullptr) + { + filename += normalizer_name + "_"; + } + + QDateTime date = QDateTime::currentDateTime(); + QString formattedTime = date.toString("yyyy.MM.dd_hh.mm.ss"); + filename += formattedTime + ".csv"; + + _str_export_filename = _export_dir.absolutePath() + QDir::separator() + filename; + int i = 0; for (auto roi_itr : roi_list) { @@ -298,6 +322,44 @@ void RoiStatisticsWidget::_createLayout() void RoiStatisticsWidget::onExport() { + QFile file(_str_export_filename); + if (!file.open(QIODevice::WriteOnly)) + { + logW<< "Could not open file for writing:"<< _str_export_filename.toStdString()<<"\n"; + return; + } + + QTextStream out(&file); + + // Write header row + QStringList headers = _base_header; + out << headers.join(",") << "\n"; + + // Write data rows + for (int i = 0; i < _table_widget->rowCount(); ++i) + { + QStringList rowData; + for (int j = 0; j < _table_widget->columnCount(); ++j) + { + QTableWidgetItem* item = _table_widget->item(i, j); + if (item) + { + rowData.append(item->text()); + } + else + { + rowData.append(""); + } + } + out << rowData.join(",") << "\n"; + } + + file.close(); + + if (false == QDesktopServices::openUrl(QUrl::fromLocalFile(_export_dir.absolutePath()))) + { + logE << "Failed to open dir " << _export_dir.absolutePath().toStdString() << "\n"; + } } @@ -314,6 +376,7 @@ void RoiStatisticsWidget::onClose() void RoiStatisticsWidget::clear_all() { _table_widget->setRowCount(0); + _str_export_filename = ""; } //--------------------------------------------------------------------------- diff --git a/src/mvc/RoiStatisticsWidget.h b/src/mvc/RoiStatisticsWidget.h index 9464399..bdd9577 100644 --- a/src/mvc/RoiStatisticsWidget.h +++ b/src/mvc/RoiStatisticsWidget.h @@ -37,10 +37,14 @@ class RoiStatisticsWidget : public QWidget */ ~RoiStatisticsWidget(); - void setData(std::unordered_map>& img_data, - std::vector& roi_list, - data_struct::ArrayXXr* normalizer, - Calibration_curve* calib_curve); + void setData(QDir model_dir, + QString dataset_name, + QString fitting_name, + QString normalizer_name, + std::unordered_map>& img_data, + std::vector& roi_list, + data_struct::ArrayXXr* normalizer, + Calibration_curve* calib_curve); void clear_all(); @@ -60,6 +64,10 @@ public slots: void _insert_item(QString roiName, QString imgName, const data_struct::ArrayXXr& img, const std::vector>& roi_pixels, int i,data_struct::ArrayXXr* normalizer,Calibration_curve* calib_curve); + QString _str_export_filename; + + QDir _export_dir; + QTableWidget* _table_widget; QPushButton* _btn_export; From 4751d3b5c555a57888e4b84cb500589ca5f4f1ff Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Wed, 29 May 2024 14:02:36 -0500 Subject: [PATCH 08/25] Updated file tab list to table. You can sort by column now and has file sizes. --- src/mvc/FileTabWidget.cpp | 50 +++---- src/mvc/FileTabWidget.h | 7 +- src/mvc/FileTableModel.h | 209 ++++++++++++++++++++++++++++++ src/mvc/FitElementsTableModel.cpp | 2 +- src/mvc/FitElementsTableModel.h | 2 +- src/mvc/RoiStatisticsWidget.cpp | 6 +- 6 files changed, 236 insertions(+), 40 deletions(-) create mode 100644 src/mvc/FileTableModel.h diff --git a/src/mvc/FileTabWidget.cpp b/src/mvc/FileTabWidget.cpp index 4ef9e61..41b0aca 100644 --- a/src/mvc/FileTabWidget.cpp +++ b/src/mvc/FileTabWidget.cpp @@ -14,6 +14,7 @@ #include #include + /*---------------------------------------------------------------------------*/ FileTabWidget::FileTabWidget(QWidget* parent) : QWidget(parent) @@ -29,13 +30,14 @@ FileTabWidget::FileTabWidget(QWidget* parent) : QWidget(parent) _action_refresh = _contextMenu->addAction("Refresh"); connect(_action_refresh, SIGNAL(triggered()), this, SIGNAL(onRefresh())); - _file_list_model = new QStandardItemModel(); - _file_list_view = new QListView(); + _file_list_model = new FileTableModel(); + _file_list_view = new QTableView(); // _file_list_view->setViewMode(QListView::IconMode); _file_list_view->setModel(_file_list_model); _file_list_view->setEditTriggers(QAbstractItemView::NoEditTriggers); _file_list_view->setContextMenuPolicy(Qt::CustomContextMenu); _file_list_view->setSelectionMode(QAbstractItemView::ExtendedSelection); //MultiSelection + _file_list_view->setSortingEnabled(true); // if preferences saves on select changes loaded dataset connect(_file_list_view->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &FileTabWidget::onFileRowChange); @@ -98,8 +100,8 @@ void FileTabWidget::_gen_visible_list(QStringList *sl) { if(false == _file_list_view->isRowHidden(i)) { - QStandardItem *val = _file_list_model->item(i, 0); - sl->append(val->text()); + auto val = _file_list_model->item(i); + sl->append(val.text); } } } @@ -167,8 +169,11 @@ void FileTabWidget::set_file_list(const std::map& fileinfo_l _file_list_model->clear(); for(auto & itr : fileinfo_list) { - _file_list_model->appendRow(new QStandardItem(QIcon(":/images/circle_gray.png"), itr.first)); + _file_list_model->appendRow( RowData(QIcon(":/images/circle_gray.png"), itr.first, itr.second.size()/1024)); } + + _file_list_view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); + _file_list_view->horizontalHeader()->resizeSections(QHeaderView::Interactive); } /*---------------------------------------------------------------------------*/ @@ -181,8 +186,8 @@ void FileTabWidget::update_file_list(const std::map& fileinf bool found = false; for(int i=0; iitem(i); - if (item->text() == itr.first) + auto item = _file_list_model->item(i); + if (item.text == itr.first) { found = true; break; @@ -191,9 +196,12 @@ void FileTabWidget::update_file_list(const std::map& fileinf if (false == found) { - _file_list_model->appendRow(new QStandardItem(QIcon(":/images/circle_gray.png"), itr.first)); + _file_list_model->appendRow(RowData(QIcon(":/images/circle_gray.png"), itr.first, itr.second.size()/1024)); } } + + _file_list_view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); + _file_list_view->horizontalHeader()->resizeSections(QHeaderView::Interactive); } /*---------------------------------------------------------------------------*/ @@ -284,8 +292,8 @@ void FileTabWidget::filterTextChanged(const QString &filter_text) for(int i=0; i < _file_list_model->rowCount(); i++) { _file_list_view->setRowHidden(i, true); - QStandardItem *val = _file_list_model->item(i, 0); - QRegularExpressionMatchIterator j = re.globalMatch(val->text()); + auto val = _file_list_model->item(i); + QRegularExpressionMatchIterator j = re.globalMatch(val.text); if (j.hasNext()) { _file_list_view->setRowHidden(i, false); @@ -305,27 +313,7 @@ void FileTabWidget::filterTextChanged(const QString &filter_text) void FileTabWidget::loaded_file_status_changed(File_Loaded_Status status, const QString& filename) { - for(int i=0; i < _file_list_model->rowCount(); i++) - { - QStandardItem *val = _file_list_model->item(i, 0); - if(filename == val->text()) - { - switch(status) - { - case UNLOADED: - val->setIcon(QIcon(":/images/circle_gray.png")); - break; - case LOADED: - val->setIcon(QIcon(":/images/circle_green.png")); - break; - case FAILED_LOADING: - val->setIcon(QIcon(":/images/circle_red.png")); - break; - } - break; - } - } - + _file_list_model->updateStatus(status, filename); } /*---------------------------------------------------------------------------*/ diff --git a/src/mvc/FileTabWidget.h b/src/mvc/FileTabWidget.h index 0c4499b..0ca93a8 100644 --- a/src/mvc/FileTabWidget.h +++ b/src/mvc/FileTabWidget.h @@ -20,11 +20,10 @@ #include #include "FitParamsTableModel.h" #include "mvc/ComboBoxDelegate.h" +#include /*---------------------------------------------------------------------------*/ -enum File_Loaded_Status {UNLOADED, LOADED, FAILED_LOADING}; - /*---------------------------------------------------------------------------*/ class FileTabWidget : public QWidget @@ -103,9 +102,9 @@ public slots: void _gen_visible_list(QStringList *sl); - QListView* _file_list_view; + QTableView* _file_list_view; - QStandardItemModel* _file_list_model; + FileTableModel* _file_list_model; QMenu *_contextMenu; diff --git a/src/mvc/FileTableModel.h b/src/mvc/FileTableModel.h new file mode 100644 index 0000000..44e1e31 --- /dev/null +++ b/src/mvc/FileTableModel.h @@ -0,0 +1,209 @@ +//----------------------------------------------------------------------------- + // Copyright (c) 2024, UChicago Argonne, LLC + // See LICENSE file. + //--------------------------------------------------------------------------- + +#ifndef FileTableModel_H +#define FileTableModel_H + +//--------------------------------------------------------------------------- + +#include + +//--------------------------------------------------------------------------- + +enum File_Loaded_Status {UNLOADED, LOADED, FAILED_LOADING}; + +//--------------------------------------------------------------------------- +struct RowData +{ + RowData(QIcon i, QString s, int n) + { + icon = i; + text = s; + number = n; + status = UNLOADED; + } + QIcon icon; + QString text; + int number; + File_Loaded_Status status; +}; +//--------------------------------------------------------------------------- + +class FileTableModel : public QAbstractTableModel +{ +public: + FileTableModel(QObject* parent = nullptr) : QAbstractTableModel(parent) + { + _headers[0] = tr("L"); + _headers[1] = tr("Name"); + _headers[2] = tr("Size (MB)"); + } + + int rowCount(const QModelIndex& parent = QModelIndex()) const override + { + return _data.size(); + } + + int columnCount(const QModelIndex& parent = QModelIndex()) const override + { + return 3; // Three columns: icon, string, integer + } + + void appendRow(const RowData& row) + { + int rown = _data.size(); + QModelIndex gIndex = index(rown, 0, QModelIndex()); + beginInsertRows(gIndex, rown, rown); + _data.append(row); + endInsertRows(); + } + + void clear() + { + _data.clear(); + } + + const RowData& item(int row) + { + return _data.at(row); + } + + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override + { + if (!index.isValid() || index.row() >= _data.size() || index.column() >= 3) + { + return QVariant(); + } + + const RowData& rowData = _data[index.row()]; + + if (role == Qt::DecorationRole && index.column() == 0) + { + return rowData.icon; + } + else if (role == Qt::DisplayRole) + { + if (index.column() == 1) + { + return rowData.text; + } + else if (index.column() == 2) + { + return rowData.number; + } + } + return QVariant(); + } + + QVariant headerData(int section, Qt::Orientation orientation, int role) const + { + // Check this is DisplayRole + if (role != Qt::DisplayRole) return QVariant(); + + // Horizontal headers + if (orientation == Qt::Horizontal) + { + if(section > (2)) + { + return QVariant(); + } + else + { + return _headers[section]; + } + } + + // Return empty data + return QVariant(); + } + + Qt::ItemFlags flags(const QModelIndex &index) const + { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + + void updateStatus(File_Loaded_Status status, const QString& filename) + { + int i=0; + for(auto &itr : _data) + { + if(filename == itr.text) + { + QModelIndex index = createIndex(i, 0, &itr); + itr.status = status; + switch(status) + { + case UNLOADED: + itr.icon = QIcon(":/images/circle_gray.png"); + emit dataChanged(index, index); + break; + case LOADED: + itr.icon = QIcon(":/images/circle_green.png"); + emit dataChanged(index, index); + break; + case FAILED_LOADING: + itr.icon = QIcon(":/images/circle_red.png"); + emit dataChanged(index, index); + break; + } + break; + } + i++; + } + } + + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override + { + if(column < 0) + { + return; + } + beginResetModel(); + std::sort(_data.begin(), _data.end(), [&](const RowData& rowA, const RowData& rowB) + { + switch (column) + { + case 0: // icon + switch(order) + { + case Qt::AscendingOrder: + return rowA.status < rowB.status; + case Qt::DescendingOrder: + return rowA.status > rowB.status; + }; + case 1: // file name + switch(order) + { + case Qt::AscendingOrder: + return rowA.text < rowB.text; + case Qt::DescendingOrder: + return rowA.text > rowB.text; + }; + //return (rowA.text.compare(rowB.text, order) == 0); + case 2: // file size + switch(order) + { + case Qt::AscendingOrder: + return rowA.number < rowB.number; + case Qt::DescendingOrder: + return rowA.number > rowB.number; + }; + }; + }); + endResetModel(); + } + +private: + QList _data; + + QString _headers[3]; +}; + + +//--------------------------------------------------------------------------- + +#endif /* FileTableModel.h */ + +//--------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/mvc/FitElementsTableModel.cpp b/src/mvc/FitElementsTableModel.cpp index eac2ee7..ff826fa 100644 --- a/src/mvc/FitElementsTableModel.cpp +++ b/src/mvc/FitElementsTableModel.cpp @@ -8,7 +8,7 @@ /*---------------------------------------------------------------------------*/ -FitElementsTableModel::FitElementsTableModel(std::string detector_element, QObject* parent) : QAbstractItemModel(parent) +FitElementsTableModel::FitElementsTableModel(std::string detector_element, QObject* parent) : QAbstractTableModel(parent) { // Initialize header data m_headers[HEADERS::SYMBOL] = tr("Symbol"); diff --git a/src/mvc/FitElementsTableModel.h b/src/mvc/FitElementsTableModel.h index 89ac8ca..b5ec8f5 100644 --- a/src/mvc/FitElementsTableModel.h +++ b/src/mvc/FitElementsTableModel.h @@ -19,7 +19,7 @@ * @brief model to control the solver table */ class FitElementsTableModel -: public QAbstractItemModel +: public QAbstractTableModel { Q_OBJECT diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp index 008b800..c4e1c87 100644 --- a/src/mvc/RoiStatisticsWidget.cpp +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -325,7 +325,7 @@ void RoiStatisticsWidget::onExport() QFile file(_str_export_filename); if (!file.open(QIODevice::WriteOnly)) { - logW<< "Could not open file for writing:"<< _str_export_filename.toStdString()<<"\n"; + logE<< "Could not open file for writing:"<< _str_export_filename.toStdString()<<"\n"; return; } @@ -358,9 +358,9 @@ void RoiStatisticsWidget::onExport() if (false == QDesktopServices::openUrl(QUrl::fromLocalFile(_export_dir.absolutePath()))) { - logE << "Failed to open dir " << _export_dir.absolutePath().toStdString() << "\n"; + logW << "Failed to open dir " << _export_dir.absolutePath().toStdString() << "\n"; } - + close(); } //--------------------------------------------------------------------------- From ba463c8f46e7c0b228263eee9c12bc22d82a2522 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Wed, 29 May 2024 16:13:52 -0500 Subject: [PATCH 09/25] added preferences to pick file size --- src/mvc/FileTabWidget.cpp | 40 +++++++++++++++++++++++-- src/mvc/FileTableModel.h | 41 ++++++++++++++++++++++---- src/preferences/Preferences.cpp | 1 + src/preferences/Preferences.h | 1 + src/preferences/PreferencesDisplay.cpp | 11 +++++++ src/preferences/PreferencesDisplay.h | 2 ++ 6 files changed, 88 insertions(+), 8 deletions(-) diff --git a/src/mvc/FileTabWidget.cpp b/src/mvc/FileTabWidget.cpp index 41b0aca..c12df25 100644 --- a/src/mvc/FileTabWidget.cpp +++ b/src/mvc/FileTabWidget.cpp @@ -166,10 +166,28 @@ void FileTabWidget::unload_all() void FileTabWidget::set_file_list(const std::map& fileinfo_list) { + double divisor = 1; + switch(Preferences::inst()->getValue(STR_PRF_FILE_SIZE).toInt()) + { + case 0: + break; + case 1: + divisor = 1024; + break; + case 2: + divisor = 1024*1024; + break; + case 3: + divisor = 1024*1024*1024; + break; + default: + break; + } + _file_list_model->clear(); for(auto & itr : fileinfo_list) { - _file_list_model->appendRow( RowData(QIcon(":/images/circle_gray.png"), itr.first, itr.second.size()/1024)); + _file_list_model->appendRow( RowData(QIcon(":/images/circle_gray.png"), itr.first, (double)itr.second.size()/divisor)); } _file_list_view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); @@ -180,6 +198,24 @@ void FileTabWidget::set_file_list(const std::map& fileinfo_l void FileTabWidget::update_file_list(const std::map& fileinfo_list) { + double divisor = 1; + switch(Preferences::inst()->getValue(STR_PRF_FILE_SIZE).toInt()) + { + case 0: + break; + case 1: + divisor = 1024; + break; + case 2: + divisor = 1024*1024; + break; + case 3: + divisor = 1024*1024*1024; + break; + default: + break; + } + int rows = _file_list_model->rowCount(); for (const auto& itr : fileinfo_list) { @@ -196,7 +232,7 @@ void FileTabWidget::update_file_list(const std::map& fileinf if (false == found) { - _file_list_model->appendRow(RowData(QIcon(":/images/circle_gray.png"), itr.first, itr.second.size()/1024)); + _file_list_model->appendRow(RowData(QIcon(":/images/circle_gray.png"), itr.first, (double)itr.second.size()/divisor)); } } diff --git a/src/mvc/FileTableModel.h b/src/mvc/FileTableModel.h index 44e1e31..4deaee8 100644 --- a/src/mvc/FileTableModel.h +++ b/src/mvc/FileTableModel.h @@ -9,6 +9,7 @@ //--------------------------------------------------------------------------- #include +#include //--------------------------------------------------------------------------- @@ -23,11 +24,13 @@ struct RowData text = s; number = n; status = UNLOADED; + number2 = 0; } QIcon icon; QString text; - int number; + double number; File_Loaded_Status status; + int number2; }; //--------------------------------------------------------------------------- @@ -36,9 +39,27 @@ class FileTableModel : public QAbstractTableModel public: FileTableModel(QObject* parent = nullptr) : QAbstractTableModel(parent) { + QString fs = "Size "; + switch(Preferences::inst()->getValue(STR_PRF_FILE_SIZE).toInt()) + { + case 0: + break; + case 1: + fs += "(Kb)"; + break; + case 2: + fs += "(Mb)"; + break; + case 3: + fs += "(Gb)"; + break; + default: + break; + } _headers[0] = tr("L"); _headers[1] = tr("Name"); - _headers[2] = tr("Size (MB)"); + _headers[2] = fs; + _headers[3] = tr("# ROI's"); } int rowCount(const QModelIndex& parent = QModelIndex()) const override @@ -48,7 +69,7 @@ class FileTableModel : public QAbstractTableModel int columnCount(const QModelIndex& parent = QModelIndex()) const override { - return 3; // Three columns: icon, string, integer + return 4; } void appendRow(const RowData& row) @@ -91,7 +112,7 @@ class FileTableModel : public QAbstractTableModel } else if (index.column() == 2) { - return rowData.number; + return QString::number(rowData.number, 'f', 2); } } return QVariant(); @@ -105,7 +126,7 @@ class FileTableModel : public QAbstractTableModel // Horizontal headers if (orientation == Qt::Horizontal) { - if(section > (2)) + if(section > 3) { return QVariant(); } @@ -190,6 +211,14 @@ class FileTableModel : public QAbstractTableModel case Qt::DescendingOrder: return rowA.number > rowB.number; }; + case 3: // # roi's + switch(order) + { + case Qt::AscendingOrder: + return rowA.number2 < rowB.number2; + case Qt::DescendingOrder: + return rowA.number2 > rowB.number2; + }; }; }); endResetModel(); @@ -198,7 +227,7 @@ class FileTableModel : public QAbstractTableModel private: QList _data; - QString _headers[3]; + QString _headers[4]; }; diff --git a/src/preferences/Preferences.cpp b/src/preferences/Preferences.cpp index 5dc063d..2134e47 100644 --- a/src/preferences/Preferences.cpp +++ b/src/preferences/Preferences.cpp @@ -62,6 +62,7 @@ Preferences::Preferences() {STR_SEARCH_SUB_DIR_FOR_DATASETS, QVariant()}, {STR_GEOMETRY, QVariant()}, {STR_WINDOWSTATE, QVariant()}, + {STR_PRF_FILE_SIZE, QVariant()}, {STR_PRF_STRICT_REGEX, QVariant()} }; load(); diff --git a/src/preferences/Preferences.h b/src/preferences/Preferences.h index 19f2189..9b4fe29 100644 --- a/src/preferences/Preferences.h +++ b/src/preferences/Preferences.h @@ -81,6 +81,7 @@ #define STR_SCATTER_DOCK "ScatterDock" #define STR_EXTRA_DOCK "ExtraDock" #define STR_PRF_STRICT_REGEX "StrictRegEx" +#define STR_PRF_FILE_SIZE "FileSize" /** * @brief Read and save preferences between application restarts, the vaule key diff --git a/src/preferences/PreferencesDisplay.cpp b/src/preferences/PreferencesDisplay.cpp index 4b9a197..f6d2b84 100644 --- a/src/preferences/PreferencesDisplay.cpp +++ b/src/preferences/PreferencesDisplay.cpp @@ -65,6 +65,14 @@ PreferencesDisplay::PreferencesDisplay(QWidget* parent) : QWidget(parent) _ck_search_datasets = new QCheckBox(); _ck_search_datasets->setChecked(Preferences::inst()->getValue(STR_SEARCH_SUB_DIR_FOR_DATASETS).toBool()); + QLabel* lblFileSize = new QLabel("Show file size in :"); + _cb_file_size = new QComboBox(); + _cb_file_size->addItem("Bytes"); + _cb_file_size->addItem("Kilobytes (Kb)"); + _cb_file_size->addItem("Megabytes (Mb)"); + _cb_file_size->addItem("Gigabytes (Gb)"); + _cb_file_size->setCurrentIndex(Preferences::inst()->getValue(STR_PRF_FILE_SIZE).toInt()); + QLabel* lblStrictRegex = new QLabel("Strict Regular Expressions for file filter.\n True: The file filter string is unchanged.\n False: Prepend and append '*' to file filter."); lblSearchDatasets->setFont(font); _ck_strict_regex = new QCheckBox(); @@ -77,6 +85,7 @@ PreferencesDisplay::PreferencesDisplay(QWidget* parent) : QWidget(parent) mainLayout->addRow(lblTitle, m_windowTitle); mainLayout->addRow(lblDeciPrecision, m_decimalPreci); mainLayout->addRow(lblUseDarkTheme, _cb_themes); + mainLayout->addRow(lblFileSize, _cb_file_size); mainLayout->addRow(lblShowDatasetOnSelect, _ck_show_dataset_on_select); mainLayout->addRow(lblSearchDatasets, _ck_search_datasets); mainLayout->addRow(lblStrictRegex, _ck_strict_regex); @@ -142,6 +151,8 @@ void PreferencesDisplay::acceptChanges() Preferences::inst()->setValue(STR_PRF_SHOW_DATASET_ON_FILE_SELECT, _ck_show_dataset_on_select->isChecked()); Preferences::inst()->setValue(STR_SEARCH_SUB_DIR_FOR_DATASETS, _ck_search_datasets->isChecked()); Preferences::inst()->setValue(STR_PRF_STRICT_REGEX, _ck_strict_regex->isChecked()); + Preferences::inst()->setValue(STR_PRF_FILE_SIZE, _cb_file_size->currentIndex()); + } /*---------------------------------------------------------------------------*/ diff --git a/src/preferences/PreferencesDisplay.h b/src/preferences/PreferencesDisplay.h index 6f89f68..ab39a7f 100644 --- a/src/preferences/PreferencesDisplay.h +++ b/src/preferences/PreferencesDisplay.h @@ -108,6 +108,8 @@ public slots: QCheckBox* _ck_search_datasets; QCheckBox* _ck_strict_regex; + + QComboBox* _cb_file_size; }; /*---------------------------------------------------------------------------*/ From 8154de7c22714263fa52dd6a61d0ed4e3517461a Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Wed, 29 May 2024 16:26:43 -0500 Subject: [PATCH 10/25] fixed preceision --- src/mvc/FileTableModel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mvc/FileTableModel.h b/src/mvc/FileTableModel.h index 4deaee8..9fa3ec4 100644 --- a/src/mvc/FileTableModel.h +++ b/src/mvc/FileTableModel.h @@ -18,7 +18,7 @@ enum File_Loaded_Status {UNLOADED, LOADED, FAILED_LOADING}; //--------------------------------------------------------------------------- struct RowData { - RowData(QIcon i, QString s, int n) + RowData(QIcon i, QString s, double n) { icon = i; text = s; From cc463f98af2ef8bf0348e24012eecab52777cf84 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Thu, 30 May 2024 09:29:25 -0500 Subject: [PATCH 11/25] Added number of rois into files widget. Made roi stats window resize on create --- src/mvc/FileTabWidget.cpp | 14 +++++-- src/mvc/FileTabWidget.h | 2 + src/mvc/FileTableModel.h | 62 ++++++++++++++++++++-------- src/mvc/MapsWorkspaceFilesWidget.cpp | 9 ++++ src/mvc/MapsWorkspaceFilesWidget.h | 2 + src/mvc/MapsWorkspaceModel.cpp | 37 ++++++++++++++--- src/mvc/MapsWorkspaceModel.h | 9 ++++ src/mvc/RoiStatisticsWidget.cpp | 8 ++++ 8 files changed, 116 insertions(+), 27 deletions(-) diff --git a/src/mvc/FileTabWidget.cpp b/src/mvc/FileTabWidget.cpp index c12df25..c81c13a 100644 --- a/src/mvc/FileTabWidget.cpp +++ b/src/mvc/FileTabWidget.cpp @@ -13,8 +13,7 @@ #include #include #include - - +#include "core/defines.h" /*---------------------------------------------------------------------------*/ FileTabWidget::FileTabWidget(QWidget* parent) : QWidget(parent) @@ -194,7 +193,14 @@ void FileTabWidget::set_file_list(const std::map& fileinfo_l _file_list_view->horizontalHeader()->resizeSections(QHeaderView::Interactive); } -/*---------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- + +void FileTabWidget:: set_roi_num_list(const std::map& roi_num_map) +{ + _file_list_model->update_roi_num(roi_num_map); +} + +//--------------------------------------------------------------------------- void FileTabWidget::update_file_list(const std::map& fileinfo_list) { @@ -254,7 +260,7 @@ void FileTabWidget::onDoubleClickElement(const QModelIndex idx) if (_load_all_btn->isEnabled()) { QStringList sl; - sl.append(idx.data(0).toString()); + sl.append(_file_list_model->getNameAtRow(idx.row())); emit loadList(sl); } } diff --git a/src/mvc/FileTabWidget.h b/src/mvc/FileTabWidget.h index 0ca93a8..a8e939b 100644 --- a/src/mvc/FileTabWidget.h +++ b/src/mvc/FileTabWidget.h @@ -38,6 +38,8 @@ class FileTabWidget : public QWidget void set_file_list(const std::map& fileinfo_list); + void set_roi_num_list(const std::map& roi_num_map); + void update_file_list(const std::map& fileinfo_list); void unload_all(); diff --git a/src/mvc/FileTableModel.h b/src/mvc/FileTableModel.h index 9fa3ec4..29ca47e 100644 --- a/src/mvc/FileTableModel.h +++ b/src/mvc/FileTableModel.h @@ -61,7 +61,7 @@ class FileTableModel : public QAbstractTableModel _headers[2] = fs; _headers[3] = tr("# ROI's"); } - + //--------------------------------------------------------------------------- int rowCount(const QModelIndex& parent = QModelIndex()) const override { return _data.size(); @@ -71,7 +71,7 @@ class FileTableModel : public QAbstractTableModel { return 4; } - + //--------------------------------------------------------------------------- void appendRow(const RowData& row) { int rown = _data.size(); @@ -80,20 +80,47 @@ class FileTableModel : public QAbstractTableModel _data.append(row); endInsertRows(); } - + //--------------------------------------------------------------------------- + void update_roi_num(const std::map& roi_num_map) + { + beginResetModel(); + for(auto &itr : _data) + { + itr.number2 = 0; + QStringList sl = itr.text.split('.'); + if(sl.size() > 0) + { + if(roi_num_map.count(sl[0]) > 0) + { + itr.number2 = roi_num_map.at(sl[0]); + } + } + } + endResetModel(); + } + //--------------------------------------------------------------------------- void clear() { _data.clear(); } - + //--------------------------------------------------------------------------- const RowData& item(int row) { return _data.at(row); } - + //--------------------------------------------------------------------------- + const QString& getNameAtRow(int row) + { + if(_data.size() > row) + { + return _data.at(row).text; + } + return ""; + } + //--------------------------------------------------------------------------- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override { - if (!index.isValid() || index.row() >= _data.size() || index.column() >= 3) + if (!index.isValid() || index.row() >= _data.size() || index.column() >= 4) { return QVariant(); } @@ -106,18 +133,19 @@ class FileTableModel : public QAbstractTableModel } else if (role == Qt::DisplayRole) { - if (index.column() == 1) + switch(index.column()) { + case 1: return rowData.text; - } - else if (index.column() == 2) - { + case 2: return QString::number(rowData.number, 'f', 2); - } + case 3: + return rowData.number2; + }; } return QVariant(); } - + //--------------------------------------------------------------------------- QVariant headerData(int section, Qt::Orientation orientation, int role) const { // Check this is DisplayRole @@ -126,7 +154,7 @@ class FileTableModel : public QAbstractTableModel // Horizontal headers if (orientation == Qt::Horizontal) { - if(section > 3) + if(section > 4) { return QVariant(); } @@ -139,12 +167,12 @@ class FileTableModel : public QAbstractTableModel // Return empty data return QVariant(); } - + //--------------------------------------------------------------------------- Qt::ItemFlags flags(const QModelIndex &index) const { return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } - + //--------------------------------------------------------------------------- void updateStatus(File_Loaded_Status status, const QString& filename) { int i=0; @@ -174,7 +202,7 @@ class FileTableModel : public QAbstractTableModel i++; } } - + //--------------------------------------------------------------------------- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override { if(column < 0) @@ -223,7 +251,7 @@ class FileTableModel : public QAbstractTableModel }); endResetModel(); } - + //--------------------------------------------------------------------------- private: QList _data; diff --git a/src/mvc/MapsWorkspaceFilesWidget.cpp b/src/mvc/MapsWorkspaceFilesWidget.cpp index 5c332f3..27028a4 100644 --- a/src/mvc/MapsWorkspaceFilesWidget.cpp +++ b/src/mvc/MapsWorkspaceFilesWidget.cpp @@ -144,6 +144,7 @@ void MapsWorkspaceFilesWidget::setModel(MapsWorkspaceModel *model) connect(_model, &MapsWorkspaceModel::doneLoadingMDA, this, &MapsWorkspaceFilesWidget::updatedMDA); connect(_model, &MapsWorkspaceModel::doneLoadingVLM, this, &MapsWorkspaceFilesWidget::updatedVLM); connect(_model, &MapsWorkspaceModel::doneLoadingImgDat, this, &MapsWorkspaceFilesWidget::updatedHDF); + connect(_model, &MapsWorkspaceModel::doneLoadingROIS, this, &MapsWorkspaceFilesWidget::updateROIS); connect(_model, &MapsWorkspaceModel::doneUnloading, this, &MapsWorkspaceFilesWidget::clearLists); connect(_model, &MapsWorkspaceModel::newFitParamsFileLoaded, this, &MapsWorkspaceFilesWidget::loadedFitParams); connect(_h5_tab_widget, &FileTabWidget::onRefresh, _model, &MapsWorkspaceModel::reload_analyzed); @@ -188,6 +189,14 @@ void MapsWorkspaceFilesWidget::updatedHDF() } } +//--------------------------------------------------------------------------- + +void MapsWorkspaceFilesWidget::updateROIS() +{ + _h5_tab_widget->set_roi_num_list(_model->get_roi_num_list()); + _vlm_tab_widget->set_roi_num_list(_model->get_roi_num_list()); +} + /*---------------------------------------------------------------------------*/ void MapsWorkspaceFilesWidget::loadedFitParams(int idx) diff --git a/src/mvc/MapsWorkspaceFilesWidget.h b/src/mvc/MapsWorkspaceFilesWidget.h index 469ff3e..c608993 100644 --- a/src/mvc/MapsWorkspaceFilesWidget.h +++ b/src/mvc/MapsWorkspaceFilesWidget.h @@ -73,6 +73,8 @@ public slots: void updatedHDF(); + void updateROIS(); + void clearLists(); void loadedFitParams(int idx); diff --git a/src/mvc/MapsWorkspaceModel.cpp b/src/mvc/MapsWorkspaceModel.cpp index 477d681..e31d3e0 100644 --- a/src/mvc/MapsWorkspaceModel.cpp +++ b/src/mvc/MapsWorkspaceModel.cpp @@ -129,7 +129,7 @@ MapsWorkspaceModel::MapsWorkspaceModel() : QObject() _vlm_suffex.append("tif"); _vlm_suffex.append("tiff"); - _all_roi_suffex.append("roi"); + _all_roi_suffex.append("r0i"); _all_region_links_suffex.append("tif"); } @@ -237,7 +237,6 @@ void MapsWorkspaceModel::load(QString filepath) case 4: _is_rois_loaded = itr.second.get(); to_delete.push_back(itr.first); - //emit doneLoadingImgDat(); break; default: to_delete.push_back(itr.first); @@ -248,9 +247,11 @@ void MapsWorkspaceModel::load(QString filepath) for (const auto& itr : to_delete) { job_queue.erase(itr); - } - + } } + // wait for all datasets to finish loading and then update roi's + _roi_files_to_num(); + emit doneLoadingROIS(); } } catch (std::string& s) @@ -295,7 +296,7 @@ void MapsWorkspaceModel::reload_vlm() void MapsWorkspaceModel::reload_roi() { _roi_fileinfo_list.clear(); - get_filesnames_in_directory(*_dir, "rois", _vlm_suffex, &_roi_fileinfo_list, check_roi, false); + get_filesnames_in_directory(*_dir, "rois", _all_roi_suffex, &_roi_fileinfo_list, check_roi, false); } /*---------------------------------------------------------------------------*/ @@ -660,4 +661,28 @@ data_struct::Fit_Element_Map_Dict* MapsWorkspaceModel::getElementToFit(i return nullptr; } -/*---------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- + +void MapsWorkspaceModel::_roi_files_to_num() +{ + for(auto itr : _roi_fileinfo_list) + { + _roi_count_map[itr.second.baseName()] = 0; + QFile roiFile(itr.second.absoluteFilePath()); + if (!roiFile.open(QIODevice::ReadOnly)) + { + continue; + } + + QJsonObject rootJson = QJsonDocument::fromJson(roiFile.readAll()).object(); + roiFile.close(); + + if (rootJson.contains(STR_MAPS_ROIS.c_str()) && rootJson[STR_MAPS_ROIS.c_str()].isArray()) + { + QJsonArray rois = rootJson[STR_MAPS_ROIS.c_str()].toArray(); + _roi_count_map[itr.second.baseName()] = rois.size(); + } + } +} + +//--------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/mvc/MapsWorkspaceModel.h b/src/mvc/MapsWorkspaceModel.h index df0e0a7..848ea10 100644 --- a/src/mvc/MapsWorkspaceModel.h +++ b/src/mvc/MapsWorkspaceModel.h @@ -87,6 +87,10 @@ class MapsWorkspaceModel : public QObject const std::map& get_vlm_file_list() { return _vlm_fileinfo_list; } + const std::map& get_roi_file_list() { return _roi_fileinfo_list; } + + const std::map& get_roi_num_list() { return _roi_count_map; } + std::vector get_loaded_raw_names(); std::vector get_loaded_h5_names(); @@ -105,6 +109,8 @@ class MapsWorkspaceModel : public QObject void doneLoadingImgDat(); + void doneLoadingROIS(); + void doneLoading(); void doneUnloading(); @@ -124,6 +130,7 @@ public slots: void reload_region_link(); protected: + void _roi_files_to_num(); bool _load_fit_params(); @@ -152,6 +159,8 @@ public slots: std::map _roi_fileinfo_list; std::map _region_links_fileinfo_list; + std::map _roi_count_map; + QDir* _dir; bool _is_vlm_loaded; diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp index c4e1c87..3f26117 100644 --- a/src/mvc/RoiStatisticsWidget.cpp +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include //--------------------------------------------------------------------------- enum HEADER_NAME { ROI_Name=0, MapName=1, SumCnts=2, MeanCts=3, MedianCts=4, StdDevCts=5, SumUgcm2=6, MeanUg=7, MedianUg=8, StdDevUg=9, Area=10, MinCnts=11, MinPixel=12, MaxCnts=13, MaxPixel=14, Min_ugcm2=15, Max_ugcm2=16, Num_Spectra=17, TotalConcentrationCts=18, TotalConcentrationUg=19, TotalContentCts=20, TotalContentUg=21 }; @@ -316,6 +318,12 @@ void RoiStatisticsWidget::_createLayout() setLayout(mainLayout); setWindowTitle("ROI Stats"); + + QRect rec = QGuiApplication::screens()[0]->geometry(); + int height1 = rec.height() - 20; + int width1 = rec.width() - 20; + resize(width1,height1); + } //--------------------------------------------------------------------------- From 24ea8c67848238331a6cb2e0a267fcf81d9323db Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Thu, 30 May 2024 10:20:54 -0500 Subject: [PATCH 12/25] Added event to update num rois when new ones are created --- src/mvc/FileTabWidget.cpp | 10 +++++++++- src/mvc/FileTabWidget.h | 2 ++ src/mvc/FileTableModel.h | 21 +++++++++++++++++++++ src/mvc/ImageStackControlWidget.cpp | 3 +++ src/mvc/MapsElementsWidget.cpp | 28 ++++++++++++++-------------- src/mvc/MapsElementsWidget.h | 4 +++- src/mvc/MapsWorkspaceFilesWidget.cpp | 12 ++++++++++-- src/mvc/MapsWorkspaceFilesWidget.h | 2 ++ 8 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/mvc/FileTabWidget.cpp b/src/mvc/FileTabWidget.cpp index c81c13a..3f4f845 100644 --- a/src/mvc/FileTabWidget.cpp +++ b/src/mvc/FileTabWidget.cpp @@ -195,13 +195,20 @@ void FileTabWidget::set_file_list(const std::map& fileinfo_l //--------------------------------------------------------------------------- -void FileTabWidget:: set_roi_num_list(const std::map& roi_num_map) +void FileTabWidget::set_roi_num_list(const std::map& roi_num_map) { _file_list_model->update_roi_num(roi_num_map); } //--------------------------------------------------------------------------- +void FileTabWidget::set_roi_num(QString name, int val) +{ + _file_list_model->update_single_roi_num(name, val); +} + +//--------------------------------------------------------------------------- + void FileTabWidget::update_file_list(const std::map& fileinfo_list) { double divisor = 1; @@ -270,6 +277,7 @@ void FileTabWidget::onDoubleClickElement(const QModelIndex idx) void FileTabWidget::setActionsAndButtonsEnabled(bool val) { _load_all_btn->setEnabled(val); + _file_list_view->setEnabled(val); _unload_all_btn->setEnabled(val); _action_load->setEnabled(val); _action_unload->setEnabled(val); diff --git a/src/mvc/FileTabWidget.h b/src/mvc/FileTabWidget.h index a8e939b..20be129 100644 --- a/src/mvc/FileTabWidget.h +++ b/src/mvc/FileTabWidget.h @@ -40,6 +40,8 @@ class FileTabWidget : public QWidget void set_roi_num_list(const std::map& roi_num_map); + void set_roi_num(QString name, int val); + void update_file_list(const std::map& fileinfo_list); void unload_all(); diff --git a/src/mvc/FileTableModel.h b/src/mvc/FileTableModel.h index 29ca47e..92810a3 100644 --- a/src/mvc/FileTableModel.h +++ b/src/mvc/FileTableModel.h @@ -99,6 +99,27 @@ class FileTableModel : public QAbstractTableModel endResetModel(); } //--------------------------------------------------------------------------- + void update_single_roi_num(QString name, int val) + { + QStringList s0 = name.split("."); + if(s0.size() > 0) + { + beginResetModel(); + for(auto &itr : _data) + { + QStringList sl = itr.text.split('.'); + if(sl.size() > 0) + { + if(s0[0] == sl[0]) + { + itr.number2 = val; + } + } + } + endResetModel(); + } + } + //--------------------------------------------------------------------------- void clear() { _data.clear(); diff --git a/src/mvc/ImageStackControlWidget.cpp b/src/mvc/ImageStackControlWidget.cpp index 37a07ef..659133e 100644 --- a/src/mvc/ImageStackControlWidget.cpp +++ b/src/mvc/ImageStackControlWidget.cpp @@ -16,6 +16,7 @@ ImageStackControlWidget::ImageStackControlWidget(QWidget* parent) : QWidget(parent) { + _model = nullptr; createLayout(); } @@ -64,6 +65,8 @@ void ImageStackControlWidget::createLayout() connect(_mapsFilsWidget, &MapsWorkspaceFilesWidget::unloadList_model, this, &ImageStackControlWidget::onUnloadList_Model); connect(_mapsFilsWidget, &MapsWorkspaceFilesWidget::datasetSelected, this, &ImageStackControlWidget::onChangeDatasetName); + connect(_imageGrid, &MapsElementsWidget::new_rois, _mapsFilsWidget, &MapsWorkspaceFilesWidget::update_roi_num); + _left_btn = new QPushButton(); _left_btn->setIcon(QIcon(":/images/previous.png")); _left_btn->setMaximumWidth(150); diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index e15a2a2..0e6f49e 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -1788,16 +1788,16 @@ void MapsElementsWidget::windowChanged(Qt::WindowStates oldState, void MapsElementsWidget::on_add_new_ROIs(std::vector roi_list) { - _model->clearAllMapRois(); - for (auto& itr : roi_list) + if (_model != nullptr) { - insertAndSelectAnnotation(m_roiTreeModel, m_roiTreeView, m_roiSelectionModel, itr->duplicate()); - std::vector> pixel_list; - itr->to_roi_vec(pixel_list); - - data_struct::Spectra* int_spectra = new data_struct::Spectra(); - if (_model != nullptr) + _model->clearAllMapRois(); + + for (auto& itr : roi_list) { + insertAndSelectAnnotation(m_roiTreeModel, m_roiTreeView, m_roiSelectionModel, itr->duplicate()); + std::vector> pixel_list; + itr->to_roi_vec(pixel_list); + data_struct::Spectra* int_spectra = new data_struct::Spectra(); if (io::file::HDF5_IO::inst()->load_integrated_spectra_analyzed_h5_roi(_model->getFilePath().toStdString(), int_spectra, pixel_list)) { struct Map_ROI roi(itr->getName().toStdString(), itr->getColor(), itr->alphaValue(), pixel_list, _model->getDatasetName().toStdString(), *int_spectra); @@ -1806,14 +1806,14 @@ void MapsElementsWidget::on_add_new_ROIs(std::vectorappendROISpectra(itr->getName().toStdString(), int_spectra, itr->getColor()); } } - } - if (_model != nullptr) - { + _model->saveAllRoiMaps(); + + //refresh roi's + _scatter_plot_widget->setModel(_model); + // update num rois in file widget + emit new_rois(_model->getDatasetName(), roi_list.size()); } - //refresh roi's - _scatter_plot_widget->setModel(_model); - _spectra_widget->replot_integrated_spectra(false); annoTabChanged(ROI_TAB); _img_seg_diag.clear_all_rois(); diff --git a/src/mvc/MapsElementsWidget.h b/src/mvc/MapsElementsWidget.h index 0333ea0..9015265 100644 --- a/src/mvc/MapsElementsWidget.h +++ b/src/mvc/MapsElementsWidget.h @@ -60,7 +60,9 @@ class MapsElementsWidget MapsH5Model *getModel(){return _model;} signals: - void loaded_perc(int, int); + void loaded_perc(int, int); + + void new_rois(QString, int); public slots: diff --git a/src/mvc/MapsWorkspaceFilesWidget.cpp b/src/mvc/MapsWorkspaceFilesWidget.cpp index 27028a4..37e4af4 100644 --- a/src/mvc/MapsWorkspaceFilesWidget.cpp +++ b/src/mvc/MapsWorkspaceFilesWidget.cpp @@ -194,10 +194,18 @@ void MapsWorkspaceFilesWidget::updatedHDF() void MapsWorkspaceFilesWidget::updateROIS() { _h5_tab_widget->set_roi_num_list(_model->get_roi_num_list()); - _vlm_tab_widget->set_roi_num_list(_model->get_roi_num_list()); + _mda_tab_widget->set_roi_num_list(_model->get_roi_num_list()); } -/*---------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- + +void MapsWorkspaceFilesWidget::update_roi_num(QString name, int val) +{ + _h5_tab_widget->set_roi_num(name, val); + _mda_tab_widget->set_roi_num(name, val); +} + +//--------------------------------------------------------------------------- void MapsWorkspaceFilesWidget::loadedFitParams(int idx) { diff --git a/src/mvc/MapsWorkspaceFilesWidget.h b/src/mvc/MapsWorkspaceFilesWidget.h index c608993..1863427 100644 --- a/src/mvc/MapsWorkspaceFilesWidget.h +++ b/src/mvc/MapsWorkspaceFilesWidget.h @@ -75,6 +75,8 @@ public slots: void updateROIS(); + void update_roi_num(QString, int); + void clearLists(); void loadedFitParams(int idx); From 7c185c36138fb8851223cf05f9b3aded3c777ebe Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Fri, 31 May 2024 08:08:34 -0500 Subject: [PATCH 13/25] revmove old cmake files --- cmake/FindNetCDF.cmake | 119 ------------------------------ cmake/linux/FindZeroMQ.cmake | 137 ----------------------------------- 2 files changed, 256 deletions(-) delete mode 100644 cmake/FindNetCDF.cmake delete mode 100644 cmake/linux/FindZeroMQ.cmake diff --git a/cmake/FindNetCDF.cmake b/cmake/FindNetCDF.cmake deleted file mode 100644 index ce4f76c..0000000 --- a/cmake/FindNetCDF.cmake +++ /dev/null @@ -1,119 +0,0 @@ -# - Find NetCDF -# Find the native NetCDF includes and library -# -# NETCDF_INCLUDE_DIR - user modifiable choice of where netcdf headers are -# NETCDF_LIBRARY - user modifiable choice of where netcdf libraries are -# -# Your package can require certain interfaces to be FOUND by setting these -# -# NETCDF_CXX - require the C++ interface and link the C++ library -# NETCDF_F77 - require the F77 interface and link the fortran library -# NETCDF_F90 - require the F90 interface and link the fortran library -# -# Or equivalently by calling FindNetCDF with a COMPONENTS argument containing one or -# more of "CXX;F77;F90". -# -# When interfaces are requested the user has access to interface specific hints: -# -# NETCDF_${LANG}_INCLUDE_DIR - where to search for interface header files -# NETCDF_${LANG}_LIBRARY - where to search for interface libraries -# -# This module returns these variables for the rest of the project to use. -# -# NETCDF_FOUND - True if NetCDF found including required interfaces (see below) -# NETCDF_LIBRARIES - All netcdf related libraries. -# NETCDF_INCLUDE_DIRS - All directories to include. -# NETCDF_HAS_INTERFACES - Whether requested interfaces were found or not. -# NETCDF_${LANG}_INCLUDE_DIRS/NETCDF_${LANG}_LIBRARIES - C/C++/F70/F90 only interface -# -# Normal usage would be: -# set (NETCDF_F90 "YES") -# find_package (NetCDF REQUIRED) -# target_link_libraries (uses_everthing ${NETCDF_LIBRARIES}) -# target_link_libraries (only_uses_f90 ${NETCDF_F90_LIBRARIES}) - -#search starting from user editable cache var -if (NETCDF_INCLUDE_DIR AND NETCDF_LIBRARY) - # Already in cache, be silent - set (NETCDF_FIND_QUIETLY TRUE) -endif () - -set(USE_DEFAULT_PATHS "NO_DEFAULT_PATH") -if(NETCDF_USE_DEFAULT_PATHS) - set(USE_DEFAULT_PATHS "") -endif() - -find_path (NETCDF_INCLUDE_DIR netcdf.h - PATHS "${NETCDF_DIR}/include") -mark_as_advanced (NETCDF_INCLUDE_DIR) -set (NETCDF_C_INCLUDE_DIRS ${NETCDF_INCLUDE_DIR}) - -find_library (NETCDF_LIBRARY NAMES netcdf - PATHS "${NETCDF_DIR}/lib" - HINTS "${NETCDF_INCLUDE_DIR}/../lib") -mark_as_advanced (NETCDF_LIBRARY) - -set (NETCDF_C_LIBRARIES ${NETCDF_LIBRARY}) - -#start finding requested language components -set (NetCDF_libs "") -set (NetCDF_includes "${NETCDF_INCLUDE_DIR}") - -get_filename_component (NetCDF_lib_dirs "${NETCDF_LIBRARY}" PATH) -set (NETCDF_HAS_INTERFACES "YES") # will be set to NO if we're missing any interfaces - -macro (NetCDF_check_interface lang header libs) - if (NETCDF_${lang}) - #search starting from user modifiable cache var - find_path (NETCDF_${lang}_INCLUDE_DIR NAMES ${header} - HINTS "${NETCDF_INCLUDE_DIR}" - HINTS "${NETCDF_${lang}_ROOT}/include" - ${USE_DEFAULT_PATHS}) - - find_library (NETCDF_${lang}_LIBRARY NAMES ${libs} - HINTS "${NetCDF_lib_dirs}" - HINTS "${NETCDF_${lang}_ROOT}/lib" - ${USE_DEFAULT_PATHS}) - - mark_as_advanced (NETCDF_${lang}_INCLUDE_DIR NETCDF_${lang}_LIBRARY) - - #export to internal varS that rest of project can use directly - set (NETCDF_${lang}_LIBRARIES ${NETCDF_${lang}_LIBRARY}) - set (NETCDF_${lang}_INCLUDE_DIRS ${NETCDF_${lang}_INCLUDE_DIR}) - - if (NETCDF_${lang}_INCLUDE_DIR AND NETCDF_${lang}_LIBRARY) - list (APPEND NetCDF_libs ${NETCDF_${lang}_LIBRARY}) - list (APPEND NetCDF_includes ${NETCDF_${lang}_INCLUDE_DIR}) - else () - set (NETCDF_HAS_INTERFACES "NO") - message (STATUS "Failed to find NetCDF interface for ${lang}") - endif () - endif () -endmacro () - -list (FIND NetCDF_FIND_COMPONENTS "CXX" _nextcomp) -if (_nextcomp GREATER -1) - set (NETCDF_CXX 1) -endif () -list (FIND NetCDF_FIND_COMPONENTS "F77" _nextcomp) -if (_nextcomp GREATER -1) - set (NETCDF_F77 1) -endif () -list (FIND NetCDF_FIND_COMPONENTS "F90" _nextcomp) -if (_nextcomp GREATER -1) - set (NETCDF_F90 1) -endif () -NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++) -NetCDF_check_interface (F77 netcdf.inc netcdff) -NetCDF_check_interface (F90 netcdf.mod netcdff) - -#export accumulated results to internal varS that rest of project can depend on -list (APPEND NetCDF_libs "${NETCDF_C_LIBRARIES}") -set (NETCDF_LIBRARIES ${NetCDF_libs}) -set (NETCDF_INCLUDE_DIRS ${NetCDF_includes}) - -# handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if -# all listed variables are TRUE -include (FindPackageHandleStandardArgs) -find_package_handle_standard_args (NetCDF - DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDE_DIRS NETCDF_HAS_INTERFACES) diff --git a/cmake/linux/FindZeroMQ.cmake b/cmake/linux/FindZeroMQ.cmake deleted file mode 100644 index 091357f..0000000 --- a/cmake/linux/FindZeroMQ.cmake +++ /dev/null @@ -1,137 +0,0 @@ -##============================================================================= -## -## Copyright (c) Kitware, Inc. -## All rights reserved. -## See LICENSE.txt for details. -## -## This software is distributed WITHOUT ANY WARRANTY; without even -## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -## PURPOSE. See the above copyright notice for more information. -## -##============================================================================= -# - Try to find ZeroMQ headers and libraries -# -# Usage of this module as follows: -# -# find_package(ZeroMQ) -# -# Variables used by this module, they can change the default behaviour and need -# to be set before calling find_package: -# -# ZeroMQ_ROOT_DIR Set this variable to the root installation of -# ZeroMQ if the module has problems finding -# the proper installation path. -# -# Variables defined by this module: -# -# ZeroMQ_FOUND System has ZeroMQ libs/headers -# ZeroMQ_LIBRARIES The ZeroMQ libraries -# ZeroMQ_INCLUDE_DIR The location of ZeroMQ headers -# ZeroMQ_VERSION The version of ZeroMQ - -find_path(ZeroMQ_ROOT_DIR - NAMES include/zmq.h - ) - -if(MSVC) - - set(_zmq_TOOLSET) - list(APPEND _zmq_TOOLSET "-v150") - list(APPEND _zmq_TOOLSET "-v141") - list(APPEND _zmq_TOOLSET "-v140") - - - set(_zmq_versions - "4_2_3" - "4_1_5" "4_1_4" "4_1_3" "4_1_2" "4_1_1" "4_1_0") - - set(_zmq_release_names) - set(_zmq_debug_names) - foreach( toolset ${_zmq_TOOLSET}) - foreach( ver ${_zmq_versions}) - find_library(ZeroMQ_LIBRARY_RELEASE - NAMES "libzmq${toolset}-mt-${ver}" - PATHS ${ZeroMQ_ROOT_DIR}/bin/Release - ${ZeroMQ_ROOT_DIR}/lib/Release - ${ZeroMQ_ROOT_DIR}/build/lib/Release - ) - IF(ZeroMQ_LIBRARY_RELEASE) - break() - ENDIF() - endforeach() - endforeach() - foreach( toolset ${_zmq_TOOLSET}) - foreach( ver ${_zmq_versions}) - find_library(ZeroMQ_LIBRARY_DEBUG - NAMES "libzmq${toolset}-mt-gd-${ver}" - PATHS ${ZeroMQ_ROOT_DIR}/bin/Debug - ${ZeroMQ_ROOT_DIR}/lib/Debug - ${ZeroMQ_ROOT_DIR}/build/lib/Debug - ) - IF(ZeroMQ_LIBRARY_DEBUG) - break() - ENDIF() - endforeach() - endforeach() - - if(ZeroMQ_LIBRARY_RELEASE AND ZeroMQ_LIBRARY_DEBUG) - set(ZeroMQ_LIBRARY - debug ${ZeroMQ_LIBRARY_DEBUG} - optimized ${ZeroMQ_LIBRARY_RELEASE} - ) - elseif(ZeroMQ_LIBRARY_RELEASE) - set(ZeroMQ_LIBRARY ${ZeroMQ_LIBRARY_RELEASE}) - elseif(ZeroMQ_LIBRARY_DEBUG) - set(ZeroMQ_LIBRARY ${ZeroMQ_LIBRARY_DEBUG}) - endif() - -else() - find_library(ZeroMQ_LIBRARY - NAMES zmq libzmq - HINTS ${ZeroMQ_ROOT_DIR}/lib - ) -endif() - -find_path(ZeroMQ_INCLUDE_DIR - NAMES zmq.h - HINTS ${ZeroMQ_ROOT_DIR}/include - ) - -function(extract_version_value value_name file_name value) - file(STRINGS ${file_name} val REGEX "${value_name} .") - string(FIND ${val} " " last REVERSE) - string(SUBSTRING ${val} ${last} -1 val) - string(STRIP ${val} val) - set(${value} ${val} PARENT_SCOPE) -endfunction(extract_version_value) -if(ZeroMQ_INCLUDE_DIR) - extract_version_value("ZMQ_VERSION_MAJOR" ${ZeroMQ_INCLUDE_DIR}/zmq.h MAJOR) - extract_version_value("ZMQ_VERSION_MINOR" ${ZeroMQ_INCLUDE_DIR}/zmq.h MINOR) - extract_version_value("ZMQ_VERSION_PATCH" ${ZeroMQ_INCLUDE_DIR}/zmq.h PATCH) -endif() -set(ZeroMQ_VER "${MAJOR}.${MINOR}.${PATCH}") - -#We are using the 2.8.10 signature of find_package_handle_standard_args, -#as that is the version that ParaView 5.1 && VTK 6/7 ship, and inject -#into the CMake module path. This allows our FindModule to work with -#projects that include VTK/ParaView before searching for Remus -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - ZeroMQ - REQUIRED_VARS ZeroMQ_LIBRARY ZeroMQ_INCLUDE_DIR - VERSION_VAR ZeroMQ_VER - ) - -set(ZeroMQ_FOUND ${ZEROMQ_FOUND}) -set(ZeroMQ_INCLUDE_DIRS ${ZeroMQ_INCLUDE_DIR}) -set(ZeroMQ_LIBRARIES ${ZeroMQ_LIBRARY}) -set(ZeroMQ_VERSION ${ZeroMQ_VER}) - -mark_as_advanced( -# ZeroMQ_ROOT_DIR - ZeroMQ_LIBRARY - ZeroMQ_LIBRARY_DEBUG - ZeroMQ_LIBRARY_RELEASE - ZeroMQ_INCLUDE_DIR - ZeroMQ_VERSION - ) From ed1dcc5e4168a56c9e136140f66bd136f98fd9d4 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Fri, 31 May 2024 08:31:25 -0500 Subject: [PATCH 14/25] Finished adding area and total conc for roi stats --- src/mvc/MapsElementsWidget.cpp | 11 ++++++++++- src/mvc/RoiStatisticsWidget.cpp | 25 +++++++++++++------------ src/mvc/RoiStatisticsWidget.h | 10 +++++++++- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index 0e6f49e..5214095 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -662,7 +662,16 @@ void MapsElementsWidget::openRoiStatsWidget() { m_roiTreeModel->get_all_of_type(item.classId(), roi_list); } - _roi_stats_diag->setData(_model->getDir(), _model->getDatasetName(), _cb_analysis->currentText(), _cb_normalize->currentText(), fit_counts, roi_list, _normalizer, _calib_curve); + + const std::vector x_axis = _model->get_x_axis(); + const std::vector y_axis = _model->get_y_axis(); + + int xidx = x_axis.size() / 2; + int yidx = y_axis.size() / 2; + + float sq_area = ((x_axis[xidx+1] - x_axis[xidx]) * (y_axis[yidx+1] - y_axis[yidx])); + + _roi_stats_diag->setData(_model->getDir(), _model->getDatasetName(), _cb_analysis->currentText(), _cb_normalize->currentText(), sq_area, fit_counts, roi_list, _normalizer, _calib_curve); _roi_stats_diag->show(); } diff --git a/src/mvc/RoiStatisticsWidget.cpp b/src/mvc/RoiStatisticsWidget.cpp index 3f26117..cab6b69 100644 --- a/src/mvc/RoiStatisticsWidget.cpp +++ b/src/mvc/RoiStatisticsWidget.cpp @@ -86,6 +86,7 @@ RoiStatisticsWidget::~RoiStatisticsWidget() void RoiStatisticsWidget::_insert_item(QString roiName, QString imgName, + float sq_area, const data_struct::ArrayXXr& img, const std::vector>& roi_pixels, int i, @@ -104,7 +105,7 @@ void RoiStatisticsWidget::_insert_item(QString roiName, double max_ug = std::numeric_limits::min(); double std_dev_ug = 0.0; double median_ug = 0.0; - + double area = sq_area * roi_pixels.size(); std::pair min_pixel; std::pair max_pixel; Eigen::ArrayXf cts_arr(roi_pixels.size()); @@ -183,6 +184,10 @@ void RoiStatisticsWidget::_insert_item(QString roiName, _table_widget->setItem(i, StdDevCts, new QTableWidgetItem(QString::number(std_dev_cts))); _table_widget->setItem(i, Num_Spectra, new QTableWidgetItem(QString::number(roi_pixels.size()))); + _table_widget->setItem(i, Area, new QTableWidgetItem(QString::number(area))); + _table_widget->setItem(i, TotalContentCts, new QTableWidgetItem(QString::number(area*mean_cts))); + _table_widget->setItem(i, TotalConcentrationCts, new QTableWidgetItem(QString::number(mean_cts * (double)roi_pixels.size()))); + if(hasNorm) { _table_widget->setItem(i, SumUgcm2, new QTableWidgetItem(QString::number(sum_ugcm2))); @@ -191,6 +196,8 @@ void RoiStatisticsWidget::_insert_item(QString roiName, _table_widget->setItem(i, MeanUg, new QTableWidgetItem(QString::number(mean_ug))); _table_widget->setItem(i, MedianUg, new QTableWidgetItem(QString::number(median_ug))); _table_widget->setItem(i, StdDevUg, new QTableWidgetItem(QString::number(std_dev_ug))); + _table_widget->setItem(i, TotalContentUg, new QTableWidgetItem(QString::number(area*mean_ug))); + _table_widget->setItem(i, TotalConcentrationUg, new QTableWidgetItem(QString::number(mean_ug * (double)roi_pixels.size()))); } else { @@ -201,13 +208,6 @@ void RoiStatisticsWidget::_insert_item(QString roiName, _table_widget->setItem(i, MedianUg, new QTableWidgetItem(" ")); _table_widget->setItem(i, StdDevUg, new QTableWidgetItem(" ")); } - - -// Area, TotalConcentration, TotalContent - _table_widget->setItem(i, TotalConcentrationCts, new QTableWidgetItem(QString::number(mean_cts * (double)roi_pixels.size()))); - _table_widget->setItem(i, TotalConcentrationUg, new QTableWidgetItem(QString::number(mean_ug * (double)roi_pixels.size()))); - - } //--------------------------------------------------------------------------- @@ -216,6 +216,7 @@ void RoiStatisticsWidget::setData(QDir model_dir, QString dataset_name, QString fitting_name, QString normalizer_name, + float sq_area, std::unordered_map>& img_data, std::vector& roi_list, data_struct::ArrayXXr* normalizer, @@ -255,7 +256,7 @@ void RoiStatisticsWidget::setData(QDir model_dir, { if (img_data.count(itr) > 0) { - _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), img_data.at(itr), roi_pixels, i, normalizer, calib_curve); + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), sq_area, img_data.at(itr), roi_pixels, i, normalizer, calib_curve); done_map[itr] = 1; i++; } @@ -266,7 +267,7 @@ void RoiStatisticsWidget::setData(QDir model_dir, { if (img_data.count(itr) > 0) { - _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), img_data.at(itr), roi_pixels, i, normalizer, calib_curve); + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), sq_area, img_data.at(itr), roi_pixels, i, normalizer, calib_curve); done_map[itr] = 1; i++; } @@ -276,7 +277,7 @@ void RoiStatisticsWidget::setData(QDir model_dir, { if (img_data.count(itr) > 0) { - _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()), img_data.at(itr), roi_pixels, i, normalizer, calib_curve); + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.c_str(), itr.length()),sq_area, img_data.at(itr), roi_pixels, i, normalizer, calib_curve); done_map[itr] = 1; i++; } @@ -286,7 +287,7 @@ void RoiStatisticsWidget::setData(QDir model_dir, { if(done_map.count(itr.first) == 0) { - _insert_item(roi_itr->getName(), QString::fromLatin1(itr.first.c_str(), itr.first.length()), itr.second, roi_pixels, i, normalizer, calib_curve); + _insert_item(roi_itr->getName(), QString::fromLatin1(itr.first.c_str(), itr.first.length()), sq_area, itr.second, roi_pixels, i, normalizer, calib_curve); i++; } } diff --git a/src/mvc/RoiStatisticsWidget.h b/src/mvc/RoiStatisticsWidget.h index bdd9577..590ba0d 100644 --- a/src/mvc/RoiStatisticsWidget.h +++ b/src/mvc/RoiStatisticsWidget.h @@ -41,6 +41,7 @@ class RoiStatisticsWidget : public QWidget QString dataset_name, QString fitting_name, QString normalizer_name, + float sq_area, std::unordered_map>& img_data, std::vector& roi_list, data_struct::ArrayXXr* normalizer, @@ -62,7 +63,14 @@ public slots: private: - void _insert_item(QString roiName, QString imgName, const data_struct::ArrayXXr& img, const std::vector>& roi_pixels, int i,data_struct::ArrayXXr* normalizer,Calibration_curve* calib_curve); + void _insert_item(QString roiName, + QString imgName, + float sq_area, + const data_struct::ArrayXXr& img, + const std::vector>& roi_pixels, + int i, + data_struct::ArrayXXr* normalizer, + Calibration_curve* calib_curve); QString _str_export_filename; From 1e3383f3e7dc805549037ff6d6e6e25df66142c4 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Fri, 31 May 2024 08:42:34 -0500 Subject: [PATCH 15/25] Added pref option show on load --- src/mvc/ImageStackControlWidget.cpp | 4 ++++ src/preferences/Preferences.cpp | 1 + src/preferences/Preferences.h | 1 + src/preferences/PreferencesDisplay.cpp | 6 ++++++ src/preferences/PreferencesDisplay.h | 2 ++ 5 files changed, 14 insertions(+) diff --git a/src/mvc/ImageStackControlWidget.cpp b/src/mvc/ImageStackControlWidget.cpp index 659133e..0686608 100644 --- a/src/mvc/ImageStackControlWidget.cpp +++ b/src/mvc/ImageStackControlWidget.cpp @@ -255,6 +255,10 @@ void ImageStackControlWidget::onLoad_Model(const QString name, MODEL_TYPE mt) } _image_name_cb->addItem(name); + if(Preferences::inst()->getValue(STR_PRF_SHOW_DATASET_ON_LOAD).toBool()) + { + _image_name_cb->setCurrentText(name); + } } } diff --git a/src/preferences/Preferences.cpp b/src/preferences/Preferences.cpp index 2134e47..d70979c 100644 --- a/src/preferences/Preferences.cpp +++ b/src/preferences/Preferences.cpp @@ -63,6 +63,7 @@ Preferences::Preferences() {STR_GEOMETRY, QVariant()}, {STR_WINDOWSTATE, QVariant()}, {STR_PRF_FILE_SIZE, QVariant()}, + {STR_PRF_SHOW_DATASET_ON_LOAD, QVariant()}, {STR_PRF_STRICT_REGEX, QVariant()} }; load(); diff --git a/src/preferences/Preferences.h b/src/preferences/Preferences.h index 9b4fe29..98d0df1 100644 --- a/src/preferences/Preferences.h +++ b/src/preferences/Preferences.h @@ -82,6 +82,7 @@ #define STR_EXTRA_DOCK "ExtraDock" #define STR_PRF_STRICT_REGEX "StrictRegEx" #define STR_PRF_FILE_SIZE "FileSize" +#define STR_PRF_SHOW_DATASET_ON_LOAD "ShowOnLoad" /** * @brief Read and save preferences between application restarts, the vaule key diff --git a/src/preferences/PreferencesDisplay.cpp b/src/preferences/PreferencesDisplay.cpp index f6d2b84..dda58d2 100644 --- a/src/preferences/PreferencesDisplay.cpp +++ b/src/preferences/PreferencesDisplay.cpp @@ -59,6 +59,10 @@ PreferencesDisplay::PreferencesDisplay(QWidget* parent) : QWidget(parent) _ck_show_dataset_on_select = new QCheckBox(); _ck_show_dataset_on_select->setChecked(Preferences::inst()->getValue(STR_PRF_SHOW_DATASET_ON_FILE_SELECT).toBool()); + QLabel* lblShowDatasetOnLoad = new QLabel("Show dataset when loading"); + lblShowDatasetOnLoad->setFont(font); + _ck_show_dataset_on_load = new QCheckBox(); + _ck_show_dataset_on_load->setChecked(Preferences::inst()->getValue(STR_PRF_SHOW_DATASET_ON_LOAD).toBool()); QLabel* lblSearchDatasets = new QLabel("Search sub folders for datasets (ESRF datasets)."); lblSearchDatasets->setFont(font); @@ -87,6 +91,7 @@ PreferencesDisplay::PreferencesDisplay(QWidget* parent) : QWidget(parent) mainLayout->addRow(lblUseDarkTheme, _cb_themes); mainLayout->addRow(lblFileSize, _cb_file_size); mainLayout->addRow(lblShowDatasetOnSelect, _ck_show_dataset_on_select); + mainLayout->addRow(lblShowDatasetOnLoad, _ck_show_dataset_on_load); mainLayout->addRow(lblSearchDatasets, _ck_search_datasets); mainLayout->addRow(lblStrictRegex, _ck_strict_regex); @@ -149,6 +154,7 @@ void PreferencesDisplay::acceptChanges() Preferences::inst()->setValue(STR_PRF_WindowTitle, getWindowTitle()); Preferences::inst()->setValue(STR_PRF_DecimalPrecision, getDecimalPrecision()); Preferences::inst()->setValue(STR_PRF_SHOW_DATASET_ON_FILE_SELECT, _ck_show_dataset_on_select->isChecked()); + Preferences::inst()->setValue(STR_PRF_SHOW_DATASET_ON_LOAD, _ck_show_dataset_on_load->isChecked()); Preferences::inst()->setValue(STR_SEARCH_SUB_DIR_FOR_DATASETS, _ck_search_datasets->isChecked()); Preferences::inst()->setValue(STR_PRF_STRICT_REGEX, _ck_strict_regex->isChecked()); Preferences::inst()->setValue(STR_PRF_FILE_SIZE, _cb_file_size->currentIndex()); diff --git a/src/preferences/PreferencesDisplay.h b/src/preferences/PreferencesDisplay.h index ab39a7f..b3598e9 100644 --- a/src/preferences/PreferencesDisplay.h +++ b/src/preferences/PreferencesDisplay.h @@ -105,6 +105,8 @@ public slots: QCheckBox* _ck_show_dataset_on_select; + QCheckBox* _ck_show_dataset_on_load; + QCheckBox* _ck_search_datasets; QCheckBox* _ck_strict_regex; From 3b4dfd12911424032476b7825140e2d489ecd758 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Fri, 31 May 2024 13:28:12 -0500 Subject: [PATCH 16/25] Bug fixes for getting proper file name from row. Fixed issue that would 0 out num rois when per pixel processing --- src/mvc/FileTabWidget.cpp | 6 +++--- src/mvc/MapsWorkspaceFilesWidget.cpp | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mvc/FileTabWidget.cpp b/src/mvc/FileTabWidget.cpp index 3f4f845..5db09be 100644 --- a/src/mvc/FileTabWidget.cpp +++ b/src/mvc/FileTabWidget.cpp @@ -301,7 +301,7 @@ void FileTabWidget::onLoadFile() for(int i =0; igetNameAtRow(idx.row())); } emit loadList(sl); } @@ -317,7 +317,7 @@ void FileTabWidget::onUnloadFile() for(int i =0; igetNameAtRow(idx.row())); } emit unloadList(sl); @@ -397,7 +397,7 @@ void FileTabWidget::onCustomContext() for(int i =0; igetNameAtRow(idx.row())); } QAction *act = qobject_cast(sender()); QVariant v = act->data(); diff --git a/src/mvc/MapsWorkspaceFilesWidget.cpp b/src/mvc/MapsWorkspaceFilesWidget.cpp index 37e4af4..a68c761 100644 --- a/src/mvc/MapsWorkspaceFilesWidget.cpp +++ b/src/mvc/MapsWorkspaceFilesWidget.cpp @@ -187,6 +187,7 @@ void MapsWorkspaceFilesWidget::updatedHDF() { _h5_tab_widget->loaded_file_status_changed(File_Loaded_Status::LOADED, itr); } + _h5_tab_widget->set_roi_num_list(_model->get_roi_num_list()); } //--------------------------------------------------------------------------- From 7873fc75c1caed0e2909a1ea9dfa381854a55f2e Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Mon, 3 Jun 2024 08:53:36 -0500 Subject: [PATCH 17/25] Added motor position to export scatter plot. --- src/mvc/ScatterPlotView.cpp | 30 +++++++++++++++++++++++++----- src/mvc/ScatterPlotView.h | 1 - 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/mvc/ScatterPlotView.cpp b/src/mvc/ScatterPlotView.cpp index 54d11c6..d53af79 100644 --- a/src/mvc/ScatterPlotView.cpp +++ b/src/mvc/ScatterPlotView.cpp @@ -155,7 +155,7 @@ void ScatterPlotView::exportPngCsv() QString apath; if (roi_name.length() > 0) { - apath = dir.absolutePath() + QDir::separator() + finfo.fileName() + QString("_scatter_" + _curAnalysis + "_" + _cb_roi->currentText() + "-" + _cb_x_axis_element->currentText() + "-" + _cb_y_axis_element->currentText() + "_" + formattedTime); + apath = dir.absolutePath() + QDir::separator() + finfo.fileName() + QString("_scatter_" + _curAnalysis + "_" + roi_name + "-" + _cb_x_axis_element->currentText() + "-" + _cb_y_axis_element->currentText() + "_" + formattedTime); } else { @@ -186,8 +186,12 @@ void ScatterPlotView::_exportScatterPlotCSV(QString filePath) { if (_model != nullptr) { + const std::unordered_map rois = _model->get_map_rois(); data_struct::ArrayXXr x_map; data_struct::ArrayXXr y_map; + std::vector x_motor = _model->get_x_axis(); + std::vector y_motor = _model->get_y_axis(); + QString roi_name = _cb_roi->currentText(); if (_getXY_Maps(x_map, y_map)) { std::ofstream out_stream(filePath.toStdString()); @@ -195,16 +199,32 @@ void ScatterPlotView::_exportScatterPlotCSV(QString filePath) { out_stream << "ascii information for file: " << _model->getDatasetName().toStdString() << "\n"; out_stream << "Analysis Type: " << _curAnalysis.toStdString() << "\n"; + if (roi_name.length() > 0) + { + out_stream << "ROI Name: " << roi_name.toStdString() << "\n"; + } out_stream << "X Axis Name: " << _cb_x_axis_element->currentText().toStdString() << "\n"; out_stream << "Y Axis Name: " << _cb_y_axis_element->currentText().toStdString() << "\n"; + out_stream << "Units: Cts/s\n"; out_stream << "Rows: " << x_map.rows() << "\n"; out_stream << "Cols: " << x_map.cols() << "\n"; - out_stream << "X Index, Y Index, X Value, Y Value \n"; - for (int y = 0; y < x_map.rows(); y++) + out_stream << "X Index, Y Index, X Value, Y Value, X Motor, Y Motor \n"; + if (rois.count(roi_name.toStdString()) > 0) + { + Map_ROI map_roi = rois.at(roi_name.toStdString()); + for (auto& itr : map_roi.pixel_list) + { + out_stream << itr.first << "," << itr.second << "," << x_map(itr.second, itr.first) << "," << y_map(itr.second, itr.first) << "," << x_motor[itr.first] << ","<< y_motor[itr.second]<< "\n"; + } + } + else { - for (int x = 0; x < x_map.cols(); x++) + for (int y = 0; y < x_map.rows(); y++) { - out_stream << x << "," << y << "," << x_map(y, x) << "," << y_map(y, x) << "\n"; + for (int x = 0; x < x_map.cols(); x++) + { + out_stream << x << "," << y << "," << x_map(y, x) << "," << y_map(y, x) << x_motor[x] << ","<< y_motor[y]<< "\n"; + } } } } diff --git a/src/mvc/ScatterPlotView.h b/src/mvc/ScatterPlotView.h index bfc9cb0..6a74126 100644 --- a/src/mvc/ScatterPlotView.h +++ b/src/mvc/ScatterPlotView.h @@ -64,7 +64,6 @@ public slots: void onNameChange(QString); private: - bool _getXY_Maps(data_struct::ArrayXXr& x_map, data_struct::ArrayXXr& y_map); void _updateNames(); From cd1c53e3ea47238526043dea90a78d1c6d45e980 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Mon, 3 Jun 2024 10:08:45 -0500 Subject: [PATCH 18/25] Fixed saving loading pref for scatter plot git status --- src/mvc/ScatterPlotView.cpp | 17 ++++++++++++--- src/mvc/ScatterPlotWidget.cpp | 24 ++++++++++++++++++--- src/preferences/Preferences.cpp | 38 +++++++++++++++++++++++++++------ src/preferences/Preferences.h | 2 ++ 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/mvc/ScatterPlotView.cpp b/src/mvc/ScatterPlotView.cpp index d53af79..bfb0efa 100644 --- a/src/mvc/ScatterPlotView.cpp +++ b/src/mvc/ScatterPlotView.cpp @@ -55,6 +55,7 @@ ScatterPlotView::ScatterPlotView(bool display_log10, bool black_background, QWid //setRenderHint(QPainter::Antialiasing); _scatter_series = new QScatterSeries(); + _scatter_series->setColor(QColor(Qt::blue)); QString marker_shape = Preferences::inst()->getValue(STR_PFR_MARKER_SHAPE).toString(); if (marker_shape == "Circle") { @@ -65,7 +66,8 @@ ScatterPlotView::ScatterPlotView(bool display_log10, bool black_background, QWid _scatter_series->setMarkerShape(QScatterSeries::MarkerShapeRectangle); } - _scatter_series->setColor(QColor(Qt::blue)); + setBlackBackground(Preferences::inst()->getValue(STR_PFR_SCATTER_DARK_BACKGROUND).toBool()); + _scatter_series->setBorderColor(Qt::transparent); _scatter_series->setMarkerSize(1.0); //_scatter_series->setUseOpenGL(true); // causes exception when deconstructor called. _chart->addSeries(_scatter_series); @@ -339,11 +341,20 @@ void ScatterPlotView::_updateNames() _cb_roi->clear(); _cb_roi->addItem(" "); + int itemAmt = 0; for (auto& itr : rois) { _cb_roi->addItem(QString(itr.first.c_str())); + itemAmt++; + } + if(itemAmt == 0) + { + _cb_roi->setEnabled(false); + } + else + { + _cb_roi->setEnabled(true); } - std::vector map_names; _model->generateNameLists(_curAnalysis, map_names); QString xSavedName = _cb_x_axis_element->currentText(); @@ -523,7 +534,7 @@ void ScatterPlotView::_updatePlot() double corr_coef = find_coefficient(x_arr, y_arr); _lb_corr_coef->setText(QString::number(corr_coef)); - + _scatter_series->setBorderColor(Qt::transparent); _chart->addSeries(_scatter_series); _axisX->setTitleText(_cb_x_axis_element->currentText()); diff --git a/src/mvc/ScatterPlotWidget.cpp b/src/mvc/ScatterPlotWidget.cpp index ff35572..c401a22 100644 --- a/src/mvc/ScatterPlotWidget.cpp +++ b/src/mvc/ScatterPlotWidget.cpp @@ -40,7 +40,7 @@ void ScatterPlotWidget::_createLayout() int num_wins = Preferences::inst()->getValue(STR_PRF_ScatterPlot_NumWindows).toInt(); bool _display_log10 = Preferences::inst()->getValue(STR_PRF_ScatterPlot_Log10).toBool(); bool display_gird_lines = Preferences::inst()->getValue(STR_PRF_ScatterPlot_GridLines).toBool(); - bool dark_theme = Preferences::inst()->getValue(STR_PFR_SPECTRA_BLACK_BG).toBool(); + bool dark_theme = Preferences::inst()->getValue(STR_PFR_SCATTER_DARK_BACKGROUND).toBool(); _ck_display_log10 = new QCheckBox("Display log10"); _ck_display_log10->setChecked(_display_log10); @@ -107,6 +107,13 @@ void ScatterPlotWidget::_createLayout() _mainlayout->addItem(_subPlotLayout); _mainlayout->addItem(_options_layout); + + setGridLinesVisible(Preferences::inst()->getValue(STR_PRF_ScatterPlot_GridLines).toBool()); + setBlackBackground(Preferences::inst()->getValue(STR_PFR_SCATTER_DARK_BACKGROUND).toBool()); + set_log10(Preferences::inst()->getValue(STR_PRF_ScatterPlot_Log10).toBool()); + updateMarkerSize(Preferences::inst()->getValue(STR_PRF_ScatterPlot_Size).toInt()); + onShapeChange(Preferences::inst()->getValue(STR_PFR_MARKER_SHAPE).toString()); + setLayout(_mainlayout); } @@ -117,7 +124,7 @@ void ScatterPlotWidget::onAdd() { bool _display_log10 = Preferences::inst()->getValue(STR_PRF_ScatterPlot_Log10).toBool(); bool display_gird_lines = Preferences::inst()->getValue(STR_PRF_ScatterPlot_GridLines).toBool(); - bool dark_theme = Preferences::inst()->getValue(STR_PFR_SPECTRA_BLACK_BG).toBool(); + bool dark_theme = Preferences::inst()->getValue(STR_PFR_SCATTER_DARK_BACKGROUND).toBool(); _plot_view_list.push_back(new ScatterPlotView(_display_log10, dark_theme, this)); int idx = _plot_view_list.size() - 1; @@ -127,6 +134,11 @@ void ScatterPlotWidget::onAdd() update(); _plot_view_list[idx]->show(); + + + //updateMarkerSize(Preferences::inst()->getValue(STR_PRF_ScatterPlot_Size).toInt()); + //onShapeChange(Preferences::inst()->getValue(STR_PFR_MARKER_SHAPE).toString()); + Preferences::inst()->setValue(STR_PRF_ScatterPlot_NumWindows, (int)_plot_view_list.size()); } @@ -176,16 +188,21 @@ void ScatterPlotWidget::setBlackBackground(int val) { itr->setBlackBackground(val); } + + Preferences::inst()->setValue(STR_PFR_SCATTER_DARK_BACKGROUND, val); } //--------------------------------------------------------------------------- void ScatterPlotWidget::updateMarkerSize(int val) { + val = std::min(val, 1); for (auto& itr : _plot_view_list) { itr->updateMarkerSize(val); } + + Preferences::inst()->setValue(STR_PRF_ScatterPlot_Size, val); } //--------------------------------------------------------------------------- @@ -222,7 +239,8 @@ void ScatterPlotWidget::set_log10(int val) { itr->setLog10(val); } - + + Preferences::inst()->setValue(STR_PRF_ScatterPlot_Log10, val); } //--------------------------------------------------------------------------- diff --git a/src/preferences/Preferences.cpp b/src/preferences/Preferences.cpp index d70979c..c346d75 100644 --- a/src/preferences/Preferences.cpp +++ b/src/preferences/Preferences.cpp @@ -32,13 +32,13 @@ Preferences::Preferences() {STR_PRF_PythonCoefficient, QVariant()}, {STR_PRF_PythonOptions, QVariant()}, {STR_PRF_SolverCheckedID, QVariant()}, - {STR_PRF_FontSize, QVariant(14)}, + {STR_PRF_FontSize, QVariant()}, {STR_PRF_RulerUnitLabel, QVariant()}, {STR_PRF_RulerUnitX, QVariant()}, {STR_PRF_RulerUnitY, QVariant()}, {STR_PRF_RegionMenuList, QVariant()}, - {STR_PRF_MainWindowSavedWidth, QVariant(1024)}, - {STR_PRF_MainWindowSavedHeight, QVariant(768)}, + {STR_PRF_MainWindowSavedWidth, QVariant()}, + {STR_PRF_MainWindowSavedHeight, QVariant()}, {STR_PRF_WindowTitle, QVariant()}, {STR_PRF_DecimalPrecision, QVariant()}, {STR_PRF_MicroProbeXPv, QVariant()}, @@ -54,17 +54,43 @@ Preferences::Preferences() {STR_PRF_ExportSelectedXmlOption, QVariant()}, {STR_PRF_LastIP, QVariant()}, {STR_PRF_LastPort, QVariant()}, - {STR_PFR_LOG_10, QVariant(true)}, + {STR_PFR_LOG_10, QVariant()}, {STR_PFR_DETAILED_FIT_SPEC, QVariant()}, + {STR_PFR_SHOW_FIT_INT_MATRIX, QVariant()}, + {STR_PFR_SHOW_FIT_INT_NNLS, QVariant()}, + {STR_PFR_SHOW_MAX_CHAN_SPEC, QVariant()}, {STR_GRID_ROWS, QVariant()}, {STR_GRID_COLS, QVariant()}, + {STR_COLORMAP, QVariant()}, + {STR_COLORMAP_GRAY, QVariant()}, + {STR_COLORMAP_HEAT, QVariant()}, + {STR_RECENT_MAPS_WORKSPACES, QVariant()}, + {STR_LOG_SCALE_COLOR, QVariant()}, + {STR_DISPLAY_COLOR_LEDGEND, QVariant()}, + {STR_INVERT_Y_AXIS, QVariant()}, + {STR_PFR_THEME, QVariant()}, + {STR_PFR_SPECTRA_BLACK_BG, QVariant()}, + {STR_PRF_ScatterPlot_NumWindows, QVariant()}, + {STR_PRF_ScatterPlot_Log10, QVariant()}, + {STR_PFR_MARKER_SHAPE, QVariant()}, + {STR_PFR_SCATTER_DARK_BACKGROUND, QVariant()}, + {STR_PRF_ScatterPlot_Size, QVariant()}, + {STR_PRF_ScatterPlot_GridLines, QVariant()}, + {STR_DEFAULT, QVariant()}, {STR_PRF_SHOW_DATASET_ON_FILE_SELECT, QVariant()}, {STR_SEARCH_SUB_DIR_FOR_DATASETS, QVariant()}, {STR_GEOMETRY, QVariant()}, {STR_WINDOWSTATE, QVariant()}, + {STR_MAPS_WIDGET_GEOMETRY, QVariant()}, + {STR_COUNTS_DOCK, QVariant()}, + {STR_INTSPEC_DOCK, QVariant()}, + {STR_QUANT_DOCK, QVariant()}, + {STR_COLOR_DOCK, QVariant()}, + {STR_SCATTER_DOCK, QVariant()}, + {STR_EXTRA_DOCK, QVariant()}, + {STR_PRF_STRICT_REGEX, QVariant()}, {STR_PRF_FILE_SIZE, QVariant()}, - {STR_PRF_SHOW_DATASET_ON_LOAD, QVariant()}, - {STR_PRF_STRICT_REGEX, QVariant()} + {STR_PRF_SHOW_DATASET_ON_LOAD, QVariant()} }; load(); } diff --git a/src/preferences/Preferences.h b/src/preferences/Preferences.h index 98d0df1..259c043 100644 --- a/src/preferences/Preferences.h +++ b/src/preferences/Preferences.h @@ -67,7 +67,9 @@ #define STR_PRF_ScatterPlot_NumWindows "ScatterPlot_NumWindows" #define STR_PRF_ScatterPlot_Log10 "ScatterPlot_Log10" #define STR_PFR_MARKER_SHAPE "ScatterPlotMarkerShape" +#define STR_PFR_SCATTER_DARK_BACKGROUND "ScatterPlotDarkBackground" #define STR_PRF_ScatterPlot_GridLines "ScatterPlotGridLines" +#define STR_PRF_ScatterPlot_Size "ScatterPlotSize" #define STR_DEFAULT "Default" #define STR_PRF_SHOW_DATASET_ON_FILE_SELECT "ShowDatasetOnFileSelect" // if you select file name on left side, it will change the current viewed dataset to that if it is loaded #define STR_SEARCH_SUB_DIR_FOR_DATASETS "SearchSubDirForDatasets" From 921c542ceb3d1e2c911ab9da0eabe75ad46c0bfc Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Mon, 3 Jun 2024 10:11:28 -0500 Subject: [PATCH 19/25] Set hybrid mpfit as default --- src/mvc/BatchRoiFitWidget.cpp | 2 +- src/mvc/FitSpectraWidget.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mvc/BatchRoiFitWidget.cpp b/src/mvc/BatchRoiFitWidget.cpp index b83f1f8..83a3d69 100644 --- a/src/mvc/BatchRoiFitWidget.cpp +++ b/src/mvc/BatchRoiFitWidget.cpp @@ -53,9 +53,9 @@ void BatchRoiFitWidget::createLayout() _le_detectors = new QLineEdit("0,1,2,3,4,5,6"); _cb_opt_method = new QComboBox(); + _cb_opt_method->addItem(STR_HYBRID_MP_FIT); _cb_opt_method->addItem(STR_LM_FIT); _cb_opt_method->addItem(STR_MP_FIT); - _cb_opt_method->addItem(STR_HYBRID_MP_FIT); connect(_cb_opt_method, &QComboBox::currentTextChanged, this, &BatchRoiFitWidget::optimizer_changed); _file_list_model = new QStandardItemModel(); diff --git a/src/mvc/FitSpectraWidget.cpp b/src/mvc/FitSpectraWidget.cpp index 4f65874..a99a959 100644 --- a/src/mvc/FitSpectraWidget.cpp +++ b/src/mvc/FitSpectraWidget.cpp @@ -218,9 +218,9 @@ void FitSpectraWidget::createLayout() _fit_params_tab_widget->addTab(element_widget, "Fit Elements"); _cb_opttimizer = new QComboBox(); + _cb_opttimizer->addItem(STR_HYBRID_MP_FIT); _cb_opttimizer->addItem(STR_LM_FIT); _cb_opttimizer->addItem(STR_MP_FIT); - _cb_opttimizer->addItem(STR_HYBRID_MP_FIT); connect(_cb_opttimizer, &QComboBox::currentTextChanged, this, &FitSpectraWidget::optimizer_changed); _chk_auto_model = new QCheckBox("Auto Update Model"); From d9665eaefc77db51c6d8c5a428145d5bbdce478d Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Mon, 3 Jun 2024 10:42:56 -0500 Subject: [PATCH 20/25] added num points for scatter export --- src/mvc/ScatterPlotView.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mvc/ScatterPlotView.cpp b/src/mvc/ScatterPlotView.cpp index bfb0efa..7e80ead 100644 --- a/src/mvc/ScatterPlotView.cpp +++ b/src/mvc/ScatterPlotView.cpp @@ -208,12 +208,12 @@ void ScatterPlotView::_exportScatterPlotCSV(QString filePath) out_stream << "X Axis Name: " << _cb_x_axis_element->currentText().toStdString() << "\n"; out_stream << "Y Axis Name: " << _cb_y_axis_element->currentText().toStdString() << "\n"; out_stream << "Units: Cts/s\n"; - out_stream << "Rows: " << x_map.rows() << "\n"; - out_stream << "Cols: " << x_map.cols() << "\n"; - out_stream << "X Index, Y Index, X Value, Y Value, X Motor, Y Motor \n"; if (rois.count(roi_name.toStdString()) > 0) { Map_ROI map_roi = rois.at(roi_name.toStdString()); + out_stream << "Num Points: " << map_roi.pixel_list.size() << "\n"; + out_stream << "X Index, Y Index, X Value, Y Value, X Motor, Y Motor \n"; + for (auto& itr : map_roi.pixel_list) { out_stream << itr.first << "," << itr.second << "," << x_map(itr.second, itr.first) << "," << y_map(itr.second, itr.first) << "," << x_motor[itr.first] << ","<< y_motor[itr.second]<< "\n"; @@ -221,6 +221,10 @@ void ScatterPlotView::_exportScatterPlotCSV(QString filePath) } else { + out_stream << "Rows: " << x_map.rows() << "\n"; + out_stream << "Cols: " << x_map.cols() << "\n"; + out_stream << "Num Points: " << x_map.rows() * x_map.cols() << "\n"; + out_stream << "X Index, Y Index, X Value, Y Value, X Motor, Y Motor \n"; for (int y = 0; y < x_map.rows(); y++) { for (int x = 0; x < x_map.cols(); x++) From 833b8219543701056288e6a633e81f237c3f480a Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Mon, 3 Jun 2024 12:09:18 -0500 Subject: [PATCH 21/25] Added quantified values for scatter plot --- src/mvc/MapsElementsWidget.cpp | 2 ++ src/mvc/MapsH5Model.cpp | 51 ++++++++++++++++++++++++++++++++-- src/mvc/MapsH5Model.h | 4 ++- src/mvc/ScatterPlotView.cpp | 18 ++++++++++-- src/mvc/ScatterPlotView.h | 4 +++ src/mvc/ScatterPlotWidget.cpp | 9 ++++++ src/mvc/ScatterPlotWidget.h | 2 ++ 7 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/mvc/MapsElementsWidget.cpp b/src/mvc/MapsElementsWidget.cpp index 5214095..8f2148f 100644 --- a/src/mvc/MapsElementsWidget.cpp +++ b/src/mvc/MapsElementsWidget.cpp @@ -865,6 +865,8 @@ void MapsElementsWidget::onSelectNormalizer(QString name) } + _scatter_plot_widget->setQuantType(name); + redrawCounts(); } diff --git a/src/mvc/MapsH5Model.cpp b/src/mvc/MapsH5Model.cpp index 06917f9..94aa23c 100644 --- a/src/mvc/MapsH5Model.cpp +++ b/src/mvc/MapsH5Model.cpp @@ -50,7 +50,7 @@ void MapsH5Model::clear_analyzed_counts() /*---------------------------------------------------------------------------*/ -void MapsH5Model::getAnalyzedCounts(std::string analysis_type, data_struct::Fit_Count_Dict& out_counts) +bool MapsH5Model::getAnalyzedCounts(std::string analysis_type, data_struct::Fit_Count_Dict& out_counts) { std::lock_guard lock(_mutex); out_counts.clear(); @@ -61,11 +61,58 @@ void MapsH5Model::getAnalyzedCounts(std::string analysis_type, data_struct::Fit_ { out_counts[itr.first] = itr.second; } + return true; + } + return false; +} + +//--------------------------------------------------------------------------- +bool MapsH5Model::getAnalyzedQuantified(std::string analysis_type, std::string quant_type, data_struct::Fit_Count_Dict& out_counts) +{ + std::lock_guard lock(_mutex); + out_counts.clear(); + std::unordered_map > *calib_map = nullptr; + if(analysis_type.length() > 0 && quant_type.length() > 0 && _analyzed_counts.count(analysis_type) > 0 && _scalers.count(quant_type) > 0) + { + if (analysis_type == STR_FIT_NNLS) + { + calib_map = &_quant_map_nnls; + } + else if(analysis_type == STR_FIT_GAUSS_MATRIX) + { + calib_map = &_quant_map_matrix; + } + else + { + return false; + } + if(calib_map->count(quant_type) > 0) + { + // get scaler quant type + auto calib = calib_map->at(quant_type).calib_curve; + auto quant_scaler = _scalers.at(quant_type); + for (const auto& itr : *(_analyzed_counts[analysis_type])) + { + if(calib.count(itr.first) > 0) + { + out_counts[itr.first] = itr.second / quant_scaler/ calib.at(itr.first); + float min_coef = out_counts.at(itr.first).minCoeff(); + out_counts[itr.first] = out_counts.at(itr.first).unaryExpr([min_coef](float v) { return std::isfinite(v) ? v : min_coef; }); + } + else + { + out_counts[itr.first] = itr.second; + } + } + return true; + } + return false; } + return false; } -/*---------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- std::vector MapsH5Model::count_names() { diff --git a/src/mvc/MapsH5Model.h b/src/mvc/MapsH5Model.h index 64abc55..7ad4949 100644 --- a/src/mvc/MapsH5Model.h +++ b/src/mvc/MapsH5Model.h @@ -122,7 +122,9 @@ class MapsH5Model : public QObject bool is_fully_loaded() { return _is_fully_loaded; } //data_struct::Fit_Count_Dict* getAnalyzedCounts(std::string analysis_type); - void getAnalyzedCounts(std::string analysis_type, data_struct::Fit_Count_Dict& out_counts); + bool getAnalyzedCounts(std::string analysis_type, data_struct::Fit_Count_Dict& out_counts); + + bool getAnalyzedQuantified(std::string analysis_type, std::string quant_type, data_struct::Fit_Count_Dict& out_counts); //const data_struct::Spectra* getIntegratedSpectra() {return &_integrated_spectra;} void getIntegratedSpectra(data_struct::Spectra& out_spectra); diff --git a/src/mvc/ScatterPlotView.cpp b/src/mvc/ScatterPlotView.cpp index 7e80ead..bf51f3a 100644 --- a/src/mvc/ScatterPlotView.cpp +++ b/src/mvc/ScatterPlotView.cpp @@ -18,6 +18,7 @@ ScatterPlotView::ScatterPlotView(bool display_log10, bool black_background, QWid _model = nullptr; _curAnalysis = QString(STR_FIT_NNLS.c_str()); + _curQuant = QString("1"); _axisXLog10 = new QLogValueAxis(); _axisXLog10->setTitleText(""); @@ -157,11 +158,11 @@ void ScatterPlotView::exportPngCsv() QString apath; if (roi_name.length() > 0) { - apath = dir.absolutePath() + QDir::separator() + finfo.fileName() + QString("_scatter_" + _curAnalysis + "_" + roi_name + "-" + _cb_x_axis_element->currentText() + "-" + _cb_y_axis_element->currentText() + "_" + formattedTime); + apath = dir.absolutePath() + QDir::separator() + finfo.fileName() + QString("_scatter_" + _curAnalysis + "_" + _curQuant + "_" + roi_name + "-" + _cb_x_axis_element->currentText() + "-" + _cb_y_axis_element->currentText() + "_" + formattedTime); } else { - apath = dir.absolutePath() + QDir::separator() + finfo.fileName() + QString("_scatter_" + _curAnalysis + "_" + _cb_x_axis_element->currentText() + "-" + _cb_y_axis_element->currentText() + "_" + formattedTime); + apath = dir.absolutePath() + QDir::separator() + finfo.fileName() + QString("_scatter_" + _curAnalysis + "_" + _curQuant + "_" + _cb_x_axis_element->currentText() + "-" + _cb_y_axis_element->currentText() + "_" + formattedTime); } QString png_path = QDir::cleanPath(apath + ".png"); if (false == pixmap.save(png_path, "PNG")) @@ -201,6 +202,7 @@ void ScatterPlotView::_exportScatterPlotCSV(QString filePath) { out_stream << "ascii information for file: " << _model->getDatasetName().toStdString() << "\n"; out_stream << "Analysis Type: " << _curAnalysis.toStdString() << "\n"; + out_stream << "Quantification Type: " << _curQuant.toStdString() << "\n"; if (roi_name.length() > 0) { out_stream << "ROI Name: " << roi_name.toStdString() << "\n"; @@ -337,6 +339,13 @@ void ScatterPlotView::setAnalysisType(QString name) //--------------------------------------------------------------------------- +void ScatterPlotView::setQuantType(QString name) +{ + _curQuant = name; +} + +//--------------------------------------------------------------------------- + void ScatterPlotView::_updateNames() { if (_model != nullptr) @@ -429,7 +438,10 @@ bool ScatterPlotView::_getXY_Maps(data_struct::ArrayXXr &x_map, data_stru std::string yName = _cb_y_axis_element->currentText().toStdString(); data_struct::Fit_Count_Dict fit_counts; - _model->getAnalyzedCounts(_curAnalysis.toStdString(), fit_counts); + if(false == _model->getAnalyzedQuantified(_curAnalysis.toStdString(), _curQuant.toStdString(), fit_counts)) + { + _model->getAnalyzedCounts(_curAnalysis.toStdString(), fit_counts); + } std::map>* scalers = _model->getScalers(); int xCnt = fit_counts.count(xName); diff --git a/src/mvc/ScatterPlotView.h b/src/mvc/ScatterPlotView.h index 6a74126..5a214e3 100644 --- a/src/mvc/ScatterPlotView.h +++ b/src/mvc/ScatterPlotView.h @@ -41,6 +41,8 @@ class ScatterPlotView : public QWidget void setAnalysisType(QString curAnalysis); + void setQuantType(QString curAnalysis); + void updateMarkerSize(qreal val); void setLog10(int val); @@ -98,6 +100,8 @@ public slots: QString _curAnalysis; + QString _curQuant; + bool _display_log10; MapsH5Model* _model; diff --git a/src/mvc/ScatterPlotWidget.cpp b/src/mvc/ScatterPlotWidget.cpp index c401a22..6aa661d 100644 --- a/src/mvc/ScatterPlotWidget.cpp +++ b/src/mvc/ScatterPlotWidget.cpp @@ -215,6 +215,15 @@ void ScatterPlotWidget::setAnalysisType(QString name) } } +//--------------------------------------------------------------------------- + +void ScatterPlotWidget::setQuantType(QString name) +{ + for (auto& itr : _plot_view_list) + { + itr->setQuantType(name); + } +} //--------------------------------------------------------------------------- diff --git a/src/mvc/ScatterPlotWidget.h b/src/mvc/ScatterPlotWidget.h index 7cbb4a3..69f9e99 100644 --- a/src/mvc/ScatterPlotWidget.h +++ b/src/mvc/ScatterPlotWidget.h @@ -47,6 +47,8 @@ class ScatterPlotWidget : public QWidget void setAnalysisType(QString name); + void setQuantType(QString name); + signals: void updateProgressBar(int, int); From 1244a421d08a2a18cc2c7686c1620072d2f8fad3 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 4 Jun 2024 12:03:10 -0500 Subject: [PATCH 22/25] Added limits to fit param element --- src/mvc/FitElementsTableModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mvc/FitElementsTableModel.cpp b/src/mvc/FitElementsTableModel.cpp index ff826fa..eb96830 100644 --- a/src/mvc/FitElementsTableModel.cpp +++ b/src/mvc/FitElementsTableModel.cpp @@ -113,7 +113,7 @@ data_struct::Fit_Parameters FitElementsTableModel::getAsFitParams() { TreeItem* node = itr.second; data_struct::Fit_Element_Map* element = node->element_data; - fit_params.add_parameter(data_struct::Fit_Param(element->full_name(), node->itemData[1].toDouble(), data_struct::E_Bound_Type::FIT)); + fit_params.add_parameter(data_struct::Fit_Param(element->full_name(), 1.0e-10, 20.0, node->itemData[1].toDouble(), 0.0005, data_struct::E_Bound_Type::LIMITED_LO_HI)); } return fit_params; } From e6cf6d067fe19ee321136ace92f0eb1c5290c1bf Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 4 Jun 2024 12:03:51 -0500 Subject: [PATCH 23/25] Change fit param table to interactive --- src/mvc/FitSpectraWidget.cpp | 4 +++- src/mvc/FittingDialog.cpp | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mvc/FitSpectraWidget.cpp b/src/mvc/FitSpectraWidget.cpp index a99a959..1305bdd 100644 --- a/src/mvc/FitSpectraWidget.cpp +++ b/src/mvc/FitSpectraWidget.cpp @@ -143,7 +143,7 @@ void FitSpectraWidget::createLayout() _fit_params_table->setItemDelegateForColumn(3, npDelegate); _fit_params_table->setItemDelegateForColumn(4, npDelegate); _fit_params_table->setItemDelegateForColumn(5, npDelegate); - _fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + _fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); _fit_params_table->setContextMenuPolicy(Qt::CustomContextMenu); connect(_fit_params_table, SIGNAL(customContextMenuRequested(QPoint)), @@ -253,6 +253,8 @@ void FitSpectraWidget::createLayout() splitter->setStretchFactor(0, 1); splitter->addWidget(tab_and_buttons_widget); + optimizer_changed(STR_HYBRID_MP_FIT); + QLayout* layout = new QVBoxLayout(); layout->addWidget(splitter); setLayout(layout); diff --git a/src/mvc/FittingDialog.cpp b/src/mvc/FittingDialog.cpp index 46b9013..9a70323 100644 --- a/src/mvc/FittingDialog.cpp +++ b/src/mvc/FittingDialog.cpp @@ -75,13 +75,13 @@ void FittingDialog::_createLayout() _fit_params_table->setItemDelegateForColumn(3, npDelegate); _fit_params_table->setItemDelegateForColumn(4, npDelegate); _fit_params_table->setItemDelegateForColumn(5, npDelegate); - _fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + _fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); _new_fit_params_table = new QTableView(); _new_fit_params_table->setModel(_new_fit_params_table_model); _new_fit_params_table->sortByColumn(0, Qt::AscendingOrder); _new_fit_params_table->setItemDelegateForColumn(2, cbDelegate); - _new_fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + _new_fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); connect(_new_fit_params_table->verticalScrollBar(), &QAbstractSlider::valueChanged, _fit_params_table->verticalScrollBar(), &QAbstractSlider::setValue); From 20d3ea63508199f4b4ca22a5a17ab8ec5ee03016 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 4 Jun 2024 12:04:24 -0500 Subject: [PATCH 24/25] Clean up unused code --- src/mvc/MapsWorkspaceFilesWidget.cpp | 29 ++---------------------- src/mvc/MapsWorkspaceFilesWidget.h | 34 ++++++++++++---------------- 2 files changed, 16 insertions(+), 47 deletions(-) diff --git a/src/mvc/MapsWorkspaceFilesWidget.cpp b/src/mvc/MapsWorkspaceFilesWidget.cpp index a68c761..3a126d2 100644 --- a/src/mvc/MapsWorkspaceFilesWidget.cpp +++ b/src/mvc/MapsWorkspaceFilesWidget.cpp @@ -91,17 +91,6 @@ void MapsWorkspaceFilesWidget::createLayout() _vlm_tab_widget->appendFilterHelpAction(tiff_file); _vlm_tab_widget->appendFilterHelpAction(tif_file); - _fit_params_table_model = new FitParamsTableModel(); - ComboBoxDelegate *cbDelegate = new ComboBoxDelegate(bound_types); - - /* - _fit_params_table = new QTableView(); - _fit_params_table->setModel(_fit_params_table_model); - //_fit_params_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - //_fit_params_table->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); - _fit_params_table->sortByColumn(0, Qt::AscendingOrder); - _fit_params_table->setItemDelegateForColumn(2, cbDelegate); - */ QLayout* vlayout = new QVBoxLayout(); _tab_widget->insertTab(0, _h5_tab_widget, "Analyized Data"); @@ -122,7 +111,7 @@ void MapsWorkspaceFilesWidget::setModel(MapsWorkspaceModel *model) disconnect(_model, &MapsWorkspaceModel::doneLoadingVLM, this, &MapsWorkspaceFilesWidget::updatedVLM); disconnect(_model, &MapsWorkspaceModel::doneLoadingImgDat, this, &MapsWorkspaceFilesWidget::updatedHDF); disconnect(_model, &MapsWorkspaceModel::doneUnloading, this, &MapsWorkspaceFilesWidget::clearLists); - disconnect(_model, &MapsWorkspaceModel::newFitParamsFileLoaded, this, &MapsWorkspaceFilesWidget::loadedFitParams); + //disconnect(_model, &MapsWorkspaceModel::newFitParamsFileLoaded, this, &MapsWorkspaceFilesWidget::loadedFitParams); } _model = model; @@ -146,7 +135,7 @@ void MapsWorkspaceFilesWidget::setModel(MapsWorkspaceModel *model) connect(_model, &MapsWorkspaceModel::doneLoadingImgDat, this, &MapsWorkspaceFilesWidget::updatedHDF); connect(_model, &MapsWorkspaceModel::doneLoadingROIS, this, &MapsWorkspaceFilesWidget::updateROIS); connect(_model, &MapsWorkspaceModel::doneUnloading, this, &MapsWorkspaceFilesWidget::clearLists); - connect(_model, &MapsWorkspaceModel::newFitParamsFileLoaded, this, &MapsWorkspaceFilesWidget::loadedFitParams); + //connect(_model, &MapsWorkspaceModel::newFitParamsFileLoaded, this, &MapsWorkspaceFilesWidget::loadedFitParams); connect(_h5_tab_widget, &FileTabWidget::onRefresh, _model, &MapsWorkspaceModel::reload_analyzed); connect(_vlm_tab_widget, &FileTabWidget::onRefresh, _model, &MapsWorkspaceModel::reload_vlm); connect(_mda_tab_widget, &FileTabWidget::onRefresh, _model, &MapsWorkspaceModel::reload_raw); @@ -206,20 +195,6 @@ void MapsWorkspaceFilesWidget::update_roi_num(QString name, int val) _mda_tab_widget->set_roi_num(name, val); } -//--------------------------------------------------------------------------- - -void MapsWorkspaceFilesWidget::loadedFitParams(int idx) -{ - if(idx == -1) //avg fit params - { - data_struct::Fit_Parameters* fit_params = _model->getFitParameters(idx); - if(fit_params != nullptr) - { - _fit_params_table_model->setFitParams(*fit_params); - } - } -} - /*---------------------------------------------------------------------------*/ void MapsWorkspaceFilesWidget::setFileTabActionsEnabled(bool val) diff --git a/src/mvc/MapsWorkspaceFilesWidget.h b/src/mvc/MapsWorkspaceFilesWidget.h index 1863427..e3c044d 100644 --- a/src/mvc/MapsWorkspaceFilesWidget.h +++ b/src/mvc/MapsWorkspaceFilesWidget.h @@ -67,35 +67,33 @@ class MapsWorkspaceFilesWidget : public QWidget public slots: - void updatedMDA(); + void updatedMDA(); - void updatedVLM(); + void updatedVLM(); - void updatedHDF(); + void updatedHDF(); - void updateROIS(); + void updateROIS(); void update_roi_num(QString, int); - void clearLists(); + void clearLists(); - void loadedFitParams(int idx); - - void onOpenModel(const QStringList& names_list, MODEL_TYPE mt); + void onOpenModel(const QStringList& names_list, MODEL_TYPE mt); - void onCloseModel(const QStringList& names_list, MODEL_TYPE mt); + void onCloseModel(const QStringList& names_list, MODEL_TYPE mt); - void onCustomContext(const QString& context_label, const QStringList& file_list); + void onCustomContext(const QString& context_label, const QStringList& file_list); - void onPerPixelProcessList(const QStringList& file_list); + void onPerPixelProcessList(const QStringList& file_list); - void onPerPixelProcessListAnalyzed(const QStringList& file_list); - - void onBatchRoiList(const QStringList& file_list); + void onPerPixelProcessListAnalyzed(const QStringList& file_list); - void onProcessed_list_update(QStringList file_list); + void onBatchRoiList(const QStringList& file_list); - void onDatasetSelected(const QString name); + void onProcessed_list_update(QStringList file_list); + + void onDatasetSelected(const QString name); protected: @@ -118,10 +116,6 @@ public slots: MapsWorkspaceModel* _model; - QTableView* _fit_params_table; - - FitParamsTableModel* _fit_params_table_model; - PerPixelFitWidget* _per_pixel_fit_widget; BatchRoiFitWidget* _batch_roi_fit_widget; From 4cf7debc8e29bbccd5e9ee1d02dc581315bc6667 Mon Sep 17 00:00:00 2001 From: Arthur Glowacki Date: Tue, 4 Jun 2024 12:04:52 -0500 Subject: [PATCH 25/25] Revert back to original step size for per pixel fitting --- src/mvc/PerPixelOptionsWidget.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mvc/PerPixelOptionsWidget.h b/src/mvc/PerPixelOptionsWidget.h index 0601588..29ddc83 100644 --- a/src/mvc/PerPixelOptionsWidget.h +++ b/src/mvc/PerPixelOptionsWidget.h @@ -76,8 +76,6 @@ class PerPixelOptionsWidget : public QWidget if (_proc_matrix->isChecked()) { analysis_job.fitting_routines.push_back(data_struct::Fitting_Routines::GAUSS_MATRIX); - - analysis_job.optimizer()->set_options({ { STR_OPT_STEP, (T_real)0.1 } }); } if (_save_avg->isChecked())