@@ -122,11 +122,15 @@ AnalysisTool::AnalysisTool(Preferences& prefs) : preferences_(prefs) {
122122 &AnalysisTool::handle_group_animate_state_changed);
123123 connect (&group_animate_timer_, &QTimer::timeout, this , &AnalysisTool::handle_group_timer);
124124
125- connect (ui_->group_box , qOverload<int >(&QComboBox::currentIndexChanged), this , &AnalysisTool::update_group_values);
125+ connect (ui_->group_combo , qOverload<int >(&QComboBox::currentIndexChanged), this , &AnalysisTool::update_group_values);
126126 connect (ui_->group_left , qOverload<int >(&QComboBox::currentIndexChanged), this , &AnalysisTool::group_changed);
127127 connect (ui_->group_right , qOverload<int >(&QComboBox::currentIndexChanged), this , &AnalysisTool::group_changed);
128128 connect (ui_->group_p_values_checkbox , &QPushButton::clicked, this , &AnalysisTool::group_p_values_clicked);
129129
130+ connect (ui_->pca_group_combo , qOverload<int >(&QComboBox::currentIndexChanged), this ,
131+ &AnalysisTool::update_pca_group_options);
132+ connect (ui_->pca_group_list , &QListWidget::itemChanged, this , &AnalysisTool::handle_pca_group_list_item_changed);
133+
130134 // network analysis
131135 connect (ui_->network_analysis_button , &QPushButton::clicked, this , &AnalysisTool::network_analysis_clicked);
132136 connect (ui_->network_analysis_display , &QCheckBox::stateChanged, this , &AnalysisTool::update_view);
@@ -136,6 +140,8 @@ AnalysisTool::AnalysisTool(Preferences& prefs) : preferences_(prefs) {
136140 connect (ui_->reference_domain , qOverload<int >(&QComboBox::currentIndexChanged), this ,
137141 &AnalysisTool::handle_alignment_changed);
138142
143+ connect (ui_->tabWidget , &QTabWidget::currentChanged, this , &AnalysisTool::handle_tab_changed);
144+
139145 ui_->surface_open_button ->setChecked (false );
140146 ui_->metrics_open_button ->setChecked (false );
141147
@@ -275,6 +281,27 @@ void AnalysisTool::on_reconstructionButton_clicked() {
275281 Q_EMIT progress (15 );
276282}
277283
284+ // ---------------------------------------------------------------------------
285+ QStringList AnalysisTool::get_checked_pca_groups () {
286+ QStringList checked_items;
287+
288+ // Get the number of items in the list
289+ int count = ui_->pca_group_list ->count ();
290+
291+ // Iterate through all items
292+ for (int i = 0 ; i < count; ++i) {
293+ QListWidgetItem* item = ui_->pca_group_list ->item (i);
294+
295+ // Check if the item is checked
296+ if (item && item->checkState () == Qt::Checked) {
297+ // Add the text of the checked item to our list
298+ checked_items.append (item->text ());
299+ }
300+ }
301+
302+ return checked_items;
303+ }
304+
278305// ---------------------------------------------------------------------------
279306int AnalysisTool::get_pca_mode () { return ui_->pcaModeSpinBox ->value () - 1 ; }
280307
@@ -344,7 +371,7 @@ bool AnalysisTool::group_pvalues_valid() {
344371}
345372
346373// ---------------------------------------------------------------------------
347- bool AnalysisTool::groups_on () { return ui_->group_box ->currentText () != " -None-" ; }
374+ bool AnalysisTool::groups_on () { return ui_->group_combo ->currentText () != " -None-" ; }
348375
349376// ---------------------------------------------------------------------------
350377void AnalysisTool::handle_analysis_options () {
@@ -493,7 +520,7 @@ void AnalysisTool::group_p_values_clicked() {
493520// ---------------------------------------------------------------------------
494521void AnalysisTool::network_analysis_clicked () {
495522 network_analysis_job_ =
496- QSharedPointer<NetworkAnalysisJob>::create (session_->get_project (), ui_->group_box ->currentText ().toStdString (),
523+ QSharedPointer<NetworkAnalysisJob>::create (session_->get_project (), ui_->group_combo ->currentText ().toStdString (),
497524 ui_->network_feature ->currentText ().toStdString ());
498525 network_analysis_job_->set_pvalue_of_interest (ui_->network_pvalue_of_interest ->text ().toDouble ());
499526 network_analysis_job_->set_pvalue_threshold (ui_->network_pvalue_threshold ->text ().toDouble ());
@@ -524,11 +551,11 @@ bool AnalysisTool::compute_stats() {
524551 std::vector<Eigen::VectorXd> points;
525552 std::vector<int > group_ids;
526553
527- std::string group_set = ui_->group_box ->currentText ().toStdString ();
554+ std::string group_set = ui_->group_combo ->currentText ().toStdString ();
528555 std::string left_group = ui_->group_left ->currentText ().toStdString ();
529556 std::string right_group = ui_->group_right ->currentText ().toStdString ();
530557
531- bool groups_enabled = groups_active ();
558+ auto pca_groups = get_checked_pca_groups ();
532559
533560 group1_list_.clear ();
534561 group2_list_.clear ();
@@ -571,19 +598,35 @@ bool AnalysisTool::compute_stats() {
571598 if (particles.size () == 0 ) {
572599 continue ; // skip any that don't have particles
573600 }
574- if (groups_enabled ) {
575- auto value = shape->get_subject ()->get_group_value (group_set);
576- if (value == left_group) {
601+ if (groups_active () ) {
602+ auto group = shape->get_subject ()->get_group_value (group_set);
603+ if (group == left_group) {
577604 points.push_back (particles);
578605 group_ids.push_back (1 );
579606 group1_list_.push_back (shape);
580- } else if (value == right_group) {
607+ } else if (group == right_group) {
581608 points.push_back (particles);
582609 group_ids.push_back (2 );
583610 group2_list_.push_back (shape);
584611 } else {
585612 // we don't include it
586613 }
614+ } else if (pca_groups_active ()) {
615+ auto group = shape->get_subject ()->get_group_value (ui_->pca_group_combo ->currentText ().toStdString ());
616+ // see if it is in the list of groups
617+ bool found = false ;
618+ for (auto && pca_group : pca_groups) {
619+ if (group == pca_group.toStdString ()) {
620+ found = true ;
621+ break ;
622+ }
623+ }
624+ if (found) {
625+ points.push_back (particles);
626+ group_ids.push_back (1 );
627+ } else {
628+ // excluded
629+ }
587630 } else {
588631 points.push_back (particles);
589632 group_ids.push_back (1 );
@@ -633,7 +676,7 @@ bool AnalysisTool::compute_stats() {
633676 // / Set this to true to export long format sample data (e.g. for import into R)
634677 const bool export_long_format = false ;
635678
636- if (export_long_format && groups_enabled ) {
679+ if (export_long_format && groups_active () ) {
637680 auto feature_names = session_->get_project ()->get_feature_names ();
638681 std::ofstream file;
639682 file.open (" /tmp/stats.csv" );
@@ -671,6 +714,7 @@ bool AnalysisTool::compute_stats() {
671714// -----------------------------------------------------------------------------
672715Particles AnalysisTool::get_mean_shape_points () {
673716 if (!compute_stats ()) {
717+ std::cerr << " Non buenas, returning empty particles\n " ;
674718 return Particles ();
675719 }
676720
@@ -858,7 +902,8 @@ void AnalysisTool::load_settings() {
858902 ui_->mesh_warp_sample_spinbox ->setValue (params.get (MESH_WARP_TEMPLATE_INDEX, -1 ));
859903 update_group_boxes ();
860904
861- ui_->group_box ->setCurrentText (QString::fromStdString (params.get (" current_group" , " -None-" )));
905+ ui_->group_combo ->setCurrentText (QString::fromStdString (params.get (" current_group" , " -None-" )));
906+ ui_->pca_group_combo ->setCurrentText (QString::fromStdString (params.get (" current_pca_group" , " -None-" )));
862907}
863908
864909// ---------------------------------------------------------------------------
@@ -1383,22 +1428,28 @@ void AnalysisTool::update_group_boxes() {
13831428 auto group_names = session_->get_project ()->get_group_names ();
13841429
13851430 ui_->group_widget ->setEnabled (!group_names.empty ());
1431+ ui_->pca_group_box ->setVisible (!group_names.empty ());
13861432
13871433 if (group_names != current_group_names_) { // only update if different
1388- ui_->group_box ->clear ();
1389- ui_->group_box ->addItem (" -None-" );
1434+ ui_->group_combo ->clear ();
1435+ ui_->pca_group_combo ->clear ();
1436+ ui_->group_combo ->addItem (" -None-" );
1437+ ui_->pca_group_combo ->addItem (" -None-" );
13901438 for (const std::string& group : group_names) {
1391- ui_->group_box ->addItem (QString::fromStdString (group));
1439+ ui_->group_combo ->addItem (QString::fromStdString (group));
1440+ ui_->pca_group_combo ->addItem (QString::fromStdString (group));
13921441 }
1442+
13931443 current_group_names_ = group_names;
13941444 group_changed ();
13951445 }
1446+ update_pca_group_options ();
13961447}
13971448
13981449// ---------------------------------------------------------------------------
13991450void AnalysisTool::update_group_values () {
14001451 block_group_change_ = true ;
1401- auto values = session_->get_project ()->get_group_values (ui_->group_box ->currentText ().toStdString ());
1452+ auto values = session_->get_project ()->get_group_values (ui_->group_combo ->currentText ().toStdString ());
14021453
14031454 if (values != current_group_values_) {
14041455 // populate group values
@@ -1457,6 +1508,45 @@ void AnalysisTool::update_domain_alignment_box() {
14571508 }
14581509}
14591510
1511+ // ---------------------------------------------------------------------------
1512+ void AnalysisTool::update_pca_group_options () {
1513+ auto values = session_->get_project ()->get_group_values (ui_->pca_group_combo ->currentText ().toStdString ());
1514+
1515+ if (values != current_pca_group_values_) {
1516+ // populate group values
1517+ ui_->pca_group_list ->clear ();
1518+ for (const std::string& value : values) {
1519+ QString item = QString::fromStdString (value);
1520+ // add checkable item
1521+ ui_->pca_group_list ->addItem (item);
1522+ auto item_widget = ui_->pca_group_list ->item (ui_->pca_group_list ->count () - 1 );
1523+ item_widget->setFlags (item_widget->flags () | Qt::ItemIsUserCheckable);
1524+ item_widget->setCheckState (Qt::Checked);
1525+ }
1526+ }
1527+
1528+ int count = ui_->pca_group_list ->count ();
1529+ // clamp the items to 2-10
1530+ count = std::max (2 , std::min (count, 10 ));
1531+
1532+ // resize the list widget to fit the items
1533+ ui_->pca_group_list ->setMinimumHeight (ui_->pca_group_list ->sizeHintForRow (0 ) * count + 2 );
1534+ ui_->pca_group_list ->setMaximumHeight (ui_->pca_group_list ->sizeHintForRow (0 ) * count + 2 );
1535+
1536+ current_pca_group_values_ = values;
1537+
1538+ stats_ready_ = false ;
1539+ compute_stats ();
1540+ }
1541+
1542+ // ---------------------------------------------------------------------------
1543+ void AnalysisTool::handle_pca_group_list_item_changed () {
1544+ stats_ready_ = false ;
1545+ compute_stats ();
1546+ // update display
1547+ Q_EMIT update_view ();
1548+ }
1549+
14601550// ---------------------------------------------------------------------------
14611551void AnalysisTool::update_lda_graph () {
14621552 if (groups_active ()) {
@@ -1545,7 +1635,18 @@ bool AnalysisTool::groups_active() {
15451635 return false ;
15461636 }
15471637
1548- std::string group_set = ui_->group_box ->currentText ().toStdString ();
1638+ std::string group_set = ui_->group_combo ->currentText ().toStdString ();
1639+ bool groups_enabled = group_set != " " && group_set != " -None-" ;
1640+ return groups_enabled;
1641+ }
1642+
1643+ // ---------------------------------------------------------------------------
1644+ bool AnalysisTool::pca_groups_active () {
1645+ if (ui_->tabWidget ->currentWidget () != ui_->pca_tab ) {
1646+ return false ;
1647+ }
1648+
1649+ std::string group_set = ui_->pca_group_combo ->currentText ().toStdString ();
15491650 bool groups_enabled = group_set != " " && group_set != " -None-" ;
15501651 return groups_enabled;
15511652}
@@ -1572,44 +1673,6 @@ void AnalysisTool::on_metrics_open_button_toggled() {
15721673 }
15731674}
15741675
1575- // ---------------------------------------------------------------------------
1576- bool AnalysisTool::is_group_active (int shape_index) {
1577- std::string group_set = ui_->group_box ->currentText ().toStdString ();
1578- std::string left_group = ui_->group_left ->currentText ().toStdString ();
1579- std::string right_group = ui_->group_right ->currentText ().toStdString ();
1580-
1581- bool groups_enabled = groups_active ();
1582-
1583- auto shapes = session_->get_non_excluded_shapes ();
1584- auto shape = shapes[shape_index];
1585-
1586- bool left = false ;
1587- bool right = false ;
1588- bool both = true ;
1589- if (ui_->group1_button ->isChecked ()) {
1590- both = false ;
1591- left = true ;
1592- } else if (ui_->group2_button ->isChecked ()) {
1593- both = false ;
1594- right = true ;
1595- }
1596-
1597- if (groups_enabled) {
1598- auto value = shape->get_subject ()->get_group_value (group_set);
1599- if (left && value == left_group) {
1600- return true ;
1601- } else if (right && value == right_group) {
1602- return true ;
1603- } else if (both) {
1604- return true ;
1605- } else {
1606- return false ;
1607- }
1608- }
1609-
1610- return true ;
1611- }
1612-
16131676// ---------------------------------------------------------------------------
16141677void AnalysisTool::initialize_mesh_warper () {
16151678 if (session_->particles_present () && session_->get_groomed_present ()) {
@@ -2007,6 +2070,12 @@ void AnalysisTool::mesh_warp_run_clicked() {
20072070 Q_EMIT reconstruction_complete ();
20082071}
20092072
2073+ // ---------------------------------------------------------------------------
2074+ void AnalysisTool::handle_tab_changed () {
2075+ stats_ready_ = false ;
2076+ compute_stats ();
2077+ }
2078+
20102079// ---------------------------------------------------------------------------
20112080void AnalysisTool::reconstruction_method_changed () {
20122081 ui_->reconstruction_options ->setVisible (ui_->distance_transform_radio_button ->isChecked ());
0 commit comments